singsalot/docs/PRD.md
Matt Bruce edc508b5e7 updated prd
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
2025-07-17 09:39:57 -05:00

184 lines
6.2 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🎤 Karaoke Web App — Product Requirements Document (PRD)
---
## 1⃣ Purpose
This document defines the functional, technical, and UX requirements for the Karaoke Web App, designed for **in-home party use**.
The app leverages **Firebase Realtime Database** for real-time synchronization, with all business logic and validation handled **client-side**.
---
## 2⃣ Scope & Business Objectives
- 🎯 Deliver a single-session karaoke experience where users connect to a controller and manage/search songs.
- ✅ Use Firebase for real-time multi-user sync of queues, history, and playback state.
- ✅ Prioritize fast performance, reusable modular architecture, and clear business logic separation.
- ✅ Enable adding songs from multiple entry points (search, history, top played).
- ✅ Ensure graceful handling of Firebase sync issues using retry patterns and partial node updates.
- ✅ True Separation of Concerns - UI components only handle presentation
- ✅ Reusable Business Logic - Hooks can be used across components
- ✅ Testable Code - Business logic separated from UI
- ✅ Maintainable - Changes to logic don't affect UI
- ✅ Performance - Memoized selectors and optimized hooks
- ✅ Type Safety - Full TypeScript coverage throughout
- The codebase needs to follow the Single Responsibility Principle perfectly - each file has one clear purpose!
---
## 3⃣ User Roles & Permissions
| Role | Search Songs | Add Songs | Delete Songs | Reorder Queue | Playback Control | Manage Singers |
|--------------|---------------|-----------|--------------|----------------|------------------|----------------|
| **Host/Admin** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Singer/User** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
---
## 4⃣ Feature Overview
- **Search:**
- Local, Redux-managed search on a preloaded song list.
- Common song item view with context-based action panel.
- **Queue Management:**
- Shared real-time synced queue.
- Admin can reorder; all users can delete songs.
- Duplicate prevention based on `fileLocation` field of each song.
- **Favorites:**
- Shared real-time synced.
- Anyone can do this
- Duplicate prevention based on `fileLocation` field of each song.
- **Latest Songs:**
- This is the newSongs node in the controller.
- Shared real-time synced.
- **Playback Control:**
- Managed by Admin only.
- Playback state synced to all clients using the `player` node in Firebase.
- The Player.state is mapped to the PlayerState enum in the types.ts.
- **History Tracking:**
- Songs added to history automatically when played.
- Append-only log, shared across clients.
- **Top Played:**
- Generated by a Firebase Cloud Function based on history.
- Stored inside the `controller` node for client reference.
- **Singer Management:**
- Admin can add/remove singers.
- All users can view the current singers list.
- **Error Handling:**
- Retry options for sync failures.
- Full controller object loaded on start; incremental sync after.
---
## 5⃣ Data Models
Data models are defined externally in:
> [`types.ts`](./types.ts)
This file contains TypeScript interfaces describing:
- `Song` — Used in queue, search results, and UI actions.
- `Controller` — Main object containing queue, singers, history, player state, and top played list.
- `PlayerState` — Playback status object synced in Firebase.
---
## 6⃣ Firebase Realtime Database Structure
Defined externally in:
> [`firebase_schema.json`](./firebase_schema.json)
Example structure:
```json
controllers: {
[controllerName]: {
favorites: { ... },
history: { ... },
topPlayed: { ... },
newSongs: { ... },
player: {
queue: { ... },
settings: { ... },
singers: { ... },
state: "..."
},
songList: { ... },
songs: { ... }
}
}
```
- Initial sync loads the full `controller` object.
- Subsequent updates target specific child nodes.
---
## 7⃣ UI/UX Behavior
- Shared **Empty State View** for empty lists or missing data.
- Toast notifications for user actions like add/remove/favorite.
- Playback controls only visible to Admin.
- Common song list item with dynamic action panel based on context (search, queue, history).
---
## 8⃣ Codebase Organization
| Folder | Purpose |
|--------|---------|
| `/components/common` | Shared UI components (EmptyState, Toast, ActionButton) |
| `/features` | Feature-specific components (Search, Queue, History, TopPlayed) |
| `/redux` | State management slices (controller, queue, player) |
| `/firebase` | Firebase CRUD and real-time sync services |
---
## 9⃣ Cloud Function Design — Top Played
- Triggered when a new song is added to `history`.
- Increments the play count inside `/controllers/{controllerName}/topPlayed/{songId}`.
- Ensures Top Played is up-to-date without blocking client-side actions.
---
## 🔟 External Reference Files
| File | Purpose |
|------|---------|
| [`types.ts`](./types.ts) | TypeScript interfaces for app data models and validation |
| [`firebase_schema.json`](./firebase_schema.json) | Firebase Realtime Database structure reference |
---
## 11⃣ Data Access Model & Validation
> **Client-Controlled Access Model**
This app does **not** use Firebase Realtime Database Security Rules.
All permissions, validation, and business logic are enforced in the client application.
### Enforced Client-Side:
- ✅ Admin-only permissions for queue reorder, playback control, and singer management.
- ✅ Duplicate song prevention enforced before adding to the queue.
- ✅ Singer is auto-added on join if not already present in the list.
- ✅ Data validated against `types.ts` before being written to Firebase.
**Assumed Environment:**
- The app is used in trusted, in-home scenarios with controlled participants.
- Open Firebase access is considered acceptable for this use case.
---
## ✅ Summary
This PRD serves as the primary source of truth for application logic, Firebase data flow, and feature requirements.
It works alongside `types.ts` and `firebase_schema.json` to inform both human developers and AI tools for accurate implementation.