Add media (object storage) and the background worker (Phase 1)
Media model + migration; an ObjectStore interface with an S3/MinIO (boto3) implementation behind the service layer. Upload (multipart) stores bytes in object storage + a metadata row (checksum, size, content-type, optional attach to person/event/source); list returns presigned URLs; delete is soft. Editor-gated, privacy-filtered, audited. 24 tests pass (object store faked). Introduces the worker container (same image, 'python -m app.worker'): its first job is the scheduled 30-day soft-delete purge across tables + media object cleanup. Compose gains worker + S3 env on backend/worker; dev override builds the worker too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Justin Paul <justin@jpaul.me>
This commit is contained in:
@@ -12,6 +12,8 @@ dependencies = [
|
||||
"asyncpg>=0.30",
|
||||
"alembic>=1.14",
|
||||
"argon2-cffi>=23.1",
|
||||
"boto3>=1.35",
|
||||
"python-multipart>=0.0.12",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
@@ -36,6 +38,10 @@ extend-exclude = ["migrations/versions"]
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F", "I", "UP", "B"]
|
||||
|
||||
[tool.ruff.lint.flake8-bugbear]
|
||||
# FastAPI uses these as call-expressions in argument defaults by design.
|
||||
extend-immutable-calls = ["fastapi.File", "fastapi.Form", "fastapi.Depends", "fastapi.Query", "fastapi.Header"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "auto"
|
||||
pythonpath = ["."]
|
||||
|
||||
Reference in New Issue
Block a user