felt/.planning/REQUIREMENTS.md
Mikkel Georgsen ae596f2722 docs(01-10): complete SvelteKit Frontend Scaffold plan
- SUMMARY.md with all accomplishments and deviations
- STATE.md updated with plan 10 position and decisions
- ROADMAP.md updated with plan progress
- REQUIREMENTS.md: UI-05, UI-06 marked complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:57:51 +01:00

22 KiB

Requirements: Felt

Defined: 2026-02-28 Core Value: A venue can run a complete tournament offline on a €100 device with wireless displays and player mobile access — and it just works, on any network, with zero IT involvement.

v1 Requirements

Requirements for Phase 1 (Development Focus: Live Tournament Management). Each maps to roadmap phases.

Platform Identity

  • PLAT-01: Players have platform-level Felt profiles (UUID, cross-venue, portable) — not tied to any single venue
  • PLAT-02: Player profile stores name, nickname, photo, email, phone, notes, custom fields
  • PLAT-03: Player tournament history, stats, and league standings are cross-venue and travel with the player
  • PLAT-04: Player can control public visibility of their profile data
  • PLAT-05: Player can request full data export (GDPR right to portability) in JSON
  • PLAT-06: Player deletion cascades: anonymize tournament entries (keep aggregate stats), remove PII, propagate via NATS

Architecture & Infrastructure

  • ARCH-01: Leaf Node runs as single Go binary on ARM64 SBC with embedded LibSQL, NATS JetStream, and WebSocket hub
  • ARCH-02: Virtual Leaf runs same Go codebase on Core cloud infrastructure for free-tier venues (requires internet)
  • ARCH-03: All financial values stored as int64 cents — never float64
  • ARCH-04: NATS JetStream embedded on Leaf with sync_interval: always for durability
  • ARCH-05: WebSocket hub broadcasts state changes to all connected clients within 100ms
  • ARCH-06: SvelteKit frontend embedded in Go binary via //go:embed for single-binary deployment
  • ARCH-07: Leaf is sovereign — all tournament logic runs locally, cloud is never required for operation
  • ARCH-08: Append-only audit trail for every state-changing action (operator, action, target, previous/new state, timestamp)
  • ARCH-09: Automated daily backup of LibSQL database to USB or cloud, with documented recovery procedure
  • ARCH-10: Leaf must recover cleanly from hard power-cycle during active tournament (verified by chaos testing)

Tournament Clock

  • CLOCK-01: Countdown timer per level with second-granularity display, millisecond-precision internally
  • CLOCK-02: Separate break durations with distinct visual treatment
  • CLOCK-03: Pause/resume with visual indicator across all displays
  • CLOCK-04: Manual advance forward/backward between levels
  • CLOCK-05: Jump to any level by number
  • CLOCK-06: Total elapsed time display
  • CLOCK-07: Configurable warning thresholds (e.g., 60s, 30s, 10s) with audio and visual alerts
  • CLOCK-08: Clock state authoritative on Leaf; clients receive ticks via WebSocket (1/sec normal, 10/sec final 10s)
  • CLOCK-09: Reconnecting clients receive full clock state immediately

Blind Structure

  • BLIND-01: Unlimited configurable levels (round or break, game type, SB/BB, ante, duration, chip-up, notes)
  • BLIND-02: Big Blind Ante support alongside standard ante
  • BLIND-03: Mixed game rotation support (HORSE, 8-Game round definitions)
  • BLIND-04: Save/load reusable blind structure templates
  • BLIND-05: Built-in templates (Turbo ~2hr, Standard ~3-4hr, Deep Stack ~5-6hr, WSOP-style)
  • BLIND-06: Structure wizard (inputs: player count, starting chips, duration, denominations → suggested structure)

Chip Management

  • CHIP-01: Define denominations with colors (hex) and values
  • CHIP-02: Chip-up tracking per break with visual indicator on displays
  • CHIP-03: Total chips in play calculation
  • CHIP-04: Average stack display

