feat(api): add POST/GET /v1/files with auth, error envelope, and request-id middleware

Why:
- Wires the ADR-0008 error envelope, per-request correlation id, and the
  /v1/files routes into the app.

Changes:
- Extend AppResources/lifespan with the ingestion CapacityLimiter and
  ObjectStorage adapter.

Impact:
- /v1 now exposes routes for the first time.
This commit is contained in:
2026-08-19 15:00:39 +03:30
parent c9cf7b368b
commit 3bced65926
10 changed files with 355 additions and 1 deletions

View File

@@ -2,13 +2,14 @@ from collections.abc import AsyncIterator, Callable
from contextlib import AbstractAsyncContextManager, asynccontextmanager
import structlog
from anyio import to_thread
from anyio import CapacityLimiter, to_thread
from fastapi import FastAPI
from src.application.ingestion import get_encoder
from src.bootstrap.dependencies import AppResources
from src.config import Settings
from src.infrastructure.minio.client import create_client as create_minio_client
from src.infrastructure.minio.storage import MinioObjectStorage
from src.infrastructure.observability.logging import configure_logging
from src.infrastructure.postgres.database import create_engine, create_sessionmaker
from src.infrastructure.qdrant.client import create_client as create_qdrant_client
@@ -43,12 +44,22 @@ def create_lifespan(
qdrant_client = create_qdrant_client(resolved_settings.qdrant)
logger.info("lifespan.qdrant.client.created")
# Bounds threads spent on blocking ingestion work (parsing, chunking,
# hashing, the sync minio SDK) so it cannot exhaust Starlette's own
# thread pool (ADR-0017).
ingestion_limiter = CapacityLimiter(resolved_settings.ingestion.thread_pool_size)
object_storage = MinioObjectStorage(
minio_client, bucket=resolved_settings.minio.bucket, limiter=ingestion_limiter
)
app.state.resources = AppResources(
settings=resolved_settings,
db_engine=db_engine,
db_sessionmaker=db_sessionmaker,
minio_client=minio_client,
qdrant_client=qdrant_client,
object_storage=object_storage,
ingestion_limiter=ingestion_limiter,
)
try: