diff --git a/docs/pre-phase10-ux/D_IMPLEMENTATION.md b/docs/pre-phase10-ux/D_IMPLEMENTATION.md new file mode 100644 index 0000000..0a2de13 --- /dev/null +++ b/docs/pre-phase10-ux/D_IMPLEMENTATION.md @@ -0,0 +1,39 @@ +# D: administrator processing monitor + +28 October2026. Branch `feature/admin-processing-monitor`, based on accepted/pushed C `0bd290e788fc525157fe59ca830d39d5748fd192`. D extends existing durable processing; it does not create a queue or start model inference. + +## Current-system audit + +| Existing owner | Observed behaviour | Scoped change / compatibility | +| --- | --- | --- | +| UserOperation/UserOperationStore | Durable owner-scoped queue, leases, retries, cancellation, progress, current failure/result metadata; terminal notification and CV-run transactions | Add structured history to successful transitions, within their transaction. Keep lease/owner/CAS checks; rejected or duplicate attempts must not create successful events. | +| AiOperationWorker/HostedService | One claim/owner/execution boundary; periodic heartbeat, handler completion/failure, recovery | Reuse operation GUID for correlation. Do not log heartbeat renewals or fabricate jobs when workers are disabled. | +| CvProcessingQueue/ProfileCvController.Import | `cv.process` with integer CV-run subject; document stages currently update the operation directly, under lease/cancellation/expiry checks | Route significant stages through the existing store so stage+event commit together. Retain exact lease/cancel/expiry guards and real Docling path. | +| StrategySnapshotService | `strategy.snapshot`; subject encodes jobId and attachmentIds using its established decoder | Resolve only supported subject types and owner-matching jobs. CV imports have no job association. | +| CvImportRetentionHostedService | Existing hourly bounded retention owner; revokes operations before source cleanup | Reuse scheduler for finite event retention, and record actual retention cancellation where applicable. Keep document/artifact policies intact. | +| AccountDeletionService/AccountDataExportService | Existing account erasure/export for operations, notifications and source files | Event ownership filter, operation cascade deletion and owner-scoped export; no separate personal-data store. | +| AdminAuditController/AdminSystemController | Strict server-side Admin role; existing installation-wide administrative identity/job metadata policy | New read-only admin processing APIs use the same boundary. Ordinary-user endpoints remain owner-scoped. No tenantId is invented: the current schema uses owner isolation and installation-wide Admin. | +| Existing React routes/MUI/i18n/PageLayout/resource patterns | Admin audit/users/system views and hidden navigation for ordinary users | Add processing route/navigation, safe summary/detail/events with filters, bounded paging and recoverable polling. Server authorization remains decisive. | + +Job enrichment, rules, reminders and exports have worker configuration but do not all emit individual durable UserOperations. Show that distinction and configured-enabled status; do not invent queue records or claim enabled means healthy. Synchronous conversion/PDF/AI calls are not automatically durable jobs. Existing historical operations have no retrospective history; explicitly identify that absence. + +## History and privacy contract + +Add one migration-owned `UserOperationEvents` table with monotonically increasing ID, operation ID, owner ID, UTC timestamp, typed event kind/status/stage, attempt and allowlisted failure code. No prompts, documents, results, free-form failure messages, stack traces, paths, model caches, credentials, tokens, lease values or arbitrary JSON in events. Status/stage/failure values use fixed allowlists and unknown values become a fixed unknown/processing-failed code. UI translates fixed codes. + +Create, claim, stage change, completion, retry/failure, cancellation request/acknowledgement, explicit retry and lease/deadline recovery must append only after the successful state mutation, within the same relational transaction. Same-stage heartbeat renewals do not add events. Use parameterized event insertion without flushing unrelated tracked entities; existing producers/terminal notification saves retain their transaction behaviour. Failure to insert rolls back the corresponding new transition. Concurrent losing claims/stale leases cannot manufacture events. Operation deletion cascades its history. Retention is30 days, using bounded physical cleanup on the existing hourly scheduler; responses exclude expired history immediately. No unrestricted log viewer or administrative command/retry/cancel API. + +Read-only projections disclose only documented operation fields, safe identity metadata under the existing Admin policy, owner-verified job links and bounded original-file metadata. Never return raw operation entities or raw failure/result/subject/lease values. File names are treated as untrusted text. Copy only the operation GUID correlation ID. Sidecar requests carry a validated operation GUID where an actual operation context exists; no claim of distributed history for old or synchronous requests. + +## API and UI + +- Admin-only bounded list/filter/paging and aggregate status counts, worker configuration and inference availability description. +- Admin-only operation detail and event cursor pages (at most100 per request); deterministic event ID ordering and explicit retained-history availability. +- Poll only after the previous request finishes; abort on navigation/filter/identity changes, bounded retry/backoff, pause/resume and explicit older-page navigation. Keep a bounded event window and show connection/error state without false success. +- Display queued/running/retry/completed/failed/cancelled, actual stage, timestamps/duration, attempt count, worker, sanitized errors, owner and verified job association. Do not expose raw JSON in user flows. EN/Bokmål, responsive themes, keyboard and accessible status/table semantics. + +## Required qualification + +RED/GREEN transition/history/redaction tests; real SQLite HTTP authentication/role tests; MariaDB migration/startup, event ordering, CAS concurrency, insertion-failure rollback and retention/account-rights tests. UI tests for states/filters/poll pause/error/recovery and identity cleanup; browser admin/ordinary isolation and synthetic actual queue lifecycle. Existing RD21/import/worker semantics and all previous A/B/C features must survive. Then commit/push/verify D and execute the final integrated regression/handoff. + +Human/device/language acceptance, B's PDF oracle/model debt and production restrictions remain unchanged. No production access, main merge or Phase10 cleanup.