mirror of
https://github.com/hanzo-apps/bistro.git
synced 2026-10-30 19:25:24 +00:00
4.6 KiB
4.6 KiB
bistro-site — agent notes
Ember — a warm restaurant website (home · menu · reservations) built on the
canonical Hanzo app stack: Vite + React 19 + @hanzo/gui (UI) + @hanzo/iam
(auth) + @hanzo/base (data). A distinct, real app forked from hanzo-starter;
the provider stack, vite.config.ts, auth, and deploy contract are unchanged —
only the views, schema, and palette differ. Keep it REAL — every surface builds
and runs, no fabricated UI.
One way, decomplected
- Providers (
src/providers.tsx) mount in the canonical order every Hanzo surface ships:GuiProvider→IamProvider→BaseProvider.BaseProvidergets aBaseClientcarrying the IAM access token; it is rebuilt when the token changes (src/lib/base.tsbaseAs). That single seam is what makes everyuseQuery/useMutationorg-scoped to the signed-in user. - The site is public (
src/app.tsx) — anyone browses home · menu · reservations (auseStateview value, no router). Signing in with Hanzo unlocks the org-scoped Base surfaces: publishing the live menu and reading reservation requests. - Env is one place (
src/env.ts), read fromimport.meta.env.VITE_*. - Palette is one place (
src/theme.ts) — the ember-and-cream identity, painted directly viabackgroundColor/color/LinearGradient(raw color strings) so the look is independent of the gui base theme. - UI is one system —
@hanzo/guiprimitives only (no second kit, no Tailwind). One button wrapper (src/ui.tsxBtn) forwards frame props toButtonand renders the label as a coloredSizableTextchild.
Gotchas (do not regress)
@hanzo/guiunder Vite needs three things invite.config.ts(it is the Tamagui line; the in-browser builder runtime can't do this, which is the whole reason this ships as a real repo): (1) aliasreact-native→react-native-web, (2)defineprocess.env.TAMAGUI_TARGET/NODE_ENV/__DEV__, (3)dedupereact/react-dom/react-native-web. No Tamagui compiler, noone, no Expo — the optimizer is a perf pass, not a correctness one.@hanzo/guiprops are Tamagui LONGHAND with this v5 config:alignItems/justifyContent/backgroundColor/padding/alignSelf/borderRadius/textAlign— NOT theitems/justify/bg/p/self/rounded/textshorthands. Shorthands pass at runtime but FAILtsc.Buttonis a Stack — it takes background/border/hover props but NOT textcolor/fontWeight(those are text props). Route every button throughBtn(src/ui.tsx), which puts the label in aSizableText.ButtonusesonPress;Inputusesvalue/onChangeText.- PKCE storage is
localStorage(not sessionStorage) so the verifier/state survive the round-trip to hanzo.id. schema.sqlis the data contract. It is thedatabaseSchemaDDL the deploy translates into Base collections (provisionBaseFromDDL). Keep it in lockstep withsrc/views/menu.tsx(menu_items) andsrc/views/reservations.tsx(reservations).
Data model (schema.sql)
menu_items(section, name, price, desc)— the dining carte, grouped bysection. The Menu view reads it; a signed-in owner publishes dishes. Until the collection has rows, the view shows the house menu as its empty state.reservations(name, party, when)— reservation requests. The form writes a row (sending requires sign-in — the row is stamped to the caller's org); signed-in, the view lists your requests.- Both are org-scoped: Base stamps
owner+organd every rule is@request.auth.org_id = org, so a teammate in your org sees the row and other orgs cannot.
Deploy contract (Hanzo Cloud)
- Static SPA:
npm run build→dist/, served at<slug>.hanzo.appfrom object storage (the*.hanzo.apppublished-sites edge). No server process. - On publish,
schema.sql→provisionBaseFromDDLcreates the collections (org-scoped, IAM-native). Runtime read/write is browser →VITE_HANZO_BASE_URLwith the IAM token. - IAM redirect registration is the one external requirement: the IAM client
(
VITE_HANZO_CLIENT_ID, defaulthanzo-app) must allow this origin's/auth/callback. Production needs ahttps://*.hanzo.app/auth/callbackwildcard on the shared client (or a per-apphanzo-bistro-siteclient).
Proven
tsc --noEmit clean · vite build → dist/ · renders under Vite with zero
console errors · login() performs a real PKCE S256 redirect to hanzo.id.
Build
CI (.github/workflows/ci.yml) runs npm ci && npm run typecheck && npm run build — build-verification only, NEVER a container image (Hanzo Cloud owns
deploys; do not build images locally).