299 lines
12 KiB
Python
299 lines
12 KiB
Python
"""Service order generation for the human-centered platform."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
import re
|
|
from typing import Sequence
|
|
|
|
from .models import OrderStatus, OrderType, PlatformHumanReport, Recommendation, ServiceOrder, incrementing_id, slugify
|
|
|
|
|
|
def order_from_recommendation(
|
|
recommendation: Recommendation,
|
|
index: int,
|
|
order_type: OrderType,
|
|
project_id: str = "tudo-para-ia-mais-humana",
|
|
) -> ServiceOrder:
|
|
title = recommendation.title
|
|
return ServiceOrder(
|
|
order_id=incrementing_id("EXECUTIVA" if order_type == OrderType.EXECUTIVE else "GERENCIAL", index, title),
|
|
order_type=order_type,
|
|
project_id=project_id,
|
|
title=title,
|
|
purpose=(
|
|
"Transformar uma lacuna detectada pela matriz humana em continuidade operacional "
|
|
"validavel, registrada e vinculada a evidencias."
|
|
),
|
|
object_scope=(
|
|
f"Plataforma relacionada: {recommendation.platform_id}. "
|
|
"Areas afetadas: " + ", ".join(recommendation.affected_paths or ("a identificar durante execucao",))
|
|
),
|
|
reason=recommendation.reason,
|
|
expected_result=recommendation.expected_impact,
|
|
affected_paths=recommendation.affected_paths,
|
|
validations=recommendation.validation_steps,
|
|
ready_criteria=(
|
|
"lacuna humana reavaliada",
|
|
"evidencia registrada",
|
|
"relatorio ou matriz atualizado",
|
|
"SQL semantico atualizado",
|
|
),
|
|
status=OrderStatus.PLANNED,
|
|
priority="alta" if recommendation.priority >= 85 else "media",
|
|
)
|
|
|
|
|
|
def select_recommendations(
|
|
recommendations: Sequence[Recommendation],
|
|
order_type: OrderType,
|
|
limit: int = 5,
|
|
) -> tuple[Recommendation, ...]:
|
|
filtered = [item for item in recommendations if item.suggested_order_type == order_type]
|
|
if len(filtered) < limit:
|
|
filtered.extend(item for item in recommendations if item.suggested_order_type != order_type)
|
|
selected: list[Recommendation] = []
|
|
seen: set[str] = set()
|
|
for item in sorted(filtered, key=lambda rec: (-rec.priority, rec.platform_id, rec.title)):
|
|
key = item.recommendation_id
|
|
if key in seen:
|
|
continue
|
|
seen.add(key)
|
|
selected.append(item)
|
|
if len(selected) >= limit:
|
|
break
|
|
return tuple(selected)
|
|
|
|
|
|
def build_exit_orders(recommendations: Sequence[Recommendation], project_id: str = "tudo-para-ia-mais-humana") -> tuple[ServiceOrder, ...]:
|
|
executive = select_recommendations(recommendations, OrderType.EXECUTIVE, limit=5)
|
|
managerial = select_recommendations(recommendations, OrderType.MANAGERIAL, limit=5)
|
|
orders: list[ServiceOrder] = []
|
|
for index, recommendation in enumerate(executive, start=1):
|
|
orders.append(order_from_recommendation(recommendation, index, OrderType.EXECUTIVE, project_id))
|
|
for index, recommendation in enumerate(managerial, start=1):
|
|
orders.append(order_from_recommendation(recommendation, index, OrderType.MANAGERIAL, project_id))
|
|
return tuple(orders)
|
|
|
|
|
|
def order_markdown(order: ServiceOrder, platform_folder: str, real_repo: str) -> str:
|
|
lines = [
|
|
f"# ORDEM DE SERVICO: {order.order_id}",
|
|
"",
|
|
"Template oficial:",
|
|
"",
|
|
"`G:/_codex-git/nucleo-gestao-operacional/templates/ordem-de-servico.md`",
|
|
"",
|
|
"## Finalidade da ordem de servico",
|
|
"",
|
|
order.purpose,
|
|
"",
|
|
"## Objeto da ordem de servico",
|
|
"",
|
|
order.object_scope,
|
|
"",
|
|
"## Motivo da criacao da ordem de servico",
|
|
"",
|
|
order.reason,
|
|
"",
|
|
"## Resultado esperado da execucao",
|
|
"",
|
|
order.expected_result,
|
|
"",
|
|
"## Tipo da ordem",
|
|
"",
|
|
f"`{order.order_type.value.upper()}`",
|
|
"",
|
|
"## Identificacao",
|
|
"",
|
|
f"- order_id: `{order.order_id}`",
|
|
f"- tipo: `{order.order_type.value}`",
|
|
f"- project_id: `{order.project_id}`",
|
|
f"- repo_name: `{real_repo}`",
|
|
f"- status: `{order.status.value}`",
|
|
f"- prioridade: `{order.priority}`",
|
|
"",
|
|
"## Caminhos",
|
|
"",
|
|
"Pasta da plataforma:",
|
|
"",
|
|
f"`{platform_folder}`",
|
|
"",
|
|
"Projeto real:",
|
|
"",
|
|
f"`G:/_codex-git/{real_repo}`",
|
|
"",
|
|
"SQLite semantico:",
|
|
"",
|
|
f"`{platform_folder}/controle-semantico.sqlite`",
|
|
"",
|
|
"## Arquivos e areas afetadas",
|
|
"",
|
|
]
|
|
for path in order.affected_paths or ("a identificar durante a execucao",):
|
|
lines.append(f"- `{path}`")
|
|
lines.extend(["", "## Validacoes", ""])
|
|
for validation in order.validations or ("validacao a definir durante execucao",):
|
|
lines.append(f"- {validation}")
|
|
lines.extend(["", "## Criterio de pronto", ""])
|
|
for criterion in order.ready_criteria:
|
|
lines.append(f"- {criterion}")
|
|
lines.extend(
|
|
[
|
|
"",
|
|
"## Fechamento obrigatorio",
|
|
"",
|
|
"- registrar EXECUTADO;",
|
|
"- registrar PENDENCIAS reais;",
|
|
"- atualizar SQL semantico;",
|
|
"- registrar funcao dos arquivos criados ou alterados;",
|
|
"- fazer commit e push quando aplicavel;",
|
|
"- informar hashes finais.",
|
|
"",
|
|
]
|
|
)
|
|
return "\n".join(lines)
|
|
|
|
|
|
def write_orders(
|
|
orders: Sequence[ServiceOrder],
|
|
platform_folder: Path,
|
|
real_repo: str = "tudo-para-ia-mais-humana",
|
|
) -> tuple[Path, ...]:
|
|
written: list[Path] = []
|
|
next_number: dict[str, int] = {}
|
|
used_existing_paths: set[Path] = set()
|
|
max_attempts_per_order = 200
|
|
for order in orders:
|
|
subfolder = "executivas" if order.order_type == OrderType.EXECUTIVE else "gerenciais"
|
|
target_dir = platform_folder / "orders" / subfolder
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
if subfolder not in next_number:
|
|
numbers: list[int] = []
|
|
for existing in target_dir.glob("*.md"):
|
|
match = re.match(r"^(\d{4})_", existing.name)
|
|
if match:
|
|
numbers.append(int(match.group(1)))
|
|
next_number[subfolder] = (max(numbers) + 1) if numbers else 1
|
|
prefix = "EXECUTIVA" if order.order_type == OrderType.EXECUTIVE else "GERENCIAL"
|
|
order_slug = slugify(order.title)
|
|
existing_same_order = [
|
|
path for path in sorted(target_dir.glob(f"*_{prefix}__{order_slug}.md"), reverse=True) if path not in used_existing_paths
|
|
]
|
|
if existing_same_order:
|
|
path = existing_same_order[0]
|
|
used_existing_paths.add(path)
|
|
order.order_id = path.stem
|
|
try:
|
|
path.write_text(order_markdown(order, str(platform_folder), real_repo), encoding="utf-8")
|
|
except PermissionError:
|
|
# The central can be dirty or temporarily locked by a previous
|
|
# round. Reusing the existing active order is safer than
|
|
# creating hundreds of duplicate continuations with the same
|
|
# semantic title.
|
|
written.append(path)
|
|
continue
|
|
written.append(path)
|
|
continue
|
|
last_error: PermissionError | None = None
|
|
for _attempt in range(max_attempts_per_order):
|
|
order.order_id = incrementing_id(prefix, next_number[subfolder], order.title)
|
|
next_number[subfolder] += 1
|
|
filename = order.order_id
|
|
if not filename.endswith(".md"):
|
|
filename += ".md"
|
|
path = target_dir / filename
|
|
if path.exists():
|
|
continue
|
|
try:
|
|
path.write_text(order_markdown(order, str(platform_folder), real_repo), encoding="utf-8")
|
|
except PermissionError as exc:
|
|
last_error = exc
|
|
continue
|
|
written.append(path)
|
|
break
|
|
else:
|
|
detail = f"Nao foi possivel gravar ordem em {target_dir} apos {max_attempts_per_order} tentativas."
|
|
if last_error is not None:
|
|
detail = f"{detail} Ultimo erro: {last_error}"
|
|
raise PermissionError(detail)
|
|
return tuple(written)
|
|
|
|
|
|
def executed_order_markdown(reports: Sequence[PlatformHumanReport], orders: Sequence[ServiceOrder]) -> str:
|
|
total_code = sum(report.scan.code_lines for report in reports)
|
|
avg = round(sum(report.average_score for report in reports) / len(reports)) if reports else 0
|
|
lines = [
|
|
"# EXECUTADO - Fundacao da plataforma tudo-para-ia-mais-humana",
|
|
"",
|
|
"## Sintese",
|
|
"",
|
|
"A rodada criou uma base operacional inicial para traduzir o estado tecnico do ecossistema em leitura humana.",
|
|
"",
|
|
f"- plataformas avaliadas: {len(reports)}",
|
|
f"- linhas de codigo analisadas: {total_code}",
|
|
f"- score medio humano: {avg}",
|
|
f"- ordens de saida criadas: {len(orders)}",
|
|
"",
|
|
"## Arquivos e capacidades criadas",
|
|
"",
|
|
"- pacote Python `mais_humana` com scanner, matriz, DOCX, SVG, SQLite e gerador de OS;",
|
|
"- relatorios DOCX e Markdown por plataforma;",
|
|
"- relatorio geral do ecossistema;",
|
|
"- graficos SVG de maturidade e matriz;",
|
|
"- dados JSON auditaveis;",
|
|
"- SQL semantico atualizado;",
|
|
"- ordens executivas e gerenciais de saida.",
|
|
"",
|
|
"## Plataformas avaliadas",
|
|
"",
|
|
]
|
|
for report in sorted(reports, key=lambda item: item.platform.platform_id):
|
|
lines.append(f"- {report.platform.platform_id}: score {report.average_score}, codigo {report.scan.code_lines} linhas")
|
|
return "\n".join(lines) + "\n"
|
|
|
|
|
|
def pending_markdown(reports: Sequence[PlatformHumanReport], push_status: str | None = None) -> str:
|
|
lines = ["# PENDENCIAS-CODEX - tudo-para-ia-mais-humana", ""]
|
|
lines.append("## Pendencias reais")
|
|
lines.append("")
|
|
if push_status:
|
|
lines.append(f"- Sincronizacao Git remota: {push_status}")
|
|
for report in sorted(reports, key=lambda item: item.platform.platform_id):
|
|
for warning in report.scan.warnings:
|
|
lines.append(f"- {report.platform.platform_id}: {warning}")
|
|
if len(lines) == 4:
|
|
lines.append("- Nenhuma pendencia material detectada nesta rodada.")
|
|
lines.append("")
|
|
lines.append("## Proximo passo")
|
|
lines.append("")
|
|
lines.append("Executar as ordens de saida criadas e comparar novos scores contra os dados desta rodada.")
|
|
return "\n".join(lines) + "\n"
|
|
|
|
|
|
def audit_markdown(reports: Sequence[PlatformHumanReport], orders: Sequence[ServiceOrder]) -> str:
|
|
lines = [
|
|
"# AUDITORIA-GPT - Fundacao tudo-para-ia-mais-humana",
|
|
"",
|
|
"## Confirmado",
|
|
"",
|
|
"- Repositorio real estruturado como plataforma propria.",
|
|
"- Base tecnica criada para gerar relatorios humanos e matrizes.",
|
|
"- Ordens de saida geradas a partir de recomendacoes reais.",
|
|
"- SQL semantico atualizado por camada compacta.",
|
|
"",
|
|
"## Parcial",
|
|
"",
|
|
"- Push remoto depende de credencial Git disponivel no ambiente.",
|
|
"- Relatorios DOCX iniciais foram gerados por escritor minimalista sem dependencia externa.",
|
|
"",
|
|
"## Amostra de scores",
|
|
"",
|
|
]
|
|
for report in sorted(reports, key=lambda item: item.average_score)[:8]:
|
|
lines.append(f"- {report.platform.platform_id}: {report.average_score}")
|
|
lines.extend(["", "## Ordens criadas", ""])
|
|
for order in orders:
|
|
lines.append(f"- {order.order_id}: {order.title}")
|
|
return "\n".join(lines) + "\n"
|