Financial Engine

  • FIN-01: Buy-in configuration (amount, starting chips, per-player rake, fixed rake, house contribution, bounty cost, points)
  • FIN-02: Multiple rake categories (staff fund, league fund, house)
  • FIN-03: Late registration cutoff (by level, by time, or by level AND remaining time — e.g., "end of Level 6 or first 90 minutes, whichever comes first")
  • FIN-04: Re-entry support (distinct from rebuy — new entry after busting)
  • FIN-05: Rebuy configuration (cost, chips, rake, points, limits, level/time cutoff, chip threshold)
  • FIN-06: Add-on configuration (cost, chips, rake, points, availability window)
  • FIN-07: Fixed bounty system (bounty cost, chip issued, hitman tracking, chain tracking, cash-out)
  • FIN-08: Prize pool auto-calculation from all financial inputs
  • FIN-09: Guaranteed pot support (house covers shortfall)
  • FIN-10: Payout structures (percentage, fixed, custom table) with configurable rounding
  • FIN-11: Chop/deal support (ICM calculator, chip-chop, even-chop, custom)
  • FIN-12: End-of-season withholding (reserve rake portion for season prizes)
  • FIN-13: Every financial action generates a receipt with full transaction log
  • FIN-14: Transaction editing with audit trail and receipt reprint capability

Player Management

  • PLYR-01: Player database persistent on Leaf (LibSQL), synced to Core (PostgreSQL)
  • PLYR-02: Search with typeahead, merge duplicates, import from CSV
  • PLYR-03: QR code generation per player for self-check-in
  • PLYR-04: Buy-in flow: search/select player → confirm → optional auto-seat → receipt → displays update
  • PLYR-05: Bust-out flow: select player → select hitman → bounty transfer → auto-rank → rebalance trigger → displays update
  • PLYR-06: Undo capability for bust-out, rebuy, add-on, buy-in with full re-ranking
  • PLYR-07: Per-player tracking: chip count, playing time, seat, moves, rebuys, add-ons, bounties, prize, points, net take, full action history

Table & Seating

  • SEAT-01: Tables with configurable seat counts (6-max to 10-max), names/labels
  • SEAT-02: Table blueprints (save venue layout)
  • SEAT-03: Dealer button tracking
  • SEAT-04: Random initial seating on buy-in (fills tables evenly)
  • SEAT-05: Automatic balancing suggestions with operator confirmation required (size difference threshold, move fairness, button awareness, locked players, break short tables first — dry-run preview, never auto-apply)
  • SEAT-06: Tap-tap manual seat moves on touch interface (tap source seat, tap destination seat)
  • SEAT-07: Break Table action (dissolve and distribute)
  • SEAT-08: Visual top-down table layout (player names in seats), list view, movement screen
  • SEAT-09: Hand-for-hand mode (clock pauses, per-table completion tracking, all tables complete → next hand)

Multi-Tournament

  • MULTI-01: Run multiple simultaneous tournaments with independent clocks, financials, and player tracking
  • MULTI-02: Tournament lobby view (multi-tournament overview on displays)

League & Season

  • LEAGUE-01: Leagues (named groups, cross-season) and seasons (time-bounded within a league)
  • LEAGUE-02: Players can belong to multiple leagues; tournaments assigned to league + season
  • LEAGUE-03: Custom point formula engine with variables (TOTAL_PLAYERS, PLAYER_PLACE, REBUYS, etc.) and functions (sqrt, pow, if, etc.)
  • LEAGUE-04: Formula testing (input test values, preview all placements, graph distribution)
  • LEAGUE-05: Season standings (cumulative, best N of M, minimum attendance, historical archives)
  • LEAGUE-06: League standings available as display node view

Regional Tournaments

  • REGION-01: Anyone can create cross-venue tournaments/leagues (free-tier feature)
  • REGION-02: Define qualifying events across participating venues
  • REGION-03: Automatic point aggregation from each venue's qualifying tournaments
  • REGION-04: Unified leaderboard across all venues
  • REGION-05: Finals event management

