A pragmatic architecture for a small team shipping fast without painting into a corner. Integration-first, one source of truth, the hard computer-vision isolated from everything else — and a build order that earns revenue while the moat matures.
Every surface — Lily, Vision, CRM, events — reads and writes one Supabase project, scoped by tenant_id with row-level security. No module owns its own siloed data.
Two interfaces hide every external dependency: CommsSource (OpenClaw→Twilio) and BookingSource (TPC/Playtomic/Padel Mates/own). The UI never talks to a vendor directly — a port becomes a config swap.
Normalise every booking system into one internal model — Player, Court, Booking, Membership, Transaction. Store raw payloads so you can re-map without re-fetching.
Vision is the one separate service — its GPU and scaling profile is nothing like the rest. Everything else is a modular monolith. Microservices are premature at this stage.
Ship sellable modules first; let Vision's hard inference mature on accumulating, labelled data. Start Vision's capture pipeline day one — gate launch on it never.
tenant_id. pgvector keeps Lily's knowledge in-DB. Auth + storage from the same provider to move fast.Settings → Developer Tools. Exposes three resources: Auth, Bookings, Players. Returns roughly the last 3 months of booking data; rate-limited (~1 call/min). Playtomic reserves the right to change or discontinue with one month's notice. Crucial caveat: clubs on Playtomic don't own their data — access is via Playtomic's terms, so this is read-centric.Read (their bookings/players → PerCorner) is available everywhere there's an API. Write-back (a change made in PerCorner pushes to the booking system) is only as good as each provider's write endpoints — and most expose read first. So the honest answer to your partner: day one is read-heavy; two-way is enabled provider-by-provider as their write APIs allow, and is fully two-way only on our own booking.
If the provider supports writes: the edit flows back and the plugin updates too (true two-way). If it's read-only: PerCorner shows the change in our UI and flags it as "pending in {provider}", and Lily/staff complete it in the source system — we never silently desync. The canonical model always holds the source of truth and reconciles on the next sync. We never let our copy and theirs drift without showing it.
How the player toggle works. Each club sets one active BookingSource in settings (Playtomic, TPC/MATCHi, Padel Mates, or PerCorner's own). That single switch repoints the adapter — the player app and owner dashboard don't change at all, because they only ever talk to the canonical model, never the vendor directly. For the player, booking simply works against whatever the club has connected: if the provider allows booking writes, the player books in-app and it lands in the club's system; if not, the player app deep-links to the provider's booking flow and reads the result back. The toggle is a club-level config, not something the player ever sees or manages.
PerCorner runs as a second app/layer beside Matchpoint. The player still books in Matchpoint (or via a PerCorner screen that deep-links into it), and PerCorner reads that schedule. Everything the incumbent doesn't do — Vision, per-corner ranking, AI highlights, detailed coaching-with-video, progress reports, combined ratings — lives in PerCorner. We don't compete with their booking; we fill the gap above it.
For greenfield clubs or those switching, booking is native and there's one app for everything — booking, ranking, coaching, events, profile. No second app, full two-way control, the cleanest experience. This is the natural upsell from Mode A once a club sees the value.
Why the companion model works. Incumbents like TPC Matchpoint have no video, no real coaching-booking flow, and no per-shot ranking — that entire surface is PerCorner's. The player tolerates a second app because it does things the first one never could; over time PerCorner becomes the app they open daily (their rank, clips, progress, combined rating) while the booking system stays the booking utility underneath. The friction sits on the boring task, not the engaging one. For the player, the only visible difference between Mode A and Mode B is where the Book button takes them — everything else is identical.
Player free vs Pro. The member app is free for what makes the club sticky — booking, club & combined rating, joining ranked matches, standard reports, profile & share links. PerCorner Pro (~£6/mo) gates the personal-value features: full video parsing, deep stats, outside-club uploads, and AI highlight reels (a monthly bundle, then a per-creation fee). Ranked matches stay free to join — the cost sits in a slightly higher ranked-court price with Vision capture included, so participation (and the data it generates) is never gated. Three revenue layers: club subscription, player subscription, per-use fees.
This is four products plus an integration platform plus a CV moonshot. The biggest risk isn't any one feature — it's building everything before anyone pays.
Multi-player + ball tracking, shot classification and homography from club video is genuinely hard. The 0–7 rating depends on accumulated labelled data first.
Playtomic owns player-network liquidity; you'd lose a head-on booking war.
A wrong autonomous rating puts a weak player into an unsafe match — clubs won't forgive it.
Before any of this: rotate every credential that has left your vault, run the formal trademark search on "Percorner" (UK IPO + EUIPO, classes 9 / 41 / 42), and lock the matching Instagram & TikTok handles — for a product whose pitch includes social automation, the handle matters as much as the domain.