feat: fundar plataforma mais humana
This commit is contained in:
389
src/mais_humana/governance_storage.py
Normal file
389
src/mais_humana/governance_storage.py
Normal file
@@ -0,0 +1,389 @@
|
||||
"""SQLite persistence for governance-specific semantic state."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
|
||||
from .governance_models import EcosystemGovernancePortfolio, PlatformGovernanceCard, GovernanceCheckResult
|
||||
from .human_readiness_registry import ReadinessRegistry, ReadinessRegistryEntry
|
||||
from .models import as_plain_data, utc_now
|
||||
from .round_assurance import AssuranceSuite, AssuranceCase
|
||||
from .runtime_budget import RoundLineBudget, RepositoryLineBudget
|
||||
from .service_order_lifecycle import RoundExecutionPackage, OrderLifecycleDecision
|
||||
from .workflow_registry import WorkflowPortfolio, WorkflowEvaluation
|
||||
from .governance_scenarios import ScenarioPortfolio, ScenarioEvaluation
|
||||
|
||||
|
||||
GOVERNANCE_SCHEMA = """
|
||||
CREATE TABLE IF NOT EXISTS governance_cards (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
platform_id TEXT UNIQUE NOT NULL,
|
||||
status_label TEXT NOT NULL,
|
||||
governance_score INTEGER NOT NULL,
|
||||
human_score INTEGER NOT NULL,
|
||||
maturity TEXT NOT NULL,
|
||||
blocker_count INTEGER NOT NULL,
|
||||
warning_count INTEGER NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS governance_checks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
check_key TEXT UNIQUE NOT NULL,
|
||||
platform_id TEXT NOT NULL,
|
||||
check_id TEXT NOT NULL,
|
||||
axis TEXT NOT NULL,
|
||||
domain TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
severity TEXT NOT NULL,
|
||||
score INTEGER NOT NULL,
|
||||
next_action TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS readiness_registry (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
entry_id TEXT UNIQUE NOT NULL,
|
||||
platform_id TEXT NOT NULL,
|
||||
profile_id TEXT NOT NULL,
|
||||
human_score INTEGER NOT NULL,
|
||||
governance_score INTEGER NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
recommended_action TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workflow_evaluations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
workflow_id TEXT UNIQUE NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
score INTEGER NOT NULL,
|
||||
passed_steps INTEGER NOT NULL,
|
||||
total_steps INTEGER NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS scenario_evaluations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
scenario_id TEXT UNIQUE NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
score INTEGER NOT NULL,
|
||||
assertion_count INTEGER NOT NULL,
|
||||
failed_assertion_count INTEGER NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS assurance_cases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
case_id TEXT UNIQUE NOT NULL,
|
||||
passed INTEGER NOT NULL,
|
||||
severity TEXT NOT NULL,
|
||||
required INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
next_action TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS lifecycle_decisions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
order_id TEXT UNIQUE NOT NULL,
|
||||
final_status TEXT NOT NULL,
|
||||
platform_id TEXT NOT NULL,
|
||||
pending_count INTEGER NOT NULL,
|
||||
resulting_candidate_count INTEGER NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS line_budgets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
repo_name TEXT UNIQUE NOT NULL,
|
||||
exists_flag INTEGER NOT NULL,
|
||||
files_seen INTEGER NOT NULL,
|
||||
files_counted INTEGER NOT NULL,
|
||||
code_lines INTEGER NOT NULL,
|
||||
technical_lines INTEGER NOT NULL,
|
||||
warnings_json TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
"""
|
||||
|
||||
|
||||
def ensure_governance_schema(conn: sqlite3.Connection) -> None:
|
||||
conn.executescript(GOVERNANCE_SCHEMA)
|
||||
|
||||
|
||||
def payload(value: object) -> str:
|
||||
return json.dumps(as_plain_data(value), ensure_ascii=False, sort_keys=True)
|
||||
|
||||
|
||||
def upsert_governance_card(conn: sqlite3.Connection, card: PlatformGovernanceCard, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO governance_cards (
|
||||
platform_id, status_label, governance_score, human_score, maturity,
|
||||
blocker_count, warning_count, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(platform_id) DO UPDATE SET
|
||||
status_label=excluded.status_label,
|
||||
governance_score=excluded.governance_score,
|
||||
human_score=excluded.human_score,
|
||||
maturity=excluded.maturity,
|
||||
blocker_count=excluded.blocker_count,
|
||||
warning_count=excluded.warning_count,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(
|
||||
card.platform_id,
|
||||
card.status_label,
|
||||
card.governance_score,
|
||||
card.human_score,
|
||||
card.maturity.value,
|
||||
len(card.blockers),
|
||||
len(card.warnings),
|
||||
payload(card),
|
||||
now,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def upsert_governance_check(conn: sqlite3.Connection, check: GovernanceCheckResult, now: str) -> None:
|
||||
key = f"{check.platform_id}:{check.check_id}"
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO governance_checks (
|
||||
check_key, platform_id, check_id, axis, domain, status, severity,
|
||||
score, next_action, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(check_key) DO UPDATE SET
|
||||
axis=excluded.axis,
|
||||
domain=excluded.domain,
|
||||
status=excluded.status,
|
||||
severity=excluded.severity,
|
||||
score=excluded.score,
|
||||
next_action=excluded.next_action,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(
|
||||
key,
|
||||
check.platform_id,
|
||||
check.check_id,
|
||||
check.axis.value,
|
||||
check.domain.value,
|
||||
check.status.value,
|
||||
check.severity.value,
|
||||
check.score,
|
||||
check.next_action,
|
||||
payload(check),
|
||||
now,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def upsert_registry_entry(conn: sqlite3.Connection, entry: ReadinessRegistryEntry, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO readiness_registry (
|
||||
entry_id, platform_id, profile_id, human_score, governance_score,
|
||||
status, recommended_action, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(entry_id) DO UPDATE SET
|
||||
human_score=excluded.human_score,
|
||||
governance_score=excluded.governance_score,
|
||||
status=excluded.status,
|
||||
recommended_action=excluded.recommended_action,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(
|
||||
entry.entry_id,
|
||||
entry.platform_id,
|
||||
entry.profile_id,
|
||||
entry.human_score,
|
||||
entry.governance_score,
|
||||
entry.status,
|
||||
entry.recommended_action,
|
||||
payload(entry),
|
||||
now,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def upsert_workflow(conn: sqlite3.Connection, evaluation: WorkflowEvaluation, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO workflow_evaluations (
|
||||
workflow_id, status, score, passed_steps, total_steps, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(workflow_id) DO UPDATE SET
|
||||
status=excluded.status,
|
||||
score=excluded.score,
|
||||
passed_steps=excluded.passed_steps,
|
||||
total_steps=excluded.total_steps,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(evaluation.workflow_id, evaluation.status, evaluation.score, evaluation.passed_steps, evaluation.total_steps, payload(evaluation), now),
|
||||
)
|
||||
|
||||
|
||||
def upsert_scenario(conn: sqlite3.Connection, evaluation: ScenarioEvaluation, now: str) -> None:
|
||||
failed = sum(1 for item in evaluation.assertion_results if not item.passed)
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO scenario_evaluations (
|
||||
scenario_id, status, score, assertion_count, failed_assertion_count, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(scenario_id) DO UPDATE SET
|
||||
status=excluded.status,
|
||||
score=excluded.score,
|
||||
assertion_count=excluded.assertion_count,
|
||||
failed_assertion_count=excluded.failed_assertion_count,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(evaluation.scenario_id, evaluation.status, evaluation.score, len(evaluation.assertion_results), failed, payload(evaluation), now),
|
||||
)
|
||||
|
||||
|
||||
def upsert_assurance_case(conn: sqlite3.Connection, case: AssuranceCase, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO assurance_cases (
|
||||
case_id, passed, severity, required, title, next_action, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(case_id) DO UPDATE SET
|
||||
passed=excluded.passed,
|
||||
severity=excluded.severity,
|
||||
required=excluded.required,
|
||||
title=excluded.title,
|
||||
next_action=excluded.next_action,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(case.case_id, 1 if case.passed else 0, case.severity, 1 if case.required else 0, case.title, case.next_action, payload(case), now),
|
||||
)
|
||||
|
||||
|
||||
def upsert_lifecycle_decision(conn: sqlite3.Connection, decision: OrderLifecycleDecision, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO lifecycle_decisions (
|
||||
order_id, final_status, platform_id, pending_count, resulting_candidate_count,
|
||||
payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(order_id) DO UPDATE SET
|
||||
final_status=excluded.final_status,
|
||||
platform_id=excluded.platform_id,
|
||||
pending_count=excluded.pending_count,
|
||||
resulting_candidate_count=excluded.resulting_candidate_count,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(
|
||||
decision.order.order_id,
|
||||
decision.final_status.value,
|
||||
decision.platform_id,
|
||||
len(decision.pending_items),
|
||||
len(decision.resulting_candidates),
|
||||
payload(decision),
|
||||
now,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def upsert_line_budget(conn: sqlite3.Connection, repo: RepositoryLineBudget, now: str) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO line_budgets (
|
||||
repo_name, exists_flag, files_seen, files_counted, code_lines,
|
||||
technical_lines, warnings_json, payload_json, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(repo_name) DO UPDATE SET
|
||||
exists_flag=excluded.exists_flag,
|
||||
files_seen=excluded.files_seen,
|
||||
files_counted=excluded.files_counted,
|
||||
code_lines=excluded.code_lines,
|
||||
technical_lines=excluded.technical_lines,
|
||||
warnings_json=excluded.warnings_json,
|
||||
payload_json=excluded.payload_json,
|
||||
updated_at=excluded.updated_at
|
||||
""",
|
||||
(
|
||||
repo.repo_name,
|
||||
1 if repo.exists else 0,
|
||||
repo.files_seen,
|
||||
repo.files_counted,
|
||||
repo.code_lines,
|
||||
repo.technical_lines,
|
||||
json.dumps(list(repo.warnings), ensure_ascii=False),
|
||||
payload(repo),
|
||||
now,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def write_governance_semantic_state(
|
||||
sqlite_path: Path,
|
||||
portfolio: EcosystemGovernancePortfolio,
|
||||
registry: ReadinessRegistry,
|
||||
workflows: WorkflowPortfolio,
|
||||
scenarios: ScenarioPortfolio,
|
||||
assurance: AssuranceSuite | None = None,
|
||||
lifecycle: RoundExecutionPackage | None = None,
|
||||
budget: RoundLineBudget | None = None,
|
||||
) -> None:
|
||||
sqlite_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
now = utc_now()
|
||||
with sqlite3.connect(sqlite_path) as conn:
|
||||
ensure_governance_schema(conn)
|
||||
for card in portfolio.cards:
|
||||
upsert_governance_card(conn, card, now)
|
||||
for check in card.checks:
|
||||
upsert_governance_check(conn, check, now)
|
||||
for entry in registry.entries:
|
||||
upsert_registry_entry(conn, entry, now)
|
||||
for evaluation in workflows.evaluations:
|
||||
upsert_workflow(conn, evaluation, now)
|
||||
for evaluation in scenarios.evaluations:
|
||||
upsert_scenario(conn, evaluation, now)
|
||||
if assurance is not None:
|
||||
for case in assurance.cases:
|
||||
upsert_assurance_case(conn, case, now)
|
||||
if lifecycle is not None:
|
||||
for decision in lifecycle.decisions:
|
||||
upsert_lifecycle_decision(conn, decision, now)
|
||||
if budget is not None:
|
||||
for repo in budget.repositories:
|
||||
upsert_line_budget(conn, repo, now)
|
||||
conn.commit()
|
||||
|
||||
|
||||
def governance_table_counts(sqlite_path: Path) -> dict[str, int]:
|
||||
tables = (
|
||||
"governance_cards",
|
||||
"governance_checks",
|
||||
"readiness_registry",
|
||||
"workflow_evaluations",
|
||||
"scenario_evaluations",
|
||||
"assurance_cases",
|
||||
"lifecycle_decisions",
|
||||
"line_budgets",
|
||||
)
|
||||
if not sqlite_path.exists():
|
||||
return {table: 0 for table in tables}
|
||||
with sqlite3.connect(sqlite_path) as conn:
|
||||
ensure_governance_schema(conn)
|
||||
return {table: int(conn.execute(f"SELECT COUNT(*) FROM {table}").fetchone()[0]) for table in tables}
|
||||
Reference in New Issue
Block a user