# RFC - Classes MVP v0 ## Status - Proposed ## Summary - Build the first student-facing Ballbox surface under `/classes`. - Use Ballbox-local coaches and class offers. - Enrich offers with real ATC public-read availability context. - Let authenticated students submit `solicitar` requests. ## Why This Wedge - The real problem is not that coaches reserve courts manually in chat. - The bigger drain is that coaches coordinate interest, answer messages, propose times, and absorb repetitive 1:N scheduling friction. - A student-facing request surface can remove that load earlier and more clearly than a coach workspace. ## Product Direction - Primary wedge: student-facing class discovery + request - Main route: `/classes` - Main CTA: `solicitar` - Future routes: - `/classes/me` - `/coaches` for operator workflows ## Auth - `/classes/*` protected by a simple dedicated session - Cookie: `ballbox_student_session` - Password env: `BALLBOX_STUDENT_PASSWORD` - Future `/coaches/*` should use separate coach auth ## Ballbox-Owned Data ### Keep local - `Coach` - `ClassOffer` - `ClassRequest` ### Do not depend on ATC for - coach identity - professor records - student request state ## ATC Scope For v0 ### Use now - public-read availability endpoints only - club, court, slot, duration, and public price context ### Do not require for v0 - ATC admin users - ATC professor records - booking writes - internal booking details ## Proposed Domain Changes ### Existing model - keep Ballbox `Coach` ### New model: `ClassOffer` - `id` - `coachId` - `venueId` - `title` - `description?` - `startsAt` - `durationMinutes?` - `priceMinor?` - `currency?` - `atcSportclubId?` - `atcCourtId?` - `status` - `createdAt` - `updatedAt` ### New model: `ClassRequest` - `id` - `classOfferId` - `studentName` - `studentEmail` - `studentPhone?` - `message?` - `status` - `createdAt` - `updatedAt` ### Suggested enums - `ClassOfferStatus`: `ACTIVE | INACTIVE` - `ClassRequestStatus`: `NEW | CONTACTED | CONFIRMED | REJECTED | EXPIRED` ## UX Scope ### `/classes` - list of active offers - visible coach name - visible venue / time - visible ATC context when linked - CTA to open detail ### `/classes/[offerId]` - richer offer detail - request form - ATC context panel ## API Scope - `POST /api/classes/session` - `POST /api/classes/logout` - `GET /api/classes/offers` - `GET /api/classes/offers/[offerId]` - `POST /api/classes/requests` ## Implementation Notes - Use the same simple auth pattern as admin, but with student-specific cookie/env names. - Add `/classes/*` protection in `proxy.ts`. - Seed a few demo coaches and class offers in Ballbox DB. - ATC availability in v0 should come from public-read endpoints, not invented fake slot data. - If ATC data is unavailable, Ballbox should still show the offer but mark availability context as unavailable. ## Non-goals - full booking checkout - ATC write integration - full coach workspace - multi-tenant identity system ## Acceptance Criteria - student can authenticate into `/classes` - student sees offers backed by Ballbox-local data - at least some offers display ATC public-read context - student can submit `solicitar` - request persists locally - no regression in `/admin` ## Immediate Follow-up - evolve generic `solicitar` into `solicitar este horario` using real ATC public-read slots - let the student choose a specific day/time before submitting, without exposing court choice yet - keep the copy as request/confirmation, not automatic reservation - add `/classes/me` - add lightweight operator review surface - expand toward coach/operator workflows under `/coaches`