- MediaAsset model with file metadata and AV scan status tracking
- ContentBlock model (richtext/image/video/embed/download) with ordered
blocks per page and unique constraint on (page, order)
- CourseTheme one-to-one per course with primary/secondary color and logo
- validate_upload/save_upload helpers with extension and size enforcement
- scan_media_asset_task Celery stub (marks clean; replace with ClamAV)
- REST API: media upload, page content blocks CRUD, block patch/delete
- Admin registrations for all three models
- Factory-boy factories and pytest test suite for views, upload, and task
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>