- Add email_verified, verification_token, reset_token fields to User model - Create email_service.py with SendGrid integration - Add auth endpoints: verify-email, resend-verification, forgot-password, reset-password - Create frontend pages: /verify-email, /forgot-password, /reset-password - Add forgot password link to login page - Add PLATFORM_ENHANCEMENT_SPEC.md specification
323 lines
9.1 KiB
Markdown
323 lines
9.1 KiB
Markdown
# Platform Enhancement Spec v2.0
|
|
|
|
> **Sprint Goal**: Complete user lifecycle management, robust admin tools, and enhanced content features.
|
|
|
|
---
|
|
|
|
## Phase 1: User Account Lifecycle
|
|
|
|
### 1.1 Email Verification
|
|
|
|
**Goal**: Ensure valid email addresses and reduce spam accounts.
|
|
|
|
#### User Stories
|
|
|
|
- As a **new user**, I want to receive a verification email so I can confirm my account.
|
|
- As a **user**, I want to resend verification if I didn't receive it.
|
|
- As an **unverified user**, I see limited functionality until verified.
|
|
|
|
#### Implementation
|
|
|
|
1. **Model Changes** - Add to `User`:
|
|
- `email_verified: bool = Field(default=False)`
|
|
- `verification_token: Optional[str]`
|
|
- `verification_token_expires: Optional[datetime]`
|
|
|
|
2. **API Endpoints**:
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/register` | Creates user + sends verification email |
|
|
| POST | `/auth/verify-email` | Verifies token, sets `email_verified=True` |
|
|
| POST | `/auth/resend-verification` | Generates new token, sends email |
|
|
|
|
3. **Frontend Pages**:
|
|
- `/verify-email?token=xxx` - Handles verification link
|
|
- Registration success page prompts to check email
|
|
|
|
4. **Email Template**: HTML email with verification link (48hr expiry)
|
|
|
|
---
|
|
|
|
### 1.2 Password Reset
|
|
|
|
**Goal**: Self-service password recovery without admin intervention.
|
|
|
|
#### User Stories
|
|
|
|
- As a **user**, I want to reset my password if I forgot it.
|
|
- As a **user**, I want a secure, time-limited reset link.
|
|
|
|
#### Implementation
|
|
|
|
1. **Model Changes** - Add to `User`:
|
|
- `reset_token: Optional[str]`
|
|
- `reset_token_expires: Optional[datetime]`
|
|
|
|
2. **API Endpoints**:
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/forgot-password` | Sends reset email (rate limited) |
|
|
| POST | `/auth/reset-password` | Validates token + sets new password |
|
|
|
|
3. **Frontend Pages**:
|
|
- `/forgot-password` - Email input form
|
|
- `/reset-password?token=xxx` - New password form
|
|
|
|
4. **Security**:
|
|
- Tokens expire in 1 hour
|
|
- Single-use tokens (invalidated after use)
|
|
- Rate limiting on forgot-password endpoint
|
|
|
|
---
|
|
|
|
### 1.3 Email Service Abstraction
|
|
|
|
**Goal**: Provider-agnostic email sending.
|
|
|
|
#### Implementation
|
|
|
|
Create `backend/email_service.py`:
|
|
|
|
```python
|
|
class EmailService:
|
|
async def send_verification_email(user, token)
|
|
async def send_password_reset_email(user, token)
|
|
async def send_notification_email(user, subject, body)
|
|
```
|
|
|
|
#### Environment Variables
|
|
|
|
```env
|
|
SMTP_HOST=smtp.sendgrid.net
|
|
SMTP_PORT=587
|
|
SMTP_USER=apikey
|
|
SMTP_PASSWORD=<secret>
|
|
EMAIL_FROM=noreply@elmeg.xyz
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 2: Admin Panel (`/admin`)
|
|
|
|
### 2.1 Overview
|
|
|
|
**Goal**: Full content management for administrators.
|
|
|
|
#### User Stories
|
|
|
|
- As an **admin**, I want to manage all users (roles, bans, verification status).
|
|
- As an **admin**, I want to CRUD shows, songs, venues, and tours.
|
|
- As an **admin**, I want to see platform statistics.
|
|
|
|
---
|
|
|
|
### 2.2 Features
|
|
|
|
#### Users Tab
|
|
|
|
- DataTable with search/filter
|
|
- Columns: Email, Username, Role, Verified, Active, Joined
|
|
- Actions: Edit role, Toggle ban, Force verify, View activity
|
|
|
|
#### Content Tabs (Shows, Songs, Venues, Tours)
|
|
|
|
- DataTable with CRUD actions
|
|
- Create/Edit modals with form validation
|
|
- YouTube link fields for Shows/Songs/Performances
|
|
- Bulk delete with confirmation
|
|
|
|
#### Stats Dashboard
|
|
|
|
- Total users, verified users
|
|
- Total shows, songs, venues
|
|
- Recent signups chart
|
|
- Activity heatmap
|
|
|
|
---
|
|
|
|
### 2.3 Access Control
|
|
|
|
```python
|
|
# backend/routers/admin.py
|
|
allow_admin = RoleChecker(["admin"])
|
|
|
|
@router.get("/users")
|
|
def list_users(user: User = Depends(allow_admin), ...):
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3: Enhanced Mod Panel (`/mod`)
|
|
|
|
### 3.1 Current Features
|
|
|
|
- ✅ Nickname approval queue
|
|
- ✅ Report queue (comments, reviews)
|
|
|
|
### 3.2 New Features
|
|
|
|
#### User Lookup
|
|
|
|
- Search user by email/username
|
|
- View user's full activity history:
|
|
- Comments, reviews, ratings
|
|
- Attendance history
|
|
- Reports submitted/received
|
|
|
|
#### Temp Bans
|
|
|
|
- Ban duration selector (1hr, 24hr, 7d, 30d, permanent)
|
|
- Ban reason (required)
|
|
- Auto-unban via scheduled job
|
|
|
|
#### Bulk Actions
|
|
|
|
- Select multiple reports → Dismiss All / Resolve All
|
|
- Select multiple nicknames → Approve All / Reject All
|
|
|
|
#### Audit Log
|
|
|
|
- Recent moderation actions by all mods
|
|
- Who did what, when
|
|
|
|
---
|
|
|
|
## Phase 4: YouTube Integration
|
|
|
|
### 4.1 Current State
|
|
|
|
- ✅ `youtube_link` field on Show, Song, Performance
|
|
- ✅ `YouTubeEmbed` component
|
|
- ✅ Show detail page displays embed
|
|
|
|
### 4.2 Enhancements
|
|
|
|
#### Song Page YouTube
|
|
|
|
- Display YouTube embed of **#1 Heady Version**
|
|
- Performance list shows YouTube icon if link exists
|
|
|
|
#### Admin Integration
|
|
|
|
- YouTube URL field in Show/Song/Performance edit forms
|
|
- URL validation (must be valid YouTube URL)
|
|
|
|
---
|
|
|
|
## Phase 5: Song Page Enhancement ("Heady Version")
|
|
|
|
### 5.1 Concept
|
|
|
|
A **Song** is the abstract composition (e.g., "Hungersite").
|
|
A **Performance** is a specific rendition (e.g., "Hungersite @ Red Rocks 2023").
|
|
|
|
The "Heady Version" is the highest-rated performance of that song.
|
|
|
|
---
|
|
|
|
### 5.2 Song Page Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ 🎵 HUNGERSITE │
|
|
│ Original: Goose │ Times Played: 127 │
|
|
├─────────────────────────────────────────────────────┤
|
|
│ ▶ HEADY VERSION │
|
|
│ [YouTube Embed of #1 Performance] │
|
|
│ 2023-07-21 @ Red Rocks ★ 9.4 (47 ratings) │
|
|
├─────────────────────────────────────────────────────┤
|
|
│ 📊 HEADY LEADERBOARD │
|
|
│ 🥇 Red Rocks 2023-07-21 9.4★ (47) │
|
|
│ 🥈 MSG 2024-03-15 9.1★ (32) │
|
|
│ 🥉 Legend Valley 2022-09-10 8.9★ (28) │
|
|
│ 4. Dillon 2023-08-15 8.7★ (19) │
|
|
│ 5. The Capitol 2024-01-20 8.5★ (22) │
|
|
├─────────────────────────────────────────────────────┤
|
|
│ 📈 RATING TREND │
|
|
│ [Line chart: avg rating over time] │
|
|
├─────────────────────────────────────────────────────┤
|
|
│ 📅 ALL PERFORMANCES │
|
|
│ [Sortable by: Date | Rating] │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ 2024-11-15 @ Orpheum 8.2★ ▶ [YouTube] │ │
|
|
│ │ 2024-10-20 @ Red Rocks 9.4★ ▶ [YouTube] │ │
|
|
│ │ ... │ │
|
|
│ └─────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
### 5.3 API Endpoints
|
|
|
|
| Endpoint | Returns |
|
|
|----------|---------|
|
|
| `GET /songs/{id}` | Song + stats (times_played, avg_rating, heady_version) |
|
|
| `GET /songs/{id}/performances` | All performances with ratings, sorted |
|
|
| `GET /songs/{id}/heady-version` | Top-rated performance with YouTube link |
|
|
|
|
---
|
|
|
|
## Migration
|
|
|
|
### Database Changes
|
|
|
|
```sql
|
|
ALTER TABLE "user" ADD COLUMN email_verified BOOLEAN DEFAULT FALSE;
|
|
ALTER TABLE "user" ADD COLUMN verification_token VARCHAR;
|
|
ALTER TABLE "user" ADD COLUMN verification_token_expires TIMESTAMP;
|
|
ALTER TABLE "user" ADD COLUMN reset_token VARCHAR;
|
|
ALTER TABLE "user" ADD COLUMN reset_token_expires TIMESTAMP;
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Requirements
|
|
|
|
```env
|
|
# Required for email
|
|
SMTP_HOST=smtp.sendgrid.net
|
|
SMTP_PORT=587
|
|
SMTP_USER=apikey
|
|
SMTP_PASSWORD=<your-sendgrid-key>
|
|
EMAIL_FROM=noreply@elmeg.xyz
|
|
```
|
|
|
|
---
|
|
|
|
## Acceptance Criteria
|
|
|
|
### Phase 1
|
|
|
|
- [ ] User registers → receives verification email
|
|
- [ ] User clicks link → account verified
|
|
- [ ] Unverified user sees "verify email" banner
|
|
- [ ] User requests password reset → receives email
|
|
- [ ] User resets password → can login with new password
|
|
|
|
### Phase 2
|
|
|
|
- [ ] Admin can list/search all users
|
|
- [ ] Admin can change user roles
|
|
- [ ] Admin can CRUD shows/songs/venues/tours
|
|
- [ ] Admin can add YouTube links via UI
|
|
|
|
### Phase 3
|
|
|
|
- [ ] Mod can lookup user activity
|
|
- [ ] Mod can temp ban users
|
|
- [ ] Mod can bulk approve/reject
|
|
|
|
### Phase 4
|
|
|
|
- [ ] YouTube embeds on song pages
|
|
- [ ] YouTube icons on performance lists
|
|
|
|
### Phase 5
|
|
|
|
- [ ] Song page shows Heady Version embed
|
|
- [ ] Song page shows Heady Leaderboard
|
|
- [ ] Song page shows rating trend chart
|
|
- [ ] Performance list sortable by date/rating
|