PRODUCT DESIGN / 23 OCTOBER 2026 / PROPOSAL V1
London, on court.
A practical plan for bringing Padel to The London Monitor.
01 / A new section, the same promise
Help people in Greater London find a suitable padel court and understand the real cost of a game. Padel sits beside Theatre in The London Monitor: one editorial identity, separate discovery screens and domain records. Start with the 32 boroughs and City of London; show nearby boundary venues only in an explicit expanded-area search. Do not imply complete London coverage.
The jobs: organise four friends around a shared time and budget; find a cheaper indoor option nearby; understand a venue before opening its booking provider. Success means a usable, correctly attributed shortlist and a transparent provider handoff. It does not mean completing a reservation here.
This delivery is a design and browser prototype. Five fictional clubs and fixed October 2026 scenarios demonstrate the flows. No production Padel ingestion, new account, payment, reservation service or paid model/vendor access is implemented or authorized.
02 / Three journeys to test
- Plan a foursome. On discovery, enter “Indoor after 6pm, under £20 each for four”. The parser sets cover, earliest time, budget and players; duration defaults to 90 minutes. Known totals rank first after hard filters. Open Canal Works: £72 for 90 minutes, £18 each for four, £48 per court-hour. Change players to three and see £24 each. Open the handoff explanation; no booking is created.
- Find a cheaper nearby court. Use area and cover filters, then compare whole-court rental over visibly different durations. Railway's £36 rental plus £2 fee for 60 minutes must not be mistaken for a cheaper 90-minute game. Unknown fees do not become free. A map pin synchronises the selected list card; locality is a manual filter, not an inferred GPS location.
- Explore a venue. Open the club page, choose a court, day and slot, then inspect facilities, eligibility and provider confidence. Try stale, unavailable and unknown-price alternatives. All remain explicit examples.
On mobile, list and map are alternatives. Pins are keyboard buttons through Leaflet; the list always provides the same club links. Map failure keeps discovery usable. Forms have labels, selection uses aria-pressed, status messages are announced, and no action relies on colour alone. Comparison stacks on narrow screens; the document has contents anchors and a print layout.
03 / MVP and later
MVP: a verified venue/court directory, published tariff comparisons, London map, constrained natural-language discovery and verified booking-provider deep links. Directory-only venues remain visible even when tariffs or inventory are unknown. Start with 20 manually verified venues before expanding; publish source coverage rather than a “live London” claim.
Later, conditional on access: authorized fresh slot feeds, separate open-match and coaching discovery, and opt-in alerts/accounts. Keep reservations, payment, refund disputes and provider account creation with providers. No new paid vendor or model service is approved by this proposal. If access cannot be secured, directory and tariff comparison remain a viable first release.
04 / Routes, components and visual system
/padel/ owns discovery; /padel/club.html?club=canal demonstrates a selected venue; /padel/compare.html?club=canal seeds a three-option comparison; /padel/design.html is this document. The theatre homepage receives one small Padel design preview link. The existing theatre app and API contracts stay intact.
Reuse the local Libre Caslon Display and DM Sans fonts, warm paper, deep green and restrained lime. Dense editorial court rows put price, duration, cover and locality before ornament. Code-native court diagrams add character without raster downloads. A shared preview banner stays visible on every page. The discovery split becomes list/map tabs below 760px; comparison cards stack. Large headings scale with viewport width; inputs remain at least 16px to avoid mobile zoom.
Use native selects/buttons, visible focus, semantic landmarks, a skip link, accessible map names and text alternatives. Aim for WCAG 2.2 AA, 44px touch targets and reduced-motion-safe interaction. The prototype keeps comparison in memory with bounded, allowlisted club IDs; refresh resets to a disclosed demo shortlist. Production can serialise nonpersonal search state into URLs.
Do not force theatre productions, performances or ticket offers into court records. Share only small coordinate, source attribution, observation-age and map helpers when contracts match. Keep Padel modules and routes isolated. No rewrite of app.mjs or theatre schema is needed.
05 / Data contracts and honest prices
| Record | Required shape and rules |
|---|---|
| Provider / source | Stable ID, official origin, approved fetch/deep-link origins, external IDs, terms/access status, attribution, robots decision, last attempt/success, health and parser version. |
| Venue | Stable ID, canonical name, aliases, address/borough, verified latitude/longitude, coordinate precision, facilities and accessibility with provenance and verified_at. Unknown facilities are null. |
| Court | Venue ID, external court ID, sport, singles/doubles, indoor/covered/outdoor/unknown cover, dimensions if verified. Covered is not automatically indoor. |
| Tariff / price observation | Source ID and URL, court/scope, GBP integer pence, basis (court/session, court/hour, player/hour or seat/session), duration minutes, expected players, member/nonmember eligibility, peak window, effective dates, mandatory fees, optional hire, observed_at. Unknown amount/fee is null, never 0. |
| Slot | Source slot ID, court ID, start/end UTC instants, IANA timezone Europe/London, checked_at, expires_at, source status, eligible tariff quote, provider handoff URL. Unique source/court/start/end key prevents duplicates. |
| Session / open match | Separate entity: type, per-seat price basis, available seats and eligibility/level if public and permitted. Never treat a seat as whole-court rental or expose participant identities. |
Maintain separate states: advertised recurring rate; dated price quote; observed available slot; provider-reserved slot; sold-out/unavailable; inventory unknown. A tariff is not availability, and absence from a feed is not proof of sold out. The Monitor must never create a reserved state from a click. A provider-confirmed reservation is outside MVP.
Price example: 7200 pence / 90 minutes means £72 court rental, £18 each for four, £48 per court-hour before additional fees. Add mandatory known fees before splitting or normalising. A player/hour tariff is multiplied by duration and the tariff's stated occupancy to derive a court equivalent only when that assumption is valid; never divide an already per-person tariff twice. Preserve the original basis and explain any conversion. Round display values only, keep integer source amounts, and show any split rounding remainder at provider handoff. Unknown mandatory fees leave the final total and split unknown; a known rental can still be shown as a subtotal.
Deduplicate using provider IDs first and verified address/coordinates second. Name aliases are search aids, not identity proof. Keep conflicting observations side by side with provenance; never merge co-located courts merely because their names resemble one another.
06 / Source feasibility, checked 23 October 2026
These primary sources were re-fetched for this proposal. Facts below support feasibility, not real offers in the mockups. No detailed real venue rates are copied into illustrative inventory. Access and redistribution rights remain unvalidated unless explicitly stated.
| Source | Verified observation | Boundary / next step |
|---|---|---|
| LTA directory guidance | Describes venue, location, court-count and contact information. | Useful directory seed; not a slot feed. Verify coordinates and reuse terms before ingestion. |
| LTA equipment guidance | Hire is offered by some venues. | Equipment availability and cost must be verified per club; do not assume free hire. |
| The Padel Yard, official | Publishes court and per-player pricing and a MATCHi split-payment surcharge. | Preserve basis and fees. Revalidate dates and restrictions; not a live slot observation. |
| MATCHi facility | Fetch returned HTTP 403 on this check. | Peak/off-peak and member/nonmember detail supplied as a research lead was not revalidated. No asserted tariff or anonymous feed permission. Seek authorized integration. |
| Padel Social membership page / official FAQ | Membership page returned no extractable text. FAQ directs court booking to Playtomic and describes earlier booking access for members. | Membership windows affect eligibility. Recheck precise plan terms rather than carrying over promotional claims. |
| Padium Canary Wharf | Official venue page points bookings to Padel Mates. | Provider link is confirmed; public slot API, redistribution and rate limits are not. No venue inventory ingested. |
| Playtomic developer docs / bookings endpoint | Credentials originate in Manager Developer tools. Bookings query is venue-scoped and includes participant-related fields. | This is an authorized booking ledger, not proof of an anonymous all-London availability API. Never ingest customer bookings, emails or participant records. Obtain a permitted availability-only contract and field allowlist before any feed work. |
| Other official venues / venue-specific booking systems | No universal interface verified. | Per-venue feasibility spike: robots, terms, tariff basis, deep-link stability, public feed access and attribution. A public webpage alone grants no bulk reuse right. |
Use bounded origin allowlists, robots/vendor rules, conditional requests, retries with jitter and exponential backoff. Stop on access denial; never bypass login, CAPTCHA or robots. Start at one concurrent request per origin, at least 2 seconds apart, 10-second timeout, 2 retries and 1 MB response cap; lower limits win if required by the source. Retain the last good snapshot with explicit age and parser health. A direct-source refusal can coexist with correctly attributed partner coverage; refusal never means the venue is closed. Search snippets and third-party directories are leads only.
07 / Freshness is part of the answer
Proposed defaults: venue details and tariffs refresh daily. This cannot guarantee live slot availability. Only a supported, authorized availability feed may refresh a bounded 5–15-minute window. Start with 10-minute checks for a two-day horizon, at most 20 opted-in venues, 200 slots per venue and a 10-minute expiry; source limits override this budget. These are proposals, not implemented capabilities.
Show directory-only, tariff-known/availability-unknown, fresh observed slot, stale and source-unavailable states separately. Once expires_at passes, remove “available” language immediately but retain the last observation as stale context. Revalidate with the source before provider handoff where permitted; otherwise clearly require checking at the provider. Never promise a hold or reservation. Failed checks update source health, not the historical observation time.
Store UTC instants and display Europe/London. On 25 October 2026 the repeated local hour must carry its UTC offset so two 01:30 slots are distinct; nonexistent spring times must be rejected. Date filters use London calendar boundaries rather than the server's timezone.
08 / Grounded agentic discovery
- Parse a bounded intent into area, day, earliest/latest time, duration, players, cover, eligibility and per-player budget. Echo interpreted constraints; ask for clarification only when a choice cannot be safely bounded.
- Resolve place names against verified local venue/borough data. Do not request GPS by default. Future approximate location is explicit, optional and ephemeral.
- Call typed read-only venue, tariff and permitted slot tools. Limit planning to 4 tool calls and 50 candidates. Do not accept arbitrary URLs or source-supplied tool instructions.
- Apply hard constraints first. Unknown mandatory costs cannot pass a hard budget. Unknown inventory cannot pass “available now”. Membership restrictions cannot be erased by semantic relevance.
- Rank survivors by explicit cost/locality/cover preferences, then explain using observed facts, timestamps and sources. Offer clearly marked constraint relaxations only when the user opts in.
The existing local semantic discovery approach can be a transparent fallback for venue descriptions. This prototype uses a smaller phrase parser: cover, “after” time, “under £” and player count, plus native filters. It is not an LLM. Unrecognised preferences are not silently claimed as satisfied. Future LLM access and budget need separate authorization; never reuse developer-assistance credentials for product traffic. Source text is untrusted data, never executable instructions or planner policy.
09 / Architecture, budgets and privacy
Proposed implementation: Python 3.11 standard-library adapters write versioned, validated Padel snapshots using atomic replacement and last-good retention. Separate source, directory, tariff and slot modules feed a read-only API. Vanilla ES-module Padel screens consume it; theatre ingestion and routes stay independent. No adapter or API is added in this design delivery.
Proposed endpoints: GET /api/padel/venues?area=East&cover=indoor, GET /api/padel/venues/{id}, GET /api/padel/tariffs?venue_id=…, GET /api/padel/slots?venue_id=…&day=…, and a bounded read-only discovery endpoint. Responses include schema version, source attribution, observed_at, checked_at, expires_at and coverage warnings. No customer booking endpoint. Allowlist query enums, cap lists at 50 with cursors, return 400 for invalid durations and preserve nulls.
Initial budgets: 10 MB compressed directory/tariff snapshot; 20 MB bounded slot cache; two global fetch workers; refresh under 60 seconds CPU and 256 MB memory; public request p95 under 300ms on warm local snapshots; client JS below 100 KB excluding existing Leaflet/fonts, at most 50 visible map pins. Measure before rollout and reduce scope if exceeded. Use ETags and a 24-hour directory cache; slot responses never cache beyond expires_at. No live provider fan-out per keystroke.
No default tracking, mandatory account, email form, silent GPS collection or local personal profile. The prototype stores no user data. Queries remain in browser memory; production logs should omit raw search text and location. OpenStreetMap tiles reveal ordinary network metadata to that provider, so list mode remains usable without tiles. Future alerts require explicit opt-in, deletion/unsubscribe, minimal retention and separate access review. Escape source strings through textContent; validate deep links to HTTPS allowlisted providers. CSP keeps scripts/fonts self-hosted and map images limited to OpenStreetMap. Credentials stay server-side outside snapshots and evidence.
10 / Delivery gates and acceptance
- Feasibility spike: verify 20 Greater London venues, tariff bases, attribution and provider rights. Gate: approved source contracts and a public-field allowlist; no private booking ledger accepted as availability.
- Directory, tariffs and map: ship useful directory-only and unknown-price states. Gate: verified coordinates, aliases, fair member/nonmember comparisons, mandatory fees, null preservation and list/map keyboard parity.
- Permitted slot feeds: add one authorized provider first. Gate: expiry, outage/backoff/last-good tests, deduplication, timezones and DST boundary fixtures. No “live” claim until source freshness can be shown.
- Grounded discovery: release constrained local filtering before any separately authorized model integration. Gate: hard constraints beat scores, unknown costs fail budgets, prompt-injection source text stays inert and answers cite observations.
- Operations rollout: independent review and exact-head CI, selective VPS install by the controller, route/CSP checks, health/readback and rollback to the prior static directory. No scheduler or new Padel backend is activated here.
Prototype acceptance covers all four routes on desktop Chromium and iPhone WebKit, persistent demo labels, actual query/filter changes, empty/reset states, price/player/duration calculations, comparison add/remove, stale/unavailable/unknown scenarios, keyboard map/list selection, blocked tiles, safe text rendering, nested links, mobile overflow and print layout. Run the theatre browser regression suite and existing backend/JS tests. Safari engine coverage uses WebKit emulation; physical iPhone Safari remains a later device check. Screenshots and actual results live in dashboard/evidence/padel; local evidence awaits controller publication.
Provider permissions and any future paid access are real external dependencies for later phases. They do not block these mockups. This proposal does not authorize new spending, customer data access or automated reservations.