mirror of
https://github.com/hanzo-apps/rally.git
synced 2026-10-30 19:07:06 +00:00
Vite + React 19 + @hanzo/gui + @hanzo/iam + @hanzo/base, forked from hanzo-starter. Color-flooded event hero + cream ticket-stub RSVP card; host shell manages the event and guest list. schema.sql provisions the event + rsvps Base collections (org-scoped, IAM-native).
4.5 KiB
4.5 KiB
event-rally — agent notes
Rally is a single-event RSVP page on the Hanzo stack, forked from the canonical
hanzo-starter. Vite + React 19 + @hanzo/gui (UI) + @hanzo/iam (auth) +
@hanzo/base (data). Keep it minimal and REAL — every surface must build and
run, no fabricated UI.
The app
One event, one page. Guests see a color-flooded hero (date · title · place) with a cream ticket-stub RSVP card; hosts sign in to manage it.
- Event page (
views/event.tsx) — public landing: the flooded hero + the ticket stub. Signed out, the stub's CTA is a PKCE sign-in; signed in, it is the live RSVP form. - RSVP (
views/rsvp.tsx) — going / can't-make-it, a guest headcount, and a note → a row in thersvpscollection. - Attendees (
views/attendees.tsx) — host guest list with live counts (heads coming · replied yes · spots left). - Edit (
views/edit.tsx) — host creates/updates the singleeventrow. - Host shell (
views/host.tsx) — the signed-in nav over those three.
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 makes everyuseQuery/useMutationorg-scoped to the signed-in user. - Env is one place (
src/env.ts), read fromimport.meta.env.VITE_*. The IAM client id isVITE_IAM_CLIENT_ID(a per-app client provisioned at deploy; falls back to the sharedhanzo-app). - Look is one place (
src/theme.ts) — a single striking accent over ink, with a cream ticket. Raw hex is used on gui color props deliberately. - UI is one system —
@hanzo/guiprimitives only (no second kit, no Tailwind).
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/borderRadius/textAlign— NOT theitems/justify/bg/p/rounded/textshorthands. Shorthands pass at runtime but FAILtsc.- A
Button's frame is a Stack. It takes stack style props (backgroundColor, border*, height, flex, pressStyle) but NOT text props. Style the label onButton.Text(color/fontSize/fontWeight) — theCtahelper inviews/ui.tsxwraps this once.onPress(not onClick);Inputusesvalue/onChangeTextandinputMode(not RNkeyboardType); multiline text isTextArea, not<Input multiline>;placeholderTextColortakes a color token / CSS name, not raw hex. - 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). Base managesid/created/updated/owner/organd enforces the org rule@request.auth.org_id = org; never re-declare those. Keep it in lockstep withsrc/lib/event.ts+src/lib/rsvp.ts.
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_IAM_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-appevent-rallyclient).
Proven
tsc --noEmit clean · vite build → dist/ · 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).