4.1 KiB
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:
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:
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 thanAGENT_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:
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.