Files
menu/README.md
T
tanshu 9cb4021229 Serve the customer-facing menus
Landing page, Section pages and archived sets rendered per request from the
store, with the approved design: hand-written CSS, self-hosted Archivo, a
copper pour line in the Section rail, an admin-only Thumbnail and a text page
index. Media is keyed by Page id so URLs survive publishing, and a Draft's
media needs a session. Includes the scrypt admin auth and the login throttle
the media rule needs.
2026-09-22 21:18:49 +05:30

58 lines
2.3 KiB
Markdown

# menu-admin
Uploads, orders and publishes the customer-facing menus of a restaurant Site as
photographed Pages, replacing the `scp`-a-JPG workflow. One instance per Site;
`docs/plan.md` is the agreed design and `CONTEXT.md` is the glossary.
## Status
Built: Site config, the Menu Set store, the image pipeline, and the
customer-facing renderer (landing page, Section pages, archived sets, media
route) with the approved design. Not yet built: the admin, the container and
the Ansible role.
## Layout
```
src/config.ts Site config: brand, theme, Sections, limits
src/storage/manifest.ts Manifest type, validation, atomic JSON writes
src/storage/sets.ts The Menu Set store: create, add Pages, publish, restore, delete
src/storage/validate.ts Boot validation: fatal problems and warnings
src/images/pipeline.ts sharp variants: Original, Viewing image, Thumbnail
src/auth.ts scrypt password hash, signed session cookie, login throttle
src/render/ HTML builder, document shell, the customer pages
src/routes/public.ts Landing, Section, archive and media routes
src/server.ts buildApp (what tests drive) and main (what the container runs)
public/ Hand-written CSS, ~2KB of progressive-enhancement JS, Archivo
config/ Per-Site config, one file per Site
test/ node:test suites
docs/plan.md The agreed plan
docs/adr/ Decisions worth remembering
```
## Working on it
Node 24 or newer runs the TypeScript sources directly.
```sh
npm install
npm test # node:test
npm run typecheck # tsc --noEmit
npm run seed # placeholder Pages in .dev/data, for design review
npm run dev # http://localhost:3000 against .dev
```
## Storage model
```
data/
├── originals/<section>/<set-id>/<page-id>.<hash>.<ext> # kept, never served
├── drafts/<section>/<set-id>/ # manifest.json + variants
└── published/<section>/<slug>/ # manifest.json + variants
```
The directory decides a Menu Set's state; the manifest carries metadata only.
`<slug>` is the valid-until date, else the publication date. The Current Menu
Set for a Section is the published one with the newest `publishedAt`. Published
sets are immutable: changing a menu means publishing a new set.