105 lines
4.1 KiB
Markdown
105 lines
4.1 KiB
Markdown
# GTI Fiscal Control Panel V1
|
|
|
|
## Architecture
|
|
|
|
The existing FastAPI Hub is the single control plane. The web interface is
|
|
server-rendered with Jinja2, project CSS, and small vanilla JavaScript. There
|
|
is no SPA, React/Vue application, Node build chain, raw log upload, or remote
|
|
shell path.
|
|
|
|
The operational hierarchy is:
|
|
|
|
```text
|
|
client -> installation -> agent -> company -> Firebird -> health -> coverage -> blockers -> jobs -> events
|
|
```
|
|
|
|
## Identity
|
|
|
|
Every Agent state database receives one UUID in `installation_identity`.
|
|
`installation_id` is sent on heartbeat/registration and remains stable across
|
|
restarts. `agent_id` is the Hub Agent record; hostname, display name and IP are
|
|
metadata only. A conflicting installation UUID is rejected rather than silently
|
|
reassigned.
|
|
|
|
Registration metadata includes display name, customer code, hostname, Agent and
|
|
Windows version, machine fingerprint, company context, masked CNPJ, Firebird
|
|
version/ODS, sanitized database identifier, capabilities, fiscal engine,
|
|
dataset versions and lifecycle times. Passwords, tokens, API keys and full
|
|
connection strings are never persisted.
|
|
|
|
## Authentication
|
|
|
|
Agents use the existing `Authorization: Bearer <agent-token>` flow. Human users
|
|
use `/login` and a separate `gti_admin_session` HttpOnly cookie backed by a
|
|
server-side session hash. The CSRF value is separate and checked for every
|
|
mutating human action. Create the first admin locally with:
|
|
|
|
```text
|
|
python -m central.scripts.create_admin
|
|
```
|
|
|
|
Passwords are PBKDF2-HMAC-SHA256 hashes with random salts. Agent tokens are not
|
|
accepted as web sessions.
|
|
|
|
## Health And Snapshots
|
|
|
|
The Hub stores one `agent_snapshots` row per installation, containing product
|
|
counts, completion, safe blockers, technical failures, coverage, blocker
|
|
aggregates, job timestamps, health and version drift. The dashboard reads this
|
|
snapshot instead of scanning product tables.
|
|
|
|
- `ONLINE`: recent heartbeat and no technical failure.
|
|
- `DEGRADED`: recent technical/job failure while processing remains possible.
|
|
- `OFFLINE`: heartbeat older than `AGENT_OFFLINE_AFTER_SECONDS`, or three
|
|
heartbeat intervals when that value is unset.
|
|
- `FAILED`: persistent technical failure that prevents processing.
|
|
- `UNKNOWN`: no usable heartbeat or snapshot.
|
|
|
|
`SAFE_BLOCKED` is fiscal work isolation and does not itself make an Agent
|
|
degraded or failed. Version drift is `CURRENT`, `OUTDATED` or `UNKNOWN` against
|
|
`CURRENT_SERVER_VERSION`.
|
|
|
|
## Events And Retention
|
|
|
|
Agents submit structured events at `POST /v1/agents/events`. Event types are
|
|
allowlisted and messages/nested JSON are redacted and size-limited before
|
|
storage. Raw log files are never uploaded.
|
|
|
|
The default retention is 90 days (`AGENT_EVENT_RETENTION_DAYS`). Run
|
|
`python -m central.scripts.maintain_events` for cleanup, or use `--dry-run` to
|
|
inspect the command without deletion. Audit events, blocker history, critical
|
|
events and write audit records are preserved.
|
|
|
|
## APIs And Screens
|
|
|
|
Agent routes remain Bearer authenticated: `POST /v1/agents/register`,
|
|
`POST /v1/agents/heartbeat`, and `POST /v1/agents/events`.
|
|
|
|
Human panel APIs provide `/v1/dashboard/summary`, `/v1/agents`,
|
|
`/v1/agents/{agent_id}` plus health, coverage, blockers, jobs and events,
|
|
global `/v1/blockers/global` and `/v1/jobs/global`, and confirmed reprocess or
|
|
blocker-resolution actions. Lists use bounded pagination and filters.
|
|
|
|
The UI pages are `/`, `/agents`, `/agents/{agent_id}`, `/blockers`, `/jobs` and
|
|
`/login`. Primary rows show client, display name and hostname; UUIDs remain in
|
|
technical detail.
|
|
|
|
## Safe Actions
|
|
|
|
Human actions require a session, CSRF, explicit confirmation and an
|
|
`audit_events` row. The panel can create reprocess jobs and resolve blockers
|
|
only with explicit context. It cannot enable Firebird/AI writes, alter
|
|
credentials/path/CRT, execute SQL or shell commands, restart Windows services,
|
|
or update Agents automatically.
|
|
|
|
## Fixture
|
|
|
|
The explicit non-production fixture command is:
|
|
|
|
```text
|
|
python -m central.scripts.generate_control_panel_fixture --agents 100 --confirm-non-production
|
|
```
|
|
|
|
It creates varied health states, snapshots, blockers, jobs and events, and is
|
|
never invoked at startup or migration time.
|