fix: reconcile final control panel coverage UX

This commit is contained in:
gti
2026-09-22 23:04:53 -03:00
parent 283749e860
commit ce606b04cc
12 changed files with 312 additions and 12 deletions
+20 -3
View File
@@ -21,15 +21,32 @@ Technical health describes Agent/installation availability and processing
failures. Fiscal status and fiscal completion are separate: safe-blocked fiscal
work does not make an otherwise healthy Agent technically degraded or failed.
Agent views show product total, fiscally complete count, safe-blocked count,
failed count, and fiscal completion percentage. The percentage is
technical-failure count, unclassified residual, and fiscal completion percentage.
At installation/snapshot grain, coverage is reconciled as:
```text
TOTAL_PRODUCTS = COMPLETE + SAFE_BLOCKED + FAILED_PRODUCTS + UNCLASSIFIED
```
`UNCLASSIFIED` is the positive residual `TOTAL_PRODUCTS - COMPLETE -
SAFE_BLOCKED - FAILED_PRODUCTS`: the snapshot did not assign those products to
one of its explicit states. It is an observability bucket, not a newly inferred
fiscal state. If explicit category counts exceed the total or contain negative
values, the panel shows an inconsistency instead of clamping it away. Fixture
snapshots assign all products explicitly and therefore reconcile to zero
unclassified products. The fiscal completion percentage is
`fiscally_complete / total_products * 100`, rounded to one decimal place and
bounded to 0–100; when the total is zero, the stored coverage percentage is
used. The fiscal status badge is `BLOCKED` when safe-blocked work exists,
`COMPLETE` when all products are complete, and otherwise `INCOMPLETE`.
Two blocker counts must remain distinct:
Coverage-state counts and blocker-registry counts have different sources and
must remain distinct:
- **Safe-blocked products**: distinct open `(tenant_id, product_code)` pairs.
- **Safe-blocked coverage products**: sum of the Agent snapshot safe-blocked
count at installation grain; this participates in the coverage invariant.
- **Products with open blockers**: distinct open `(tenant_id, product_code)`
pairs in the blocker registry.
- **Open blockers**: open blocker rows; one product can have multiple rows for
different fields or evidence.
@@ -0,0 +1,81 @@
# Control Panel Final Pre-Deploy Fixes V1 Implementation Plan
> **For agentic workers:** Execute inline; the operator mission authorizes autonomous completion. Steps use checkbox syntax for tracking.
**Goal:** Reconcile fiscal coverage counts, correct the fixture gap, and apply the narrowly scoped login/Agent-list/Agent-detail presentation fixes before deploy freeze.
**Architecture:** Preserve the FastAPI/Jinja2/CSS/vanilla-JS panel and fiscal/Agent behavior. Add a derived, explicitly named `unclassified_products` residual from snapshot coverage, expose a consistency flag for over-counted categories, correct only fixture counts that are known synthetic gaps, and make requested UI-only changes.
**Tech Stack:** Python 3.12, FastAPI, Jinja2, SQLAlchemy, CSS, pytest, Docker Compose local runtime.
## Global Constraints
- Do not deploy, alter fiscal engine/requiredness, call AI, enable Firebird writes, change architecture, add SPA, modify Proxmox, or integrate GTI Gerenciador.
- A product coverage state is counted at installation/snapshot grain; existing distinct blocker registry totals remain separately labeled.
- Define `UNCLASSIFIED = TOTAL - COMPLETE - SAFE_BLOCKED - FAILED_PRODUCTS` only when nonnegative; show an inconsistency warning and fail `coverage_invariant_pass` when the explicit categories exceed total.
- Do not use an unexplained generic “other” label; the residual is “Não classificados (sem estado informado)” and documentation says precisely that snapshot telemetry did not assign a known state.
- Keep Agent percentage and technical IDs in detail/API; remove UUID only from the main Agents table.
- Do not modify Firebird databases or run fixture generation against production/client data.
---
### Task 1: Prove coverage gap and add view-model/UI tests
**Files:**
- Modify `central/tests/test_operational_view_models.py`
- Modify `central/tests/test_control_panel_fixture.py`
- Modify `central/tests/test_control_panel_pages.py`
- Add focused assertions to `central/tests/test_control_plane.py` only if needed.
- [ ] Test coverage partition arithmetic for normal, residual, and over-counted snapshots.
- [ ] Test dashboard sums total/complete/snapshot-safe-blocked/failed and explicit residual; require nonnegative invariant pass only when components do not exceed total.
- [ ] Test Agent detail/list expose explicit residual and the fiscal percentage.
- [ ] Test fixture total equals complete + safe-blocked + failed + residual; assert fixture residual zero after correction.
- [ ] Test login form labels/container, Agent list does not contain technical UUID, detail shows missing fields as `Não informado`/`Desconhecida`, and no empty green anchor/button exists in company card.
- [ ] Run targeted tests and capture expected failures before implementation.
### Task 2: Implement reconciled coverage view-models and fixture
**Files:**
- Modify `central/app/control_plane.py`
- Modify `central/scripts/generate_control_panel_fixture.py`
- Modify dashboard, Agent list, and Agent detail templates.
**Interfaces:**
- Add a single helper returning `complete`, `safe_blocked`, `failed`, `unclassified`, `total`, `consistent`, and `overcount` for a snapshot.
- Agent view adds `unclassified_products`, `coverage_invariant_pass`, `coverage_overcount_products`.
- Dashboard returns `safe_blocked_coverage_products`, `unclassified_products`, `coverage_invariant_pass`, and `coverage_overcount_products`; retain registry `safe_blocked_products` as a separately labeled blocker metric if displayed.
- [ ] Implement arithmetic with explicit consistency behavior; do not clamp or silently hide over-count.
- [ ] Dashboard SQL aggregate sums snapshot fields and computes residual at presentation/query aggregation without loading products.
- [ ] Fixture sets complete to `total - safe_blocked - failed_products`; set coverage percentage from complete/total rounded one decimal.
- [ ] Add template rows/cards for safe-blocked coverage, failed technical products, and unclassified products; display inconsistency warning when needed.
- [ ] Agent list explains the remaining percentage beside complete/blocked/failed/unclassified counts.
- [ ] Run targeted model/fixture/page tests green.
### Task 3: Minimal visual fixes and technical missing values
**Files:**
- Modify `central/templates/login.html`
- Modify `central/templates/agents.html`
- Modify `central/templates/agent_detail.html`
- Modify `central/static/control-panel.css`
- Modify `central/tests/test_control_panel_pages.py`
- [ ] Add a login wrapper/card sizing and center layout, explicit `for`/`id` labels, spacing, responsive width, and existing accent colors.
- [ ] Remove the installation UUID secondary text from the Agents table; retain it in detail technical IDs/API.
- [ ] Replace empty/unknown technical displays with `Não informado` and `Desconhecida`; do not invent Firebird version/ODS or version drift.
- [ ] Investigate green empty control: confirm rendered anchor is a real reprocess link with visible text; if visually empty due styles, correct styles; if action absent, remove element. Add assertion for non-empty accessible name/text.
- [ ] Run focused page tests green.
### Task 4: Documentation and final verification
**Files:**
- Modify `docs/CONTROL_PANEL_V1.md` and/or `docs/CONTROL_PANEL_OPERATIONAL_UX_V1.md` only if required to define the residual precisely.
- [ ] Document that unclassified is the snapshot residual without a supplied operational state, not a fiscal rule.
- [ ] Run exactly `python -m pytest tests -q`, `python -m pytest central/tests -q`, and `python -m pytest agent/tests -q`.
- [ ] Rebuild only local Compose `fiscal-hub`; verify PostgreSQL healthy and Hub `/health` 200.
- [ ] Smoke `/login`, `/`, `/agents`, `/agents/{id}`; check coverage reconciliation, login, UUID removal, visible reprocess control, and missing technical values.
- [ ] Measure route latency and record maximum.
- [ ] Verify flags, no deploy/Firebird operations, diff check, commits, and clean worktree; report exact requested final fields.