curo1305
f47e36d93d
test(13-05): add failing RED tests for upload conflict semantics and keep-both naming
...
- TestUploadConflictSemantics: typed upload results across all 4 providers
- TestKeepBothNaming: keep_both_name() helper with counter before extension
- Tests verify credentials never appear in upload results (T-13-17)
- Upload kind values must be MUT_KINDS constants
- 16/23 pass (providers already have upload_file); 7 fail (keep_both_name missing)
2026-06-22 19:17:13 +02:00
curo1305
94a0617b9b
feat(13-04): add authorized cloud content and mutation routes with typed bodies
...
- backend/api/cloud/operations.py: owner-scoped open, preview, download, create-folder,
rename, move, delete, upload routes with typed kind/reason response bodies (D-02, D-03,
D-05, D-07, D-08, D-09, D-10, D-11, D-18, T-13-01, T-13-14)
- backend/api/cloud/__init__.py: register operations_router on /api/cloud
- backend/api/cloud/connections.py: Google Drive OAuth scope broadened to 'drive' (D-17)
- backend/api/cloud/schemas.py: ConnectionHealthOut, ReconnectOut, ContentResultOut,
MutationResultOut, CreateFolderRequest, RenameItemRequest, MoveItemRequest typed schemas
- frontend/src/api/cloud.js: centralized helpers for all Phase 13 routes
- backend/tests/test_cloud_mutations.py: mock adapter + settings key fixture; 21 tests pass
- backend/tests/test_cloud_audit.py: mark 6 RED audit tests as xfail (audit writes are
T-13-05 scope for a later plan); update credential fixture to use settings key
2026-06-22 19:09:38 +02:00
curo1305
5c0bc2a3b4
feat(13-04): upgrade Google Drive scope to drive, add health/reconnect/content API helpers
...
- connections.py: Update Google Drive OAuth to broader `drive` scope (D-17)
instead of `drive.file` so authorized users can operate on all existing Drive
items, not just files created by this app. Both initiation and callback flows
updated to keep scopes consistent.
- schemas.py: Add Phase 13 typed response schemas — ConnectionHealthOut, ReconnectOut,
ContentResultOut, MutationResultOut, and request schemas CreateFolderRequest,
RenameItemRequest, MoveItemRequest. All credential-free (T-13-14, CONN-03).
- api/cloud.js: Add centralized frontend helpers for getConnectionHealth,
reconnectCloudConnection, testCloudConnection (D-12, D-13), plus authorized
cloud content and mutation helpers: openCloudFile, previewCloudFile,
createCloudFolder, renameCloudItem, moveCloudItem, deleteCloudItem, uploadCloudFile.
All reconnect/health/test tests pass (14/14). Security suite passes (19/19).
2026-06-22 18:49:47 +02:00
curo1305
6784d3bdb7
feat(13-03): add cloud operations service and reconnect/health/test routes
...
- Create backend/services/cloud_operations.py as the single Phase 13 orchestration seam:
get_connection_health (D-12), test_connection (D-13), reconnect_connection (CONN-01/02/03,
D-14), disconnect_connection (D-16, explicit CloudItem cascade for SQLite compatibility)
- Add POST /connections/{id}/reconnect route (CONN-01/02/03, D-14)
- Add GET /connections/{id}/health route (D-12, T-13-02)
- Add POST /connections/{id}/test route (D-13, T-13-02)
- Update DELETE /connections/{id} to use service-layer disconnect with explicit
CloudItem deletion (D-16; covers FK-cascade-less environments like SQLite tests)
- Fix (Rule 2 - T-13-02): add _scrub_audit_metadata() to admin audit log API to
remove credential fields before returning audit rows to admin callers
- All 14 reconnect tests pass + 110 provider-contract tests pass
- Pre-existing failures in test_cloud_mutations and test_extractor are unrelated
2026-06-22 18:43:50 +02:00
curo1305
88a62da4c4
feat(13-03): extend cloud contract with mutable adapter and provider implementations
...
- Add MutableCloudResourceAdapter abstract class to cloud_base.py with Phase 13
mutable-operation vocabulary (MUT_KIND_* / MUT_REASON_* constants, PreviewSupport)
- Add abstract methods: create_folder, rename, move, delete, upload_file + _normalize_error
- Update GoogleDriveBackend to implement MutableCloudResourceAdapter with Drive-scope
methods; prefer trash() for delete (D-11); update SCOPES to drive (D-17)
- Update OneDriveBackend to implement MutableCloudResourceAdapter; use
PublicClientApplication for refresh_token flow; Graph DELETE is always permanent (D-11)
- Update WebDAVBackend to implement MutableCloudResourceAdapter; SSRF guard via __init__
(not per-call) for mutable methods; _validate_destination for MOVE SSRF (T-13-04)
- NextcloudBackend inherits all mutable methods from WebDAVBackend (no changes needed)
- Add build_mutable_cloud_adapter() to cloud_backend_factory.py
- All 184 tests pass (test_cloud_backends.py + test_cloud_provider_contract.py)
2026-06-22 18:31:53 +02:00
curo1305
fd6b561899
test(13-01): extend provider contract suites for four-provider mutable-operation parity
...
- Add Phase 13 mutable-operation RED tests to test_cloud_backends.py:
TestGoogleDriveMutableContract (D-17 scope, create/rename/move/delete/upload),
TestOneDriveMutableContract (CONN-02 token handoff, permanent-delete disclosure,
nextLink SSRF guard), TestNextcloudMutableContract (create-folder SSRF, delete
normalization), TestWebDAVMutableContract (permanent-delete, move SSRF, no
cloud_items imports)
- Add Phase 13 mutable-operation RED tests to test_cloud_provider_contract.py:
TestMutableAdapterContract (method existence, async contract, canonical signatures
for all four providers), TestMutableAdapterResultNormalization (normalized kind/reason
return types, conflict normalization documentation, unsupported-capability disclosure)
- All new tests fail against the current codebase — mutable adapter methods do not
exist yet (expected RED); all prior Phase 12 tests remain green
2026-06-22 18:01:15 +02:00
curo1305
efb596433c
test(13-01): add red API and audit contracts for reconnect, content, and mutation flows
...
- Create test_cloud_mutations.py: IDOR, admin block, credential secrecy, and typed
kind/reason body coverage for open, preview, upload, create-folder, rename, move,
and delete endpoint contracts (D-02 through D-11, D-18)
- Create test_cloud_reconnect.py: reconnect patch-in-place (CONN-01), encrypted credential
persistence (CONN-02), response secrecy (CONN-03), health endpoint, test action,
cache-preservation on reconnect (D-14), transient-outage data preservation (D-15),
and disconnect metadata cleanup (D-16)
- Create test_cloud_audit.py: metadata-only audit rows for every successful cloud operation,
false-overwrite prevention (T-13-05), admin audit log credential exclusion (T-13-02)
- All tests fail against current codebase — Phase 13 routes do not exist yet (expected RED)
2026-06-22 17:57:55 +02:00
curo1305
b00218e5c5
test(phase-12.1): repair live browse validation guard
2026-06-22 12:03:06 +02:00
curo1305
46b7ea6c12
test(12.1): verify live cloud browse integration
...
Phase 12.1 close — docs, version, and security evidence:
- Bump version 0.2.5 → 0.2.6 in backend/main.py, frontend/package.json
- CLAUDE.md: update current state to Phase 12.1 complete v0.2.6
- README.md: add Phase 12.1 corrections, live smoke variable names, Phase 13/14 exclusions
- RUNBOOK.md: add live smoke invocation, warning semantics table, fixture reconciliation procedure
- SECURITY.md: add Phase 12.1 Plan 04 threat table (T-12.1-16..20, T-12.1-SC) and gate evidence
- 12.1-VALIDATION.md: mark Plan 04 complete with final gate evidence
2026-06-22 09:46:25 +02:00
curo1305
1ec5158c65
test(12.1): owner-confirmed expected root manifest
...
- Create backend/tests/fixtures/cloud/nextcloud_expected_root.json with
owner_confirmed: true and corrected 10-item name/kind manifest
- Add test_nextcloud_expected_root_manifest: exact set and kind equality
against fixture (T-12.1-19 — count-only acceptance blocked)
- Update 12.1-VALIDATION.md: manifest status OWNER CONFIRMED, add
exact-acceptance row to Nyquist matrix
2026-06-22 09:35:36 +02:00
curo1305
779b05086b
test(12.1-04): add opt-in live Nextcloud smoke test suite
...
- backend/tests/test_nextcloud_live.py: three read-only live tests behind
live_nextcloud marker (adapter root metadata, sanitized diagnostic, connection-ID
browse as testuser@docuvault.example with IDOR/admin negatives)
- backend/pytest.ini: register live_nextcloud marker; addopts excludes it from
ordinary runs so CI never contacts Nextcloud without explicit selection
- 12.1-VALIDATION.md: live test contract, commands, skip behaviour, sanitized
7-of-10 probe result, and threat references T-12.1-16 through T-12.1-20
- Manifest status: unconfirmed — Task 2 exact-name gate pending owner decision
2026-06-22 09:02:42 +02:00
curo1305
7bb046ac41
fix(12.1): align cloud browser contract — kind, provider_item_id, server freshness
...
Normalized cloud frontend for DocuVault v0.2.5:
- Cloud UI classifies items by kind=folder/file (is_dir removed from all active paths)
- Folder navigation uses provider_item_id (opaque provider ref) — DocuVault id kept for row identity
- Server freshness (refresh_state, last_refreshed_at) mapped verbatim — no browser-clock evidence
- Breadcrumb lineage built from explicit visited nodes — never split(provider_item_id)
- CloudFolderTreeItem: expandable/icon/navigate/loadChildren all use kind and provider_item_id
- Version bump 0.2.4 → 0.2.5
- SECURITY.md: T-12.1-11 through T-12.1-15 closed
- 369 tests pass, npm audit clean, production build clean
2026-06-22 08:51:14 +02:00
curo1305
70a543a8c1
fix(12.1): make cloud freshness authoritative — plan 02 documentation and version
...
- Version bump 0.2.3 → 0.2.4 (user-visible sync status corrected)
- CLAUDE.md: update current state; add apply_listing_and_finalize to module map; add no-independent-fresh rule
- README.md: bump version
- RUNBOOK.md: update freshness state docs; explain complete=True gate and last_refreshed_at behavior
- SECURITY.md: add T-12.1-06..10 threat closure evidence for Plan 02
2026-06-22 08:34:51 +02:00
curo1305
bfa4dc502a
feat(12.1-02): centralize listing freshness gate — apply_listing_and_finalize
...
- Add ListingResult dataclass to cloud_items.py
- Add apply_listing_and_finalize() — single shared gate for complete/incomplete semantics
- complete=True: upserts, soft-deletes unseen children, marks fresh, advances last_refreshed_at
- complete=False: upserts seen items only, never deletes unseen, preserves prior timestamp, warns
- browse.py: replace unconditional update_folder_state('fresh') with apply_listing_and_finalize
- cloud_tasks.py: replace unconditional fresh transition with apply_listing_and_finalize
- Celery task returns structured warning status on incomplete (no credentials/provider item names)
- Fix timezone naive/aware comparison in test (SQLite strips tzinfo)
2026-06-22 08:29:41 +02:00
curo1305
fe08afd740
test(12.1-02): add failing tests for truthful freshness gate (RED)
...
- test_incomplete_listing_never_marks_folder_fresh
- test_incomplete_listing_retains_cached_rows_and_last_success
- test_complete_empty_listing_is_authoritative_and_fresh
- test_partial_items_upsert_without_deleting_unseen_children
- test_apply_listing_returns_warning_for_complete_false
- test_sync_browse_returns_warning_for_complete_false
- test_worker_returns_warning_for_complete_false
- security: browse_complete_false_never_sets_fresh, no_raw_provider_error, owner_scoped_on_incomplete
2026-06-22 08:26:35 +02:00
curo1305
62128730e8
fix(12.1-01): restore asyncio import, bump version to 0.2.3, update docs
...
- Restore asyncio import removed when legacy list_folder was deleted (health_check
still uses asyncio.to_thread); fixes test_nextcloud_connect_persists regression
- Bump backend/main.py and frontend/package.json version to 0.2.3
- Update CLAUDE.md: note Phase 12.1 Plan 01 complete, add normalize_nextcloud_url
to shared module map, add NextcloudBackend no-override rule
- Update README.md: version 0.2.3, note canonical Nextcloud URL normalization and
OneDrive nextLink origin guard
- Full backend suite: 585 passed, 1 pre-existing failure (missing python-docx module)
2026-06-22 08:18:23 +02:00
curo1305
805fe44bfb
feat(12.1-01): add cross-origin nextLink guard and Drive/OneDrive contract tests
...
- Validate @odata.nextLink hostname against graph.microsoft.com before following
(T-12.1-03); cross-origin nextLink returns complete=False with prior items retained
- Add TestOneDriveCrossOriginNextLink: cross-origin rejection, same-origin follows,
page failure retains prior items
- Add TestGoogleDriveAuthFailureControl: 401 returns complete=False, page1+page2
error retains page1 items
- All 163 four-provider contract tests pass
2026-06-22 08:12:39 +02:00
curo1305
2b46f74329
feat(12.1-01): repair Nextcloud adapter contract and add URL normalization
...
- Remove incompatible NextcloudBackend.list_folder(folder_path="") override
so Nextcloud inherits canonical WebDAVBackend.list_folder(connection_id,
user_id, parent_ref=None, page_token=None) -> CloudListing
- Add normalize_nextcloud_url() to cloud_utils.py: idempotent canonical DAV
root derivation, username percent-encoding, https-only, rejects userinfo/
query/fragment, validates via SSRF guard before return
- Use normalize_nextcloud_url in cloud_backend_factory for nextcloud provider
- Add TestNextcloudBackendNoListFolderOverride and TestNextcloudUrlNormalization
to test_webdav_backend.py
- All 9 Nextcloud contract failures now pass; full focused suite: 158 passed
2026-06-22 08:11:06 +02:00
curo1305
eb68facd6c
test(12.1-01): add failing four-provider contract suite and fixtures
...
- Create test_cloud_provider_contract.py with parametrized suite for
Nextcloud, WebDAV, Google Drive, OneDrive
- Assert canonical (connection_id, user_id, parent_ref=None, page_token=None)
signature, CloudListing return type, trusted caller identity propagation,
metadata normalization, pagination completeness, and forbidden-operation spies
- Add synthetic credential-free fixtures: nextcloud_root.xml, webdav_root.xml,
google_drive_pages.json, onedrive_pages.json
- 9 tests fail for nextcloud (expected RED state — incompatible list_folder override)
- All webdav, google_drive, onedrive contract tests pass
2026-06-22 08:09:00 +02:00
curo1305
c85e4abd91
chore(12-06): bump version 0.2.1 → 0.2.2
2026-06-21 22:30:11 +02:00
curo1305
731b65ecdd
feat(12-06): connection-ID native lifecycle — always INSERT, PUT credentials, connectionsFor multi-account
...
- Replace _upsert_cloud_connection with _insert_cloud_connection (always inserts new UUID row)
- Add PUT /connections/{id}/credentials endpoint (owner-scoped, SSRF + health-check, password-preserve)
- SettingsCloudTab: connectionsFor() renders all same-provider connections with Add account row
- CloudCredentialModal.submit: calls updateWebDavCredentials on edit, connectWebDav on create
- utils.js: FastAPI validation arrays normalised to concise field messages (Rule 2)
- Backend tests: same-provider independence + IDOR negative test for credential update
2026-06-21 22:29:59 +02:00
curo1305 and Claude Sonnet 4.6
206f564248
test(12-05): fix test_nextcloud_connect_persists + compose migration test path
...
- test_nextcloud_connect_persists: provider=nextcloud routes to NextcloudBackend
(not WebDAVBackend) — add storage.nextcloud_backend.validate_cloud_url patch
and use AsyncMock for asyncio.to_thread (plain return_value=True is not
awaitable, swallowed by except → False). Test now passes HTTP 201.
- test_compose_migrations: skip module when docker-compose.yml is not found at
the expected repo-root path (file is not mounted inside the backend container).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 12:35:35 +02:00
curo1305 and Claude Sonnet 4.6
043a7817e2
fix(12-uat): add display_name_override schema regression + Compose hardening
...
- test_list_connections_reads_display_name_override_column: proves GET /api/cloud/connections
does not raise UndefinedColumn (direct Phase 12 UAT blocker regression)
- docker-compose: promtail socket :ro, Grafana password fail-fast (:?)
- test_migration_0006: DDL privilege test fails not skips when role absent
- README: version 0.2.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 11:07:30 +02:00
curo1305 and Claude Sonnet 4.6
760a8d4bcd
fix(12-uat): resolve critical code review findings in gap closure (CR-01 through CR-03, IN-01)
...
- CR-01: promtail Docker socket mounted :ro (was read-write)
- CR-02: Grafana admin password uses :? fail-fast (was :-changeme default)
- CR-03: DDL privilege test fails not skips when docuvault_app role absent
- IN-01: README version synced to 0.2.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 10:55:23 +02:00
curo1305
3ca57dcd0c
fix(12-05): bump version to 0.2.1 and update docs for migration-gated startup
...
- backend/main.py, frontend/package.json: version 0.2.0 → 0.2.1
- CLAUDE.md, AGENTS.md: current state updated to reflect gap-closure
- README.md: startup instructions note migrate runs automatically; update migration commands
- RUNBOOK.md: startup diagram includes migrate service; migration gate explanation
- SECURITY.md: Phase 12 gap-closure threat register and security gate evidence
2026-06-20 10:49:21 +02:00
curo1305
de2efd1664
test(12-05): add migration 0005→0006 integration regression and RUNBOOK migration ops
...
- test_migration_0006.py: proves display_name_override, cloud_items, cloud_item_topics,
cloud_folder_states, unique constraints, indexes, and DDL privilege boundary
- Tests skip cleanly without INTEGRATION=1/INTEGRATION_DATABASE_URL (no dev DB mutation)
- RUNBOOK: add Database Migrations section with revision check, upgrade, recovery, and
emergency schema-drift remediation commands
2026-06-20 10:47:11 +02:00
curo1305
1b3084ddfa
feat(12-05): add migration-gated Compose startup path
...
- Add one-shot migrate service using DATABASE_MIGRATE_URL and alembic upgrade head
- Add migrate dependency (service_completed_successfully) to backend, celery-worker, celery-beat
- migrate service has same read_only/cap_drop/no-new-privileges hardening as other services
- Add test_compose_migrations.py: 7 static assertions on Compose configuration
2026-06-20 10:45:22 +02:00
curo1305 and Claude Sonnet 4.6
b6911fb4ed
fix(12): resolve critical code review findings (CR-01 through CR-04)
...
- CR-01: fix browse URL from /folders/{id} to /items?parent_ref= (broken feature)
- CR-02: remove raw provider exception text from _TerminalProviderError messages
- CR-03: add user_id predicate to get_or_create_folder_state query (ownership boundary)
- CR-04: add max_length=255 to ConnectionRenameRequest.display_name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 02:00:05 +02:00
curo1305
c441fc63e5
chore(12-04): bump version to 0.2.0 and finalize Phase 12 documentation
...
- backend/main.py, frontend/package.json: 0.1.6 → 0.2.0 (phase-complete minor bump)
- AGENTS.md: current state updated to Phase 12 complete; cloud-resource-foundation
summary with browse contract, security suite, and Phase 13/14 boundary note
- README.md: version updated to 0.2.0
- All existing shared module map rules and frontend architecture constraints unchanged
2026-06-19 01:54:24 +02:00
curo1305
3b24058e15
test(12-04): add dedicated cloud security-negative integration suite
...
- test_foreign_user_cannot_browse_cloud_item (IDOR T-12-01, CONN-04)
- test_admin_cannot_browse_cloud_connection (admin block T-12-01, D-03)
- test_browse_response_excludes_credentials_and_raw_fields (T-12-03, D-06)
- test_ssrf_url_validation_invariants (T-12-04, D-14)
- test_browse_no_quota_mutation (T-12-09, D-07)
- test_browse_no_minio_calls (T-12-09, D-08)
- test_disabled_connection_browse_blocked (D-17)
- test_same_provider_items_scoped_to_connection (D-01, D-05 PostgreSQL)
- test_no_byte_download_during_browse (D-18)
- 16 tests pass; full suite 509 passed
2026-06-19 01:51:13 +02:00
curo1305
c6c0742267
feat(12-03): breadcrumb freshness, formatRelativeTime, v0.1.6, docs
...
- BreadcrumbBar: refreshing spinner, fresh checkmark (fades 3s), stale warning banner
- Accessible labels and role=status for all freshness states
- formatters.js: add formatRelativeTime (shared, no duplication)
- Version bump 0.1.5 → 0.1.6 in backend/main.py and frontend/package.json
- AGENTS.md: update state, shared module map (formatRelativeTime)
- README.md: unified connection-root browsing and capability explanations feature text
- 17 BreadcrumbBar tests pass; 323 total; production build clean
2026-06-18 23:31:50 +02:00
curo1305
c6237ca57f
feat(12-02): add refresh_cloud_folder Celery task, staleness trigger, version 0.1.5
...
- Add tasks/cloud_tasks.py: durable refresh_cloud_folder task with 3-retry
bounded backoff (30s/90s/270s +jitter), credential decryption in worker only
- Register tasks.cloud_tasks.* on documents queue in celery_app.py
- Add stale-while-revalidate staleness trigger in browse.py (5-min threshold)
- Add 4 Task 3 tests: idempotency, cached-row retention on failure, task structure,
no-byte-download contract; add background-refresh scheduling integration test
- Bump backend version 0.1.4 → 0.1.5, frontend package.json 0.1.4 → 0.1.5
- Update AGENTS.md with Phase 12 Plan 02 state and new shared module map entries
- Update README with connection-ID browse API table and v0.1.5
2026-06-18 23:17:34 +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
ff33439f0a
feat(12-02): normalize all four providers into CloudResourceAdapter contract
...
- GoogleDriveBackend: list_folder with full pagination, native doc size=None, get_capabilities
- OneDriveBackend: list_folder with @odata.nextLink pagination, get_capabilities
- WebDAVBackend: list_folder via PROPFIND with SSRF re-validation, get_capabilities
- NextcloudBackend: inherits CloudResourceAdapter from WebDAVBackend
- build_cloud_resource_adapter() added to factory
- 22 new contract/behavior/pagination/no-byte-download tests (51 total pass)
2026-06-18 22:45:09 +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
0a7273b9fe
feat(12-01): normalized cloud resource capability contract and unit tests
...
- Define 9 action keys, 3 capability states, 6 reason codes in cloud_base.py
- Immutable CloudCapability, CloudResource, CloudListing frozen dataclasses
- Abstract CloudResourceAdapter with list_folder, get_capabilities, merge_item_capabilities
- No mutation methods in Phase 12 interface (Phase 13 boundary enforced)
- 29 unit tests covering vocabulary, validation, merge behavior, fake adapter
2026-06-18 22:34:23 +02:00
curo1305
595b33a68c
fix(phase-11): close mobile storage UAT gaps
2026-06-17 10:48:35 +02:00
curo1305
e97ca164d7
Refactor backend and frontend cleanup paths
2026-06-16 11:50:17 +02:00
curo1305
6d1c02f703
refactor(09-05): CODE-09 purge — Phase 8 backend sub-packages (WHAT comments removed)
...
- api/admin/users.py: removed module docstring + 7 WHAT function docstrings
- api/admin/quotas.py: removed module docstring + 2 WHAT function docstrings
- api/admin/ai.py: removed module docstring + 3 WHAT inline comments; security invariant docstrings preserved
- api/admin/shared.py: unchanged (all comments are WHY — constraint notes)
- api/documents/upload.py: removed 4 WHAT inline comments; T-03-05/T-03-06 WHY notes preserved
- api/documents/content.py: removed WHAT function docstring + WHAT inline comment
- api/documents/crud.py: removed 7 WHAT inline comments; D-16 + security constraint docstrings preserved
- api/auth/shared.py: removed module docstring + 1 WHAT inline comment
- api/auth/tokens.py: removed module docstring + 8 WHAT function docstrings/comments; family-revocation + SEC-02 WHY notes preserved
- api/auth/totp.py: removed module docstring + 2 WHAT function docstrings + 2 WHAT inline comments
- api/auth/password.py: removed module docstring + 2 WHAT function docstrings + 3 WHAT inline comments
- All NO-prefix anchor comments and security-invariant WHY comments preserved
- pytest: 413 passed, 1 failed (pre-existing ModuleNotFoundError unrelated to purge)
2026-06-12 16:59:46 +02:00
curo1305
41d81c089f
feat(09-01): implement GET /api/admin/overview endpoint — ADMIN-11
...
- New backend/api/admin/overview.py: aggregate stats (user_count,
total_storage_bytes, doc_status) + last 10 audit entries in one payload
- Sub-router carries NO prefix (parent __init__.py carries /api/admin)
- Reuses _build_filtered_query_with_handles + _audit_to_dict_with_handles
from api.audit — no new serializer or query logic
- Registered overview_router on admin parent router in __init__.py
- All 8 ADMIN-11 tests pass; existing admin and audit suites stay green
2026-06-12 15:50:38 +02:00
curo1305
4caeed2d22
test(09-01): add failing xfail tests for ADMIN-11 overview endpoint
...
- 8 xfail tests covering auth guards, aggregate stats, and sensitive field scan
- Tests will become real assertions once overview.py is implemented in Task 2
2026-06-12 15:47:18 +02:00
curo1305 and Claude Sonnet 4.6
6bda133c81
chore(08-08): PERF-01 packages + Vite 6 upgrade + pin requirements.txt
...
- Upgraded vite 5.4.21 → 6.4.3 (fixes CVE-2026-39363, CVE-2026-39364)
- Upgraded @vitejs/plugin-vue 5.2.4 → 6.0.7 (Vite 6 peer dep)
- Installed @vueuse/core@14.3.0, @vueuse/integrations@14.3.0,
sortablejs@1.15 .7, @tailwindcss/forms@0.5.11,
rollup-plugin-visualizer@7.0.1, @types/sortablejs@1.15 .9
- Wired @tailwindcss/forms plugin in tailwind.config.js (VISUAL-02 ready)
- Pinned backend/requirements.txt to exact == versions per D-17 (32 packages)
- Frontend: 136/136 tests pass on Vite 6; 0 npm audit vulnerabilities
- Backend: 408 passed, 4 skipped, 7 xfailed (baseline 405+1)
- Phase 8 complete (8/8 plans)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-12 10:54:34 +02:00
curo1305 and Claude Sonnet 4.6
81337bd9e3
feat(08-05): decompose documents API monolith into documents/ package — CODE-02 CODE-08
...
- upload.py: request_upload_url, upload_document, confirm_upload (3 routes)
- crud.py: list_documents, get_document, patch_document, delete_document, classify_document (5 routes)
- content.py: stream_document_content + _parse_range (1 route)
- shared.py: _CLOUD_PROVIDERS, UploadUrlRequest, DocumentPatch (single definitions)
- __init__.py: router aggregator prefix=/api/documents, 9 routes total
- documents.py monolith deleted; all URL paths unchanged
- list_documents registered on parent router to avoid FastAPI empty-path/prefix check
- get_storage_backend_for_document re-exported for test monkeypatching compatibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-12 10:27:48 +02:00
curo1305 and Claude Sonnet 4.6
f01fb0e6d5
feat(08-04): delete admin.py monolith after URL regression — CODE-01 CODE-08
...
Task 3: 54 admin+cloud+ai-config tests pass with package; admin.py and
admin_OLD_REMOVE_IN_TASK_3.py removed. admin/ package is the sole definition.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-12 10:16:38 +02:00
curo1305
3ec198768d
feat(08-04): create backend/api/admin/ package — users, quotas, ai, shared, init
...
- users.py: list_users, create_user, update_user_status, initiate_password_reset,
update_ai_config, delete_user, create_system_topic (7 routes)
- quotas.py: get_user_quota, update_user_quota (2 routes)
- ai.py: get_ai_config_models, test_ai_connection, get_ai_config,
update_system_ai_config (4 routes); validate_provider_id call-through (D-11)
- shared.py: _user_to_dict helper (T-02-27 / SEC-07 field whitelist)
- __init__.py: router aggregator with prefix=/api/admin; 13 routes total
- admin.py monolith renamed to admin_OLD_REMOVE_IN_TASK_3.py (deleted in task 3)
- All sub-routers have NO prefix (D-04)
- All handlers inject Depends(get_current_admin) (T-08-04-01)
2026-06-10 18:43:01 +02:00
curo1305
5117e2542a
feat(08-06): create backend/api/auth/ package — Task 1
...
- Create api/auth/shared.py: limiter, all Pydantic request models, _set_refresh_cookie, _user_dict
- Create api/auth/tokens.py: register, login, refresh, logout, logout-all, me, quota, preferences handlers
- Create api/auth/totp.py: totp/setup, totp/enable, totp DELETE handlers (CR-02, CR-03 preserved)
- Create api/auth/password.py: change-password, password-reset, password-reset/confirm handlers (CR-01 preserved)
- Create api/auth/__init__.py: router aggregator with prefix=/api/auth; re-exports limiter
- Rename auth.py monolith to auth_OLD_REMOVE_IN_TASK_2.py (deleted in Task 2 after tests pass)
- All 15 routes confirmed; limiter re-export verified; skip_token_hash calls preserved verbatim
2026-06-10 18:42:27 +02:00
curo1305
4d7157d7fc
feat(08-04): add validate_provider_id helper to services/ai_config.py (D-11)
...
- Migrate inline provider_id validator to service layer per CLAUDE.md
- Raises ValueError (not HTTPException) — service-layer rule
- PROVIDER_DEFAULTS already imported; placed after load_provider_config helpers
2026-06-10 18:39:03 +02:00
curo1305
44ec28d474
test(08-03): promote CR-01/CR-02/CR-03 session-revocation tests from xfail to passing
...
- Remove @pytest.mark.xfail decorator from test_change_password_revokes_other_sessions (CR-01)
- Remove @pytest.mark.xfail decorator from test_enable_totp_revokes_other_sessions (CR-02)
- Remove @pytest.mark.xfail decorator from test_disable_totp_revokes_other_sessions (CR-03)
- All three tests now show PASSED (not XPASS) in strict pytest runs
2026-06-08 16:35:26 +02:00
curo1305
98dcf809b2
chore: merge executor worktree (worktree-agent-ad0b098c151ab9e3f)
2026-06-08 16:24:51 +02:00
curo1305
f750d30224
test(08-01): add xfail stubs for CR-01/CR-02/CR-03 session revocation
...
- test_change_password_revokes_other_sessions: verifies skip_token_hash
preserves current session while revoking all other refresh tokens
- test_enable_totp_revokes_other_sessions: verifies TOTP enrollment
revokes other sessions via skip_token_hash
- test_disable_totp_revokes_other_sessions: verifies TOTP disablement
revokes other sessions via skip_token_hash
- All three marked xfail(strict=False); currently xpassed (backend already complete)
- Plan 08-03 promotes these to strict passing tests
2026-06-08 16:21:58 +02:00