Skip to content
shiva.wm

tandoori

a bilingual restaurant site with a CMS the owner actually runs

  • owner-run admin CMS
  • DE/EN with field-level fallback
  • EU allergen labeling
  • 22 REST endpoints
activefull-stack product2026 — present

A bilingual (DE/EN) restaurant website backed by a German-language admin CMS. The owner self-manages the menu, opening hours, gallery, page copy, legal text, and a holiday-closure banner, with no code. Built on Next.js 16 (App Router) and React 19 server components, it renders directly from a 14-table SQLite schema via Drizzle (better-sqlite3 in WAL mode, with foreign-key enforcement).

A normalized many-to-many menu-item↔allergen model (composite primary key, ON DELETE CASCADE) backs EU food-labeling disclosure. Field-level DE→EN fallback means partially translated content never renders blank.

Twenty-two REST endpoints drive every mutation, each guarded by Zod validation and server-side iron-session auth, with bcrypt-hashed credentials behind a per-IP login rate limiter. A Sharp pipeline derives thumbnail, medium, and optimized JPEGs per upload, with a size cap, MIME allowlist, and UUID filenames.

German legal compliance is modeled in the data itself: a structured Impressum, editable Datenschutz sections, EU ODR dispute text in both languages, and a policy-correct Restaurant JSON-LD block. It ships with a real deployment story (Next.js standalone under PM2 and nginx, sitemap/robots, hreflang alternates, localized 404s). An 8-dimension automated audit covering security, correctness, GDPR, i18n, SEO, deploy, content, and accessibility triaged 77 findings.

stack
TypeScriptNext.js 16React 19Drizzle ORMbetter-sqlite3iron-sessionZodnext-intlSharpTailwind CSS v4PM2nginx