feat: fundar plataforma mais humana
This commit is contained in:
196
src/mais_humana/narratives.py
Normal file
196
src/mais_humana/narratives.py
Normal file
@@ -0,0 +1,196 @@
|
||||
"""Human-readable narratives generated from scans and matrix cells."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from .catalog import HUMAN_PROFILES, HUMAN_NEEDS, PROFILE_BY_ID
|
||||
from .models import MatrixCell, PlatformHumanReport, PlatformScan, Recommendation, score_label
|
||||
|
||||
|
||||
def sentence_list(items: Sequence[str], fallback: str = "nao informado") -> str:
|
||||
values = [item.strip() for item in items if item and item.strip()]
|
||||
if not values:
|
||||
return fallback
|
||||
if len(values) == 1:
|
||||
return values[0]
|
||||
return ", ".join(values[:-1]) + " e " + values[-1]
|
||||
|
||||
|
||||
def platform_intro(scan: PlatformScan) -> str:
|
||||
if not scan.exists:
|
||||
return (
|
||||
f"{scan.platform.title} ainda nao possui repositorio local analisavel. "
|
||||
"Para pessoas reais, isso significa ausencia de prova operacional na base desta plataforma."
|
||||
)
|
||||
git_state = "com Git local" if scan.git_present else "sem Git local"
|
||||
return (
|
||||
f"{scan.platform.title} existe em {scan.repo_path}, {git_state}, "
|
||||
f"com {scan.code_lines} linhas de codigo analisaveis e {len(scan.evidence)} evidencias coletadas."
|
||||
)
|
||||
|
||||
|
||||
def profile_section(cell: MatrixCell) -> tuple[str, ...]:
|
||||
profile = PROFILE_BY_ID[cell.profile_id]
|
||||
lines = [
|
||||
f"Perfil: {profile.name}",
|
||||
f"Score: {cell.score} ({score_label(cell.score)}), maturidade: {cell.maturity.value}.",
|
||||
f"Leitura: {cell.explanation}",
|
||||
"Forcas: " + sentence_list(cell.strengths),
|
||||
"Lacunas: " + sentence_list(cell.gaps),
|
||||
]
|
||||
if cell.evidence_refs:
|
||||
lines.append("Evidencias: " + sentence_list(cell.evidence_refs[:5]))
|
||||
return tuple(lines)
|
||||
|
||||
|
||||
def current_state_paragraph(report: PlatformHumanReport) -> str:
|
||||
return (
|
||||
"Estado atual humano: "
|
||||
+ sentence_list(report.current_state, "a plataforma precisa de evidencias iniciais")
|
||||
+ "."
|
||||
)
|
||||
|
||||
|
||||
def future_state_paragraph(report: PlatformHumanReport) -> str:
|
||||
return "Estado futuro esperado: " + sentence_list(report.future_state) + "."
|
||||
|
||||
|
||||
def missing_state_paragraph(report: PlatformHumanReport) -> str:
|
||||
return "O que ainda falta para atender melhor: " + sentence_list(report.missing_for_humans) + "."
|
||||
|
||||
|
||||
def recommendation_paragraph(recommendation: Recommendation) -> str:
|
||||
categories = ", ".join(category.value for category in recommendation.categories)
|
||||
validations = sentence_list(recommendation.validation_steps, "validacao a definir")
|
||||
return (
|
||||
f"{recommendation.title}. Motivo: {recommendation.reason} "
|
||||
f"Impacto esperado: {recommendation.expected_impact} "
|
||||
f"Categorias: {categories}. Validacao: {validations}."
|
||||
)
|
||||
|
||||
|
||||
def platform_report_lines(report: PlatformHumanReport) -> list[str]:
|
||||
lines: list[str] = []
|
||||
lines.append(report.platform.title)
|
||||
lines.append(report.platform.mission)
|
||||
lines.append(platform_intro(report.scan))
|
||||
lines.append(report.summary)
|
||||
lines.append(current_state_paragraph(report))
|
||||
lines.append(future_state_paragraph(report))
|
||||
lines.append(missing_state_paragraph(report))
|
||||
lines.append("Perfis humanos")
|
||||
for cell in sorted(report.cells, key=lambda item: item.profile_id):
|
||||
lines.extend(profile_section(cell))
|
||||
lines.append("Recomendacoes")
|
||||
for recommendation in report.recommendations[:10]:
|
||||
lines.append(recommendation_paragraph(recommendation))
|
||||
if report.scan.warnings:
|
||||
lines.append("Avisos operacionais: " + sentence_list(report.scan.warnings))
|
||||
return lines
|
||||
|
||||
|
||||
def ecosystem_summary_lines(reports: Sequence[PlatformHumanReport]) -> list[str]:
|
||||
total_code = sum(report.scan.code_lines for report in reports)
|
||||
total_evidence = sum(len(report.scan.evidence) for report in reports)
|
||||
average = round(sum(report.average_score for report in reports) / len(reports)) if reports else 0
|
||||
lines = [
|
||||
"Relatorio Geral do Ecossistema Mais Humano",
|
||||
(
|
||||
f"Foram avaliadas {len(reports)} plataformas, com {total_code} linhas de codigo "
|
||||
f"e {total_evidence} evidencias locais."
|
||||
),
|
||||
f"Score medio humano do ecossistema: {average}.",
|
||||
(
|
||||
"A pergunta central desta plataforma e simples: quem e atendido, como e atendido, "
|
||||
"o que ja funciona hoje e o que precisa virar ordem de servico para servir melhor pessoas reais."
|
||||
),
|
||||
]
|
||||
lines.append("Leitura por necessidade humana")
|
||||
for need in HUMAN_NEEDS:
|
||||
related = [
|
||||
report.platform.platform_id
|
||||
for report in reports
|
||||
if need.category in report.platform.primary_categories
|
||||
]
|
||||
lines.append(
|
||||
f"{need.title}: plataformas relacionadas {sentence_list(related, 'nenhuma principal')}. "
|
||||
f"Risco se faltar: {need.risk_if_missing}"
|
||||
)
|
||||
lines.append("Plataformas com menor score medio")
|
||||
for report in sorted(reports, key=lambda item: item.average_score)[:8]:
|
||||
lines.append(
|
||||
f"{report.platform.title}: score {report.average_score}; "
|
||||
f"lacunas principais: {sentence_list(report.missing_for_humans[:3])}."
|
||||
)
|
||||
lines.append("Plataformas com maior prontidao humana")
|
||||
for report in sorted(reports, key=lambda item: item.average_score, reverse=True)[:8]:
|
||||
lines.append(
|
||||
f"{report.platform.title}: score {report.average_score}; "
|
||||
f"forcas: {sentence_list(report.current_state[:3])}."
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
def markdown_table(headers: Sequence[str], rows: Sequence[Sequence[str]]) -> str:
|
||||
output = ["| " + " | ".join(headers) + " |"]
|
||||
output.append("| " + " | ".join("---" for _ in headers) + " |")
|
||||
for row in rows:
|
||||
output.append("| " + " | ".join(str(value).replace("|", "/") for value in row) + " |")
|
||||
return "\n".join(output)
|
||||
|
||||
|
||||
def platform_markdown(report: PlatformHumanReport) -> str:
|
||||
lines = [f"# {report.platform.title}", "", report.platform.mission, ""]
|
||||
lines.append("## Sintese")
|
||||
lines.append("")
|
||||
lines.append(report.summary)
|
||||
lines.append("")
|
||||
lines.append(current_state_paragraph(report))
|
||||
lines.append("")
|
||||
lines.append(future_state_paragraph(report))
|
||||
lines.append("")
|
||||
lines.append(missing_state_paragraph(report))
|
||||
lines.append("")
|
||||
lines.append("## Matriz por perfil")
|
||||
rows = []
|
||||
for cell in sorted(report.cells, key=lambda item: item.profile_id):
|
||||
profile = PROFILE_BY_ID[cell.profile_id]
|
||||
rows.append([profile.name, str(cell.score), cell.maturity.value, cell.explanation])
|
||||
lines.append(markdown_table(["Perfil", "Score", "Maturidade", "Leitura"], rows))
|
||||
lines.append("")
|
||||
lines.append("## Recomendacoes")
|
||||
lines.append("")
|
||||
for recommendation in report.recommendations:
|
||||
lines.append(f"- {recommendation_paragraph(recommendation)}")
|
||||
if report.scan.warnings:
|
||||
lines.append("")
|
||||
lines.append("## Avisos")
|
||||
lines.extend(f"- {warning}" for warning in report.scan.warnings)
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
|
||||
|
||||
def ecosystem_markdown(reports: Sequence[PlatformHumanReport]) -> str:
|
||||
lines = ["# Relatorio Geral do Ecossistema Mais Humano", ""]
|
||||
lines.extend(ecosystem_summary_lines(reports)[1:])
|
||||
lines.append("")
|
||||
lines.append("## Matriz plataforma x perfil")
|
||||
rows = []
|
||||
for report in sorted(reports, key=lambda item: item.platform.platform_id):
|
||||
strongest = sorted(report.cells, key=lambda item: item.score, reverse=True)[:3]
|
||||
weakest = sorted(report.cells, key=lambda item: item.score)[:3]
|
||||
rows.append(
|
||||
[
|
||||
report.platform.platform_id,
|
||||
str(report.average_score),
|
||||
sentence_list([PROFILE_BY_ID[cell.profile_id].name for cell in strongest]),
|
||||
sentence_list([PROFILE_BY_ID[cell.profile_id].name for cell in weakest]),
|
||||
]
|
||||
)
|
||||
lines.append(markdown_table(["Plataforma", "Score", "Mais atendidos", "Mais frageis"], rows))
|
||||
lines.append("")
|
||||
lines.append("## Perfis considerados")
|
||||
for profile in HUMAN_PROFILES:
|
||||
lines.append(f"- {profile.name}: {profile.description}")
|
||||
return "\n".join(lines).strip() + "\n"
|
||||
|
||||
Reference in New Issue
Block a user