curo1305
fd76d06b3a
feat(14-02): add migration 0007 and ORM models for cloud analysis cache schema
...
- 0007_cloud_analysis_cache.py: new Alembic migration adding 4 Phase 14 tables
- cloud_byte_cache_entries: durable MinIO cache with version_key uniqueness,
pin_count/active_job_count guards, LRU eviction indexes
- cloud_analysis_jobs: batch job rows (scope_kind, status, aggregate counters,
provider_bytes_estimate, failure_behavior)
- cloud_analysis_job_items: per-item idempotency rows (status vocabulary,
controlled error fields, cache_entry_id, retry_count, version_key fingerprint)
- user_analysis_settings: per-user preferences (progress_detail, failure_behavior,
cloud_cache_limit_bytes)
- Reversible downgrade drops Phase 14 objects only
- db/models.py: CloudByteCacheEntry, CloudAnalysisJob, CloudAnalysisJobItem,
UserAnalysisSettings ORM models mirroring migration
2026-06-23 15:06:24 +02:00
curo1305
e186019066
feat(12-02): decompose api/cloud.py into package with connection-ID browse endpoint
...
- Add api/cloud/ package: connections.py, browse.py, schemas.py, __init__.py
- Add GET /api/cloud/connections/{connection_id}/items (T-12-01 IDOR, T-12-03 cred-free)
- Add PATCH /api/cloud/connections/{id} for display_name_override rename
- Add display_name_override ORM field to CloudConnection model
- Add CloudResourceAdapter service layer with str/UUID coercion
- Fix UUID type compatibility: test_cloud_items.py now uses UUID(as_uuid=True)
matching conftest — removes String(36) patch that caused type incompatibility
- Add 11 Phase 12 integration tests (IDOR, admin block, credential exclusion,
duplicate providers, rename, malformed UUID)
- Remove deleted api/cloud.py (replaced by api/cloud/ package)
2026-06-18 23:10:30 +02:00
curo1305
718fb2c2b5
feat(12-01): durable owner-scoped cloud metadata schema (migration 0006 + models)
...
- Migration 0006: cloud_items, cloud_item_topics, cloud_folder_states tables
- cloud_connections: add display_name_override column for same-provider disambiguation
- CloudItem, CloudItemTopic, CloudFolderState ORM models with owner/connection indexes
- Unique (connection_id, provider_item_id) boundary; no MinIO object_key field
- Root folder state representable as parent_ref='' without CloudItem parent row
- services/cloud_items.py: resolve_owned_connection, upsert, list, reconcile, folder state
- 17 unit/integration tests covering model fields, isolation, quota invariant, idempotency
2026-06-18 22:37:28 +02:00
curo1305
4eb317749f
feat(07-01): Alembic migration 0005 + SystemSettings ORM model
...
- Add backend/migrations/versions/0005_system_settings.py (revision 0005, down_revision 0004)
- Creates system_settings table with 9 columns: id (UUID PK gen_random_uuid()), provider_id (String NOT NULL UNIQUE), api_key_enc (Text NULL), base_url (Text NULL), model_name (Text NOT NULL default ''), context_chars (Integer NOT NULL default 8000), is_active (Boolean NOT NULL default false), created_at/updated_at (TIMESTAMPTZ default now())
- UniqueConstraint uq_system_settings_provider_id on provider_id
- Add SystemSettings ORM model to backend/db/models.py following CloudConnection style
- downgrade() drops system_settings table cleanly
2026-06-04 18:46:11 +02:00
curo1305
f868a4e0c7
feat(phase-4-05): document streaming proxy GET /api/documents/{id}/content (DOC-02)
...
- Add _parse_range() helper: validates Range header bounds, raises 416 on invalid
- Add stream_document_content endpoint with get_regular_user dep (admin → 403)
- Access check: owner OR Share.recipient_id; neither → 404
- Bytes fetched via get_object() only — presigned_get_url() never called
- Range requests return 206 + Content-Range header
- Add pdf_open_mode column to User ORM model (migration 0004 already applied)
- Use HTTP_416_RANGE_NOT_SATISFIABLE (non-deprecated constant)
2026-05-25 18:48:32 +02:00
curo1305
12c6487855
feat(02-01): add BackupCode ORM model, password_must_change field, Alembic migration, extend Settings
...
- Add BackupCode model to db/models.py with user_id FK, code_hash (Argon2), used_at (nullable)
- Add ix_backup_codes_user_id index on backup_codes.user_id
- Add password_must_change BOOLEAN NOT NULL DEFAULT false to User model (ADMIN-01)
- Extend config.py Settings with JWT, SMTP, admin bootstrap, and CORS fields (D-01, D-04, D-09)
- Add env_list_separator=',' for cors_origins env var parsing
- Append PyJWT, pwdlib[argon2], pyotp, aioredis, slowapi to requirements.txt
- Add .env.example entries for SECRET_KEY, ADMIN_EMAIL, SMTP_*, CORS_ORIGINS
- Create migration 0002 adding backup_codes table and password_must_change column
- Add TDD tests for all Task 1 acceptance criteria (7 tests pass)
2026-05-22 19:19:52 +02:00
curo1305
3e1fcd69b5
feat(01-03): add full v1 ORM schema, async session factory, and DB dependency
...
- backend/db/models.py: 11 SQLAlchemy 2.0 ORM models (User, Quota, RefreshToken,
Folder, Document, Topic, DocumentTopic, Share, AuditLog, CloudConnection, Group)
- Document.user_id declared nullable=True per D-03 (Phase 2 adds NOT NULL)
- AuditLog.metadata_ uses mapped_column("metadata", JSONB) to avoid DeclarativeBase
reserved-attribute conflict
- Group table stub for D-02 (v2 feature, seeded per PROJECT.md)
- Uses Optional[X] instead of X | None for Python < 3.10 compatibility
- backend/db/session.py: async engine (pool_pre_ping=True, expire_on_commit=False)
- backend/deps/db.py: async get_db() FastAPI dependency yielding AsyncSession
2026-05-22 09:16:21 +02:00