# Control Panel Operational UX Refinement V1 ## Scope Refine the existing FastAPI/Jinja2 control panel for daily GTI operations. The panel must answer which client/server needs attention, why, and which safe operator action is available. This work does not change fiscal rules, the Hub/Agent protocol, Firebird access, AI write controls, or deployment. ## Design Choices The implementation keeps the existing server-rendered architecture: - `control_plane.py` remains the bounded query/view-model layer. - A small presentation helper formats UTC timestamps using a configurable UI timezone, defaulting to `America/Bahia`. - Existing models are reused. `FiscalContextEntry` stores validated operator context, `Job` schedules reprocessing, and `AuditEvent` records the complete action context. No new write capability is introduced. - Jinja2 templates receive operational view models, not raw ORM rows. Technical IDs remain secondary detail information. - CSS remains project-local and JavaScript is limited to progressive enhancement; blocker resolution is a server-rendered form, not a `window.confirm` action. ## Dashboard Semantics Health cards include `ONLINE`, `DEGRADED`, `OFFLINE`, `FAILED`, and `UNKNOWN`. The query layer exposes a reconciled total and tests enforce: `agents_total == online + degraded + offline + failed + unknown`. Fiscal metrics are separate: - `safe_blocked_products`: distinct active products represented by open blockers. - `open_blockers`: active blocker rows. The dashboard labels these independently and never presents one as the other. Attention items are a deterministic maximum of ten, ordered by `FAILED`, `DEGRADED`, `OFFLINE`, `UNKNOWN`, required blockers, and important version drift. Each item contains client, display name, hostname, main problem, age, and a safe detail/filter link. Failed jobs and outdated Agents are compact sections with empty states. ## Presentation UTC remains the storage/API representation. The UI renders both a human short form (`22/09/2026 16:11`) and relative age (`há 8 min`); the full technical timestamp is available as a `title` attribute. The timezone comes from `UI_TIMEZONE`, with `America/Bahia` as the development default. Agents lead with client, display name, and hostname. Technical health and fiscal status are separate badges. Fiscal coverage includes total, complete, safe blocked, failed, and percentage with a worst-coverage sort option. Jobs show client, installation/display name, hostname, job ID, kind, status, human timestamps, duration, and error. Blockers show client/installation, product, field, type, deterministic operational priority, age, and links to a detail page. ## Blocker Operations The blockers page has visible server-side filters for client, installation, field, blocker type, status, age, and product/search. Its summary reports open blockers, distinct affected products, distinct affected clients, and field breakdown (`CFOP`, `ST`, `ICMS`, `CSOSN`, `NCM`, `OTHER`). Priority is operational only and deterministic: - `CRITICAL`: technical/unsafe condition that prevents processing. - `HIGH`: required field missing for an active product or a relevant conflict. - `NORMAL`: safe blocker without immediate operational urgency. - `LOW`: optional/reference enrichment. Clicking a blocker opens a detail page with evidence, first/last seen, retry count, related events/jobs, and resolution history. The resolution form shows the client, server, product, description, field, type, reason, evidence, and current value. It accepts a validated context key, value, scope (`PRODUCT`, `GROUP`, or `COMPANY`), and reason/note. Known enum keys are validated by the existing `context_keys` rules; arbitrary context values cannot bypass backend validation. On save, the transaction creates/updates the validated `FiscalContextEntry`, creates a bounded reprocess job for the product, and records an audit event containing operator, timestamp, client, installation, product, blocker, context key/scope/value, reason, before/after values, and reprocess job ID. The operation remains protected by human auth, CSRF, and authorization. It cannot enable AI writes, Firebird writes, SQL, or shell execution. ## Detail Pages and Events Agent detail shows client/display name/hostname first, technical/fiscal/version badges, human last-seen, version, company, UF, CRT, and secondary technical IDs. Fiscal summary is bounded and links to filtered blockers. Event rows have human timestamps, severity, event type, message, and related job/product links, with server-side severity/type/date/job/product filters and pagination. ## Password Policy Weak local development passwords are allowed only when explicitly enabled by `ALLOW_WEAK_DEV_PASSWORD=1` and only when `APP_ENV` is not `production`. Production always requires the strong password policy. The existing local admin credential is not changed. ## Verification Tests cover health reconciliation, metrics distinction, timestamps, attention ordering/limit, fiscal percentage, human job identity/duration, blocker filters and detail, resolution validation/audit/CSRF/authorization, events, and environment-aware password policy. Full `tests`, `central/tests`, and `agent/tests` regressions plus local route/runtime and bounded performance smokes are required before completion.