Display System

  • DISP-01: Display node registry showing all connected nodes (name, status, resolution, view, group)
  • DISP-02: Actions: assign view, rename, group, reboot, remove
  • DISP-03: Tournament views: Clock, Rankings, Seating Chart, Blind Schedule, Final Table, Player Movement, Prize Pool, Tournament Lobby
  • DISP-04: General views: Welcome/Promo, League Standings, Upcoming Events
  • DISP-05: Theme system with pre-built dark/light themes and custom theme builder (colors, fonts, logo, background)
  • DISP-06: Sponsor banner areas (configurable per view)
  • DISP-07: Screen cycling with rotation config, conditional routing, override, lock
  • DISP-08: Multi-tournament routing (assign displays to specific tournaments or lobby)
  • DISP-09: Auto font-scaling to resolution; readable from 10+ feet
  • DISP-10: Display nodes connect via WebSocket, heartbeat every 5s, Leaf tracks status
  • DISP-11: All display views must stay under 350MB RSS on Pi Zero 2W during 4-hour continuous operation (non-functional, verified by soak testing)

Digital Signage

  • SIGN-01: Info screen content types: info_card, event_promo, sponsor_ad, menu_board, league_table, custom_html, media
  • SIGN-02: WYSIWYG drag-and-drop content editor with template gallery
  • SIGN-03: Venue branding auto-applied (logo, colors, fonts from venue profile)
  • SIGN-04: AI content generation (text prompt → polished promo card with layout, typography, imagery)
  • SIGN-05: AI image generation (thematic backgrounds, poker graphics, event artwork from prompts)
  • SIGN-06: Rich text editing with headlines, images, QR codes, countdowns, live data widgets
  • SIGN-07: Content scheduling (time slots, automated playlists, priority, fallback content)
  • SIGN-08: Per-screen content assignment (different screens show different content simultaneously)
  • SIGN-09: Tournament override (screens auto-switch to tournament views during play, revert to signage after)
  • SIGN-10: Content bundles stored on Leaf as static HTML/CSS/JS, rendered in Chromium kiosk

Player Mobile PWA

  • PWA-01: Access via QR code scan, no login required for public views
  • PWA-02: Live clock view (blinds, timer, next level)
  • PWA-03: Full blind schedule (current level highlighted)
  • PWA-04: Rankings (live bust-out order)
  • PWA-05: Prize pool and payout structure
  • PWA-06: Personal status (seat, points — after PIN claim)
  • PWA-07: League standings
  • PWA-08: Upcoming tournaments
  • PWA-09: WebSocket real-time updates with auto-reconnect and polling fallback
  • PWA-10: "Add to Home Screen" PWA prompt

Events Engine

  • EVENT-01: Triggers: tournament.started/ended, level.started/ended, break.started/ended, player.busted/bought_in/rebought, tables.consolidated, final_table.reached, bubble.reached, timer.warning, timer.N_remaining
  • EVENT-02: Actions: play_sound, show_message, change_view, flash_screen, change_theme, announce (TTS), webhook, run_command
  • EVENT-03: Visual rule builder (select trigger → set conditions → add actions, no code required)
  • EVENT-04: Rules can be global or per-tournament

Networking & Access

  • NET-01: Netbird WireGuard mesh (Leaf ↔ Core ↔ Display Nodes, zero-trust, encrypted)
  • NET-02: Netbird reverse proxy (player + operator access to Leaf via HTTPS from anywhere)
  • NET-03: Custom DNS zone (felt.internal for service discovery)
  • NET-04: Identity-aware SSH (admin access to Leaves via Authentik OIDC)
  • NET-05: Firewall policies (drop-inbound on display nodes, zero-trust ACLs)
  • NET-06: Lazy connections (on-demand tunnels at scale for 500+ venues)
  • NET-07: Custom domain support (venue CNAME → felt subdomain, Netbird handles TLS, felt subdomain as fallback)

Sync

  • SYNC-01: NATS-based event sync from Leaf to Core (queued offline, replayed in order on reconnect)
  • SYNC-02: Idempotent upserts on Core (safe to replay, keyed on event ID)
  • SYNC-03: Reverse sync (Core → Leaf) for player profiles, league config, tournament templates, new registrations, branding
  • SYNC-04: During running tournament, Core never overrides Leaf data for that tournament

