Foundry phase 03 · App Router build
Seven lads, one Istanbul, no arguments about money.
Every screen runs the real split, FX and settlement arithmetic. Data is held in memory for now — Postgres, join-code auth and the live geocoders arrive in phase 4.
Screens
- 01Join
Trip code plus display name. The only unauthenticated route. - 02Map
Leaflet and OSM, every location pinned, category filters, add a location. - 03Vote
One vote per member per location. Change it and the score moves in place. - 04Itinerary
Version 1 is the operator plan, fully pinned. Version history is browsable. - 05Results
Tallies, category breakdown, who has voted, spend and balances. - 06Costs
GBP or TRY at an agreed rate, reversing entries, settle-up in at most six transfers.
What is real here
- Money is integer minor units end to end. No float touches an amount until it is rendered.
- FX runs through an integer
rate_microscaptured per expense, so a later rate change cannot rewrite a recorded one. - Equal split allocates the remainder deterministically, and a reversing entry cancels its original share for share.
- Settlement is greedy cash flow. It zeroes every balance in at most six transfers for seven members — that bound is the guarantee, not a claim of the smallest possible set.
- A negative score ranks a location lower. Nothing is filtered out.
- The itinerary generator runs live: pins first, then descending score, ties broken by distance then id.
What is stubbed
- No Postgres, so no append-only triggers and no server-side session. Vote state lives in
localStorage. - Join takes any code. There is no argon2id hash, no cookie and no rate limit behind it yet.
- Nominatim, Overpass and SearXNG are canned fixtures. The map tile layer is the one genuine outbound call.
- Seed coordinates are hand-placed. The real seed resolves them once and commits
fixtures/base-itinerary.json.