# Project Felt — Phase 3 Product Specification ## Complete Venue Platform **Version:** 0.1 Draft **Date:** 2026-02-28 **Depends on:** Phase 1 (Tournaments) + Phase 2 (Cash Games) --- ## Table of Contents 1. [Overview](#1-overview) 2. [Dealer Management](#2-dealer-management) 3. [Player Loyalty System](#3-player-loyalty-system) 4. [Private Venues & Memberships](#4-private-venues--memberships) 5. [Venue Analytics & Reporting](#5-venue-analytics--reporting) 6. [Public Venue Presence](#6-public-venue-presence) 7. [Data Architecture](#7-data-architecture) 8. [API Design](#8-api-design) 9. [Roadmap](#9-roadmap) --- ## 1. Overview ### What Phase 3 Adds Phase 1 manages tournaments. Phase 2 manages cash games. Phase 3 manages **everything else** — the people, the relationships, and the business intelligence that turn a poker room into a venue that players return to. Phase 3 has four pillars: 1. **Dealer Management** — Scheduling, skills, shifts, rotation 2. **Player Loyalty** — Points, tiers, rewards, promotions 3. **Private Venues & Memberships** — Access control, member management, invitations 4. **Analytics & Public Presence** — Business intelligence, venue profiles, event publishing ### Design Principles 1. **Everything connects.** Dealer scheduling integrates with tournament and cash table assignments. Loyalty points accrue from tournaments AND cash games. Analytics aggregate across all operations. 2. **Progressive adoption.** Venues can enable Phase 3 features individually. A small bar might only want dealer scheduling. A large room wants everything. No feature forces adoption of another. 3. **Player-visible value.** Players should see the value of Phase 3 — loyalty rewards, membership benefits, career stats. This drives word-of-mouth to other venues. 4. **Operator simplicity.** Every Phase 3 feature must be simpler to use than the spreadsheet/whiteboard it replaces. If it's not, we've failed. --- ## 2. Dealer Management ### 2.1 Dealer Profiles Each dealer is a user in the system (they may also be a player — dual roles supported). Their profile contains: **Identity:** Name, contact info, photo, employee ID (venue-assigned) **Skill Tags:** | Category | Tags (examples) | |----------|----------------| | Game variants | Hold'em, Omaha, PLO Hi-Lo, Stud, Razz, Draw, Short Deck, Mixed | | Betting structures | No-Limit, Pot-Limit, Fixed-Limit | | Format specialization | Cash games, Tournaments, Both | | Experience level | Trainee, Standard, Experienced, Senior | | Special skills | High-stakes tables, Final table dealing, Celebrity/VIP events | | Languages | Danish, English, German, etc. | Skills are tagged by the venue manager. A dealer can request skill additions (e.g., after training on a new game), subject to manager approval. **Availability Windows:** Dealers set weekly recurring availability (e.g., "Available Mon-Fri 4PM-12AM, Sat 12PM-12AM, not available Sunday"). They can override specific dates (e.g., "Unavailable Dec 24-26"). The scheduling system respects these. ### 2.2 Schedule Management **Shift Templates:** Venues define recurring shift templates: ``` Morning: 10:00 — 18:00 Afternoon: 14:00 — 22:00 Evening: 18:00 — 02:00 Tournament: Based on tournament schedule (variable) Split: 10:00 — 14:00, 18:00 — 22:00 ``` Templates are building blocks. The actual schedule is assembled from templates assigned to specific dealers on specific dates. **Schedule Builder (Operator UI):** Week view with dealers on the Y-axis and days on the X-axis. Drag-and-drop shift assignment. Color-coded by shift type. Conflict detection (double-booking, availability violations, skill mismatch) shown in real-time. ``` ┌──────────────────────────────────────────────────────────────┐ │ DEALER SCHEDULE — Week of Mar 2 │ │ │ │ Mon Tue Wed Thu Fri Sat Sun │ │ Anna K. [Eve] [Eve] [---] [Eve] [Eve] [Aft] [---] │ │ Mike S. [Mor] [Mor] [Mor] [Mor] [Mor] [---] [---] │ │ Chris L. [Aft] [---] [Aft] [Aft] [Eve] [Eve] [Aft] │ │ Sarah D. [---] [Aft] [Eve] [---] [Aft] [Eve] [Eve] │ │ Tom H. [Mor] [Mor] [Mor] [Mor] [---] [Mor] [---] │ │ │ │ ⚠ Warning: Friday Evening needs 3 dealers, only 2 assigned │ │ ⚠ Warning: Chris L. exceeds 40h this week │ └──────────────────────────────────────────────────────────────┘ ``` **Scheduling constraints (auto-enforced):** - Maximum hours per week (configurable, default 40) - Minimum rest between shifts (configurable, default 10 hours) - Availability windows respected - Skill requirements per table/game met - Minimum staffing levels per shift (configurable) ### 2.3 Shift Trading Dealers can trade shifts with each other — the system facilitates this while enforcing skill requirements. **Trading flow:** 1. Dealer A posts a shift for trade ("Friday Evening available") 2. System shows the post to all dealers who: (a) are available that day, (b) have the required skills, (c) wouldn't exceed hour limits 3. Dealer B offers to take it 4. If manager approval is required (venue-configurable): manager approves/rejects 5. If no approval required: trade is instant 6. Both dealers notified. Schedule updated. Audit log recorded. **Drop without trade:** A dealer can drop a shift (with enough notice, venue-configurable). The system posts it as an open shift. If unclaimed by a threshold time, the manager is notified. ### 2.4 Dealer Assignment to Tables Phase 3 connects dealer scheduling to Phase 1 (tournaments) and Phase 2 (cash games): **Cash game dealer assignment:** - Operator assigns a dealer to a cash table from the on-shift dealer pool - System shows only dealers who: (a) are on shift, (b) have the matching game skill - Dealer rotation timer (configurable: push every 30/45/60 minutes) - When the rotation timer hits, system suggests the next dealer and shows who's available **Tournament dealer assignment:** - Tournament tables can have assigned dealers - Multi-table tournaments: dealers rotate across tables per the rotation schedule - Final table: system can flag dealers with "final table" skill for assignment ### 2.5 Dealer Mobile Experience Dealers access their schedule and shift management via the same mobile PWA (role-based views): - **My Schedule:** See upcoming shifts, with venue details and game/table assignments - **Trade Board:** See available shifts for trade. Offer to take shifts. Post own shifts. - **Clock In/Out:** Tap to start/end shift. Automatic time tracking. - **Notifications:** Shift reminders, trade offers, schedule changes, rotation alerts - **Hours Summary:** Current week hours, pay period total, overtime status ### 2.6 Work Hours & Reporting **Automatic tracking:** Clock-in/clock-out via mobile or Leaf UI. Break tracking (configurable: paid/unpaid breaks, minimum break duration compliance). **Reports (for venue manager):** - Hours per dealer per period (week, month, pay period) - Overtime alerts - No-show / late arrival log - Shift trade history - Skill utilization (which game skills are most in-demand) **Export:** CSV for payroll integration. Standard format compatible with common payroll systems. --- ## 3. Player Loyalty System ### 3.1 Points Engine Points are the currency of loyalty. Venues configure how players earn them. **Point accrual rules (all configurable):** | Activity | Default Points | Example | |----------|---------------|---------| | Tournament entry | 1 point per €1 buy-in | €50 tournament = 50 points | | Tournament finish (top 10%) | Bonus 50 points | ITM finish = bonus | | Cash game play | 1 point per hour | 4-hour session = 4 points | | Cash game buy-in | 0.5 points per €1 | €200 buy-in = 100 points | | League participation | 10 points per event | Season regular = loyalty bonus | | Referral | 25 points per new player | Bring a friend | | Special events | Custom | Venue-defined promotions | **Multipliers (stackable):** - Time-based: "2x points on Tuesday nights" (drive traffic on slow nights) - Game-based: "1.5x points on PLO tables" (incentivize new games) - Tier-based: "Gold members earn 1.5x base points" - Event-based: "3x points during anniversary week" **Point expiry:** Configurable. Options: never expire, expire after X months of inactivity, expire after calendar year. Venues choose. ### 3.2 Tier System Players progress through tiers based on point accumulation: | Tier | Threshold (example) | Benefits (example) | |------|--------------------|--------------------| | Bronze | 0 points | Base point earning, basic profile | | Silver | 500 points/quarter | 1.25x point multiplier, priority waitlist | | Gold | 2,000 points/quarter | 1.5x multiplier, free tournament entry/month, comp credits | | Platinum | 5,000 points/quarter | 2x multiplier, VIP event access, dedicated floor contact | **Tier configuration:** - Tier names, thresholds, and benefits are fully customizable per venue - Evaluation period: monthly, quarterly, or annual - Tier maintenance: "maintain or drop" vs. "earn once, keep forever" (venue choice) - Grace period: configurable period before tier demotion (e.g., 1 month grace after missing threshold) ### 3.3 Rewards Catalog Venues define what players can spend points on: | Category | Examples | |----------|---------| | Tournament entries | Free buy-in to weekly tournament (500 points) | | Food & beverage | €10 bar credit (200 points), free coffee (50 points) | | Merchandise | Venue t-shirt (1,000 points), branded card protector (300 points) | | Seat upgrades | Priority seat selection in next tournament (100 points) | | Cash game | Free hour of rake-free play (800 points) | | Events | VIP event invitation (2,000 points) | | Custom | Whatever the venue wants to offer | **Redemption flow:** 1. Player views rewards on mobile → selects reward → confirms 2. System deducts points, generates reward voucher with unique code 3. Player shows voucher to staff (or staff scans QR code) 4. Staff marks voucher as redeemed in the system 5. All tracked for analytics (which rewards are popular, cost per redemption) ### 3.4 Automated Promotions Venues can create promotions that trigger automatically: **Promotion types:** - **Time-based:** "Double points every Wednesday 2-6PM" - **Birthday:** "100 bonus points on your birthday month" - **Win-back:** "Been away 30+ days? Come back and earn 3x points this visit" - **Achievement:** "Play your 100th tournament? 500 bonus points" - **Seasonal:** "Holiday tournament series — 2x points on all December events" - **Referral:** "Refer a friend who plays 3 events — both get 200 bonus points" Promotions are created in the operator UI with start/end dates, targeting rules, and automatic application. No manual tracking. ### 3.5 Cross-Venue Loyalty (Multi-Venue Operators) For operators running multiple venues: - Player loyalty tier is shared across all venues - Points earned at any venue count toward tier status - Rewards can be redeemed at any venue (or restricted to earning venue — operator choice) - Leaderboards can span all venues or be venue-specific - Corporate-level promotions push to all venues ### 3.6 Display & Mobile Integration **Player mobile view:** ``` ┌─────────────────────────────┐ │ MY LOYALTY │ │ │ │ ★ GOLD MEMBER │ │ 2,450 / 5,000 to Platinum │ │ ████████░░░░ 49% │ │ │ │ Available Points: 1,200 │ │ Lifetime Points: 8,750 │ │ │ │ [View Rewards] [History] │ │ │ │ Active Promotions: │ │ 🔥 2x points tonight! │ │ 🎂 Birthday month bonus │ └─────────────────────────────┘ ``` **Display node views:** - Loyalty leaderboard (top earners this month/quarter) - Current promotions ("2x Points Tonight!") - Tier benefits overview - All auto-cycle in signage playlists --- ## 4. Private Venues & Memberships ### 4.1 Venue Privacy Modes | Mode | Visibility | Registration | |------|-----------|-------------| | Public | Anyone sees schedule, events, games | Open — anyone can join | | Semi-Private | Schedule visible, limited detail | Requires application + approval | | Private | Invisible to non-members | Invite-only | Privacy mode affects: - Public venue page visibility - Whether the venue appears in search/discovery - Whether events are listed publicly - Whether non-members can join waitlists or register for tournaments ### 4.2 Membership Management **Membership tiers (venue-defined):** | Tier | Example | Access | |------|---------|--------| | Standard | €20/month | Tournament access, cash game access | | Premium | €50/month | + Priority waitlist, league eligibility | | VIP | €100/month | + High-stakes games, private events, guest passes | | Founding | By invitation | Full access, lifetime rate, governance input | **Member lifecycle:** 1. **Application:** Player applies via venue page or invitation link 2. **Approval:** Venue operator reviews application. Auto-approve rules (e.g., referred by existing member) available. 3. **Payment:** Monthly/annual fee (tracked in Felt — payment processing via Stripe or venue's own system) 4. **Active membership:** Access granted per tier 5. **Renewal:** Auto-reminder before expiry. Grace period configurable. 6. **Suspension/Cancellation:** Operator can suspend or cancel. Player can self-cancel with configurable notice period. **Invite system:** - Members generate invite links (limited per member per month — configurable) - Invited players get a pre-approved application - Referral credit for the inviting member (loyalty points or other reward) - Guest passes: temporary access for specific events (configurable per tier — e.g., VIP members get 2 guest passes per month) ### 4.3 Member Communications **In-app messaging:** - Venue → all members (announcements) - Venue → tier-specific (e.g., VIP event invitations) - Venue → individual member (private message) - Delivered via mobile PWA notification + optional email/SMS **Automated communications:** - Welcome message on membership approval - Renewal reminders (7 days, 1 day before expiry) - Event announcements (new tournaments, special events) - Membership tier changes (upgrade/downgrade notifications) - Win-back messages for lapsed members ### 4.4 Member Directory (Optional) Venues can enable a member directory (privacy settings per member): - Members can see who else is a member (first name + last initial) - Opt-in: members choose what to share (photo, game preferences, bio) - Useful for building community in private clubs - Disabled by default — venue must explicitly enable --- ## 5. Venue Analytics & Reporting ### 5.1 Revenue Dashboard **Real-time revenue tracking:** - Tournament revenue: entry fees collected, house take - Cash game revenue: rake collected per table, per game type - Membership revenue: fees collected - Combined: total revenue by day/week/month/year **Visualizations:** - Revenue trend line (last 30/90/365 days) - Revenue by source (pie: tournaments vs. cash vs. memberships) - Revenue by game type (which games make the most money?) - Revenue by day of week (which nights are strongest?) - Revenue by time of day (when are the peak revenue hours?) ### 5.2 Player Analytics **Player engagement metrics:** - Active players (played in last 7/30/90 days) - New player acquisition rate - Player retention rate (% returning within 30 days) - Player lifetime value (total revenue attributed per player) - Visit frequency distribution **Player segmentation:** - By game preference (tournament vs. cash vs. both) - By stakes level - By loyalty tier - By visit frequency (regular, occasional, lapsed) - By value (high-value, medium, low) All player analytics are aggregated — individual player data is not exposed to other players. ### 5.3 Operational Analytics **Table utilization:** - Seats occupied vs. available over time (heatmap by hour of day / day of week) - Average table utilization rate - Table open/close patterns **Tournament analytics:** - Fill rates (registered vs. capacity) - Average entries per tournament - Most popular tournament formats - Late registration patterns - Prize pool trends **Waitlist analytics:** - Average wait time by game/stakes - Waitlist conversion rate (joined → seated) - Waitlist abandonment rate - Peak demand times **Dealer analytics:** - Hours worked per dealer - Shift coverage rates - Trade frequency - Rotation compliance ### 5.4 Multi-Venue Benchmarking For operators with multiple venues: - Side-by-side venue comparison (revenue, utilization, player engagement) - Identify best practices from top-performing venues - Flag underperforming venues with specific metrics - Cross-venue player flow (which players play at multiple venues?) ### 5.5 Export & Integration - **CSV export:** All reports exportable for Excel/accounting - **PDF reports:** Formatted reports for stakeholders - **API access:** All analytics available via REST API for custom integrations - **Scheduled reports:** Auto-generate and email weekly/monthly reports to venue owner --- ## 6. Public Venue Presence ### 6.1 Venue Profile Page Each venue gets a public page at `venue-name.felt.io` (or custom domain): - Venue name, logo, photos, description - Location with map - Hours of operation - Current games running (live, for public venues) - Upcoming events and tournaments - Game offerings (types and stakes) - Contact information SEO-optimized for "poker near [city]" searches. ### 6.2 Event Publishing **Automated schedule publishing:** - Weekly tournament schedule auto-published to venue page - Upcoming special events with registration - League schedules and current standings **External publishing (API integrations):** - Poker Atlas format export (automatic submission) - Hendon Mob format export (tournament results) - Social media API integration (auto-post new events to venue's Facebook/Instagram) - iCal feed for players to subscribe to venue schedule ### 6.3 Online Registration Players can register for upcoming tournaments from the venue page: - View tournament details (format, buy-in, blind structure, starting stack) - Register (with or without pre-payment — venue configurable) - See current registrant count and capacity - Cancel registration (within venue's cancellation policy) - Automatic reminders before the event --- ## 7. Data Architecture ### New Tables (extends Phase 1 + 2 schema) ```sql -- ===================== -- DEALER MANAGEMENT -- ===================== CREATE TABLE dealers ( id TEXT PRIMARY KEY, player_id TEXT REFERENCES players(id), -- Dealer may also be a player name TEXT NOT NULL, email TEXT, phone TEXT, photo_url TEXT, employee_id TEXT, status TEXT NOT NULL DEFAULT 'active', -- active, inactive, terminated hire_date DATE, notes TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE dealer_skills ( id TEXT PRIMARY KEY, dealer_id TEXT NOT NULL REFERENCES dealers(id), skill_type TEXT NOT NULL, -- game_variant, betting, format, experience, special, language skill_value TEXT NOT NULL, -- "holdem", "no_limit", "tournament", "senior", "high_stakes", "danish" verified BOOLEAN NOT NULL DEFAULT false, verified_by TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE shift_templates ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- "Evening" start_time TIME NOT NULL, -- "18:00" end_time TIME NOT NULL, -- "02:00" break_minutes INTEGER DEFAULT 0, color TEXT, -- Hex color for schedule UI created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE dealer_schedules ( id TEXT PRIMARY KEY, dealer_id TEXT NOT NULL REFERENCES dealers(id), date DATE NOT NULL, template_id TEXT REFERENCES shift_templates(id), start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, status TEXT NOT NULL DEFAULT 'scheduled', -- scheduled, confirmed, in_progress, completed, no_show, traded actual_start DATETIME, actual_end DATETIME, notes TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE(dealer_id, date, template_id) ); CREATE TABLE dealer_availability ( id TEXT PRIMARY KEY, dealer_id TEXT NOT NULL REFERENCES dealers(id), day_of_week INTEGER, -- 0=Mon, 6=Sun (NULL for specific date override) specific_date DATE, -- For one-off availability changes available_from TIME, -- NULL = not available available_to TIME, is_available BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE shift_trades ( id TEXT PRIMARY KEY, schedule_id TEXT NOT NULL REFERENCES dealer_schedules(id), offering_dealer TEXT NOT NULL REFERENCES dealers(id), taking_dealer TEXT REFERENCES dealers(id), -- NULL = open for offers status TEXT NOT NULL DEFAULT 'posted', -- posted, offered, approved, completed, cancelled requires_approval BOOLEAN NOT NULL DEFAULT false, approved_by TEXT, approved_at DATETIME, notes TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE dealer_time_clock ( id TEXT PRIMARY KEY, dealer_id TEXT NOT NULL REFERENCES dealers(id), schedule_id TEXT REFERENCES dealer_schedules(id), clock_in DATETIME NOT NULL, clock_out DATETIME, break_start DATETIME, break_end DATETIME, total_hours REAL, -- Calculated on clock-out created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- ===================== -- LOYALTY SYSTEM -- ===================== CREATE TABLE loyalty_config ( id TEXT PRIMARY KEY, venue_id TEXT NOT NULL, point_expiry_months INTEGER, -- NULL = never expire evaluation_period TEXT DEFAULT 'quarterly', -- monthly, quarterly, annual grace_period_days INTEGER DEFAULT 30, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_tiers ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- "Gold" sort_order INTEGER NOT NULL, threshold_points INTEGER NOT NULL, -- Points needed per evaluation period point_multiplier REAL NOT NULL DEFAULT 1.0, color TEXT, -- Hex color for UI icon TEXT, -- Icon identifier benefits_json TEXT, -- JSON description of benefits created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_accrual_rules ( id TEXT PRIMARY KEY, activity_type TEXT NOT NULL, -- tournament_entry, cash_hour, cash_buyin, league_event, referral, custom points_per_unit REAL NOT NULL, -- Points per €1, per hour, per event, etc. unit TEXT NOT NULL, -- "currency", "hour", "event", "flat" conditions_json TEXT, -- Optional JSON conditions (game type, stakes, time window) is_active BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_multipliers ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- "Tuesday Double Points" multiplier REAL NOT NULL, -- 2.0 for double conditions_json TEXT NOT NULL, -- Time windows, game types, tier requirements start_date DATETIME, end_date DATETIME, is_active BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE player_loyalty ( id TEXT PRIMARY KEY, player_id TEXT NOT NULL REFERENCES players(id) UNIQUE, current_tier_id TEXT REFERENCES loyalty_tiers(id), current_points INTEGER NOT NULL DEFAULT 0, lifetime_points INTEGER NOT NULL DEFAULT 0, period_points INTEGER NOT NULL DEFAULT 0, -- Points in current evaluation period tier_locked_until DATETIME, -- Grace period end created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_transactions ( id TEXT PRIMARY KEY, player_id TEXT NOT NULL REFERENCES players(id), type TEXT NOT NULL, -- earn, redeem, expire, adjust points INTEGER NOT NULL, -- Positive for earn, negative for redeem/expire source TEXT, -- tournament_id, session_id, promotion_id, reward_id description TEXT, -- "Tournament entry: Friday €50 NLH" balance_after INTEGER NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_rewards ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- "Free Tournament Entry" description TEXT, category TEXT NOT NULL, -- tournament, food_beverage, merchandise, seat, cash_game, event, custom points_cost INTEGER NOT NULL, min_tier_id TEXT REFERENCES loyalty_tiers(id), -- Minimum tier to access this reward quantity_available INTEGER, -- NULL = unlimited quantity_redeemed INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_redemptions ( id TEXT PRIMARY KEY, player_id TEXT NOT NULL REFERENCES players(id), reward_id TEXT NOT NULL REFERENCES loyalty_rewards(id), points_spent INTEGER NOT NULL, voucher_code TEXT NOT NULL UNIQUE, status TEXT NOT NULL DEFAULT 'issued', -- issued, redeemed, expired, cancelled redeemed_at DATETIME, redeemed_by TEXT, -- Staff member who confirmed redemption expires_at DATETIME, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE loyalty_promotions ( id TEXT PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL, -- time_based, birthday, winback, achievement, seasonal, referral config_json TEXT NOT NULL, -- Trigger conditions, point amounts, multipliers start_date DATETIME, end_date DATETIME, is_active BOOLEAN NOT NULL DEFAULT true, auto_apply BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- ===================== -- MEMBERSHIPS -- ===================== CREATE TABLE membership_tiers ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- "VIP" description TEXT, monthly_fee INTEGER, -- Cents (NULL = free tier) annual_fee INTEGER, -- Cents (discounted annual option) max_members INTEGER, -- NULL = unlimited guest_passes_monthly INTEGER DEFAULT 0, benefits_json TEXT, -- JSON description of access and benefits sort_order INTEGER NOT NULL, is_active BOOLEAN NOT NULL DEFAULT true, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE memberships ( id TEXT PRIMARY KEY, player_id TEXT NOT NULL REFERENCES players(id), tier_id TEXT NOT NULL REFERENCES membership_tiers(id), status TEXT NOT NULL DEFAULT 'pending', -- pending, active, suspended, cancelled, expired applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, approved_at DATETIME, approved_by TEXT, billing_cycle TEXT DEFAULT 'monthly', -- monthly, annual current_period_start DATETIME, current_period_end DATETIME, auto_renew BOOLEAN NOT NULL DEFAULT true, cancelled_at DATETIME, cancel_reason TEXT, invited_by TEXT REFERENCES players(id), invite_code TEXT, notes TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE guest_passes ( id TEXT PRIMARY KEY, member_id TEXT NOT NULL REFERENCES memberships(id), guest_name TEXT NOT NULL, guest_email TEXT, event_id TEXT, -- Specific event, or NULL for general access valid_date DATE NOT NULL, status TEXT NOT NULL DEFAULT 'issued', -- issued, used, expired, cancelled used_at DATETIME, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE venue_settings_privacy ( id TEXT PRIMARY KEY, privacy_mode TEXT NOT NULL DEFAULT 'public', -- public, semi_private, private show_schedule BOOLEAN NOT NULL DEFAULT true, show_games BOOLEAN NOT NULL DEFAULT true, show_waitlist BOOLEAN NOT NULL DEFAULT false, require_membership BOOLEAN NOT NULL DEFAULT false, member_directory_enabled BOOLEAN NOT NULL DEFAULT false, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); ``` --- ## 8. API Design ### Dealer Management ``` GET /dealers List dealers POST /dealers Create dealer profile GET /dealers/:id Get dealer detail PUT /dealers/:id Update dealer POST /dealers/:id/skills Add skill DELETE /dealers/:id/skills/:skillId Remove skill GET /schedule Get schedule (date range, filters) POST /schedule Assign shift PUT /schedule/:id Update shift DELETE /schedule/:id Remove shift GET /shifts/templates List shift templates POST /shifts/templates Create template POST /shifts/trades Post shift for trade GET /shifts/trades List available trades POST /shifts/trades/:id/offer Offer to take shift POST /shifts/trades/:id/approve Approve trade (manager) POST /dealers/:id/clock-in Clock in POST /dealers/:id/clock-out Clock out GET /dealers/:id/hours Hours report (date range) ``` ### Loyalty System ``` GET /loyalty/config Get loyalty configuration PUT /loyalty/config Update loyalty configuration GET /loyalty/tiers List tiers POST /loyalty/tiers Create tier PUT /loyalty/tiers/:id Update tier GET /loyalty/rules List accrual rules POST /loyalty/rules Create rule GET /loyalty/multipliers List active multipliers POST /loyalty/multipliers Create multiplier GET /loyalty/rewards List available rewards POST /loyalty/rewards Create reward POST /loyalty/redeem Redeem reward (player) POST /loyalty/redemptions/:id/confirm Confirm redemption (staff) GET /loyalty/promotions List promotions POST /loyalty/promotions Create promotion GET /loyalty/leaderboard Loyalty leaderboard ``` ### Player Loyalty (Mobile) ``` GET /me/loyalty My loyalty status (tier, points, promotions) GET /me/loyalty/history My point transaction history GET /me/loyalty/rewards Available rewards for my tier POST /me/loyalty/redeem Redeem a reward GET /me/loyalty/vouchers My active vouchers ``` ### Memberships ``` GET /memberships/tiers List membership tiers POST /memberships/apply Apply for membership GET /memberships List all memberships (operator) PUT /memberships/:id Update membership (approve, suspend, etc.) POST /memberships/:id/renew Trigger renewal POST /memberships/:id/guest-pass Issue guest pass GET /memberships/:id/guest-passes List guest passes GET /me/membership My membership status POST /me/membership/cancel Cancel my membership POST /me/membership/invite Generate invite link ``` ### Analytics ``` GET /analytics/revenue Revenue dashboard (date range, source filters) GET /analytics/players Player engagement metrics GET /analytics/tables Table utilization metrics GET /analytics/tournaments Tournament performance metrics GET /analytics/waitlist Waitlist analytics GET /analytics/dealers Dealer metrics GET /analytics/loyalty Loyalty program metrics GET /analytics/export Export report (CSV/PDF) ``` ### Public Venue ``` GET /venue/profile Public venue profile PUT /venue/profile Update venue profile (operator) GET /venue/schedule Public event schedule GET /venue/games Current games (public venues) POST /venue/events/:id/register Register for event (player) GET /venue/events/:id/registrations List registrations (operator) ``` --- ## 9. Roadmap ### v3.0 — Dealer Management - Dealer profiles with skill tags - Shift templates and schedule builder - Shift trading system - Clock-in/clock-out with hours tracking - Dealer assignment to cash tables and tournaments - Dealer mobile experience (schedule, trade board, clock) - Basic reporting (hours, shifts, trades) ### v3.1 — Player Loyalty - Points engine with configurable accrual rules - Tier system with automated evaluation - Rewards catalog and redemption flow - Point multipliers (time-based, game-based, tier-based) - Loyalty display on mobile and venue screens - Basic promotions (birthday, time-based) ### v3.2 — Memberships & Privacy - Venue privacy modes (public, semi-private, private) - Membership tiers with fee tracking - Application and approval workflow - Invite system and guest passes - Member communications - Optional member directory ### v3.3 — Analytics & Public Presence - Revenue dashboards - Player engagement analytics - Operational analytics (tables, waitlists, tournaments) - Public venue profile page - Event publishing with online registration - External publishing (Poker Atlas, Hendon Mob, social) - Scheduled reports ### v3.4 — Advanced Features - Cross-venue loyalty (multi-venue operators) - Multi-venue benchmarking analytics - Dealer rotation automation - Advanced promotions engine (winback, achievement, referral chains) - Custom reporting builder - API access for third-party integrations - White-label options for enterprise --- *Phase 3 turns Felt from a poker management tool into the operating system for the venue. At this point, every tournament, every cash game, every dealer shift, every player visit, every dollar — it all flows through Felt. That's the endgame.*