Authentication & Security

  • AUTH-01: Operator PIN login → local JWT (bcrypt hash in LibSQL, works offline)
  • AUTH-02: Operator OIDC via Authentik when Leaf has internet
  • AUTH-03: Operator roles: Admin (full control), Floor (runtime actions), Viewer (read-only)
  • AUTH-04: Core Admin: OIDC via Authentik with mandatory MFA
  • AUTH-05: Player mobile: no auth for public views, 6-digit PIN claim for personal data (rate limited: exponential backoff after 5 failures, lockout after 10)
  • AUTH-06: Leaf ↔ Core sync: mTLS certificate + API key per venue
  • AUTH-07: LUKS full-disk encryption on Leaf NVMe
  • AUTH-08: PostgreSQL Row-Level Security (RLS) for multi-tenant isolation on Core
  • AUTH-09: NATS subject namespacing (venue.{id}.*) enforced by NATS authorization

Export & Import

  • EXPORT-01: CSV export (configurable columns)
  • EXPORT-02: JSON export (full tournament data)
  • EXPORT-03: HTML export (themed with venue branding)
  • EXPORT-04: Print output from operator UI

TDD Migration

  • TDD-01: Import blind structures and tournament templates from TDD XML export
  • TDD-02: Import player database (names, contact info, aliases, notes)
  • TDD-03: Import tournament history (results, payouts, bust-out order)
  • TDD-04: Import league standings and season data
  • TDD-05: Import custom payout structures
  • TDD-06: Import wizard with preview, player name matching, template naming
  • TDD-07: Zero data loss on migration — venue's Felt instance shows complete history from day one

Operator UI

  • UI-01: Mobile-first bottom tab bar (Overview, Players, Tables, Financials, More)
  • UI-02: Floating Action Button (FAB) for quick actions (Bust, Buy In, Rebuy, Add-On, Pause/Resume)
  • UI-03: Persistent header showing clock, level, blinds, player count
  • UI-04: Desktop/laptop sidebar navigation with wider content area
  • UI-05: Catppuccin Mocha dark theme (default) and Latte light theme
  • UI-06: 48px minimum touch targets, press-state animations, loading states
  • UI-07: Toast notifications (success, info, warning, error) with auto-dismiss
  • UI-08: Data tables with sort, sticky header, search/filter, swipe actions (mobile)

v2 Requirements

Deferred to Development Phases 2-4. Tracked but not in current roadmap.

Cash Game Operations (Dev Phase 2)

  • CASH-01: Waitlist management by game type and stakes with display integration
  • CASH-02: Table management (open/close, game types, stakes, seat tracking, status board)
  • CASH-03: Game type registry (all poker variants, configurable stakes/betting)
  • CASH-04: Session tracking (player sessions, buy-in/cashout, duration, history)
  • CASH-05: Rake tracking (percentage/time/flat, per-table reporting)
  • CASH-06: Must-move tables (automated progression, main game priority)
  • CASH-07: Seat change requests (queue, notification)
  • CASH-08: Table transfers within sessions
  • CASH-09: Player alerts (waitlist position, seat available, preferred game opened)

Complete Venue Platform (Dev Phase 3)

  • DEALER-01: Dealer scheduling, skill profiles, shift trading, clock-in/out, rotation
  • DEALER-02: Dealer profiles are platform-level (portable across venues)
  • LOYAL-01: Points engine, tier system, rewards catalog, automated promos
  • LOYAL-02: Cross-venue loyalty for multi-venue operators
  • MEMBER-01: Private venues, memberships, invite codes, member tiers, guest system
  • ANALYTICS-01: Revenue dashboards, player analytics, operational analytics, benchmarking
  • PUBLIC-01: Venue profile page, online event registration, schedule publishing

