Files
padelnomics/PROJECT.md
2026-02-23 21:11:34 +01:00

12 KiB
Raw Blame History

Padelnomics — Project Tracker

Move tasks across columns as you work. Add new tasks at the top of the relevant column. Last updated: 2026-02-23.


Done

Confirmed by full code audit (2026-02-22). More is built than the original strategy docs assumed.

Infrastructure & Deploy

  • UV workspace monorepo structure (web/, transform/, extract/ members)
  • Docker + docker-compose production deploy
  • Litestream R2 backup (1-year retention, auto-restore on startup)
  • CI pipeline (GitLab, health check gated deploys)
  • SOPS + age encrypted secrets (.env.dev.sops / .env.prod.sops; deploy.sh auto-decrypts; setup_server.sh installs sops+age)
  • Pre-migration DB backup + auto-restore on failed deploy
  • Nginx router config

Auth & Users

  • Magic link auth (signup + login)
  • User accounts + sessions
  • RBAC (admin role, supplier role)
  • User dashboard (stats, settings, account deletion)
  • Admin impersonation (login as any user, return to admin)

Planner / Calculator

  • Full 60-var financial planner — fully open, no login required
  • HTMX refactor (server-rendered tabs, ~200 line JS)
  • Planner i18n (EN + DE, all strings translated)
  • Currency formatting by country (€ / £ / $)
  • Market data endpoint (/planner/api/market-data) — city-specific defaults from DuckDB
  • Scenario save/load (requires login)
  • "Get Supplier Quotes" button linking to quote wizard

Leads / Quote Flow

  • 9-step quote wizard — no login required, heat scoring, email verification
  • Lead heat scoring (hot 35 credits / warm 20 / cool 8)
  • Guest email verification (magic link sent before lead activates)
  • Admin lead management (list, detail, status transitions, manual forwarding)
  • Supplier credit-based lead unlock (atomic credit spend + email notification to both sides)
  • i18n for full quote flow

Supplier Directory & Dashboard

  • Directory — fully public, search/FTS/filter/pagination/detail/enquiry
  • Tier-based ordering (sticky > pro > growth > basic > free)
  • Boost badges on directory cards
  • Supplier signup wizard (4-step, plan selection, Paddle checkout, waitlist-gatable)
  • Supplier dashboard (4 tabs: overview, leads feed, listing editor, boosts)
  • Listing editor with live HTMX preview, logo/cover upload
  • Boost purchase from dashboard (Paddle checkout)
  • Credit pack purchase from dashboard
  • i18n for directory + supplier pages

Billing & Credits

  • Paddle billing (SDK, 18 products, webhooks, checkout, subscription lifecycle)
  • Credit system (balance, ledger, atomic unlock, monthly refill on 1st of month)
  • Business Plan PDF purchase flow (Paddle one-time → webhook → async generation)
  • Boost purchases (logo, highlight, verified, card color, sticky week/month)
  • Credit pack purchases (25/50/100/250)
  • Supplier subscription tiers (Basic free / Growth €149 / Pro €399, monthly + annual)
  • Feature flags (DB-backed, migration 0019) — is_flag_enabled() + feature_gate() decorator replace WAITLIST_MODE; 5 flags (markets, payments, planner_export, supplier_signup, lead_unlock); admin UI at /admin/flags with toggle
  • Python supervisor (src/padelnomics/supervisor.py) + workflows.toml — replaces supervisor.sh; topological wave scheduling; croniter-based is_due(); systemd service updated
  • Proxy rotation (extract/padelnomics_extract/proxy.py) — round-robin + sticky hash-based selector via PROXY_URLS env var
  • Resend email integration (transactional: magic link, welcome, quote verify, lead forward, enquiry)
  • Auto-create Resend audiences per blueprint (waitlist, planner nurture)

