Wedding planning · build status

VELA

A Hungarian-first wedding planner on top of a supplier marketplace. The ledger below is the authority; this page is generated from it.

generated 2026-08-03 20:43 UTC tree f0ddcc9 (uncommitted changes present) 27 slices from docs/BUILD-LEDGER.md

Overall

67%complete
18 complete4 in progress5 not started 27 total

Phases

Cross-product couplings and the site

V1 – V24 · 27 slices

18 complete · 4 in progress · 5 not started

Every module

SliceNameStatusThe ledger’s note
Cross-product couplings and the site
V1FoundationcompleteNext 15 App Router on Cloudflare Workers via OpenNext, Drizzle, Neon Postgres, Wrangler deploy. Five custom domains on one Worker
V2Identity and sessionscompleteidentity.user, identity.session, hashed session tokens, actorForWedding resolving owner or collaborator
V3Authorisationcomplete@vela/auth can() over typed resources. Every server action re-checks — a page's check is not inherited
V4Copy cataloguecompletecontent.message is the render-time source of truth, not the seed files. ICU MessageFormat, market-scoped keys, machine status renders
V5Hungarian couple lenscompleteEvery non-operator surface localised. 1 314 keys, 1 169 messages
V6Couple overview and plancompleteCountdown, health signals with a severity reduce, task timeline
V7Guests and householdscompleteHouseholds that split, plus-ones, child/infant/adult, side, dietary
V8RSVPcompleteTokenised per-household links, no login, Hungarian-first
V9InvitationscompleteCompose, send, track. Real mail through the Worker
V10SeatingcompleteTables, drag-and-drop assignment, per-guest seating so a household can split, printing, capacity fit at 90% = tight
V11AccommodationcompleteRoom blocks held not booked; release date is the loudest thing on the page. StayProvider seam for RateHawk / Booking.com
V12Marketplace (in-wedding)partialVenues and suppliers by region, photos, demo labelling on the row. Session-gated — no public surface exists
V13event.clinic directory clientcomplete@vela/directory, three-state result (ok with items / ok empty / unavailable). Shape-checked, not cast
V14Enquiry flowcompleteCouple → supplier enquiry. Demo listings refuse at the write, not only in the UI
V15Supplier replypartialTokenised link matching event.clinic's method: written reply, yes/no on the date, price range, visit date, attachments. No supplier inbox, so seen and replied are unreachable states
V16Enquiry emailcompleteBrevo-backed send so the reply link actually arrives
V17BudgetcompleteFour kinds kept apart, spend rows always add, per-category rollup, uncosted categories named. Verified at 4 690 000 Ft against the database
V18Astro site typecheckcomplete@astrojs/check had never once run — neither it nor typescript was installed. 7 errors found and fixed; astro check now gates verify
V19Couple-lens leak harnesscompleteDrives the real server, signs in, sweeps rendered HTML for professional vocabulary. Coverage guard fails by name if a route is unswept
V20Revenue modelschema onlybilling: vendor accounts, plans, subscriptions, agreements, placements, credit ledger, one append-only revenue_event. Nothing reads or writes it yet
V21Public marketplacenot startedThe SEO surface and the whole acquisition story. Own route group — app/(marketing)/ belongs to another batch
V22Taxonomy expansionnot started14 → ~28 categories, market-scoped. Missing: szertartásvezető, vőfély, anyakönyvi hivatal, meghívó, nászút, ruha, táncoktatás
V23Accept a quotenot startedWhere four axes of the mesh meet: fills a need, closes a task, writes a budget commitment, accrues commission. Highest-value thing outstanding
V24Supplier inboxnot startedWithout it V15 cannot complete and lead credits cannot be metered
V-ECevent.clinic directorypartialReal venues now published, but venue_type, capacity_max_pax and overview are null on every row — their plan is import-first-then-AI. VELA can show geography and photographs only until Phase B
V-SITEMarketing site (apps/site)completeAstro, 15 pages, 78 tests, font-coverage and HTML checks in verify
V-MKTGIn-app marketing routesnot startedapp/(marketing)/ is owned by a separate batch. Hands off

What “done” means here

Done means a verification script exited zero on the committed tree. Not that somebody opened the screen and it looked right, and not that an agent reported success. Every slice marked complete above has a script in scripts/ that exits 0 against the code as committed; a slice whose script has not exited 0 in a single run is not complete here, whatever else was built. pnpm verify does NOT run the couple-lens leak sweep — that needs a running server and a local database, and it refuses a remote URL because it mints a session.

Run every gate at once:
pnpm verify

Run it locally

# 1 · the app (Next dev; pick a free port)
cd ~/Documents/wedding/vela/apps/app && DATABASE_URL="postgresql://localhost:5433/vela_dev" pnpm exec next dev -p 5185
# 2 · marketing site (optional)
cd ~/Documents/wedding/vela/apps/site && pnpm dev
# prove the tree before believing any status above
cd ~/Documents/wedding/vela && pnpm verify
# sweep the couple lens for English leaks and non-200s
DATABASE_URL="postgresql://localhost:5433/vela_dev" VELA_BASE_URL="http://localhost:5185" pnpm --filter @vela/app verify:couple-lens

Every couple route needs a signed-in session AND a wedding id, which is exactly the problem V21 exists to fix. Reach them by seeding (pnpm db:seed) and signing in as couple@vela.example; the ids below come from wedding.wedding_project.

Screens with data

Screen
Open at
What is on it
Overview
landing
/wedding/<id>
Countdown, health signals, what needs attention
Plan
list
/wedding/<id>/plan
The task timeline
★ Budget
signature
/wedding/<id>/budget
Four kinds of money kept apart; rows always add
Guests
list + detail
/wedding/<id>/guests
Households that split, plus-ones, dietary
★ Seating
signature
/wedding/<id>/seating
Drag-and-drop, per-guest so a household can split, printable
Stays
list
/wedding/<id>/stays
Room blocks held not booked; release date is the deadline that costs money
Market
list
/wedding/<id>/market
Venues and suppliers — session-gated, which V21 fixes
Booking
list
/wedding/<id>/booking
Enquiries sent and their replies
Day / Legal / Help
list
/wedding/<id>/day
Running order, Hungarian legal prose, ask a question
RSVP
needs a token
in-app navigation
Tokenised, no login. Open from a household in Guests
Supplier reply
needs a token
/reply/<token>
Tokenised, no login. Arrives by email when an enquiry is sent