479b72ef9a
- 02-01-SUMMARY.md: 3 tasks complete, 31 tests passing, all verification checks passed - STATE.md: Phase 2 plan 1/5 complete, decisions added, open questions resolved
100 lines
5.0 KiB
Markdown
100 lines
5.0 KiB
Markdown
---
|
|
gsd_state_version: 1.0
|
|
milestone: v1.0
|
|
milestone_name: milestone
|
|
current_phase: 2
|
|
status: in_progress
|
|
last_updated: "2026-05-22T20:00:00.000Z"
|
|
progress:
|
|
total_phases: 5
|
|
completed_phases: 1
|
|
total_plans: 10
|
|
completed_plans: 5
|
|
percent: 20
|
|
---
|
|
|
|
# Project State
|
|
|
|
**Project:** DocuVault
|
|
**Status:** Phase 2 In Progress — Executing
|
|
**Current Phase:** 2
|
|
**Last Updated:** 2026-05-22
|
|
|
|
## Phase Status
|
|
|
|
| Phase | Name | Status |
|
|
|---|---|---|
|
|
| 1 | Infrastructure Foundation | ✓ Complete |
|
|
| 2 | Users & Authentication | In Progress (1/5 plans complete) |
|
|
| 3 | Document Migration & Multi-User Isolation | Not Started |
|
|
| 4 | Folders, Sharing, Quotas & Document UX | Not Started |
|
|
| 5 | Cloud Storage Backends | Not Started |
|
|
|
|
## Current Position
|
|
|
|
**Phase:** 02-users-authentication — In Progress
|
|
**Plan:** 1/5 complete (Plan 01: Auth service layer)
|
|
**Progress:** ██░░░░░░░░ 24% (1/5 phases + 1/5 Phase 2 plans)
|
|
|
|
## Performance Metrics
|
|
|
|
| Metric | Value |
|
|
|---|---|
|
|
| Phases complete | 1 / 5 |
|
|
| Requirements mapped | 54 / 54 |
|
|
| Plans written | 5 (Phase 1) |
|
|
| Plans complete | 5 |
|
|
|
|
## Accumulated Context
|
|
|
|
### Key Decisions
|
|
|
|
| Decision | Rationale |
|
|
|---|---|
|
|
| PostgreSQL + MinIO | Multi-user quotas and horizontal scaling require shared, consistent state |
|
|
| HKDF per-user key derivation | Single Fernet key would be catastrophic on leak — must be derived before first credential is stored |
|
|
| Presigned MinIO URL flow | FastAPI handles metadata only; bytes never pass through the API layer |
|
|
| Atomic PostgreSQL quota UPDATE | Never perform quota arithmetic in Python between two DB statements |
|
|
| JWT in httpOnly cookie | Refresh token in httpOnly cookie; access token in Pinia memory only — never localStorage |
|
|
| Refresh token family revocation | RFC 9700 — reuse of a rotated token revokes entire family and alerts user |
|
|
| BackgroundTasks replacement | FastAPI BackgroundTasks is per-instance; replace with Celery+Redis or pgqueuer before horizontal scale |
|
|
| AuditLog metadata_ ORM attribute | `metadata` is reserved on DeclarativeBase; ORM attribute is `metadata_` with `name="metadata"` kwarg to avoid silent collision |
|
|
| documents.user_id nullable Phase 1 | D-03 — no auth in Phase 1; Phase 2 migration adds NOT NULL after auth lands |
|
|
| groups stub table Phase 1 | D-02 — groups is a v2 feature; table created now for schema completeness, no rows until Phase 2+ |
|
|
| SEQUENCES grants in migration | GRANT USAGE/SELECT on sequences required for audit_log.id autoincrement nextval() by docuvault_app |
|
|
| Admin impersonation excluded | Explicit architectural exclusion — no endpoint or UI pathway; violates privacy-first core value |
|
|
| user_id as refresh token family proxy | No separate family_id column; user_id serves as family per RFC 9700 — simpler schema |
|
|
| pwdlib over passlib | pwdlib actively maintained with clean Argon2Hasher API; passlib unmaintained |
|
|
| TOTP replay TTL=90s | valid_window=1 covers ±30s (90s total) — TTL matches window |
|
|
| HIBP fail-open | Network errors return False + log warning; auth never blocked by external service |
|
|
| Two-DSN PostgreSQL strategy | DATABASE_URL (docuvault_app, DML only) + DATABASE_MIGRATE_URL (docuvault_migrate, DDL only); celery-worker gets only DATABASE_URL |
|
|
| MinIO healthcheck via mc ready local | curl removed from MinIO Docker image since Oct 2023; mc is the correct in-container healthcheck tool |
|
|
| pydantic-settings v2 SettingsConfigDict | SettingsConfigDict API used (not deprecated class Config form) for env var config |
|
|
| async_client fixture name | Distinct from legacy sync `client` fixture to avoid collision; both coexist until Plan 05 |
|
|
| xfail(strict=False) for Wave 0 | All pre-implementation scaffolds use strict=False so unexpected passes don't break CI |
|
|
| StorageBackend ABC + factory mirrors ai/ pattern | 5 abstract methods; get_storage_backend() factory; MinIOBackend wraps all sync Minio SDK calls in asyncio.to_thread() |
|
|
| STORE-02 key enforced in code | MinIOBackend.put_object constructs {user_id}/{document_id}/{uuid4()}{ext}; no filename parameter — only extension passes through |
|
|
| null-user D-03 sentinel | services/storage.save_upload uses user_id="null-user" in Phase 1 (no auth); Phase 2 replaces with str(current_user.id) |
|
|
| load_settings flat-file Phase 1 | users.ai_provider/ai_model columns cannot be populated until Phase 2; settings remain flat-file JSON for Phase 1 |
|
|
|
|
### Open Questions
|
|
|
|
- Celery + Redis vs pgqueuer for Phase 3 (depends on Redis availability in deployment target)
|
|
- Verify cloud SDK minor versions on PyPI before Phase 5 pinning
|
|
- Celery + Redis vs pgqueuer for Phase 3 (depends on Redis availability in deployment target)
|
|
- Verify cloud SDK minor versions on PyPI before Phase 5 pinning
|
|
|
|
### Blockers
|
|
|
|
None.
|
|
|
|
## Session Continuity
|
|
|
|
_Updated at each phase transition._
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Last session | 2026-05-22 — Executed Phase 2 Plan 01 (auth service layer, deps, migration) |
|
|
| Next action | Run `/gsd:execute-phase 2` to continue Phase 2 (Plan 02: auth endpoints) |
|
|
| Pending decisions | See Open Questions above |
|