PProvenance by Ascend Systems

Build plan

Schema, application pages, and website pages. The database is written and tested; everything else here is the inventory to build against it. Phase tags match the PRD.

Aug 5, 2026v1Charcoal + Carolina locked

Three things exist on disk now: the D1 schema, the design tokens, and this plan. The schema is not a sketch. It applies cleanly to SQLite 3.51 and the derived logic has been smoke-tested, including the case most likely to be wrong.

01

Schema

21 tables, 4 views. Applied and tested.
db/0001_core.sql orgs, users, org_members, properties, rooms, property_access, room_state_events, client_mutations db/0002_inspections.sql templates, sections, items, inspections, inspection_rooms, inspection_results, deficiencies, photos db/0003_vendors_inventory.sql vendors, work_orders, vendor_contacts, inventory_items, inventory_counts app/tokens.css the locked design system, contrast figures in comments

Four design rules are enforced in the database rather than left to application code, because application code drifts and a schema does not.

RuleHow it is enforced
Room state is append-only room_state_events is never updated or deleted. A correction is a new row pointing at the old one via supersedes_id. Current state comes from the room_current_state view. Days-down is derived, never typed in.
N/A never counts as a failure The inspection_scores view puts only pass and fail in the denominator. Verified: 2 pass, 1 fail, 1 N/A returns 66.7%, not 50%.
History cannot be rewritten inspection_results stores frozen snapshots of the item text, section name and criticality. Editing a template next year cannot change last year's score.
Offline replay is idempotent client_mutations is keyed on a UUID the device mints before it has network. A second sync of the same queue is a no-op, not a duplicate inspection.
Verified end to end, not assumed

All three migrations apply cleanly. The scoring view returns 66.7% on a 2-pass / 1-fail / 1-N/A inspection and flags the critical failure. A room taken out of order at 09:02 on Aug 5 and returned at 14:00 on Aug 8 derives 3.21 room-nights down, which against the seeded ADR of $129.66 produces $415.81 revenue at risk. That number was computed by the database, not by me.

The one number the product must never invent

properties.adr_cents is deliberately nullable. When a pilot property will not share ADR, the record shows room-nights only and says so. There is a dedicated .figure__unavailable style for exactly this. A fabricated dollar figure on a document a lender might read would end the product, so the honest empty state is designed rather than improvised.

02

Application pages

Field is phone-first. Record is desktop and print.

Field surface — charcoal, one-handed, offline. Everything a tech or GM touches on property.

RoutePhaseWhat it does
/loginP0Server-side session auth. The page is gated, not just the action.
/P0Today. Property picker with last score, or straight into the single property a tech can see.
/inspect/newP0Pick property and template, choose which rooms to sample.
/inspect/:idP0Walk & Tap. Property-scope sections. Assume-pass, live score, 44px targets.
/inspect/:id/room/:roomIdP0Room-scope sections, swipe room to room.
/inspect/:id/reviewP0Score by section, deficiency list, submit. Last stop before it becomes a record.
/roomsP0Room status board. Mark out of order with a reason; the clock starts.
/rooms/:idP0Room detail and full state history. Return to service requires a resolution note.
/deficienciesP0The punch-list. Filter by property, room, status.
/deficiencies/:idP1Detail, photo, assign, and the vendor call action.
/vendorsP1Directory by trade. Tap-to-call via the device dialer. No telephony vendor.
/vendors/:idP1Vendor detail and full contact history.
/inventoryP2Count entry and the below-par reorder list, linked to vendors.

Record surface — white, printable. What the owner, and eventually their lender, reads.

RoutePhaseWhat it does
/portfolioP1All properties: latest score, 6-month trend, delta, open items, last walked.
/property/:idP0Property dashboard. Rooms down now, open deficiencies, score trend.
/property/:id/record/:periodP0The Condition Record. The product. Revenue at risk with its arithmetic shown, rooms down, median days down, score. Prints to one page.
/vendors/performanceP1Vendor accountability. Suppresses any vendor under 5 completed jobs and says why.
/inspections/:idP0A single completed inspection, read-only, with photos.
/capital/:yearP3Capital & renovation plan. Refuses to render under 12 months of data.
/admin/*P1Properties, rooms, users, access, templates.
Build order inside P0

Offline capture first, not last. The service worker and the IndexedDB replay queue are the only genuinely hard engineering in this phase; everything else is forms over a database. Building it last is how a project discovers in week six that its data model cannot survive a dead zone.

Suggested sequence: offline queue → Walk & Tap → room state → punch-list → the Record. The Record comes last because it is the easiest to build and the most satisfying to demo, and it is worth nothing if the capture underneath it is not trustworthy.

03

Website pages

Marketing. Sells to owners and to management companies.

Two audiences, and they want different things. An owner wants to know what it recovers. A management company wants to know what it proves to the owners they answer to.

RoutePhaseJob of the page
/P0One promise: know what your property is costing you while it sits out of order. Hero is a real Condition Record, not an illustration.
/how-it-worksP0The loop in four steps: walk, flag, fix, report. Show the actual phone screens.
/for-ownersP1Revenue at risk, vendor accountability, and what you hand a lender at refinance.
/for-management-companiesP1Portfolio rollup and the reporting artifact you give the owners you answer to.
/the-recordP1The differentiator page. What a Condition Record is, why it compounds, and why it needs a year of data.
/pricingP1Platform fee plus per property. Numbers wait for the pricing pass.
/aboutP0Brian and Mandeep. Operator credibility plus build credibility. Endorsed by Ascend Systems.
/demoP0Single form. The only conversion point on the site during pilot.
/legal/privacyP0Required. Guest-adjacent data and photos of private property are involved.
/legal/termsP0Required before any pilot agreement is signed.
A pilot-stage site should not oversell

Nothing on the site may claim the capital report exists until it does. During the free pilot the honest position is the strong one: we are collecting the record now because the report that matters needs a year behind it. That is also the argument that creates urgency to start.

04

What I need from you

Everything else can proceed without waiting.
DomainNothing is registered. roomprovenance.com, provenanceportfolio.com and provenance.management were confirmed available earlier today, but availability moves. Your card, your call.
TrademarkStill unsearched. It does not block the prototype. It does block spending on identity or signage.
ADR for the pilotsAsk Mandeep whether the pilot properties will share it. It decides whether the flagship report shows dollars or room-nights.
CloudflareThe cloudflare-api connector is not authorised in this session, so I cannot create the D1 database or R2 bucket for you. Authorise it in your claude.ai connector settings, or run wrangler d1 create provenance and wrangler r2 bucket create provenance-photos yourself and paste me the database id.