curo1305
203c225a3e
feat(06-02): add Loki + Promtail + Grafana stack to docker-compose
...
- Create docker/loki/loki-config.yaml: single-binary filesystem-mode Loki
(schema v13, tsdb store, embedded_cache 100MB, auth_enabled: false)
- Create docker/loki/promtail-config.yaml: docker_sd_configs scrape with
label filter logging=promtail; relabels container name and service labels
- docker-compose.yml: add loki (:3100), promtail, grafana (:3000) services
after celery-beat; loki_data and grafana_data named volumes; GF_AUTH
anonymous enabled for local dev; backend + celery-worker get logging:
"promtail" label; backend gets LOG_LEVEL/LOG_JSON env vars
- celery-beat deliberately left without logging: label (not a network-facing
service; schedule file write concerns deferred per D-08 Pitfall 7 notes)
2026-06-03 18:49:41 +02:00
curo1305
abe8f8ee90
feat(06-02): wire CorrelationIDMiddleware + config fields + promote 5 test stubs
...
- backend/config.py: add log_level: str = "INFO" and log_json: bool = False
fields under Observability (Phase 6 — D-01) comment; pydantic-settings reads
LOG_LEVEL / LOG_JSON env vars automatically
- backend/main.py: add imports (uuid, time, structlog, ASGIApp/Receive/Scope/Send,
setup_logging); add CorrelationIDMiddleware raw-ASGI class (NOT BaseHTTPMiddleware
— avoids streaming buffering); call setup_logging() as first lifespan statement;
register CorrelationIDMiddleware LAST so it runs FIRST (Starlette reverse order)
- backend/tests/test_logging.py: remove all 5 xfail decorators; replace single-line
bodies with real assertions for JSON renderer, contextvar binding, X-Correlation-ID
header, no-bleed between requests, uvicorn.access propagate=False
2026-06-03 18:47:49 +02:00
curo1305
9fa74a91f5
feat(06-02): add structlog dependency + create services/logging.py
...
- Append structlog>=25.5.0 to requirements.txt under Phase 6 D-01 comment
- Create backend/services/logging.py with setup_logging(json_logs, log_level)
- shared_processors: merge_contextvars first, then add_log_level, add_logger_name,
PositionalArgumentsFormatter, ExtraAdder, TimeStamper(iso), StackInfoRenderer
- JSON branch appends format_exc_info to shared_processors
- JSONRenderer when json_logs=True, ConsoleRenderer when False
- ProcessorFormatter bridges uvicorn/stdlib loggers through same chain
- Idempotent: clears root handlers before installing new one
- uvicorn.access propagate=False — middleware owns request logging
2026-06-03 18:44:37 +02:00
curo1305
c11984c66c
docs(phase-06): update tracking after wave 0 — 06-01 complete
2026-06-03 18:41:46 +02:00
curo1305
3e3f980466
docs(06-01): complete Wave 0 Nyquist scaffold plan summary
...
- 13 xfail stubs: 5 for D-01/D-02 (logging), 8 for D-11/D-12+A1 (rate limiting)
- load_tests package skeleton (D-04/D-05/D-06) excluded from pytest
- Package legitimacy decisions recorded (structlog + locust both approved)
- Full suite: 344 passed, 20 xfailed, 1 pre-existing failure, 0 regressions
2026-06-03 18:39:21 +02:00
curo1305
594eb46efe
feat(06-01): add backend/load_tests/ package skeleton with Locust stub (D-04/D-05/D-06)
...
- backend/load_tests/__init__.py — empty package marker; stops pytest discovery
- backend/load_tests/locustfile.py — DocuVaultUser skeleton (on_start,
_auth_headers, list_documents, upload_document, refresh_token methods)
and check_sla SLA listener; all bodies raise NotImplementedError
- No application imports; TEST_EMAIL/TEST_PASSWORD from env vars only
- Full implementation in plan 06-03
2026-06-03 18:37:23 +02:00
curo1305
56d9da7be1
test(06-01): add 8 xfail stubs for rate limiting (D-11/D-12 + A1)
...
- D-11: 4 stubs for trusted-proxy CIDR logic in get_client_ip
(untrusted peer, trusted+XFF, trusted+no-XFF, None client)
- D-12: 2 stubs for account_limiter key_func (user_id, fallback to IP)
- A1: test_account_limiter_key_ordering_assumption — explicit gate that
request.state.current_user is readable by key_func before counting
- D-12 integration: 429 after 100 req/min with same auth_user
All strict=False xfail stubs; implementation target: plan 06-04
2026-06-03 18:36:35 +02:00
curo1305
e1f8874b9d
test(06-01): add 5 xfail stubs for structured logging (D-01/D-02)
...
- test_setup_logging_emits_json_when_LOG_JSON_true
- test_correlation_id_middleware_binds_contextvar
- test_correlation_id_response_header_present
- test_contextvars_cleared_between_requests (Pitfall 2 guard)
- test_uvicorn_access_log_suppressed
All strict=False xfail stubs; implementation target: plan 06-02
2026-06-03 18:35:55 +02:00
curo1305 and Claude Sonnet 4.6
bdd784341f
wip: phase 7 planning paused — ready to execute
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 18:34:49 +02:00
curo1305 and Claude Sonnet 4.6
3df62506c9
docs(07): create phase plan — 5 plans, verification passed
...
5 waves: system_settings DB + HKDF encryption (01), ProviderConfig +
GenericOpenAIProvider + singleton client fix (02), Anthropic output_config +
classifier wiring (03), Celery retry 30/90/270s + re-queue endpoint (04),
admin AI panel + DocumentCard badge + human checkpoint (05).
All 18 decisions D-01..D-18 covered. Plan checker passed after 1 revision
round (4 blockers fixed: D-02/D-14 coverage, D-11 Vitest tests, Plan 05
files_modified).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 18:25:00 +02:00
curo1305 and Claude Sonnet 4.6
6c8e0d8bde
docs(07): research phase — Anthropic output_config, client singleton pattern, Celery retry, system_settings design
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 20:41:03 +02:00
curo1305 and Claude Sonnet 4.6
70c09f6cd4
docs(06): create phase 6 plan — performance & production hardening
...
6 plans across 4 waves covering structlog/Loki observability, Locust
load testing, multi-stage Dockerfile hardening, trusted-proxy rate
limiting, and RUNBOOK.md. Verification passed (0 blockers).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 20:35:03 +02:00
curo1305
b7503cdff4
docs(state): record phase 7 context session
2026-06-02 20:24:12 +02:00
curo1305
b8d128ee5e
docs(07): capture phase context
2026-06-02 20:24:08 +02:00
curo1305
ad237dbaf1
docs(06): research phase — structlog, Locust, container hardening, per-account rate limiting
2026-06-02 16:34:02 +02:00
curo1305 and Claude Sonnet 4.6
eaa3399ec0
docs: add shared module map to CLAUDE.md, SECURITY.md, planning artifacts
...
- CLAUDE.md: add Code Standards section with backend and frontend shared
module maps, component architecture rules, duplication checklist, and
no-dead-code enforcement rule
- SECURITY.md: Phase 02 + 03 security audit results (all threats CLOSED)
- .planning: update milestone audit, config, and add plan/UAT files for
phases 01, 02-06, and 06.2-05
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 16:10:59 +02:00
curo1305 and Claude Sonnet 4.6
cce70b2ef6
refactor(frontend): extract shared modules, thin views, delete dead code
...
Shared utilities:
- Add src/utils/formatters.js — formatDate, formatSize, providerColor,
providerBg, providerLabel; all components import from here, no inline duplicates
- Add src/components/ui/TreeItem.vue — generic expand/collapse tree node;
FolderTreeItem, CloudFolderTreeItem, CloudProviderTreeItem now wrap it
- Add src/components/storage/StorageBrowser.vue — unified file browser grid
used by both FileManagerView and CloudFolderView
View refactor (thin data-providers):
- FileManagerView.vue: stripped to props + event wiring; all layout moved to StorageBrowser
- CloudFolderView.vue: same treatment — feeds props into StorageBrowser
- All tree sidebar components delegate expand/collapse to TreeItem.vue
Dead code removed:
- Delete HomeView.vue — no active route, replaced by FileManagerView
- Delete FolderView.vue — no active route, logic merged into FileManagerView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 16:10:47 +02:00
curo1305 and Claude Sonnet 4.6
a548266461
refactor(backend): extract shared helper modules per architecture rules
...
- Add backend/ai/utils.py — parse_classification, parse_suggestions, strip_code_fences
shared by all AI providers; removes duplicated private functions from
anthropic_provider.py and openai_provider.py
- Add backend/deps/utils.py — get_client_ip, parse_uuid request-parsing helpers;
removes local _ip() variants from admin.py, auth.py, shares.py, folders.py
- Add backend/storage/exceptions.py — canonical CloudConnectionError definition;
all routers and backends import from here instead of redefining
- Move validate_password_strength to backend/services/auth.py; removes duplicated
_validate_password_strength from admin.py and auth.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 16:10:35 +02:00
curo1305 and Claude Sonnet 4.6
89f8d5a654
docs(codebase): refresh codebase map after Phase 06.2 completion
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 15:32:06 +02:00
curo1305 and Claude Sonnet 4.6
bd17b4b22f
docs(06.2): mark phase 6.2 complete — all gates passed
...
UAT complete (7/7 re-tests passed or skipped with reason), security gate
passed (threats_open: 0), 344 backend tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 21:09:04 +02:00
curo1305 and Claude Sonnet 4.6
2686fde2d7
feat(06.2): log attempted email on failed login and surface it in audit log
...
- auth.py: store attempted_email in metadata_ and link user_id when the account exists (wrong password case); previously logged no PII at all
- AuditLogTab: Email column falls back to metadata_.attempted_email in amber with "(attempted)" label when no confirmed user_email is available
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 21:02:37 +02:00
curo1305 and Claude Sonnet 4.6
7027347597
fix(06.2): audit log — add email column, remove @ prefix from handles
...
- Backend: add user_email to _build_filtered_query_with_handles (UserSubject join) and _audit_to_dict_with_handles; propagate through JSON viewer and CSV export including empty-result path
- Frontend: AuditLogTab adds Email column between User and Action Type; removes @ prefix from handle cell
- Test: update expected CSV header to include user_email
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 20:59:09 +02:00
curo1305 and Claude Sonnet 4.6
d771f0805d
fix(06.2): shared badge and recipient handle missing in FileManagerView
...
- shares.py grant_share: include recipient_handle in response so ShareModal shows the name immediately without reload
- FileManagerView: add Shared pill badge next to document name (badge only existed in DocumentCard, not the main file manager view)
- FileManagerView ShareModal: wire @unshared to clear is_shared flag when last recipient is removed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 19:47:00 +02:00
curo1305 and Claude Sonnet 4.6
089da94d8b
fix(security): apply two findings from sharing security review
...
- get_document: strip extracted_text for share recipients (T-04-04-03 consistency)
- ShareModal: emit 'unshared' when last recipient is revoked; DocumentCard clears is_shared badge
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 19:41:15 +02:00
curo1305 and Claude Sonnet 4.6
a0f6c2f663
fix(06.2): resolve four sharing UX issues found in re-test UAT
...
- AccountView: remove hardcoded @ prefix so handle matches what share dialog expects
- documents store: set is_shared=true optimistically after successful share so badge shows without refetch
- GET /api/documents/{id}: allow recipients of an active share to view the document (was returning 404 for non-owners)
- ShareModal: move Share button to its own full-width row so it no longer overflows the input area
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 19:32:51 +02:00
curo1305 and Claude Sonnet 4.6
52e54b859a
docs(phase-04): update validation strategy — 1 gap resolved, suite green
...
Audit 2026-06-01: test_daily_export_download was returning 404 because
the mock_backend failed the isinstance(backend, MinIOBackend) check.
Fixed. 87 passed, 4 xfailed, 0 failed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 18:14:59 +02:00
curo1305 and Claude Sonnet 4.6
cc2825b3b7
fix(phase-04): use MagicMock(spec=MinIOBackend) in test_daily_export_download
...
Plain MagicMock() failed the isinstance(backend, MinIOBackend) guard in
download_daily_export(), returning 404. spec=MinIOBackend sets __class__
so isinstance passes and the mock path executes correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 18:14:54 +02:00
curo1305
bfcc09958c
docs(phase-04): add security threat verification — 41/41 threats closed
2026-06-01 18:05:49 +02:00
curo1305 and Claude Sonnet 4.6
a3f9e701d8
docs(phase-03): update validation strategy — 4 gaps resolved, STORE-06 promoted from manual-only
...
Validation audit 2026-06-01: fix UUID format mismatch resolved 3 PARTIAL tests
(test_confirm_endpoint, test_quota_increment_atomic, test_quota_exceeded_response)
and promoted test_delete_decrements_quota (STORE-06) from manual-only to green.
Suite now 53 passed, 0 failed. Phase 3 fully Nyquist-compliant.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 15:43:07 +02:00
curo1305 and Claude Sonnet 4.6
b245fcc527
fix(phase-03): use UUID.hex in raw SQL to fix SQLite UUID format mismatch
...
str(uuid_obj) produces dashed 36-char format; SQLite stores UUID as 32-char
hex without dashes, so WHERE user_id = :uid never matched. Using .hex fixes
confirm_upload (api/documents.py) and delete_document (services/storage.py).
Removes stale xfail from test_delete_decrements_quota — now passes on SQLite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 15:43:01 +02:00
curo1305
908bd9d4e3
docs(phase-03): add security threat verification — 27/27 threats closed
2026-06-01 15:30:52 +02:00
curo1305 and Claude Sonnet 4.6
a89ed65be9
docs(phase-02): update validation strategy with plan 06 coverage
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 15:17:29 +02:00
curo1305 and Claude Sonnet 4.6
0505beb0a4
test(phase-02): add Nyquist validation tests for plan 06 gaps
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 15:17:25 +02:00
curo1305 and Claude Sonnet 4.6
da526cb727
docs(02): add security threat verification — 43/43 threats closed
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 14:55:15 +02:00
curo1305
cd3d1d528c
docs(06.2): add code review fix report
2026-06-01 14:38:59 +02:00
curo1305
8601a02189
docs(02): update verification report after plan 06 gap closure — 2 security blockers flagged
2026-06-01 14:37:23 +02:00
curo1305
a6c227cc7e
merge(06.2): integrate code review fixes from gsd-reviewfix/06.2-2490
2026-06-01 14:37:21 +02:00
curo1305
1433273328
docs(06.2): update review status after fixes — all 15 CR/WR findings resolved
2026-06-01 14:33:41 +02:00
curo1305
9e8f8d5bbc
fix(06.2): WR-06 use URLSearchParams in listShares for consistent encoding
2026-06-01 14:31:50 +02:00
curo1305
683670afa1
fix(06.2): WR-02 constrain format parameter to Literal[csv] to reject unsupported formats
2026-06-01 14:31:32 +02:00
curo1305
fdb18300d9
docs(02): add code review report for plan 06 gap closure
2026-06-01 14:31:21 +02:00
curo1305
1cba903c34
fix(06.2): WR-01 replace fixed-suffix password generation with fully-random positional injection
2026-06-01 14:31:00 +02:00
curo1305
2072c3ddcd
fix(06.2): WR-08 delete_document defers commit so audit log writes in same transaction
2026-06-01 14:30:31 +02:00
curo1305
50b6e7fd06
fix(06.2): WR-07 document X-Forwarded-For trust boundary in all IP extraction code
2026-06-01 14:29:35 +02:00
curo1305
2542c81602
fix(06.2): WR-03 WR-04 fix pagination off-by-one and surface daily exports load errors
2026-06-01 14:27:47 +02:00
curo1305
1f2cec9ac3
fix(06.2): CR-07 add audit log entry for PATCH /shares/{share_id} permission change
2026-06-01 14:27:08 +02:00
curo1305
1a34209bb0
fix(06.2): CR-06 RFC 5987-encode Content-Disposition filename to prevent header injection
2026-06-01 14:26:46 +02:00
curo1305
653cb3a98b
fix(06.2): CR-05 remove UUID dash-stripping in quota SQL — PostgreSQL expects dashed UUID format
2026-06-01 14:26:24 +02:00
curo1305
3fa7e8b866
fix(06.2): CR-04 WR-05 audit export functions use 401-refresh-retry and safe URL.revokeObjectURL
2026-06-01 14:26:05 +02:00
curo1305
792d4639d1
fix(06.2): CR-03 serialize metadata_ with json.dumps in CSV export instead of Python repr
2026-06-01 14:25:29 +02:00
curo1305
50859bb430
fix(06.2): CR-02 add MinIOBackend guard in download_daily_export before accessing _client
2026-06-01 14:25:06 +02:00
curo1305
a3ad36cc82
fix(06.2): CR-01 event-type filter uses prefix LIKE match instead of exact equality
2026-06-01 14:24:50 +02:00
curo1305
5093aa5630
docs(phase-02): update tracking after plan 06 gap closure — 6/6 plans complete
2026-06-01 14:24:46 +02:00
curo1305
7e549b6312
docs(02-06): complete UAT gap closure plan summary
...
- SUMMARY.md for plan 02-06 (5 UAT gaps closed)
- Backend fix verified; frontend auth layout, admin guard, Account tab, QR code implemented
2026-05-31 20:41:36 +02:00
curo1305
c08ea42b1b
feat(02-06): Account tab in SettingsView + QR code in TotpEnrollment (GAPs 3, 5)
...
- frontend/package.json: add qrcode@1.5.4 to runtime dependencies
- TotpEnrollment.vue: import QRCode; generate data URL in startSetup(); render img tag
- SettingsAccountTab.vue: new component with all AccountView content (2FA, password, sessions)
- SettingsView.vue: add Account tab rendering SettingsAccountTab; import SettingsAccountTab
2026-05-31 20:40:28 +02:00
curo1305
97314ce486
docs(06.2): add code review report
2026-05-31 20:38:59 +02:00
curo1305
aa957d6c50
feat(02-06): auth layout switching + admin role guard (GAPs 2, 3, 4)
...
- App.vue: conditionally renders AuthLayout for auth routes, app shell otherwise
- router/index.js: meta.layout='auth' on all four auth routes
- router/index.js: meta.requiresAdmin=true on /admin route
- router/index.js: beforeEach role check redirects non-admin to /
- router/index.js: /account redirects to /settings
2026-05-31 20:37:46 +02:00
curo1305
579c8366e9
docs(06.2): update phase verification report after plan-05 gap closure
2026-05-31 20:30:43 +02:00
curo1305
b2488c91c8
docs(02): add root causes from diagnosis
2026-05-31 20:28:57 +02:00
curo1305
52d6efb8a2
docs(06.2): add code review report
2026-05-31 20:23:32 +02:00
curo1305 and Claude Sonnet 4.6
33697f2713
test(02): complete UAT — 10 passed, 6 issues, 2 blocked
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 20:21:16 +02:00
curo1305
8cc46a8d8d
docs(phase-06.2): resolve UAT gaps after 06.2-05 gap closure
2026-05-31 20:16:43 +02:00
curo1305
c3c7030e91
docs(phase-06.2): update tracking after wave 3 — all 5 plans complete
2026-05-31 20:16:08 +02:00
curo1305
8a078e4040
chore: merge executor worktree (worktree-agent-ad4015e9fb03e9447)
2026-05-31 20:13:19 +02:00
curo1305
e30401ddff
docs(06.2-05): complete plan summary — 4 UAT gaps closed
...
- Task 1: @handle in AccountView + AdminUsersTab
- Task 2: actionable cloud error (Settings link) + audit log @ prefix
- Task 3: clearFilters() + activeFilterCount + Clear filters button + filter count badge
2026-05-31 20:12:27 +02:00
curo1305
5d457d68bf
feat(06.2-05): clear filters button and active filter count in AuditLogTab
...
- Add clearFilters() function that resets all filter fields and refetches
- Add activeFilterCount computed property (counts non-empty filter fields)
- Add "Clear filters" button (visible only when activeFilterCount > 0)
- Wrap Export CSV button with filter count indicator (amber text below button)
- Add computed to vue import
2026-05-31 20:11:02 +02:00
curo1305
f5e111bfa2
feat(06.2-05): actionable cloud error + audit log @ prefix
...
- CloudFolderView: detect no-connection error and show actionable message
directing user to Settings; add router-link to /settings and Retry button
- AuditLogTab: prefix user handles with @ in the User column
2026-05-31 20:10:22 +02:00
curo1305
045e723f7a
feat(06.2-05): show @handle in AccountView and AdminUsersTab
...
- Add Username row (@handle) to Account information section in AccountView.vue
- Add Handle column (th + td with @prefix) to users table in AdminUsersTab.vue
- Both use existing data already present in API responses (no backend changes)
2026-05-31 20:09:50 +02:00
curo1305
6307d9dd86
test(06.2): update UAT with root cause diagnoses for all 4 gaps
2026-05-31 20:01:56 +02:00
curo1305
1d8c7dba91
test(06.2): complete UAT — 3 passed, 4 issues, 2 skipped, 2 blocked
2026-05-31 16:10:54 +02:00
curo1305 and Claude Sonnet 4.6
77263bd569
docs(phase-06.2): mark validation strategy nyquist-compliant
...
All 11 Wave 0 test stubs verified green (50 passed, 4 xfailed).
Updated per-task map, wave 0 checklist, sign-off, and audit trail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:44:25 +02:00
curo1305 and Claude Sonnet 4.6
73b180ac9d
docs(phase-06.2): add security threat verification report
...
16/16 threats CLOSED — mitigate dispositions verified in code with exact file:line citations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:41:33 +02:00
curo1305
f037d2be45
docs(06.2): add phase verification report
2026-05-31 15:36:08 +02:00
curo1305
758d1a687e
docs(06.2): add code review report
2026-05-31 15:29:57 +02:00
curo1305
abb964531f
docs(phase-06.2): update tracking after wave 2 — plan 06.2-04 complete
2026-05-31 15:24:44 +02:00
curo1305
46f7505e36
chore: merge executor worktree (worktree-agent-af66944050628b0e4)
2026-05-31 15:23:36 +02:00
curo1305
893da5b9ba
docs(06.2-04): complete ADMIN-06 audit enrichment + daily exports — 10 tests pass
...
- Handle-enriched audit log (user_handle, actor_handle via aliased double-JOIN)
- user_handle filter with handle-to-UUID resolution, empty result for unknown handles
- fetch+Blob CSV export replacing window.location.href (T-06.2-04-03)
- GET /audit-log/daily-exports and /daily-exports/{date} with date regex validation
- Daily exports section in AuditLogTab with date dropdown + Download button
- Full audit test suite: 10 passed; backend suite: 337 passed, 1 pre-existing failure
2026-05-31 15:22:46 +02:00
curo1305
0647e6e9bf
feat(06.2-04): frontend — user_handle filter, fetch+Blob export, daily-export section
...
- adminListAuditLog: rename user_id param to user_handle (backend API change)
- adminExportAuditLogCsv(): fetch+Blob pattern — sends Bearer header (D-13, T-06.2-04-03)
- adminListDailyExports(): raw fetch returning JSON for daily export listing (D-17)
- adminDownloadDailyExport(date): fetch+Blob download with audit-{date}.csv filename (D-17)
- AuditLogTab: rename filters.user_id to filters.user_handle + label 'User handle' (D-12, C-5)
- AuditLogTab: exportCsv() replaced with async fetch+Blob call, exportingCsv loading state
- AuditLogTab: daily exports section below pagination — date dropdown + Download button (D-17, C-4)
- window.location.href removed from AuditLogTab (broken auth bypass closed)
- Build exits 0, full backend suite: 337 passed, 1 pre-existing failure
2026-05-31 15:21:23 +02:00
curo1305 and Claude Sonnet 4.6
f176235ee8
docs(phase-04): update VALIDATION.md — Nyquist-compliant (all gaps resolved)
...
Mark nyquist_compliant: true. All 22 tasks now have automated coverage.
4 gaps resolved: FOLD-04 sort, FOLD-05 FTS, SEC-08 credentials_enc, SEC-09
MinIO cleanup. 1 impl bug logged and fixed (FTS try/except misplacement).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:21:08 +02:00
curo1305 and Claude Sonnet 4.6
62daf0d750
test(phase-04): fill Nyquist validation gaps — FOLD-04, FOLD-05, SEC-08, SEC-09
...
Add 6 new tests covering document sort (name/size), FTS search cross-user
isolation, credentials_enc exclusion from all responses, and MinIO object
cleanup on user deletion.
Fix FTS try/except misplacement in api/documents.py — was wrapping the ORM
statement builder (never raises) instead of the execute call, causing HTTP 500
on SQLite test env. Now falls back to unfiltered results when @@ unsupported.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:21:02 +02:00
curo1305
839bfe0ffe
feat(06.2-04): backend — handle enrichment, user_handle filter, two daily-export endpoints
...
- Add _audit_to_dict_with_handles() with user_handle + actor_handle fields
- Add _build_filtered_query_with_handles() with aliased User double-JOIN
- Change list_audit_log user_id param to user_handle string with handle→UUID resolution
- Change export_audit_log user_id param to user_handle (Pitfall 7 — both endpoints enriched)
- Add GET /audit-log/daily-exports — lists MinIO audit-logs bucket, asyncio.to_thread
- Add GET /audit-log/daily-exports/{date} — streams CSV, date regex validation (T-06.2-04-01)
- Move daily-export endpoints before viewer to ensure specific path registration order
- Update test_audit_log_export_csv to match enriched CSV header (user_handle, actor_handle)
- All 10 test_audit.py tests pass
2026-05-31 15:17:53 +02:00
curo1305
d7cfc5ccee
test(06.2-04): add failing tests for handle enrichment, user_handle filter, daily exports
...
- test_audit_log_includes_user_handle: asserts user_handle/actor_handle in items
- test_audit_log_filter_by_handle: asserts filtering by handle works correctly
- test_audit_log_filter_unknown_handle: asserts 200+empty for unknown handle
- test_daily_exports_list: mocks MinIO list_objects, asserts sorted items
- test_daily_export_download: mocks MinIO get_object, asserts CSV response + 404 on bad date
2026-05-31 15:15:46 +02:00
curo1305 and Claude Sonnet 4.6
eab5f124f6
docs(06.2-03): complete cloud-delete gap closure — 24 tests pass
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:11:51 +02:00
curo1305 and Claude Sonnet 4.6
cce8586235
feat(06.2-03): frontend — CloudDeleteWarningModal + remove_only path in DocumentView
...
- api/client.js: deleteDocument gains removeOnly param; deleteDocumentRemoveOnly wrapper added
- DocumentView.vue: confirmDelete inspects response.cloud_delete_failed, shows modal on failure
- DocumentView.vue: inline CloudDeleteWarningModal (C-3 contract) with Remove from app / Cancel
- confirmRemoveOnly() calls DELETE ?remove_only=true and navigates to /
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:11:31 +02:00
curo1305 and Claude Sonnet 4.6
95c7ed786a
feat(06.2-03): backend — cloud-aware delete routing + skip_quota + remove_only param
...
- storage.delete_document gains skip_quota=False param; quota decrement gated on it
- DELETE /api/documents/{id} gains remove_only=bool query param
- Cloud docs (storage_backend != minio): attempt cloud backend delete_object first
- On failure: return HTTP 200 {success: false, cloud_delete_failed: true} (not 4xx)
- On success or remove_only: delete DB row with skip_quota=True
- Cloud creds/exception message never included in response body (T-06.2-03-02)
- Promote 3 xfail stubs to real tests (propagates, failure, remove_only)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:09:44 +02:00
curo1305 and Claude Sonnet 4.6
e812922a26
docs(06.2-02): complete SHARE-05 + SHARE-03 gap closure — 12 tests pass
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:07:26 +02:00
curo1305 and Claude Sonnet 4.6
3cc4a5335d
docs(phase-03): update VALIDATION.md — Nyquist-compliant (partial)
...
15 automated tests green, 4 manual-only (PostgreSQL/migration infra).
Added 4 previously unlisted passing tests to task map (D-15, D-16, D-09×2).
Audit trail appended. Status: nyquist_compliant: true, status: partial.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:07:23 +02:00
curo1305 and Claude Sonnet 4.6
1ee27da332
test(phase-03): remove stale xfail markers from quota tests
...
test_quota_increment_atomic and test_quota_exceeded_response were marked
xfail for PostgreSQL but pass on SQLite — markers removed, tests now PASSED.
Concurrent race and delete decrement keep xfail; they require real PG locking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:07:18 +02:00
curo1305 and Claude Sonnet 4.6
34b18a9f08
feat(06.2-02): frontend — is_shared badge fix + permission dropdown + View/Edit toggle
...
- DocumentCard.vue: fix Shared pill to read doc.is_shared (was doc.share_count > 0)
- ShareModal.vue: add permission select between handle input and submit button
- ShareModal.vue: replace static "view" span with View/Edit toggle group per share row
- ShareModal.vue: add handlePermissionChange with optimistic update + rollback on error
- documents.js: update shareDocument(docId, handle, permission='view') signature
- documents.js: add updateSharePermission(shareId, permission) action
- api/client.js: pass permission in createShare POST body
- api/client.js: add updateSharePermission PATCH helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:07:04 +02:00
curo1305 and Claude Sonnet 4.6
ea231853e9
feat(06.2-02): backend — ShareCreate.permission field + PATCH /{share_id} endpoint
...
- Add permission field (default "view") with field_validator to ShareCreate
- Add SharePermissionPatch model with same validator
- Wire body.permission into grant_share() Share constructor
- Add PATCH /{share_id} endpoint with IDOR protection (T-06.2-02-01)
- Promote 3 xfail stubs to real tests (create_with_permission, patch_permission, patch_idor)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:04:53 +02:00
curo1305 and Claude Sonnet 4.6
7e62868fea
docs(phase-02): add VALIDATION.md — Nyquist-compliant, all 24 tasks mapped, 4 manual-only
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 12:04:28 +02:00
curo1305 and Claude Sonnet 4.6
d98e3ab7a1
test(phase-02): add Nyquist validation tests — fill SEC-05, AUTH-08, SEC-03 and frontend gaps
...
8 test files, 60 new tests (14 backend + 46 frontend). All green.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 12:04:21 +02:00
curo1305
6c79f92d70
chore: merge executor worktree (worktree-agent-a3dd74026d1efb9af)
2026-05-31 12:01:28 +02:00
curo1305
21fde406e7
docs(06.2-01): complete Wave 0 Nyquist scaffold — 11 xfail stubs across 3 test files
...
- 3 stubs in test_shares.py (SHARE-03 permission field, PATCH, IDOR)
- 3 stubs in test_documents.py (cloud delete propagation, failure, remove_only)
- 5 stubs in test_audit.py (handle enrichment, handle filter x2, daily exports x2)
- All 11 reported as XFAIL; full 3-file suite: 35 passed, 15 xfailed, exits 0
2026-05-31 11:58:58 +02:00
curo1305
7271eeb53c
test(06.2-01): add xfail stubs for ADMIN-06 audit enrichment + daily exports (Task 3)
...
- test_audit_log_includes_user_handle: user_handle and actor_handle in audit items (D-11)
- test_audit_log_filter_by_handle: user_handle query param filters entries (D-12)
- test_audit_log_filter_unknown_handle: unknown handle returns empty list, not 422 (D-12)
- test_daily_exports_list: daily-exports listing endpoint returns {items} (D-15)
- test_daily_export_download: daily export download returns CSV bytes with Content-Disposition (D-16)
2026-05-31 11:58:05 +02:00
curo1305
bbf5355edb
test(06.2-01): add xfail stubs for cloud-delete document tests (Task 2)
...
- test_delete_cloud_document_propagates: cloud backend delete_object called for non-minio docs (D-01)
- test_delete_cloud_document_failure: structured JSON error when provider raises (D-03)
- test_delete_cloud_remove_only: remove_only=true skips cloud delete, removes DB row only (D-02)
2026-05-31 11:57:55 +02:00
curo1305
ecdeffb63d
test(06.2-01): add xfail stubs for SHARE-03 permission tests (Task 1)
...
- test_share_create_with_permission: POST /api/shares permission field (SHARE-03, D-08, D-10)
- test_share_patch_permission: PATCH /api/shares/{id} permission change (SHARE-03, D-09)
- test_share_patch_idor: PATCH by non-owner returns 404 IDOR protection (SHARE-03, T-IDOR)
2026-05-31 11:54:52 +02:00
curo1305 and Claude Sonnet 4.6
708fd7fad0
docs(phase-6.2): record planning complete — 4 plans verified, state updated
...
- ROADMAP.md: progress table → Planned; wave annotations already added by planner
- STATE.md: phase 6.2 row → Planned (4 plans, 3 waves); session note added
- 06.2-03-PLAN.md: remove incorrect SHARE-03/SHARE-05 from requirements field
- 06.2-RESEARCH.md: mark Open Questions section as RESOLVED
- 06.2-UI-SPEC.md: add to version control (was untracked)
Verification: 0 blockers, 2 cosmetic warnings fixed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 11:41:32 +02:00
curo1305 and Claude Sonnet 4.6
4adc77d8cc
docs(06.2): create 4-plan phase covering SHARE-03, SHARE-05, cloud-delete, ADMIN-06
...
Wave 0: 11 xfail stubs across test_shares/test_documents/test_audit
Wave 1 (parallel): SHARE-05 badge + SHARE-03 permission control; cloud-delete propagation
Wave 2: audit handle enrichment, user_handle filter, CSV fetch+Blob, daily-export UI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 11:36:33 +02:00
curo1305
67f0c01540
docs(phase-6.2): add validation strategy
2026-05-31 11:12:23 +02:00