feat(files): add source-file upload with MinIO storage and Postgres repositories
Why: - Implements plan 001 Phase 3's upload orchestration. Changes: - ObjectStorage port and MinIO adapter, thread-offloaded per ADR-0017. - Tenant-scoped repositories for api_keys, source_files, ingestion_jobs. - upload_source_file implementing the two-transaction shape with (tenant_id, domain, content_sha256) idempotency. Impact: - This phase stores bytes only -- chunks_indexed is always 0 until Phase 4/5 add parsing/embedding.
This commit is contained in:
17
src/infrastructure/postgres/repositories/api_keys.py
Normal file
17
src/infrastructure/postgres/repositories/api_keys.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""API-key lookups (ADR-0008, ADR-0009).
|
||||
|
||||
Plain functions over an `AsyncSession` the caller owns. No function here
|
||||
commits, rolls back, or closes the session (ADR-0012). Secret comparison
|
||||
happens in `src/application/auth`, not here — this module only fetches rows
|
||||
by their non-secret `key_prefix`.
|
||||
"""
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.infrastructure.postgres.models.api_key import ApiKey
|
||||
|
||||
|
||||
async def get_by_prefix(session: AsyncSession, key_prefix: str) -> ApiKey | None:
|
||||
result = await session.execute(select(ApiKey).where(ApiKey.key_prefix == key_prefix))
|
||||
return result.scalar_one_or_none()
|
||||
Reference in New Issue
Block a user