feat(1c): add executive regulation to manager brief
This commit is contained in:
@@ -466,6 +466,33 @@ def render_manager_brief_html(payload: dict[str, Any]) -> str:
|
|||||||
summary_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in brief.get("summary", []))
|
summary_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in brief.get("summary", []))
|
||||||
action_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in actions)
|
action_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in actions)
|
||||||
caveat_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in caveats)
|
caveat_items = "\n".join(f"<li>{html.escape(str(item))}</li>" for item in caveats)
|
||||||
|
morning_regulation_items = "\n".join(
|
||||||
|
f"<li>{html.escape(str(item))}</li>"
|
||||||
|
for item in [
|
||||||
|
"Открыть brief, changes и weekly digest. Сначала понять: хвост кейсов растёт или сокращается.",
|
||||||
|
"Выбрать не больше 5 компаний первой очереди. Критерии: рост open cases, active locks, manual-match, повторный critical без улучшения.",
|
||||||
|
"По каждой компании требовать только 4 вещи: причина, владелец, срок, измеримый результат к вечеру.",
|
||||||
|
"Не принимать формулировки «смотрим», «разбираемся», «в работе». Принимать только конкретный план закрытия.",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
evening_regulation_items = "\n".join(
|
||||||
|
f"<li>{html.escape(str(item))}</li>"
|
||||||
|
for item in [
|
||||||
|
"По каждой компании дня спросить только факт: сколько кейсов было утром и сколько стало вечером.",
|
||||||
|
"Отдельно проверить, снялись ли блокировки и исчез ли прирост новых кейсов.",
|
||||||
|
"По каждой компании зафиксировать один статус: снято, частично снято, не снято.",
|
||||||
|
"Если результата нет, менять владельца или усиливать контроль; не переносить хвост молча.",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
hard_rules_items = "\n".join(
|
||||||
|
f"<li>{html.escape(str(item))}</li>"
|
||||||
|
for item in [
|
||||||
|
"Не пытаться разбирать все 41 компании сразу.",
|
||||||
|
"Не путать operational critical с финансовым крахом портфеля.",
|
||||||
|
"Не делать жёстких оргвыводов по manual-match компаниям без проверки соответствия реестру.",
|
||||||
|
"Главный KPI на сейчас: закрытые кейсы и снятые блокировки, а не количество проведённых разборов.",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return f"""<!doctype html>
|
return f"""<!doctype html>
|
||||||
<html lang="ru">
|
<html lang="ru">
|
||||||
@@ -787,6 +814,27 @@ def render_manager_brief_html(payload: dict[str, Any]) -> str:
|
|||||||
</ul>
|
</ul>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="panel span-6">
|
||||||
|
<h2>Регламент руководителя: утро</h2>
|
||||||
|
<ul class="action-list">
|
||||||
|
{morning_regulation_items}
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="panel span-6">
|
||||||
|
<h2>Регламент руководителя: вечер</h2>
|
||||||
|
<ul class="action-list">
|
||||||
|
{evening_regulation_items}
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="panel span-12">
|
||||||
|
<h2>Жёсткие правила управления</h2>
|
||||||
|
<ul class="action-list">
|
||||||
|
{hard_rules_items}
|
||||||
|
</ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
<article class="panel span-12">
|
<article class="panel span-12">
|
||||||
<h2>Свежесть источников</h2>
|
<h2>Свежесть источников</h2>
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
@@ -56,6 +56,40 @@ import company_intelligence_api as api
|
|||||||
|
|
||||||
|
|
||||||
class CompanyIntelligenceApiTests(unittest.TestCase):
|
class CompanyIntelligenceApiTests(unittest.TestCase):
|
||||||
|
def test_render_manager_brief_includes_executive_regulation(self) -> None:
|
||||||
|
payload = {
|
||||||
|
"generated_at": "2026-05-22T12:00:00+00:00",
|
||||||
|
"render_mode": "codex",
|
||||||
|
"brief": {
|
||||||
|
"headline": "Портфель 1С под давлением.",
|
||||||
|
"summary": ["Кейсы растут.", "Нужен triage.", "Manual-match требует осторожности."],
|
||||||
|
"top_risks": [],
|
||||||
|
"top_forecasts": [],
|
||||||
|
"actions": ["Разобрать 5 компаний первой очереди."],
|
||||||
|
"caveats": ["Operational severity не равна финансам."],
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"portfolio_summary": {
|
||||||
|
"companies_total": 41,
|
||||||
|
"critical_total": 41,
|
||||||
|
"open_cases_total": 2744,
|
||||||
|
"activity_forecast_30d_total": 1723233.3,
|
||||||
|
},
|
||||||
|
"freshness": [
|
||||||
|
{
|
||||||
|
"source": "documents_ts",
|
||||||
|
"latest_ts": "2026-05-22T09:00:02+00:00",
|
||||||
|
"lag_hours": 3.84,
|
||||||
|
"stale": False,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
html_page = api.render_manager_brief_html(payload)
|
||||||
|
self.assertIn("Регламент руководителя: утро", html_page)
|
||||||
|
self.assertIn("Регламент руководителя: вечер", html_page)
|
||||||
|
self.assertIn("Жёсткие правила управления", html_page)
|
||||||
|
|
||||||
def test_build_company_priority_context(self) -> None:
|
def test_build_company_priority_context(self) -> None:
|
||||||
latest_payload = {
|
latest_payload = {
|
||||||
"generated_at": "2026-05-22T12:00:00+00:00",
|
"generated_at": "2026-05-22T12:00:00+00:00",
|
||||||
|
|||||||
Reference in New Issue
Block a user