7.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
This is a cloud photo and video storage service with a React frontend (SPA hosted in S3) and a Python FastAPI backend. The project uses S3 for file storage and starts with SQLite for metadata, with a migration path to PostgreSQL.
Primary Language: Russian (comments and documentation may be in Russian)
Tech Stack
Backend
- Framework: FastAPI (ASGI)
- ORM: SQLAlchemy 2.x (async) with Alembic migrations
- Database: SQLite (MVP) → PostgreSQL (future)
- S3 SDK: boto3 or aioboto3
- Authentication: JWT (access + refresh tokens)
- Background Tasks: Redis + RQ (recommended for thumbnail generation)
- Testing: pytest + httpx
- Linting/Formatting: ruff + black (or ruff format)
Frontend
- Framework: React
- UI Library: Material UI (MUI)
- Build Tool: Vite
- Deployment: Static files in
static/folder → S3 hosting
Infrastructure
- File Storage: S3 or S3-compatible (MinIO for development)
- Queue: Redis (for background workers)
Architecture Principles
Layered Architecture (Clean Architecture)
The backend follows strict separation of concerns:
api/- Routes, schemas, dependencies, auth middlewareservices/- Business logic (upload, library, share management)repositories/- Data access layer (CRUD operations)infra/- S3 client, database session factory, config, background tasksdomain/- Domain models and interfaces (as needed)
Code Quality Standards
- SOLID principles are mandatory
- DRY (Don't Repeat Yourself)
- Docstrings required for all public methods/classes and main services
- Minimal code comments - prefer self-documenting code and docstrings
- Stable API contract - maintain OpenAPI/Swagger compatibility
Security Requirements
- Never store passwords in plaintext - use argon2id or bcrypt
- All S3 access must use pre-signed URLs with short TTL
- Validate all input with Pydantic
- Check asset ownership in all endpoints
- CORS must be strictly configured
- CSRF protection for cookie-based auth
Planned Project Structure
repo/
backend/
src/
app/
api/
v1/ # API routes versioned
services/ # Business logic layer
repositories/ # Data access layer
infra/ # Infrastructure (S3, DB, config)
domain/ # Domain models
main.py # Application entry point
alembic/ # Database migrations
tests/
pyproject.toml
Dockerfile
frontend/
src/
public/
vite.config.js
package.json
static/ # Build output (deployed to S3)
docker-compose.yml
Data Model
Core Entities
users: User accounts (id, email, password_hash, created_at, updated_at, is_active)
assets: Media files with metadata
- Type: photo | video
- Status: uploading | ready | failed | deleted
- Includes: original_filename, content_type, size_bytes, sha256, captured_at
- S3 keys: storage_key_original, storage_key_thumb
- Soft delete support via deleted_at
shares: Public/private sharing links
- Links to either a single asset or album
- Supports expiration (expires_at) and revocation (revoked_at)
- Optional password protection
albums (v1): Logical grouping of assets
tags (v1): Tagging system for assets
S3 Storage Structure
- Bucket: Private, access only via pre-signed URLs
- Original files:
u/{user_id}/o/{yyyy}/{mm}/{asset_id}{ext} - Thumbnails:
u/{user_id}/t/{yyyy}/{mm}/{asset_id}.jpg - Video posters (v1):
u/{user_id}/p/{yyyy}/{mm}/{asset_id}.jpg
Upload Flow
- Frontend requests
POST /api/v1/uploads/createwith file metadata - Backend returns pre-signed URL or multipart upload credentials
- Frontend uploads file directly to S3
- Frontend calls
POST /api/v1/uploads/{asset_id}/finalize - Backend saves metadata and enqueues thumbnail generation task
API Structure
Base path: /api/v1
Authentication
POST /api/v1/auth/registerPOST /api/v1/auth/loginPOST /api/v1/auth/logoutGET /api/v1/auth/me
Assets (Library)
GET /api/v1/assets- List with cursor-based paginationGET /api/v1/assets/{asset_id}DELETE /api/v1/assets/{asset_id}- Soft deletePOST /api/v1/assets/{asset_id}/restoreDELETE /api/v1/assets/{asset_id}/purge- Hard delete from trash
Upload
POST /api/v1/uploads/createPOST /api/v1/uploads/{asset_id}/finalize
Access URLs
GET /api/v1/assets/{asset_id}/download-url?kind=original|thumbGET /api/v1/assets/{asset_id}/stream-url- For video
Shares
POST /api/v1/shares- Create share linkGET /api/v1/shares/{token}GET /api/v1/shares/{token}/download-url?asset_id=&kind=POST /api/v1/shares/{token}/revoke
Environment Variables
Key backend environment variables (see tech_spec_cloud_media_storage.md section 13 for full list):
APP_ENV=dev|prodDATABASE_URL=sqlite+aiosqlite:///./app.db(or PostgreSQL connection string)S3_ENDPOINT_URL- For MinIO or custom S3-compatible storageS3_REGION,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEYMEDIA_BUCKET- S3 bucket nameSIGNED_URL_TTL_SECONDS=600JWT_SECRET,JWT_ACCESS_TTL_SECONDS,JWT_REFRESH_TTL_SECONDSMAX_UPLOAD_SIZE_BYTES- File size limitCORS_ORIGINS- Allowed frontend origins
Database Migrations
- All schema changes MUST go through Alembic migrations
- No raw SQL in application code (except migrations)
- Schema must be compatible with both SQLite (MVP) and PostgreSQL
- UUID stored as TEXT in SQLite, native UUID in PostgreSQL
Development Workflow (When Implemented)
Backend Development
Expected commands once backend is set up:
- Start server:
uvicorn app.main:app --reload - Run tests:
pytest - Create migration:
alembic revision --autogenerate -m "description" - Apply migrations:
alembic upgrade head - Format code:
ruff format .orblack . - Lint:
ruff check .
Frontend Development
Expected commands once frontend is set up:
- Install dependencies:
npm install - Dev server:
npm run dev - Build for production:
npm run build(outputs tostatic/) - Lint:
npm run lint
Docker Compose (Development)
Recommended setup: docker-compose up to start:
- Backend service
- MinIO (S3-compatible storage)
- Redis (for background tasks)
- PostgreSQL (when migrating from SQLite)
MVP Acceptance Criteria
- User registration and authentication working
- Upload photo and video files (including batch upload of 100+ files)
- Library displays thumbnails for photos
- Photo/video viewer works in browser
- Soft delete to trash with restore capability
- Public share links work without authentication
- SQLite database with migration path to PostgreSQL ready
Implementation Phases
- Foundation: FastAPI skeleton, DB config, migrations, auth
- Assets: CRUD for assets, library listing with pagination, trash management
- Frontend MVP: Login, library grid, upload dialog, viewer, trash UI
- Thumbnails: Background generation and display
- Shares: Create and access share links, shared view UI
Important Notes
- This project follows Clean Architecture - respect layer boundaries
- All file access goes through pre-signed S3 URLs, never direct access
- Use cursor-based pagination for listing endpoints
- Thumbnails reduce bandwidth - originals loaded only on demand
- For large files, use S3 multipart upload
- Background tasks via Redis + RQ for thumbnail/poster generation
- Support both inline (MVP acceptable) and background thumbnail generation
Reference Documentation
For detailed technical requirements, see tech_spec_cloud_media_storage.md.