World Vibe Web
The distributed app store for vibe-coded projects. Browse, discover, and install open-source apps from across GitHub.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Shipped: M0 · M2–M4 · S1–S4 · R1–R9 · J0–J6 · the W-track through W22f + W23 · Option A (A1–A7b) · the polish plan's Phase 0–2 and Phase 3a–3d (part) — M1 🟡 (code done, owner-blocked infra tail) · Next: the live-payments cutover (OPEN-ITEMS C2) and the owner checklist (docs/HANDOFF.md) · Gate: 9346 qr tests + 428 ui tests · 5023 verify:slice mutants · Stack: $0/mo software (Stripe per-txn only)
One Turborepo monorepo for the QR half of the Mandalay Morning Star ordering surface. The delivery PWA is a separate repo (min-hinthar/mandalay-morning-star-delivery-app) — the two share one Stripe account and one design vocabulary, and each runs on its own Supabase project (QR owns its catalog on fasnpdhtvqtzjlvruqcu; delivery stays on ukuzkhuppqwtrdkjqrkv):
apps/qr — the in-store app: Dine-in / Pickup restaurant ordering, Grocery Scan & Go (barcode self-checkout), and the staff/kitchen console. Server-authoritative cart, category-aware CA tax, multi-device group cart, Stripe Payment Element.docs/QR_FROM_DELIVERY.md) instead of absorbing it; co-location is reconsidered at M6.The app began as the productionization of the v7.2 prototype and has outgrown it: docs/DESIGN-LANGUAGE.md is the as-built authority, and v7.2 stays the source for verbatim copy on the surfaces it still covers. The look is editorial warm paper in light + "Night" in dark — glass frost is Night-only and scaled by one data-fx dial on <html> — always bilingual EN + Burmese on one surface, with receipt-language money surfaces and honesty rules (claims data-backed, copy promises only what the code keeps). Read DESIGN-LANGUAGE before any visual, motion or copy work.
graph TD
subgraph apps
Q[apps/qr<br/>dine-in · pickup · grocery · staff]
end
subgraph packages
UI[@mms/ui<br/>tokens · Sheet · primitives · motion hooks]
DB[@mms/db<br/>Supabase clients · generated types · Zod schemas]
CFG[@mms/config<br/>ESLint + Prettier preset]
end
Q --> UI
Q --> DB
Q --> CFG
DB --> SUPA[(Supabase<br/>Postgres + RLS + Realtime)]
Q --> STRIPE[[Stripe<br/>PaymentIntent + webhook]]
Q --> RESEND[[Resend<br/>receipt + staff email]]
Q --> PH[[PostHog<br/>funnel · flags]]
D[delivery PWA<br/>separate repo] -. shares Stripe + design vocabulary .-> Q
Order → pay (server-authoritative):
sequenceDiagram
participant C as Client (apps/qr)
participant S as Server Action / Route
participant DB as Supabase (RLS)
participant ST as Stripe
C->>S: addItem(cartId, itemId, mods) %% never a price
S->>DB: re-derive price + category-aware tax, write cart_item
C->>S: POST /api/stripe/create-intent (cartId, tip)
S->>DB: getCartTotals() → server amount
S->>ST: PaymentIntent(amount) → clientSecret
C->>ST: Payment Element (Apple/Google Pay, card) %% PAN stays in Stripe
ST-->>S: webhook payment_intent.succeeded (signed, idempotent)
S->>DB: mms_fulfill_order() → order snapshot, gems
The client never computes a price; the server re-derives every amount from the menu row + validated modifiers. Group ordering rides private Supabase Realtime channels authorized by RLS off a short-lived table-session JWT. Full spec in docs/ARCHITECTURE.md.
| Workspace | What | Status |
|---|---|---|
apps/qr | QR dine-in/pickup + grocery scan-and-go, and the staff/kitchen console | ✅ live — see What it does today |
@mms/ui | tokens (light + Night, the data-fx dial) and the primitives, motion and gesture hooks — packages/ui/src/index.ts | ✅ in use |
@mms/db | Supabase clients (browser/server/service) · generated types · Zod schemas — migrations live in supabase/migrations/ | ✅ in use |
@mms/config | the shared ESLint + Prettier preset every workspace extends | ✅ in use |
| (delivery PWA) | its own repo — QR only learns from it (M5 reshaped 2026-06-24) | ↗ mandalay-morning-star-delivery-app |
Diner (dine-in · pickup) — browse first: a toolbar-first menu (search, categories, dietary filters in a sheet behind one chip, the free-from disclaimer travelling with them) and ONE static picks row with three lenses — your favorites, Most ordered (POS-backed, a set never a rank) and an honest Surprise draw. The Menu · Order · Account spine follows the order (Phase 3a/3b); the Bill reads as a receipt with one hero verb per state and a server-clocked Undo after Send (3c-i); dine-in asks for the table once, inside the first Send (3c-ii). Group cart + host lock · promo codes · honest pickup slots · Morning Star Rewards · order history + "Order again" · ungated feedback. Detail: docs/PHASE3_JOURNEYS.md and DESIGN-LANGUAGE §21–§27 · §30–§33.
Staff & kitchen — five screens (Kitchen · Counter & tables · Menu · Tips · Sign-in, A4) plus the order pad, the order-ready board (/board) and the glossary. Burmese / Both / English per device (2e); counter orders cook before they are paid (2f); a stuck tablet never traps staff (2h); new builds land without losing work (2i). Tips reporting shows an unattributable settle as a shared bucket, never an invented per-head split.
Grocery Scan & Go — phone-camera barcode scanning (native BarcodeDetector + @zxing fallback), a UPC catalog, category-aware tax (food exempt / retail taxable) and EBT-eligibility tags (SNAP checkout = 2027 via Forage). The market's next phase waits on real shelf UPCs and price confirmation (OPEN-ITEMS C6). Spec: docs/context/SPEC-GROCERY.md · docs/GROCERY_MARKET_PLAN.md.
Receipts, email & live tracking — one identity module (apps/qr/lib/brand.ts), one tracked-order shape and one receipt derivation feed the durable receipt, the receipt email and /track; every money row is the fulfillment-time snapshot rendered verbatim, and a refunded order never reads "Paid in full" (DESIGN-LANGUAGE §8 · §10).
Platform — server-authoritative cart + pricing · category-aware CA tax (one 10.5% Covina rate; CDTFA Reg 1603/80-80 decides what is taxable — hot/prepared + retail always, cold food dine-in only, grocery staples exempt — TS lib/tax.ts and SQL mms_line_tax pinned in parity by tests) · Stripe Payment Element (SAQ-A) · multi-device group cart (Realtime + RLS) · PostHog funnel · CSP/security headers · WCAG 2.2 AA.
Parked in production (SURFACES in apps/qr/lib/surfaces.ts, Option A · A1) — self-serve split pay across phones, card-on-file tabs and the kiosk. Their code and mutants stay; no screen offers the door and the server refuses it. A dine-in guest can also ask to pay at the counter (A1), where staff settle by cash or Terminal (A3). Planned: PD2 puts phone pay on the dine-in Bill behind its own switch until live card keys (OPEN-ITEMS C2).
The steps a guest takes today, in the words the screens use. Open the app at
qr.mandalaymorningstar.com or scan a QR code at the restaurant. The home screen has three doors:
Dine-in, To-go and Grocery. The menu, the buttons and the order screens show English and Burmese together (a few newer lines, like the first-visit guide, are English for now).
Dine-in at a table
To-go (pickup)
Grocery
Stars, receipts and help
For the team: card payments run on Stripe test keys until the live cutover (OPEN-ITEMS C2), so no real card money moves today. The grocery catalog still needs real shelf codes and confirmed prices (C6). The draft customer posts are in
docs/marketing/SOCIAL_POSTS_2026-10-18.md.
Tracked in ROADMAP.md (milestones → phases → tasks), the single open-work registry docs/OPEN-ITEMS.md, and the pickup point docs/HANDOFF.md. Changelog: CHANGELOG.md.
| Milestone | Scope | State |
|---|---|---|
| M0 Scaffold | monorepo, RLS migration, tax fn, server cart, Stripe routes, Realtime hook, grocery scan, CI | ✅ done |
| M1 Walking pay path | sign table-session JWT · Payment Element + cart-create · authz Server Actions · webhook reconcile · nonce CSP | 🟡 P1.0–P1.6 ✅ (owner-blocked infra left) |
| M2 Tax + promos + scheduling | server promos · honest pickup slots · grocery sessions · QBO sync | ✅ P2.1–P2.4 |
| M3 Group cart | table session + RLS + Realtime presence + host lock (multi-device) · split-tender · abuse limits | ✅ done |
| M4 Rewards & account | Morning Star Rewards (QR-local, mirrors delivery's ladder) · redemption · history/reorder · ungated feedback | ✅ P4.1–P4.3 |
| M5 QR learns from delivery | repos stay separate (reshaped 2026-06-24) — adopt delivery's mobile/a11y/motion patterns + shared primitives | 🟡 |
| M6 Kiosk + EBT (2027) | kiosk shell · Forage EBT — Stripe Terminal was pulled forward and shipped as W6c | ⏸ |
| Tracks S · R · J · W | S1–S4 service model · R1–R9 richness · J0–J6 journey · W5–W23 polish arcs (W22d's light half open, M86) | ✅ through W22f + W23 |
| Option A subtract to the core | park split pay · card-on-file tabs · kiosk; settlement = cash + Terminal; /staff to five screens | ✅ A1–A7b |
| Polish plan Phase 0 → 4 | design system in code · the guest flow · staff · the journeys · production signals | 🟡 0–2 ✅ · 3a–3d (part) ✅ · 3e/3f/4 ⬜ |
| Path designs PD1–PD13 | the owner's picks, 2026-10-07 — docs/PATH_DESIGN_2026-10-07.md | ✅ PD1–PD12 built (#326–#348) · PD13 gated |
Done means the definition in docs/WORKFLOW.md §Definition of done (with CLAUDE.md's "Gate before done"). Start any session with docs/HANDOFF.md, then docs/context/INDEX.md.
Next.js 16 (App Router, RSC, Server Actions) · React 19 · TypeScript strict · Tailwind v4 · Turborepo + pnpm · Supabase (Postgres · RLS · Realtime · Auth) · Stripe (Payment Element + webhooks) · Resend + React Email · framer-motion · next-view-transitions · Zustand · Serwist (PWA) · PostHog (free tier) · Radix UI · @number-flow/react (re-exported from @mms/ui) · @zxing/library · Vitest. The $0/month free stack is documented in docs/context/FREE-KIT-MAP.md.
corepack enable && corepack prepare [email protected] --activate # Node >= 22.13 (pnpm 11's floor; CI runs 24)
pnpm install
supabase start # a LOCAL stack (Docker): applies every migration + supabase/seed.sql, as CI does
cp .env.example apps/qr/.env.local # point the Supabase vars at the URL/keys `supabase start` printed; Stripe test keys
pnpm dev # apps/qr on http://localhost:3000
⚠️ Never supabase db push or SQL-editor DDL against the QR project. Prod's migration history is divergent from this repo (OPEN-ITEMS M125), and preview shares that one project. A prod migration is applied ONE file at a time with the Supabase MCP apply_migration, on the owner's go, verifying the objects that file creates before the next — see CLAUDE.md § Commands.
pnpm turbo lint typecheck build test # CI's build job
pnpm check:docs # GFM table parity + live-state counts measured, never transcribed
pnpm verify:slice --no-gate --only=<module> # each money/authority module you touched — the pre-push step
pnpm verify:slice --list --only=<module> # what a filter selects, without running anything
The full mutation battery runs in CI as the verify-slice check: 12 cost-balanced shards on every non-draft PR head and every push to main, code lane only — about 10.5–11 min wall after the changes job, measured 2026-10-08. A full serial local run measured 164–180 min, so it is not the pre-PR step. Only CAUGHT passes: a SURVIVING mutant means the fixture is degenerate, not that the mutant is wrong — find inputs that separate the two code paths; a STALE mutant is a failure too, not a skip; a TIMEOUT or ERROR is never a kill. Never re-run a red verify-slice hoping for green: a mutant that SURVIVES on one run and is CAUGHT on another of the same tree is a suite defect — fix the read, red-first (LEARNINGS #248).
⚠️ verify:slice rewrites the 412 money/authority modules it mutates IN PLACE (277 under apps/qr/lib) and restores them. It aborts on a dirty target; run ONE per checkout and never commit while a run is live (LEARNINGS #74). After a stalled or killed run: kill all runs; git status --short names the module left mutated — restore it with git checkout -- <file> and confirm clean. Check for a live run with ps -eo pid,comm,args | awk '$2=="node" && /verify-slice\.mjs/' (not pgrep -f — LEARNINGS #92), and list the target files with grep -oE '^\s+file: "[^"]+"' scripts/verify-slice.mjs | sort -u — that command, not a prose list, is the record of what a killed run may leave broken.
QR runs on its own Supabase project (fasnpdhtvqtzjlvruqcu) and shares the Stripe account with the delivery app. Manage keys per environment (docs/ENV.md is the wiring map):
| Supabase | Stripe | |
|---|---|---|
Production (Vercel main) | the QR project · service-role + SUPABASE_JWT_SECRET (server-only) | test keys today (C2, measured 2026-09-07: livemode: false); live sk_live_… only at C2's cutover (ruling #8) · the QR app's own webhook endpoint → its own whsec_… |
| Preview (PRs) | the same QR project — one project for dev + preview + prod; staging is deferred (T3) | test keys sk_test_… · test webhook secret |
| Local | a supabase start stack: fill .env.example's placeholders with the URL/keys it prints (never the QR project's — that is prod data) | test keys · stripe listen prints a temporary webhook secret |
Two rules:
supabase db push, no SQL-editor DDL. Apply ONE migration file at a time with the Supabase MCP apply_migration on the owner's go, verify the objects it creates, then the next; reconciling the two histories is M125. Migrations live in supabase/migrations/.menu_categories/menu_items/modifier_*/grocery_items (with tax_category as a column), seeded from supabase/seed.sql. Loyalty / account-link with the delivery side is an M4 concern, not a shared-DB dependency.Set values in Vercel → Project → Settings → Environment Variables (scoped Production/Preview/Development) and never commit them (.gitignore excludes .env*). Full list in .env.example.
One Vercel project, Root Directory = apps/qr — the only app in this repo (the delivery PWA deploys from its own). apps/qr/vercel.json's turbo-ignore skips a build when the app didn't change, and its regions pin the functions to pdx1 (C27). Push to main = production; every PR = a preview URL.
| Workflow | Trigger | Does |
|---|---|---|
ci.yml | PR / push | a changes job picks the lanes (diagram below); a push to main runs every lane |
require-docs-update.yml | PR | require-docs — a PR touching apps/** or packages/** must also touch docs/**, CHANGELOG.md, ROADMAP.md or README.md (or skip-docs) |
ensure-preview.yml | PR | safety net — force a Vercel preview if the GitHub→Vercel webhook drops the commit |
require-codex-review.yml | PR | codex-review — RED until Codex has reviewed the PR's current head; drafts stand down |
changes ─┬─ docs docs-only PR: check:docs + format:check
├─ build code lane: the fast lane + lint/typecheck/build/test
├─ migrations-check + types-fresh sql lane: migrations, types-fresh, SQL tests, race harnesses
└─ verify-slice shard ×12 ─ verify-slice code lane, non-draft heads + main pushes
Read the fast lane's steps in ci.yml itself; never count them in prose. A draft's verify-slice is RED on purpose ("not run — DRAFT"); a docs-only PR's is green ("not run — docs-only lane").
Required checks to wire (OPEN-ITEMS C28): codex-review, verify-slice, build, migrations-check + types-fresh, docs, require-docs — never a verify-slice shard leg, publish-codex-verdict, the retired codex-reviewed, Supabase Preview or Vercel Preview Comments. Keep admin bypass available and do not require Code Owner review (the sole code owner authors every PR and cannot approve their own). None is enforced yet: measured 2026-10-08 with an admin-scoped token, /branches/main/protection answers 404 and no ruleset exists, so every check is advisory until a re-measure shows the rule (C16 · C28).
The review is in-session, not in CI. ONE capped blind adversarial pass per PR over the full PR diff (pnpm review:bundle → the adversarial-auditor agent; ≤3 lenses, ≤10 agents, ~15 min) runs in parallel with the verify-slice check, its verdict posted as a PR comment. Codex reviews too: @codex review on the draft, two triaged rounds, fix-or-justify, round 3+ to OPEN-ITEMS. Merge only a head whose codex-review says "Codex has reviewed" it (unless Codex's usage-limit reply is on that head: then WORKFLOW step 5 (g)) AND whose verify-slice is green — mark-ready and merge are never one motion, and a pushed fix is a new head that waits again. codex-review proves a review EXISTS on the head, never that anyone read it; and until the checks are required, only that ritual enforces the wait — #241 was merged eleven seconds after it went red. Normative copy: docs/WORKFLOW.md §Review, step 5.
Codex out of quota (owner, 2026-10-08). When Codex answers with its usage-limit message, the capped blind review of the EXACT head stands in: its verdict is posted on the PR naming that SHA, with verify-slice and the rest of CI green on it, and the OWNER merges that head with GitHub's admin bypass, by hand. An agent never merges a head whose codex-review is red (the .md-only waiver, under the conditions in WORKFLOW §Review step 5 (f), is the one exception) — even though its admin-scoped token could — and never automates the bypass. The bypass covers a red codex-review only (WORKFLOW §Review step 5 (g), which also holds the owner's ruling for a fix pushed after the capped pass: one more capped pass over those fix commits — "Yes one more", 2026-10-08).
Quality: ESLint + Prettier + knip via the shared @mms/config preset (pnpm lint / pnpm format / pnpm knip). Claude Code is configured by CLAUDE.md + .claude/ — settings, a post-edit auto-format hook, session-memory hooks, LEARNINGS / ERROR_HISTORY, the adversarial-auditor agent and the design-prototyping skill (the standard design-thinking loop). ⚠️ .mcp.json's Supabase entry points at the QR project (fasnpdhtvqtzjlvruqcu; the owner, 2026-10-08) and its GitHub/Sentry entries use the Windows-only npx.cmd — a session can load another MCP config, so confirm the target project (e.g. get_project_url) before any MCP write. Contributing + templates: .github/.
Server-authoritative pricing (no client-trusted amounts) · Supabase RLS on every table + private Realtime · Stripe PCI SAQ-A (PAN only in Stripe's iframe) · server-validated promos · CSP/security headers · SB-1524 disclosure wherever a fee row shows (the service charge itself was retired in W16a) · never surcharge debit · EBT/SNAP deferred to 2027 (Forage + FNS, 50%-rule). The acceptance gate: docs/context/QA-CHECKLIST.md — tick the items a change touches in its PR body.
Start here: docs/HANDOFF.md (the pickup point) · docs/OPEN-ITEMS.md (the single open-work registry) · docs/WORKFLOW.md (the loop and the merge ritual) · docs/OWNER_RULINGS_2026-10-07.md (the owner's binding rulings) · docs/context/INDEX.md (decisions · rubric · QA gate · red-team · v7.2 prototype)
Every docs file, one line each, grouped: docs/README.md. History: ROADMAP.md · CHANGELOG.md
Proprietary © Mandalay Morning Star LLC. The repo is public for free CI/Actions and transparency; the code is not licensed for reuse.