Business Plan PDF Export

  • Full WeasyPrint PDF pipeline (not just a CTA — actually generates PDFs)
  • Paddle checkout for PDF purchase
  • Async generation via worker queue, email on completion
  • PDF content: executive summary, CAPEX, OPEX, 5-year P&L, financing, IRR/MOIC/payback/DSCR
  • EN + DE PDF localization

CMS / Programmatic SEO

  • Article template engine (Jinja2 Markdown + [scenario:slug:section] markers)
  • Seed script (seed_content.py) — 40 cities × EN + DE = 80 articles
  • City coverage: DE (8), US (6), UK (4), ES (5), FR (3), IT (2), NL, AT, CH, SE, PT (2), BE, AE, AU (2), IE
  • Per-city financial model overrides (rates, rent, utilities, permits, court config)
  • Admin CMS (template CRUD, data row management, bulk CSV upload, bulk generate, publish toggle, rebuild)
  • Markets hub (/<lang>/markets) — article listing with FTS + country/region filters
  • DuckDB refresh script (refresh_from_daas.py)

Data Pipeline (DaaS)

  • Overpass API extractor (OSM padel courts)
  • Eurostat extractor (city demographics)
  • Playtomic unauthenticated tenant search extractor
  • SQLMesh 3-layer DuckDB pipeline (staging → foundation → serving)
  • dim_venues (OSM + Playtomic deduped), dim_cities (Eurostat population)
  • city_market_profile (market score OBT), planner_defaults (per-city calculator pre-fill)
  • DuckDB analytics reader in app lifecycle

i18n

  • Full i18n across entire app (EN + DE)
  • URL prefixes (/en/, /de/) on all public blueprints
  • Language detection (cookie + Accept-Language header)
  • tformat Jinja2 filter for parameterized translations
  • German copy: informal "Du/Dein" throughout
  • hreflang tags + x-default

Admin Panel

  • Comprehensive admin: users, tasks, leads, suppliers, CMS templates, scenarios, articles, feedback
  • Task queue management (list, retry, delete)
  • Lead funnel stats on admin dashboard
  • Email hub (/admin/emails) — sent log, inbox, compose, audiences, delivery event tracking via Resend webhooks
  • Sitemap (both language variants, <lastmod> on all entries)
  • robots.txt
  • JSON-LD schemas (Organization, FAQPage, Article)
  • OG tags + canonical on all pages
  • German legal pages (Impressum, Datenschutz, AGB — DSGVO compliant)
  • English legal pages (GDPR, proper controller identity)
  • Cookie consent banner (functional/A/B categories, 1-year cookie)
  • Virtual office address on imprint
  • SEO/GEO admin hub — GSC + Bing + Umami sync, search/funnel/scorecard views, daily background sync

Testing

  • Playwright visual/E2E test suite — 77 tests across 3 files (visual, e2e flows, quote wizard); single session-scoped server + browser; mocked emails + waitlist mode; ~59s runtime
  • Unit test suite — auth, billing webhooks, planner calculator, PDF export, RBAC, scenarios, lead scoring

Other

  • A/B testing framework (@ab_test decorator + Umami data-tag)
  • Mobile nav (hamburger < 900px, full overlay panel)
  • Padel racket SVG logo/favicon
  • Feedback widget (HTMX POST, rate-limited)
  • Interactive ROI calculator widget on landing page (JS sliders, no server call)

In Progress 🔄

Move here when you start working on it.


Next Up 📋

Two independent tracks — pick from either at any time, no sequencing between them. Tech tasks can be shipped in hours. Business tasks depend on other people and run in parallel.

Go-Live (config, not code)

🛠 Tech 📣 Business
Paddle: set production env vars + run setup_paddle against prod First 35 supplier outreach emails
Publish SEO articles: run seed_content --generate on prod (or trigger from admin) First LinkedIn post
Wipe 5 test suppliers (example.com entries from seed_dev_data.py)
Verify Resend production API key — test magic link email
Submit sitemap to Google Search Console Set up Google Search Console + Bing Webmaster Tools (SEO hub ready — just add env vars)
Verify Litestream R2 backup running on prod

