feat: add autonomous fiscal control panel
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
"""Create a human panel administrator without ever printing the password."""
|
||||
|
||||
import getpass
|
||||
|
||||
from central.app.db import SessionLocal
|
||||
from central.app.human_auth import create_admin
|
||||
|
||||
|
||||
def main():
|
||||
username = input("Admin username: ").strip()
|
||||
password = getpass.getpass("Admin password (12+ chars): ")
|
||||
confirmation = getpass.getpass("Confirm password: ")
|
||||
if password != confirmation:
|
||||
raise SystemExit("passwords do not match")
|
||||
with SessionLocal() as session:
|
||||
admin = create_admin(session, username, password)
|
||||
print(f"created admin {admin.username}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,52 @@
|
||||
"""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"] * 55 + ["DEGRADED"] * 20 + ["OFFLINE"] * 15 + ["FAILED"] * 10
|
||||
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 = Agent(tenant_id=tenant.id, name=f"fixture-agent-{index:03d}", token_hash=(f"fixture-{index:03d}".ljust(64, "0"))[:64], agent_version="1.0.0rc1"); session.add(agent); session.flush()
|
||||
state = states[index % len(states)]
|
||||
last_seen = 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=index % 9, failed_products=1 if state == "FAILED" else 0, coverage_percent=98.0, blockers={"CFOP": index % 7, "ST": index % 5}, agent_health=state, last_job_status="FAILED" if state in {"DEGRADED", "FAILED"} else "COMPLETED")
|
||||
session.add(snapshot); created["agents"] += 1
|
||||
for event_index in range(5):
|
||||
session.add(AgentEvent(tenant_id=tenant.id, installation_id=installation.id, agent_id=agent.id, severity="ERROR" if state == "FAILED" and event_index == 0 else "INFO", event_type="JOB_FAILED" if state in {"DEGRADED", "FAILED"} and event_index == 0 else "HEARTBEAT", message="Fixture operational event", structured_context={"fixture": True}, occurred_at=now - timedelta(minutes=event_index)))
|
||||
created["events"] += 1
|
||||
session.add(Job(agent_id=agent.id, kind="REPROCESS_ALL", status="FAILED" if state in {"DEGRADED", "FAILED"} else "COMPLETED", payload={}, result_summary={"fixture": True}, error="fixture technical failure" if state in {"DEGRADED", "FAILED"} else None))
|
||||
created["jobs"] += 1
|
||||
if index % 2 == 0:
|
||||
session.add(BlockedProduct(tenant_id=tenant.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}"))
|
||||
created["blockers"] += 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()
|
||||
@@ -0,0 +1,22 @@
|
||||
"""Expire eligible operational events; audit and critical events are preserved."""
|
||||
|
||||
import argparse
|
||||
|
||||
from central.app.db import SessionLocal
|
||||
from central.app.events import purge_expired_events
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
parser.add_argument("--retention-days", type=int, default=None)
|
||||
args = parser.parse_args()
|
||||
if args.dry_run:
|
||||
print("dry-run: no events deleted")
|
||||
return
|
||||
with SessionLocal() as session:
|
||||
print(f"deleted_events={purge_expired_events(session, retention_days=args.retention_days)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user