Files
digiserver-v2/BLUEPRINT_GUIDE.md
ske087 244b44f5e0 Initial commit: DigiServer v2 with Blueprint Architecture
Features implemented:
- Application factory pattern with environment-based config
- 7 modular blueprints (main, auth, admin, players, groups, content, api)
- Flask-Caching with Redis support for production
- Flask-Login authentication with bcrypt password hashing
- API endpoints with rate limiting and Bearer token auth
- Comprehensive error handling and logging
- CLI commands (init-db, create-admin, seed-db)

Blueprint Structure:
- main: Dashboard with caching, health check endpoint
- auth: Login, register, logout, password change
- admin: User management, system settings, theme, logo upload
- players: Full CRUD, fullscreen view, bulk operations, playlist management
- groups: Group management, player assignments, content management
- content: Upload with progress tracking, file management, preview/download
- api: RESTful endpoints with authentication, rate limiting, player feedback

Performance Optimizations:
- Dashboard caching (60s timeout)
- Playlist caching (5min timeout)
- Redis caching for production
- Memoized functions for expensive operations
- Cache clearing on data changes

Security Features:
- Bcrypt password hashing
- Flask-Login session management
- admin_required decorator for authorization
- Player authentication via auth codes
- API Bearer token authentication
- Rate limiting on API endpoints (60 req/min default)
- Input validation and sanitization

Documentation:
- README.md: Full project documentation with quick start
- PROGRESS.md: Detailed progress tracking and roadmap
- BLUEPRINT_GUIDE.md: Quick reference for blueprint architecture

Pending work:
- Models migration from v1 with database indexes
- Utils migration from v1 with type hints
- Templates migration with updated route references
- Docker multi-stage build configuration
- Unit tests for all blueprints

Ready for models and utils migration from digiserver v1
2025-11-12 10:00:30 +02:00

337 lines
9.3 KiB
Markdown

