# Project Brief: OYS Borrow a Boat (oysqn.app) **Created:** 2026-04-21 **Owner:** Patrick Toal --- ## Identity - **App name:** OYS Borrow a Boat (oysqn.app) - **Previous app:** bab-app (Appwrite backend — retired) - **Purpose:** Manage a Borrow a Boat program for a Yacht Club (OYS = Oakville Yacht Squadron) - **Club:** Oakville Yacht Club, Oakville, ON Canada - **Target users:** Club members enrolled in the Borrow a Boat program --- ## Personas | Persona | Description | |---------|-------------| | BAB Member | Enrolled club member; can browse boats and make reservations | | Certified Skipper | Credentialed to take boats without supervision | | Program Administrator | Manages boats, intervals, rules, and member access | | Boatswain | Responsible for boat maintenance and readiness | | Volunteer | Assists with program logistics | | Instructor | Delivers sailing instruction; may certify members | --- ## Stack | Layer | Technology | |-------|-----------| | Framework | Nuxt 4 (SSR=false, SPA mode) | | UI | Ionic Vue (@ionic/vue) + PrimeVue 4 | | Language | TypeScript | | Backend | Supabase (Auth, DB, Edge Functions, Storage) | | Testing | Vitest (unit), Vitest (integration, hits real Supabase), Playwright (E2E) | | Package manager | Yarn | --- ## Architecture Highlights - `app/app.vue` — IonApp + IonMenu + IonRouterOutlet (no NuxtLayout/NuxtPage) - Auth: magic link + OTP only; no password auth; no self-service signup; admin-only invite - Edge Functions: Bearer JWT → `adminClient.auth.getUser(token)` pattern; all DB ops via service role - Icons: Ionicons only (`ionicons/icons`) --- ## CI/CD Pipeline - **Source control:** Gitea - **CI:** Gitea Actions (unit tests + build on PR) - **Deploy (dev):** EDA (Event-Driven Ansible) → AAP → nginx artifact swap on bab1 - **Deploy (prod):** EDA → AAP (manual approval gate) → S3 sync - **E2E:** Playwright, run post-deploy via AAP - **Supabase environments:** Two projects — dev and prod (project IDs in Vault) - **Secrets:** HashiCorp Vault at `http://nas.lan.toal.ca:8200`, path `kv/oys/` --- ## Current Phase [FILL: e.g., "Active development — reservations UI", "Beta testing", "Production"] --- ## Key Constraints - Deadline: April 30th (Launch Day) - Four boats in the program - Between 20 - 30 Members --- ## Booking Rules (known so far) - Weekly pre-booking limit enforced (exact number: 2) - Overlap constraint: same boat cannot be double-booked --- ## Planned Features (not yet built) See `docs/planning/user-stories.md` for full stories and open questions. | Feature | Stories | Phase | |---------|---------|-------| | Open Reservations + crew sign-up | US-01 – US-07 | Near-term | | Discord notifications (open reservations) | US-08 | Near-term | | Check-out / Check-in forms | US-10, US-11 | Near-term | | SMS / in-app notifications | US-09 | Longer-term | --- ## Open Items - [ ] Are cancel-reservation and admin Edge Functions planned? - [ ] What is the full set of admin pages needed? - [ ] What is the club name for display in the app? - [X] What is the season start date / go-live target? - [ ] US-07: What constitutes a "non-member" on a reservation? - [ ] US-10: What fields are on the check-out/in forms? - [ ] US-08: Discord webhook URL / channel — confirm stored in Vault at kv/oys/