Week 12 — First Revenue

🛠 Tech 📣 Business
Email nurture sequence (3-email drip for planner users who save scenarios — Resend infra ready, just need content + scheduling) 3050 supplier outreach emails
23 founding member deals (free leads for 3 months)
"State of Padel Q1 2026" report written + published
First 3 priority SEO articles (see docs/MARKETING.md for titles)
LinkedIn: 5 posts published

Week 24 — Market Map

🛠 Tech 📣 Business
Market map UI (geographic visualization over DuckDB city data — no map exists yet) Follow up on founding member outreach
More SEO articles

Month 2 — Market Intelligence

🛠 Tech 📣 Business
Market Intelligence Dashboard (city analytics, occupancy estimates, demand map) Explorer tier (€79/mo) promoted to email list
Explorer tier paywall (€79/mo subscription gate) Email drip running

Backlog 🗂️

Validated ideas not yet scheduled. Pick up when capacity allows.

Product

  • Market Intelligence Pro tier (€149/mo — hall-level data, competitor tracking, historical)
  • Location Scorer (mechanical turk first: form → manual PDF delivery → automate if demand)
  • Operational analytics for running venues (€4999/mo, Phase 3 product)
  • Business Plan Pro subscription (€39/mo, saved scenarios + auto-updates)
  • Site Selection Reports (€499999 high-ticket, productized)
  • "State of Padel" quarterly report product (€299499, gated)
  • Enterprise / API tier (custom pricing)
  • Padel Hall Accelerator (€999 — report + call + supplier intros)

Data & Intelligence

  • Multi-source data aggregation (add booking platforms beyond Playtomic)
  • Google Maps signals (reviews, ratings)
  • Weather + demographic overlays
  • Voluntary data sharing from operating venues (benchmarking network effects)
  • ML/forecasting layer (demand forecasting, pricing optimization)
  • Scraping risk mitigation: rotate sources, voluntary sharing fallback

Bugs / Tech Debt

  • Resend audiences: two segments both using "waitlist-auth" — review audience/segment model and fix duplication
  • Transactional emails not all translated to German — some emails still sent in English regardless of user language
  • Resend inbound emails enabled — integrated: webhook handler + admin inbox with reply (done in email hub)
  • Extraction: Playtomic API only returns ~20 venues per bbox — investigate smaller/targeted bboxes

Marketing & Content

  • LinkedIn presence (ongoing — founder posts, thought leadership)
  • "Wirecutter for padel" affiliate site (racket reviews, gear guides)
  • "The Padel Business Report" newsletter
  • Equipment supplier affiliate partnerships (€5001,000/lead or 5%)
  • Padel podcasts (guest appearances)
  • Sports business media outreach
  • National padel associations (DTB, LTA — co-distribution)
  • Franchise partnerships (market data / leads)
  • Lender distribution (banks recommending Padelnomics plans)

Geographic Expansion

  • Austria + Switzerland (language done, cities seeded — just outreach + supplier onboarding)
  • France (cities seeded in CMS)
  • Italy, Netherlands, Sweden (cities seeded)
  • UAE / Middle East (cities seeded)
  • Pan-European supplier directory

Decisions Log

Date Decision Rationale
2026-02-22 Two-sided marketplace framing (Side A = aspiring owners, Side B = suppliers) Suppliers are the main revenue engine; calling them "secondary" was wrong
2026-02-22 Tennis/sports club owner as beachhead Faster decision cycle, talk to each other, ~5001,000 targets, small enough to dominate
2026-02-22 Credit system over pay-per-lead blast Suppliers self-select → higher quality perception; scales without manual intervention
2026-02-22 No soft email gate on planner Planner already captures emails at natural points (scenario save → login, quote wizard step 9). Gate would add friction without meaningful list value. Revisit if data shows a gap.
2026-02-22 Wipe test suppliers before launch 5 example.com entries from seed_dev_data.py — empty directory with "Be the first" CTA is better than obviously fake data