Native Apps & Platform Maturity (Dev Phase 4)

  • NATIVE-01: Native player app (iOS + Android)
  • NATIVE-02: Native venue management app (iOS + Android)
  • SOCIAL-01: Private groups, activity feed, achievements, friend-based venue discovery

Out of Scope

Feature Reason
Online poker / real-money gambling Felt is a management tool, not a gambling platform
Payment processing Tracks amounts, doesn't process transactions
Video streaming / live broadcast Different infrastructure, niche use case
BYO hardware Security, reliability, support consistency
Third-party cloud (Cloudflare, AWS) Self-hosted everything, no MITM
Crypto payments Volatile, regulatory uncertainty, wrong market
Real-time chip count entry by players Cheating surface, operational chaos
Staking / backing / action splitting Legal complexity, out of scope
Casino CMS integration (IGT, Bally's) Out of scope for Phase 1-3; planned for Casino Enterprise tier in Phase 4+

Traceability

Which phases cover which requirements. Updated during roadmap reorganization.

Requirement Phase Status
ARCH-01 Phase 1 Complete
ARCH-02 Phase 3 Pending
ARCH-03 Phase 1 Complete
ARCH-04 Phase 1 Complete
ARCH-05 Phase 1 Complete
ARCH-06 Phase 1 Complete
ARCH-07 Phase 1 Complete
ARCH-08 Phase 1 Complete
ARCH-09 Phase 7 Pending
ARCH-10 Phase 7 Pending
AUTH-01 Phase 1 Pending
AUTH-02 Phase 7 Pending
AUTH-03 Phase 1 Pending
AUTH-04 Phase 3 Pending
AUTH-05 Phase 2 Pending
AUTH-06 Phase 3 Pending
AUTH-07 Phase 7 Pending
AUTH-08 Phase 3 Pending
AUTH-09 Phase 3 Pending
NET-01 Phase 7 Pending
NET-02 Phase 7 Pending
NET-03 Phase 7 Pending
NET-04 Phase 7 Pending
NET-05 Phase 7 Pending
NET-06 Phase 7 Pending
NET-07 Phase 7 Pending
PLAT-01 Phase 3 Pending
PLAT-02 Phase 3 Pending
PLAT-03 Phase 3 Pending
PLAT-04 Phase 3 Pending
PLAT-05 Phase 3 Pending
PLAT-06 Phase 3 Pending
SYNC-01 Phase 3 Pending
SYNC-02 Phase 3 Pending
SYNC-03 Phase 3 Pending
SYNC-04 Phase 3 Pending
EXPORT-01 Phase 2 Pending
EXPORT-02 Phase 2 Pending
EXPORT-03 Phase 2 Pending
EXPORT-04 Phase 2 Pending
CLOCK-01 Phase 1 Pending
CLOCK-02 Phase 1 Pending
CLOCK-03 Phase 1 Pending
CLOCK-04 Phase 1 Pending
CLOCK-05 Phase 1 Pending
CLOCK-06 Phase 1 Pending
CLOCK-07 Phase 1 Pending
CLOCK-08 Phase 1 Pending
CLOCK-09 Phase 1 Pending
BLIND-01 Phase 1 Pending
BLIND-02 Phase 1 Pending
BLIND-03 Phase 1 Pending
BLIND-04 Phase 1 Pending
BLIND-05 Phase 1 Pending
BLIND-06 Phase 1 Pending
CHIP-01 Phase 1 Pending
CHIP-02 Phase 1 Pending
CHIP-03 Phase 1 Pending
CHIP-04 Phase 1 Pending
MULTI-01 Phase 1 Pending
MULTI-02 Phase 1 Pending
FIN-01 Phase 1 Pending
FIN-02 Phase 1 Pending
FIN-03 Phase 1 Pending
FIN-04 Phase 1 Pending
FIN-05 Phase 1 Pending
FIN-06 Phase 1 Pending
FIN-07 Phase 1 Pending
FIN-08 Phase 1 Pending
FIN-09 Phase 1 Pending
FIN-10 Phase 1 Pending
FIN-11 Phase 1 Pending
FIN-12 Phase 1 Pending
FIN-13 Phase 1 Pending
FIN-14 Phase 1 Pending
PLYR-01 Phase 1 Complete
PLYR-02 Phase 1 Pending
PLYR-03 Phase 1 Pending
PLYR-04 Phase 1 Pending
PLYR-05 Phase 1 Pending
PLYR-06 Phase 1 Pending
PLYR-07 Phase 1 Complete
SEAT-01 Phase 1 Complete
SEAT-02 Phase 1 Complete
SEAT-03 Phase 1 Pending
SEAT-04 Phase 1 Pending
SEAT-05 Phase 1 Pending
SEAT-06 Phase 1 Pending
SEAT-07 Phase 1 Pending
SEAT-08 Phase 1 Pending
SEAT-09 Phase 1 Pending
UI-01 Phase 1 Pending
UI-02 Phase 1 Pending
UI-03 Phase 1 Pending
UI-04 Phase 1 Pending
UI-05 Phase 1 Complete
UI-06 Phase 1 Complete
UI-07 Phase 1 Pending
UI-08 Phase 1 Pending
DISP-01 Phase 2 Pending
DISP-02 Phase 2 Pending
DISP-03 Phase 2 Pending
DISP-04 Phase 2 Pending
DISP-05 Phase 2 Pending
DISP-06 Phase 2 Pending
DISP-07 Phase 2 Pending
DISP-08 Phase 2 Pending
DISP-09 Phase 2 Pending
DISP-10 Phase 2 Pending
DISP-11 Phase 7 Pending
PWA-01 Phase 2 Pending
PWA-02 Phase 2 Pending
PWA-03 Phase 2 Pending
PWA-04 Phase 2 Pending
PWA-05 Phase 2 Pending
PWA-06 Phase 2 Pending
PWA-07 Phase 2 Pending
PWA-08 Phase 2 Pending
PWA-09 Phase 2 Pending
PWA-10 Phase 2 Pending
SIGN-01 Phase 4 Pending
SIGN-02 Phase 4 Pending
SIGN-03 Phase 4 Pending
SIGN-04 Phase 4 Pending
SIGN-05 Phase 4 Pending
SIGN-06 Phase 4 Pending
SIGN-07 Phase 4 Pending
SIGN-08 Phase 4 Pending
SIGN-09 Phase 4 Pending
SIGN-10 Phase 4 Pending
EVENT-01 Phase 4 Pending
EVENT-02 Phase 4 Pending
EVENT-03 Phase 4 Pending
EVENT-04 Phase 4 Pending
LEAGUE-01 Phase 5 Pending
LEAGUE-02 Phase 5 Pending
LEAGUE-03 Phase 5 Pending
LEAGUE-04 Phase 5 Pending
LEAGUE-05 Phase 5 Pending
LEAGUE-06 Phase 5 Pending
REGION-01 Phase 5 Pending
REGION-02 Phase 5 Pending
REGION-03 Phase 5 Pending
REGION-04 Phase 5 Pending
REGION-05 Phase 5 Pending
TDD-01 Phase 6 Pending
TDD-02 Phase 6 Pending
TDD-03 Phase 6 Pending
TDD-04 Phase 6 Pending
TDD-05 Phase 6 Pending
TDD-06 Phase 6 Pending
TDD-07 Phase 6 Pending

Coverage:

  • v1 requirements: 152 total
  • Mapped to phases: 152
  • Unmapped: 0

Per-phase breakdown:

  • Phase 1 (Tournament Engine): 68
  • Phase 2 (Display Views + Player PWA): 25
  • Phase 3 (Core Sync + Platform Identity): 15
  • Phase 4 (Digital Signage + Events Engine): 14
  • Phase 5 (Leagues, Seasons + Regional Tournaments): 11
  • Phase 6 (TDD Migration): 7
  • Phase 7 (Hardware Leaf): 12

Requirements defined: 2026-02-28 Last updated: 2026-03-01 — roadmap reorganized from 11 phases to 7 (vertical slices, software-first/hardware-later, dev environment is x86 LXC not ARM64)