diff --git a/CLAUDE.md b/CLAUDE.md index 9663081..44f1e79 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -112,17 +112,48 @@ python main.py flask --app main run ``` +## User Authentication + +The application includes a complete user authentication system using Flask-Login and bcrypt: + +**Authentication Pages:** +- `/register` - User registration with email and password +- `/login` - User login with "remember me" functionality +- `/logout` - User logout + +**Security Features:** +- Passwords hashed with bcrypt and salt +- Session-based authentication via Flask-Login +- Protected routes with `@login_required` decorator +- User-specific data isolation (multi-tenant architecture) +- Secure password requirements (minimum 8 characters) +- Flash messages for all auth actions +- Redirect to requested page after login + +**First Time Setup:** +1. Start the application +2. Navigate to http://localhost:5000/register +3. Create an account +4. Login and start subscribing to channels + +**User Data Isolation:** +- Each user can only see their own channels and videos +- Channels are scoped by user_id +- All routes filter data by current_user.id +- Users cannot access other users' content + ## Frontend Interface The application includes a full-featured web interface built with Jinja2 templates: -**Pages:** -- `/` - Dashboard showing all videos sorted by date (newest first) -- `/channels` - Channel management page with refresh functionality +**Pages:** (all require authentication) +- `/` - Dashboard showing user's videos sorted by date (newest first) +- `/channels` - User's channel management page with refresh functionality - `/add-channel` - Form to subscribe to new YouTube channels - `/watch/` - Video player page for watching downloaded videos **Features:** +- User registration and login system - Video grid with thumbnails and metadata - Real-time download status indicators (pending, downloading, completed, failed) - Inline video downloads from dashboard @@ -130,6 +161,7 @@ The application includes a full-featured web interface built with Jinja2 templat - Channel subscription and management - Refresh individual channels to fetch new videos - Responsive design for mobile and desktop +- User-specific navigation showing username **API Endpoints:** - `/api/feed` - Fetch YouTube channel feed and save to database (GET) @@ -177,11 +209,21 @@ The codebase follows a clean layered architecture with separation of concerns: ### Database Layer **`models.py`** - SQLAlchemy ORM models - `Base`: Declarative base for all models +- `User`: User model with Flask-Login integration + - Stores username, email, password_hash, created_at + - Methods: `set_password()`, `check_password()` for bcrypt password handling + - Implements UserMixin for Flask-Login compatibility - `DownloadStatus`: Enum for download states (pending, downloading, completed, failed) -- `Channel`: Stores YouTube channel metadata (channel_id, title, link, last_fetched) -- `VideoEntry`: Stores individual video entries with foreign key to Channel, plus download tracking fields: - - `download_status`, `download_path`, `download_started_at`, `download_completed_at`, `download_error`, `file_size` -- Relationships: One Channel has many VideoEntry records +- `Channel`: Stores YouTube channel metadata per user + - Fields: user_id, channel_id, title, link, rss_url, last_fetched_at + - Unique constraint: (user_id, channel_id) - one user can't subscribe twice +- `VideoEntry`: Stores individual video entries with full metadata + - Fields: video_id, title, video_url, thumbnail_url, description, published_at + - Download tracking: download_status, download_path, download_started_at, download_completed_at, download_error, file_size + - Unique constraint: (video_id, channel_id) - prevents duplicate videos +- Relationships: + - One User has many Channels + - One Channel has many VideoEntries **`database.py`** - Database configuration and session management - `DATABASE_URL`: Database URL from environment variable (PostgreSQL in production, SQLite fallback for local dev) @@ -315,18 +357,32 @@ source .venv/bin/activate && alembic downgrade -1 ## Database Schema +**users table:** +- `id`: Primary key +- `username`: Unique username (indexed) +- `email`: Unique email address (indexed) +- `password_hash`: Bcrypt-hashed password +- `created_at`: Timestamp when user registered + **channels table:** - `id`: Primary key -- `channel_id`: YouTube channel ID (unique, indexed) +- `user_id`: Foreign key to users.id (indexed) +- `channel_id`: YouTube channel ID (indexed) - `title`: Channel title - `link`: Channel URL -- `last_fetched`: Timestamp of last feed fetch +- `rss_url`: YouTube RSS feed URL +- `last_fetched_at`: Timestamp of last feed fetch +- Unique index: `idx_user_channel` on (user_id, channel_id) - prevents duplicate subscriptions **video_entries table:** - `id`: Primary key - `channel_id`: Foreign key to channels.id +- `video_id`: YouTube video ID (indexed) - `title`: Video title -- `link`: Video URL (unique) +- `video_url`: YouTube video URL (indexed) +- `thumbnail_url`: Video thumbnail URL +- `description`: Video description +- `published_at`: When video was published on YouTube (indexed) - `created_at`: Timestamp when video was first recorded - `download_status`: Enum (pending, downloading, completed, failed) - `download_path`: Local file path to downloaded MP4 @@ -334,8 +390,10 @@ source .venv/bin/activate && alembic downgrade -1 - `download_completed_at`: When download finished - `download_error`: Error message if download failed - `file_size`: Size in bytes of downloaded file +- Unique index: `idx_video_id_channel` on (video_id, channel_id) - prevents duplicates - Index: `idx_channel_created` on (channel_id, created_at) for fast queries - Index: `idx_download_status` on download_status for filtering +- Index: `idx_published_at` on published_at for date sorting ## Video Download System @@ -386,6 +444,8 @@ All services have health checks and automatic restarts configured. ## Dependencies - **Flask 3.1.2+**: Web framework +- **Flask-Login 0.6.0+**: User session management +- **bcrypt 4.0.0+**: Password hashing - **feedparser 6.0.12+**: RSS/Atom feed parsing - **SQLAlchemy 2.0.0+**: ORM for database operations - **psycopg2-binary 2.9.0+**: PostgreSQL database driver