feat: GTI Gerenciador as the single source of truth for clients; bump to 1.1.2

Tenant gains source (LOCAL|GTI_GERENCIADOR), external_client_id, external_code,
active and synced_at (migration 0024). central/app/client_sync.py fetches from
the panel's new GET /internal/fiscal/clients (dedicated bearer token, never
MySQL credentials) and upserts Tenant rows, never touching a LOCAL row.
/agents/new now offers only active GTI_GERENCIADOR tenants, with a client-side
search box; the POST validates the same rule server-side, not just in the
dropdown. central/scripts/sync_clients_from_gerenciador.py is the operator-run
sync + reconciliation report.

GTI_FISCAL_VERSION/AGENT_VERSION bumped to 1.1.2 (release/VERSION single
source of truth), incorporating the installation_id persistence fix. Rebuilt
the EXE installer trio at 1.1.2 (scripts/build_windows_installer.ps1).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-23 22:38:58 -03:00
co-authored by Claude Sonnet 5
parent ac7b503c2f
commit e7d77beb26
29 changed files with 453 additions and 38 deletions
@@ -90,7 +90,14 @@ def io_bytes_bundle(version):
def tenant_id(factory):
with factory() as session:
return session.scalar(select(Tenant).where(Tenant.name == "Acme")).id
tenant = session.scalar(select(Tenant).where(Tenant.name == "Acme"))
# /agents/new only offers active GTI_GERENCIADOR-sourced tenants
# (central/app/client_sync.py) — flip the shared fixture tenant so
# existing form-based tests keep working under that rule.
if tenant.source != "GTI_GERENCIADOR" or not tenant.active:
tenant.source, tenant.external_client_id, tenant.active = "GTI_GERENCIADOR", tenant.id, True
session.commit()
return tenant.id
def make_installation(factory, release_id, name="Servidor E2E"):