"""Generate explicit, deterministic non-production control-panel data.""" import argparse import uuid from datetime import datetime, timedelta, timezone from central.app.config import settings from central.app.db import SessionLocal from central.app.models import Agent, AgentEvent, AgentSnapshot, BlockedProduct, Installation, Job, Tenant from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker def generate_fixture(session, agent_count=100, seed=7): now = datetime.now(timezone.utc) states = ["ONLINE"] * 50 + ["DEGRADED"] * 20 + ["OFFLINE"] * 15 + ["FAILED"] * 10 + ["UNKNOWN"] * 5 created = {"agents": 0, "events": 0, "blockers": 0, "jobs": 0} for index in range(agent_count): tenant = Tenant(name=f"Fixture Client {index:03d}"); session.add(tenant); session.flush() agent_version = None if index % 17 == 0 else ("0.9.0" if index % 5 == 0 else "1.0.0rc1") agent = Agent(tenant_id=tenant.id, name=f"fixture-agent-{index:03d}", token_hash=(f"fixture-{index:03d}".ljust(64, "0"))[:64], agent_version=agent_version); session.add(agent); session.flush() state = states[index % len(states)] last_seen = None if state == "UNKNOWN" else now - timedelta(seconds=10 if state in {"ONLINE", "DEGRADED"} else 10_000) installation = Installation(agent_id=agent.id, tenant_id=tenant.id, installation_id=str(uuid.uuid5(uuid.NAMESPACE_DNS, f"fixture-{index}")), display_name=f"{tenant.name} - Servidor Principal", customer_code=f"F{index:03d}", hostname=f"srv-{index:03d}", company_name=f"Empresa {index:03d}", company_uf="BA", company_crt="1", last_seen_at=last_seen, last_status="IDLE") session.add(installation); session.flush() snapshot = AgentSnapshot(installation_id=installation.id, total_products=5000 + index, fiscally_complete=4900 + index, safe_blocked=1 if index % 2 == 0 else 0, failed_products=1 if state == "FAILED" else 0, coverage_percent=98.0, blockers={"CFOP": index % 7, "ST": index % 5}, agent_health=state, version_drift="UNKNOWN" if agent_version is None else ("OUTDATED" if agent_version != "1.0.0rc1" else "CURRENT"), last_job_status="FAILED" if state in {"DEGRADED", "FAILED"} else "COMPLETED") session.add(snapshot); created["agents"] += 1 failed = state in {"DEGRADED", "FAILED"} job = Job(agent_id=agent.id, kind="REPROCESS_ALL", status="FAILED" if failed else "COMPLETED", payload={}, result_summary={"fixture": True}, error="fixture technical failure" if failed else None, started_at=now - timedelta(minutes=6) if failed else None, finished_at=now - timedelta(minutes=5) if failed else None) session.add(job); session.flush() created["jobs"] += 1 fixture_blocker = None if index % 2 == 0: fixture_blocker = BlockedProduct(tenant_id=tenant.id, installation_id=installation.id, company=tenant.name, product_code=f"P{index:06d}", description="Fixture product", blocker_type="CFOP", field="CFOP", reason_code="INSUFFICIENT_EVIDENCE", evidence_summary={"fixture": True}, input_fingerprint=f"{index:064d}", blocker_fingerprint=f"{index+1000:064d}") session.add(fixture_blocker); session.flush() created["blockers"] += 1 if index == 0: session.add(BlockedProduct(tenant_id=tenant.id, installation_id=installation.id, company=tenant.name, product_code=fixture_blocker.product_code, description="Fixture product", blocker_type="TAX_RULE_MISSING", field="ST", reason_code="MISSING_REFERENCE", evidence_summary={"fixture": True}, input_fingerprint=f"{index+2000:064d}", blocker_fingerprint=f"{index+3000:064d}")) created["blockers"] += 1 for event_index in range(5): linked = event_index == 0 session.add(AgentEvent(tenant_id=tenant.id, installation_id=installation.id, agent_id=agent.id, severity="ERROR" if failed and linked else "INFO", event_type="JOB_FAILED" if failed and linked else "HEARTBEAT", message="Fixture job failed" if failed and linked else "Fixture operational event", structured_context={"fixture": True}, job_id=job.id if linked else None, product_code=fixture_blocker.product_code if linked and fixture_blocker else None, blocker_id=fixture_blocker.id if linked and fixture_blocker else None, occurred_at=now - timedelta(minutes=event_index))) created["events"] += 1 session.commit() return created def main(): parser = argparse.ArgumentParser(); parser.add_argument("--database-url", default=None); parser.add_argument("--agents", type=int, default=100); parser.add_argument("--seed", type=int, default=7); parser.add_argument("--confirm-non-production", action="store_true") args = parser.parse_args() if settings.environment == "production" or not args.confirm_non_production: raise SystemExit("refusing fixture generation without --confirm-non-production in non-production") session_factory = SessionLocal if args.database_url: session_factory = sessionmaker(bind=create_engine(args.database_url)) with session_factory() as session: print(generate_fixture(session, args.agents, args.seed)) if __name__ == "__main__": main()