"""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"