feat: fundar plataforma mais humana

This commit is contained in:
Ami Soares
2026-04-30 06:42:00 -03:00
commit c9c1056193
183 changed files with 639629 additions and 0 deletions

526
src/mais_humana/models.py Normal file
View File

@@ -0,0 +1,526 @@
"""Core models for human-centered ecosystem analysis.
The module intentionally keeps the data model dependency-free. The platform is
expected to run inside operational mirrors where installing new packages is not
always desirable, so every object can be serialized with the standard library.
"""
from __future__ import annotations
from dataclasses import dataclass, field, fields, is_dataclass
from datetime import datetime, timezone
from enum import Enum
from pathlib import Path
from typing import Any, Iterable, Mapping, MutableMapping, Sequence
def utc_now() -> str:
"""Return an ISO-8601 timestamp without relying on local locale settings."""
return datetime.now(timezone.utc).replace(microsecond=0).isoformat()
def slugify(value: str) -> str:
"""Create a stable ASCII-ish slug for filenames and object ids."""
allowed: list[str] = []
last_dash = False
for char in value.lower().strip():
if "a" <= char <= "z" or "0" <= char <= "9":
allowed.append(char)
last_dash = False
elif char in {" ", "_", "-", ".", "/", "\\"} and not last_dash:
allowed.append("-")
last_dash = True
return "".join(allowed).strip("-") or "item"
def as_plain_data(value: Any) -> Any:
"""Convert dataclasses, enums, paths, and nested values to JSON-safe data."""
if isinstance(value, Enum):
return value.value
if isinstance(value, Path):
return str(value)
if is_dataclass(value):
return {item.name: as_plain_data(getattr(value, item.name)) for item in fields(value)}
if isinstance(value, Mapping):
return {str(key): as_plain_data(inner) for key, inner in value.items()}
if isinstance(value, (list, tuple, set)):
return [as_plain_data(item) for item in value]
return value
class EvidenceKind(str, Enum):
"""Kinds of evidence detected in a platform repository."""
README = "readme"
PACKAGE_SCRIPT = "package_script"
ROUTE = "route"
OPENAPI = "openapi"
TEST = "test"
CONFIG = "config"
DOC = "doc"
WORKER = "worker"
STORAGE = "storage"
MCP_TOOL = "mcp_tool"
UI_SURFACE = "ui_surface"
SECURITY = "security"
BUSINESS_RULE = "business_rule"
OBSERVABILITY = "observability"
UNKNOWN = "unknown"
class NeedCategory(str, Enum):
"""Human need categories used by the matrix engine."""
ADMINISTRATION = "administration"
SUPPORT = "support"
FINANCE = "finance"
LEGAL = "legal"
SECURITY = "security"
OPERATIONS = "operations"
STRATEGY = "strategy"
DOCUMENTATION = "documentation"
SELF_SERVICE = "self_service"
COMMERCIAL = "commercial"
EXPERIENCE = "experience"
GOVERNANCE = "governance"
INTEGRATION = "integration"
OBSERVABILITY = "observability"
class MaturityLevel(str, Enum):
"""Operational maturity level from a human point of view."""
NOT_FOUND = "not_found"
PLANNED = "planned"
CATALOGED = "cataloged"
TECHNICAL = "technical"
EXPLAINABLE = "explainable"
ACTIONABLE = "actionable"
READY_FOR_HUMAN = "ready_for_human"
AUDITABLE = "auditable"
class OrderType(str, Enum):
"""Service-order type used by the order generator."""
EXECUTIVE = "executiva"
MANAGERIAL = "gerencial"
class OrderStatus(str, Enum):
"""Compact status for generated and executed orders."""
PLANNED = "planejada"
RUNNING = "em_execucao"
COMPLETED = "concluida"
PARTIAL = "parcial"
BLOCKED = "bloqueada"
@dataclass(slots=True)
class Evidence:
"""A small, inspectable proof that a capability exists or is missing."""
kind: EvidenceKind
path: str
summary: str
line: int | None = None
confidence: float = 0.5
tags: tuple[str, ...] = ()
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@property
def reference(self) -> str:
if self.line is None:
return self.path
return f"{self.path}:{self.line}"
def is_strong(self) -> bool:
return self.confidence >= 0.75
@dataclass(slots=True)
class HumanNeed:
"""A concrete need a person may have while using the ecosystem."""
need_id: str
title: str
category: NeedCategory
description: str
success_markers: tuple[str, ...]
risk_if_missing: str
expected_surfaces: tuple[str, ...] = ()
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class HumanProfile:
"""A human role that should be served by one or more platforms."""
profile_id: str
name: str
description: str
priority_needs: tuple[NeedCategory, ...]
typical_questions: tuple[str, ...]
expected_outputs: tuple[str, ...]
sensitive_concerns: tuple[str, ...] = ()
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
def wants(self, category: NeedCategory) -> bool:
return category in self.priority_needs
@dataclass(slots=True)
class PlatformDefinition:
"""Canonical description of a managed platform."""
platform_id: str
repo_name: str
central_folder: str
title: str
mission: str
primary_categories: tuple[NeedCategory, ...]
expected_profiles: tuple[str, ...]
related_platforms: tuple[str, ...] = ()
expected_surfaces: tuple[str, ...] = ()
known_blockers: tuple[str, ...] = ()
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class FileMetric:
"""Line and extension metric for a repository file."""
path: str
extension: str
lines: int
bytes_size: int
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class ScriptCommand:
"""A command exposed by package.json or other local metadata."""
name: str
command: str
source_file: str
intent: str = "unknown"
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class PlatformScan:
"""Repository scan result used as input for matrix and report generation."""
platform: PlatformDefinition
repo_path: str
exists: bool
git_present: bool
branch: str | None
head: str | None
remote_origin: str | None
readme_excerpt: str
file_metrics: tuple[FileMetric, ...]
scripts: tuple[ScriptCommand, ...]
evidence: tuple[Evidence, ...]
warnings: tuple[str, ...]
scanned_at: str = field(default_factory=utc_now)
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@property
def total_lines(self) -> int:
return sum(metric.lines for metric in self.file_metrics)
@property
def code_lines(self) -> int:
code_ext = {".ts", ".tsx", ".js", ".mjs", ".cjs", ".py", ".java"}
return sum(metric.lines for metric in self.file_metrics if metric.extension in code_ext)
@property
def has_tests(self) -> bool:
return any(item.kind == EvidenceKind.TEST for item in self.evidence)
@property
def has_openapi(self) -> bool:
return any(item.kind == EvidenceKind.OPENAPI for item in self.evidence)
@property
def has_worker(self) -> bool:
return any(item.kind == EvidenceKind.WORKER for item in self.evidence)
@property
def strong_evidence_count(self) -> int:
return sum(1 for item in self.evidence if item.is_strong())
def evidence_by_kind(self, kind: EvidenceKind) -> tuple[Evidence, ...]:
return tuple(item for item in self.evidence if item.kind == kind)
@dataclass(slots=True)
class MatrixCell:
"""Human service score for one platform and one profile."""
platform_id: str
profile_id: str
score: int
maturity: MaturityLevel
explanation: str
strengths: tuple[str, ...]
gaps: tuple[str, ...]
evidence_refs: tuple[str, ...]
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@property
def normalized_score(self) -> float:
return max(0.0, min(1.0, self.score / 100.0))
def is_ready(self) -> bool:
return self.score >= 75
@dataclass(slots=True)
class Recommendation:
"""Actionable recommendation derived from scan and matrix signals."""
recommendation_id: str
platform_id: str
title: str
reason: str
expected_impact: str
categories: tuple[NeedCategory, ...]
priority: int
suggested_order_type: OrderType
affected_paths: tuple[str, ...] = ()
validation_steps: tuple[str, ...] = ()
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class PlatformHumanReport:
"""Report model for one platform."""
platform: PlatformDefinition
scan: PlatformScan
cells: tuple[MatrixCell, ...]
recommendations: tuple[Recommendation, ...]
summary: str
current_state: tuple[str, ...]
future_state: tuple[str, ...]
missing_for_humans: tuple[str, ...]
generated_at: str = field(default_factory=utc_now)
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@property
def average_score(self) -> int:
if not self.cells:
return 0
return round(sum(cell.score for cell in self.cells) / len(self.cells))
@property
def ready_profiles(self) -> tuple[str, ...]:
return tuple(cell.profile_id for cell in self.cells if cell.is_ready())
@dataclass(slots=True)
class EcosystemHumanReport:
"""Full ecosystem report model."""
scans: tuple[PlatformScan, ...]
platform_reports: tuple[PlatformHumanReport, ...]
recommendations: tuple[Recommendation, ...]
generated_at: str = field(default_factory=utc_now)
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@property
def total_code_lines(self) -> int:
return sum(scan.code_lines for scan in self.scans)
@property
def total_files(self) -> int:
return sum(len(scan.file_metrics) for scan in self.scans)
@property
def average_score(self) -> int:
cells = [cell for report in self.platform_reports for cell in report.cells]
if not cells:
return 0
return round(sum(cell.score for cell in cells) / len(cells))
def report_for(self, platform_id: str) -> PlatformHumanReport | None:
for report in self.platform_reports:
if report.platform.platform_id == platform_id:
return report
return None
@dataclass(slots=True)
class ServiceOrder:
"""Generated service order metadata and body."""
order_id: str
order_type: OrderType
project_id: str
title: str
purpose: str
object_scope: str
reason: str
expected_result: str
affected_paths: tuple[str, ...]
validations: tuple[str, ...]
ready_criteria: tuple[str, ...]
status: OrderStatus = OrderStatus.PLANNED
priority: str = "media"
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class GeneratedFile:
"""File generated or updated by the platform runtime."""
path: str
description: str
function: str
file_type: str
changed_by: str
change_summary: str
relation_to_order: str
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
@dataclass(slots=True)
class ReportBundle:
"""Paths and counters produced by a generation run."""
output_root: str
generated_files: tuple[GeneratedFile, ...]
platform_count: int
profile_count: int
matrix_cells: int
total_code_lines_analyzed: int
warnings: tuple[str, ...]
generated_at: str = field(default_factory=utc_now)
def to_dict(self) -> dict[str, Any]:
return as_plain_data(self)
def clamp_score(value: int | float) -> int:
"""Clamp a numeric score into the 0..100 range."""
return int(max(0, min(100, round(float(value)))))
def maturity_from_score(score: int) -> MaturityLevel:
"""Map numeric score to a human maturity label."""
score = clamp_score(score)
if score == 0:
return MaturityLevel.NOT_FOUND
if score < 20:
return MaturityLevel.PLANNED
if score < 35:
return MaturityLevel.CATALOGED
if score < 50:
return MaturityLevel.TECHNICAL
if score < 65:
return MaturityLevel.EXPLAINABLE
if score < 80:
return MaturityLevel.ACTIONABLE
if score < 92:
return MaturityLevel.READY_FOR_HUMAN
return MaturityLevel.AUDITABLE
def merge_unique(values: Iterable[str]) -> tuple[str, ...]:
"""Return values in input order while dropping empty strings and duplicates."""
seen: set[str] = set()
output: list[str] = []
for value in values:
cleaned = str(value).strip()
if not cleaned or cleaned in seen:
continue
seen.add(cleaned)
output.append(cleaned)
return tuple(output)
def group_by_platform(recommendations: Sequence[Recommendation]) -> dict[str, list[Recommendation]]:
grouped: dict[str, list[Recommendation]] = {}
for item in recommendations:
grouped.setdefault(item.platform_id, []).append(item)
for items in grouped.values():
items.sort(key=lambda rec: (-rec.priority, rec.title))
return grouped
def incrementing_id(prefix: str, index: int, title: str) -> str:
"""Create a readable id with a numeric prefix and a slug."""
return f"{index:04d}_{prefix}__{slugify(title)}"
def summarize_warnings(scans: Sequence[PlatformScan]) -> tuple[str, ...]:
warnings: list[str] = []
for scan in scans:
for warning in scan.warnings:
warnings.append(f"{scan.platform.platform_id}: {warning}")
return merge_unique(warnings)
def score_label(score: int) -> str:
"""Return a compact label for user-facing matrix tables."""
score = clamp_score(score)
if score >= 90:
return "excelente"
if score >= 75:
return "forte"
if score >= 60:
return "util"
if score >= 40:
return "tecnico"
if score >= 20:
return "inicial"
if score > 0:
return "fragil"
return "ausente"
def ensure_mapping(data: MutableMapping[str, Any], key: str, default: Any) -> Any:
"""Small helper used by storage migration code."""
if key not in data:
data[key] = default
return data[key]