# Blueprint Architecture - Quick Reference
## 📦 Blueprint Structure
```
app/
├── blueprints/
│ ├── __init__.py # Package initialization
│ ├── main.py # Dashboard, health check
│ ├── auth.py # Login, register, logout
│ ├── admin.py # Admin panel, user management
│ ├── players.py # Player CRUD, fullscreen view
│ ├── groups.py # Group management, assignments
│ ├── content.py # Media upload, file management
│ └── api.py # REST API endpoints
```
---
## 🔗 URL Mapping
### Main Blueprint (`/`)
- `GET /` - Dashboard with statistics
- `GET /health` - Health check (database, disk)
### Auth Blueprint (`/auth`)
- `GET /auth/login` - Login page
- `POST /auth/login` - Process login
- `GET /auth/logout` - Logout
- `GET /auth/register` - Register page
- `POST /auth/register` - Process registration
- `GET /auth/change-password` - Change password page
- `POST /auth/change-password` - Update password
### Admin Blueprint (`/admin`)
- `GET /admin/` - Admin panel
- `POST /admin/user/create` - Create user
- `POST /admin/user/<id>/role` - Change user role
- `POST /admin/user/<id>/delete` - Delete user
- `POST /admin/theme` - Change theme
- `POST /admin/logo/upload` - Upload logo
- `POST /admin/logs/clear` - Clear logs
- `GET /admin/system/info` - System info (JSON)
### Players Blueprint (`/players`)
- `GET /players/` - List all players
- `GET /players/add` - Add player page
- `POST /players/add` - Create player
- `GET /players/<id>/edit` - Edit player page
- `POST /players/<id>/edit` - Update player
- `POST /players/<id>/delete` - Delete player
- `POST /players/<id>/regenerate-auth` - Regenerate auth code
- `GET /players/<id>` - Player page
- `GET /players/<id>/fullscreen` - Player fullscreen view
- `POST /players/<id>/reorder` - Reorder content
- `POST /players/bulk/delete` - Bulk delete players
- `POST /players/bulk/assign-group` - Bulk assign to group
### Groups Blueprint (`/groups`)
- `GET /groups/` - List all groups
- `GET /groups/create` - Create group page
- `POST /groups/create` - Create group
- `GET /groups/<id>/edit` - Edit group page
- `POST /groups/<id>/edit` - Update group
- `POST /groups/<id>/delete` - Delete group
- `GET /groups/<id>/manage` - Manage group page
- `GET /groups/<id>/fullscreen` - Group fullscreen view
- `POST /groups/<id>/add-player` - Add player to group
- `POST /groups/<id>/remove-player/<player_id>` - Remove player
- `POST /groups/<id>/add-content` - Add content to group
- `POST /groups/<id>/remove-content/<content_id>` - Remove content
- `POST /groups/<id>/reorder-content` - Reorder content
- `GET /groups/<id>/stats` - Group statistics (JSON)
### Content Blueprint (`/content`)
- `GET /content/` - List all content
- `GET /content/upload` - Upload page
- `POST /content/upload` - Upload file
- `GET /content/<id>/edit` - Edit content page
- `POST /content/<id>/edit` - Update content
- `POST /content/<id>/delete` - Delete content
- `POST /content/bulk/delete` - Bulk delete content
- `GET /content/upload-progress/<upload_id>` - Upload progress (JSON)
- `GET /content/preview/<id>` - Preview content
- `GET /content/<id>/download` - Download content
- `GET /content/statistics` - Content statistics (JSON)
- `GET /content/check-duplicates` - Check duplicates (JSON)
- `GET /content/<id>/groups` - Content groups info (JSON)
### API Blueprint (`/api`)
- `GET /api/health` - API health check
- `GET /api/playlists/<player_id>` - Get player playlist (auth required)
- `POST /api/player-feedback` - Submit player feedback (auth required)
- `GET /api/player-status/<player_id>` - Get player status
- `GET /api/upload-progress/<upload_id>` - Get upload progress
- `GET /api/system-info` - System statistics
- `GET /api/groups` - List all groups
- `GET /api/content` - List all content
- `GET /api/logs` - Get server logs (query params: limit, level, since)
---
## 🔒 Authentication & Authorization
### Login Required
Most routes require authentication via `@login_required` decorator:
```python
from flask_login import login_required
@players_bp.route('/')
@login_required
def players_list():
# Route logic
```
### Admin Required
Admin routes use custom `@admin_required` decorator:
```python
from app.blueprints.admin import admin_required
@admin_bp.route('/')
@login_required
@admin_required
def admin_panel():
# Route logic
```
### API Authentication
API routes use `@verify_player_auth` for player authentication:
```python
from app.blueprints.api import verify_player_auth
@api_bp.route('/playlists/<int:player_id>')
@verify_player_auth
def get_player_playlist(player_id):
# Access authenticated player via request.player
```
---
## 🚀 Performance Features
### Caching
Routes with caching enabled:
- Dashboard: 60 seconds
- Player playlist: 5 minutes (memoized function)
Clear cache on data changes:
```python
from app.extensions import cache
# Clear specific memoized function
cache.delete_memoized(get_player_playlist, player_id)
# Clear all cache
cache.clear()
```
### Rate Limiting
API endpoints have rate limiting:
```python
@api_bp.route('/playlists/<int:player_id>')
@rate_limit(max_requests=30, window=60) # 30 requests per minute
def get_player_playlist(player_id):
# Route logic
```
---
## 🎨 Template Usage
### URL Generation
Always use blueprint-qualified names in templates:
**Old (v1):**
```html
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('dashboard') }}">Dashboard</a>
<a href="{{ url_for('add_player') }}">Add Player</a>
```
**New (v2):**
```html
<a href="{{ url_for('auth.login') }}">Login</a>
<a href="{{ url_for('main.dashboard') }}">Dashboard</a>
<a href="{{ url_for('players.add_player') }}">Add Player</a>
```
### Context Processors
Available in all templates:
- `server_version` - Server version string
- `build_date` - Build date string
- `logo_exists` - Boolean, whether custom logo exists
- `theme` - Current theme ('light' or 'dark')
---
## 📝 Common Patterns
### Creating a New Route
1. **Choose the appropriate blueprint** based on functionality
2. **Add the route** with proper decorators:
```python
@blueprint_name.route('/path', methods=['GET', 'POST'])
@login_required # If authentication needed
def route_name():
try:
# Route logic
log_action('info', 'Success message')
flash('Success message', 'success')
return redirect(url_for('blueprint.route'))
except Exception as e:
db.session.rollback()
log_action('error', f'Error: {str(e)}')
flash('Error message', 'danger')
return redirect(url_for('blueprint.route'))
```
### Adding Caching
For view caching:
```python
@cache.cached(timeout=60, key_prefix='my_key')
def my_route():
# Route logic
```
For function memoization:
```python
@cache.memoize(timeout=300)
def my_function(param):
# Function logic
```
### API Response Format
Consistent JSON responses:
```python
# Success
return jsonify({
'success': True,
'data': {...}
})
# Error
return jsonify({
'error': 'Error message'
}), 400
```
---
## 🔧 Extension Access
Import extensions from centralized location:
```python
from app.extensions import db, bcrypt, cache, login_manager
```
Never initialize extensions directly in blueprints - they're initialized in `extensions.py` and registered in `app.py`.
---
## 🧪 Testing Routes
### Manual Testing
```bash
# Start development server
flask run
# Test specific blueprint
curl http://localhost:5000/api/health
curl http://localhost:5000/health
# Test authenticated route
curl -H "Authorization: Bearer <auth_code>" http://localhost:5000/api/playlists/1
```
### Unit Testing
```python
def test_dashboard(client, auth):
auth.login()
response = client.get('/')
assert response.status_code == 200
```
---
## 📊 Blueprint Registration
Blueprints are registered in `app/app.py`:
```python
def register_blueprints(app: Flask) -> None:
"""Register all blueprints."""
from app.blueprints.main import main_bp
from app.blueprints.auth import auth_bp
from app.blueprints.admin import admin_bp
from app.blueprints.players import players_bp
from app.blueprints.groups import groups_bp
from app.blueprints.content import content_bp
from app.blueprints.api import api_bp
app.register_blueprint(main_bp)
app.register_blueprint(auth_bp)
app.register_blueprint(admin_bp)
app.register_blueprint(players_bp)
app.register_blueprint(groups_bp)
app.register_blueprint(content_bp)
app.register_blueprint(api_bp)
```
---
## ✅ Checklist for Adding New Features
- [ ] Choose appropriate blueprint
- [ ] Add route with proper decorators
- [ ] Implement error handling (try/except)
- [ ] Add logging with `log_action()`
- [ ] Add flash messages for user feedback
- [ ] Clear cache if data changes
- [ ] Add type hints to parameters
- [ ] Update this documentation
- [ ] Add unit tests
- [ ] Test manually in browser/API client
---
This architecture provides:
-**Separation of concerns** - Each blueprint handles specific functionality
-**Scalability** - Easy to add new blueprints
-**Maintainability** - Clear organization and naming
-**Performance** - Built-in caching and optimization
-**Security** - Proper authentication and authorization
-**API-first** - RESTful API alongside web interface