From baf7c6939595aa9bd03223885fb34f7ed5dfcf41 Mon Sep 17 00:00:00 2001 From: manoraga Date: Fri, 21 Aug 2026 13:13:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BC,=20=D0=BA=D0=B0=D0=BA=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D1=8F=D1=82=D1=8C=20=D0=B2=D1=8B=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=B7=D0=BA=D1=83=20=D1=81=D0=BA=D1=83=D0=B4=20=D1=81=20=D0=B3?= =?UTF-8?q?=D0=BB=D1=83=D0=BF=D1=8B=D0=BC=20Gemini-Lite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/scud_orion_ai.db | Bin 7520256 -> 7520256 bytes data/scud_orion_ai.db-shm | Bin 0 -> 32768 bytes data/scud_orion_ai.db-wal | Bin 0 -> 2727472 bytes main_etl.py | 125 +- modules/ai_engine/__init__.py | 0 modules/ai_engine/context_builder.py | 84 + modules/ai_engine/handlers/__init__.py | 0 modules/ai_engine/handlers/prompt_handler.py | 98 + .../ai_engine/handlers/snapshot_handler.py | 91 + modules/ai_engine/handlers/task_handler.py | 97 + modules/web_api/llm/core/fast_path.py | 211 +- modules/web_api/llm/core/prompt_merger.py | 74 - modules/web_api/llm/db/db_snapshots.py | 112 - modules/web_api/llm/db/db_tasks.py | 297 -- modules/web_api/llm/db_tools.py | 49 +- modules/web_api/llm/schemas.py | 38 +- modules/web_api/main.py | 6 + modules/web_api/routers/auth.py | 23 +- modules/web_api/routers/chat.py | 2 +- modules/web_api/routers/tasks.py | 15 +- project_code_snapshot.md | 2912 ++++++++++++----- scripts/db_cli.py | 7 +- services/scud_etl/anomaly_detector.py | 75 +- services/scud_etl/merger.py | 188 +- services/scud_etl/pipeline.py | 165 +- services/snapshots/service.py | 69 + services/text_reporter/__init__.py | 0 services/text_reporter/service.py | 49 + 28 files changed, 3064 insertions(+), 1723 deletions(-) create mode 100644 data/scud_orion_ai.db-shm create mode 100644 data/scud_orion_ai.db-wal create mode 100644 modules/ai_engine/__init__.py create mode 100644 modules/ai_engine/context_builder.py create mode 100644 modules/ai_engine/handlers/__init__.py create mode 100644 modules/ai_engine/handlers/prompt_handler.py create mode 100644 modules/ai_engine/handlers/snapshot_handler.py create mode 100644 modules/ai_engine/handlers/task_handler.py delete mode 100644 modules/web_api/llm/core/prompt_merger.py delete mode 100644 modules/web_api/llm/db/db_snapshots.py delete mode 100644 modules/web_api/llm/db/db_tasks.py create mode 100644 services/snapshots/service.py create mode 100644 services/text_reporter/__init__.py create mode 100644 services/text_reporter/service.py diff --git a/data/scud_orion_ai.db b/data/scud_orion_ai.db index a78f4a475bdcfdf5bb40f0865431b5c005a3e8da..a36ea3a54a0bbf24a6eb4dbdb44730bb35e00eb7 100644 GIT binary patch delta 36601 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 diff --git a/data/scud_orion_ai.db-shm b/data/scud_orion_ai.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..d436032dea373dc7b041e669c405ab4d3e48f9b6 GIT binary patch literal 32768 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 WDl4M9(N(?I{0OX2KMR!6HU10A!Kh~d literal 0 HcmV?d00001 diff --git a/data/scud_orion_ai.db-wal b/data/scud_orion_ai.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..ff1bdc93754498dea49c78e71e8c65d15b45eafd GIT binary patch literal 2727472 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�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�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%0A6Q3SNArgv|6_TtVU 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 str: + """Формирует полный динамический системный контекст агента с правилами из БД.""" + + # 1. Загружаем актуальный базовый системный промпт из SQLite БД + base_system_prompt = get_active_system_prompt() + + # 2. Серверный календарь и контекст дат + calendar_context = get_dynamic_calendar_context() + user_info = f"Пользователь ID={user_id}" if user_id != 0 else "Гость" + + # 3. Контекст текущего активного стейта сессии + current_state_type = session_state.get("state_type") if session_state else None + state_data = session_state.get("data_json") or {} if session_state else {} + if not isinstance(state_data, dict): + state_data = {} + + active_state_context = "" + if current_state_type == "PROMPT_PREVIEW": + active_state_context = ( + "\n[ТЕКУЩИЙ РЕЖИМ: ПРЕДПРОСМОТР СИСТЕМНОГО ПРОМПТА]\n" + "- Открыт предпросмотр изменений промпта. Для любых правок вызывай db_prompt_node_edit.\n" + ) + elif current_state_type == "PROMPT_FOLLOWUP": + active_state_context = ( + "\n[ТЕКУЩИЙ РЕЖИМ: СЕССИЯ РЕДАКТИРОВАНИЯ ПРОМПТА]\n" + "- Оператор просматривает или редактирует системный промпт.\n" + "- На любые команды вида 'удали пункт X.Y' или 'удали X.Y' ТЫ ОБЯЗАН ВЫЗВАТЬ db_prompt_node_edit с action='DELETE', section_id=X, item_id=Y.\n" + "- На любые команды 'добавь пункт X.Y ...' вызывай action='ADD'.\n" + "- Запрещено путать ADD и DELETE.\n" + ) + elif current_state_type == "SNAPSHOTS_VIEW": + active_date = state_data.get("query_date", "выбранную дату") + active_state_context = ( + f"\n[ТЕКУЩИЙ РЕЖИМ: ПРОСМОТР СНАПШОТОВ СКУД]\n" + f"- Сейчас на экране отображаются снапшоты за {active_date}.\n" + f"- Ты можешь форматировать, фильтровать или анализировать этот текущий срез.\n" + f"- Если оператор запрашивает ДРУГУЮ дату или день недели (например: 'за вчера', 'а за 13.08') — " + f"ТЫ ОБЯЗАН СРАЗУ ВЫЗВАТЬ db_get_snapshots(date_str=...).\n" + f"- Запрещено генерировать текст за другую дату по памяти.\n" + ) + elif current_state_type == "SNAPSHOT_DELETE_CONFIRM": + active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ СНАПШОТОВ]\n" + elif current_state_type == "TASK_DELETE_CONFIRM": + active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ ЗАДАЧИ]\n" + + # 4. Сборка полного системного сообщения + return ( + f"{base_system_prompt}\n\n" + f"СТРОГИЕ ПРАВИЛА ВЫЗОВА ИНСТРУМЕНТОВ:\n" + f"1. Для системного промпта:\n" + f" - 'добавь X.Y Текст' -> СРАЗУ вызывай db_prompt_node_edit(action='ADD', section_id=X, item_id=Y, content='Текст').\n" + f" - 'удали X.Y' -> СРАЗУ вызывай db_prompt_node_edit(action='DELETE', section_id=X, item_id=Y, content='').\n" + f" - 'покажи системный промпт' -> СРАЗУ вызывай db_get_system_prompt().\n" + f"2. Для задач:\n" + f" - 'удали задачу N' -> СРАЗУ вызывай db_tasks_edit(action='DELETE', task_id='N').\n" + f" - 'возьми в работу N' -> СРАЗУ вызывай db_tasks_edit(action='UPDATE', task_id='N', status='IN_PROGRESS').\n" + f" - 'заверши N' / 'готово N' -> СРАЗУ вызывай db_tasks_edit(action='UPDATE', task_id='N', status='COMPLETED').\n" + f"3. Запрещено задавать вопросы и писать подтверждения текстом — СРАЗУ вызывай соответствующий инструмент!\n\n" + f"[СИСТЕМНЫЙ КАЛЕНДАРЬ СЕРВЕРА]\n" + f"- Пользователь: {user_info}\n" + f"- {calendar_context}\n" + f"{active_state_context}" + ) \ No newline at end of file diff --git a/modules/ai_engine/handlers/__init__.py b/modules/ai_engine/handlers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/ai_engine/handlers/prompt_handler.py b/modules/ai_engine/handlers/prompt_handler.py new file mode 100644 index 0000000..02ca6a8 --- /dev/null +++ b/modules/ai_engine/handlers/prompt_handler.py @@ -0,0 +1,98 @@ +""" +=============================================================================== +FILE: modules/ai_engine/handlers/prompt_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка команд управления системным промптом. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional +from services.prompts.service import get_active_system_prompt, create_prompt_preview +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[PROMPT_HANDLER_DISPATCH] +def handle_prompt_call( + fn_name: str, + fn_args: Dict[str, Any], + session_id: str +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает вызовы просмотра и изменения системного промпта.""" + + # 1. Просмотр промпта с кнопкой быстрого перехода в редактор + if fn_name == "db_get_system_prompt": + active_prompt = get_active_system_prompt() + reply_text = f"Актуальный системный промпт:\n\n{active_prompt}" + + # Сохраняем состояние сессии для возможности мгновенного редактирования и подтверждения + db_set_session_state(session_id, "PROMPT_PREVIEW", { + "draft_text": active_prompt, + "action": "MANUAL_EDIT", + "idle_turns": 0 + }) + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + + return reply_text, db_get_chat_history(session_id), { + "type": "PROMPT_PREVIEW", + "raw_draft": active_prompt, + "baseline_prompt": active_prompt, + "buttons": [ + {"label": "✏️ Редактировать", "value": "action:open_editor", "style": "secondary"}, + {"label": "Готово", "value": "нет, спасибо", "style": "secondary"} + ] + } + + # 2. Предпросмотр точечных или пакетных изменений (ADD / EDIT / DELETE / BATCH_DELETE) + action = str(fn_args.get("action", "ADD")).upper() + nodes_list = fn_args.get("nodes_list", []) + delete_nodes_tuples = [] + + if nodes_list: + for n_str in nodes_list: + parts = str(n_str).strip().split(".") + if len(parts) == 2 and parts[0].isdigit() and parts[1].isdigit(): + delete_nodes_tuples.append((int(parts[0]), int(parts[1]))) + + sec_id = None + itm_id = None + try: + if fn_args.get("section_id") is not None: + sec_id = int(str(fn_args.get("section_id")).strip()) + if fn_args.get("item_id") is not None: + itm_id = int(str(fn_args.get("item_id")).strip()) + except Exception: + pass + + content = str(fn_args.get("content", "")).strip() + + merged_prompt, diff_html, baseline_prompt = create_prompt_preview( + action=action, + section_id=sec_id, + item_id=itm_id, + content=content, + delete_nodes=delete_nodes_tuples if delete_nodes_tuples else None + ) + + db_set_session_state(session_id, "PROMPT_PREVIEW", { + "draft_text": merged_prompt, + "action": "MANUAL_EDIT", + "section_id": sec_id, + "item_id": itm_id, + "content": content, + "idle_turns": 0 + }) + + preview_reply = f"Предпросмотр изменений системного промпта:\n\n{diff_html}\n\nДля применения подтвердите действие, отредактируйте или отмените." + db_save_chat_message(session_id, "assistant", preview_reply, is_ephemeral=1) + return preview_reply, db_get_chat_history(session_id), { + "type": "PROMPT_PREVIEW", + "raw_draft": merged_prompt, + "baseline_prompt": baseline_prompt, + "buttons": [ + {"label": "Подтвердить", "value": "подтверждаю", "style": "primary"}, + {"label": "Отменить", "value": "отмена", "style": "danger"}, + {"label": "✏️ Редактировать", "value": "action:open_editor", "style": "secondary"} + ] + } \ No newline at end of file diff --git a/modules/ai_engine/handlers/snapshot_handler.py b/modules/ai_engine/handlers/snapshot_handler.py new file mode 100644 index 0000000..3b7b425 --- /dev/null +++ b/modules/ai_engine/handlers/snapshot_handler.py @@ -0,0 +1,91 @@ +""" +=============================================================================== +FILE: modules/ai_engine/handlers/snapshot_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка запросов просмотра и удаления срезов СКУД. + +AI-CONTEXT-ANCHORS: + - ANCHOR[SNAPSHOT_HANDLER_DISPATCH]: Обработка db_get_snapshots и db_delete_snapshots. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional, List +from services.snapshots.service import get_snapshots_registry, delete_snapshots_safely +from modules.web_api.llm.core.calendar_utils import parse_relative_date_ru +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[SNAPSHOT_HANDLER_DISPATCH] +def handle_snapshots_call( + fn_name: str, + fn_args: Dict[str, Any], + session_id: str, + user_message: str, + state_data: Dict[str, Any] +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает запросы реестра и безопасного удаления срезов.""" + + # 1. Получение срезов + if fn_name == "db_get_snapshots": + date_param = fn_args.get("date_str") + if not date_param and user_message: + date_param = parse_relative_date_ru(user_message) + + snapshots_res = get_snapshots_registry(date_str=date_param) + query_date = snapshots_res.get("query_date", "выбранную дату") + + db_set_session_state(session_id, "SNAPSHOTS_VIEW", snapshots_res) + reply_text = f"Реестр срезов СКУД за {query_date}:" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOTS_CARD", + "data": snapshots_res + } + + # 2. Удаление срезов (двухфазное подтверждение) + raw_id = fn_args.get("snapshot_id") or fn_args.get("day_str") + raw_ids = fn_args.get("snapshot_ids") or [] + is_confirmed = fn_args.get("confirmed", False) + + if raw_id and not raw_ids: + if isinstance(raw_id, str) and "," in raw_id: + raw_ids = [s.strip() for s in raw_id.split(",")] + else: + raw_ids = [raw_id] + + safe_ids = [s.strip() for s in raw_ids if s and not str(s).strip().startswith("Y")] + if not safe_ids: + reply_text = "⚠️ Итоговый срез Y защищен от удаления. Выберите дневные снапшоты." + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), None + + if not is_confirmed: + query_date = state_data.get("query_date", "") + db_set_session_state(session_id, "SNAPSHOT_DELETE_CONFIRM", { + "snapshot_ids": safe_ids, + "query_date": query_date, + "idle_turns": 0 + }) + ids_str = ", ".join(safe_ids) + reply_text = f"Вы действительно хотите удалить дневные снапшоты: {ids_str}?" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOT_DELETE_CONFIRM", + "buttons": [ + {"label": f"Удалить ({len(safe_ids)} шт.)", "value": f"подтверждаю удаление снапшотов {ids_str}", "style": "danger"}, + {"label": "Отмена", "value": "отмена", "style": "secondary"} + ] + } + else: + delete_snapshots_safely(snapshot_ids=safe_ids) + query_date = state_data.get("query_date", "") + updated_data = get_snapshots_registry(date_str=query_date) + + reply_text = f"✅ Успешно удалено снапшотов: {len(safe_ids)} шт." + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOTS_CARD", + "data": updated_data + } \ No newline at end of file diff --git a/modules/ai_engine/handlers/task_handler.py b/modules/ai_engine/handlers/task_handler.py new file mode 100644 index 0000000..f5d7e39 --- /dev/null +++ b/modules/ai_engine/handlers/task_handler.py @@ -0,0 +1,97 @@ +""" +=============================================================================== +FILE: modules/ai_engine/handlers/task_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка вызовов инструментов задач (get, edit, delete, export). + +AI-CONTEXT-ANCHORS: + - ANCHOR[TASK_HANDLER_DISPATCH]: Обработка вызовов db_get_tasks и db_tasks_edit. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional +from services.tasks.service import get_tasks, execute_task_action +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[TASK_HANDLER_DISPATCH] +def handle_tasks_call( + fn_name: str, + fn_args: Dict[str, Any], + user_id: int, + session_id: str +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает нативные tool-вызовы по задачам.""" + + # 1. Просмотр задач + if fn_name == "db_get_tasks": + raw_tasks = get_tasks(user_id, status=fn_args.get("status")) + reply_text = "Вот интерактивный список ваших текущих задач:" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_INTERACTIVE_CARD", + "tasks": raw_tasks + } + + # 2. Модификация / Удаление / Экспорт + action = (fn_args.get("action") or "UPDATE").upper() + if fn_name == "db_add_task": action = "ADD" + elif fn_name == "db_delete_task": action = "DELETE" + elif fn_name == "db_update_task_status": action = "UPDATE" + + # Двухфазное подтверждение удаления + if action == "DELETE": + task_id_raw = str(fn_args.get("task_id", "")).replace("#", "").replace("TASK-", "").strip() + db_set_session_state(session_id, "TASK_DELETE_CONFIRM", {"task_id": task_id_raw, "idle_turns": 0}) + reply_text = f"Вы действительно хотите удалить задачу #{task_id_raw}?" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_DELETE_CONFIRM", + "buttons": [ + {"label": f"Удалить #{task_id_raw}", "value": f"подтверждаю удаление задачи {task_id_raw}", "style": "danger"}, + {"label": "Отмена", "value": "отмена", "style": "secondary"} + ] + } + + # Экспорт в Markdown + elif action == "EXPORT": + export_res = execute_task_action( + user_id=user_id, + action="EXPORT", + filename=fn_args.get("filename"), + status=fn_args.get("status") + ) + reply_text = export_res.get("message", "Отчет по задачам успешно экспортирован.") + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=0) + + action_payload = None + if export_res.get("status") == "success": + action_payload = { + "type": "FILE_DOWNLOAD_CARD", + "filename": export_res.get("filename"), + "download_url": export_res.get("download_url"), + "tasks_count": export_res.get("tasks_count") + } + return reply_text, db_get_chat_history(session_id), action_payload + + # Создание и обновление + else: + res = execute_task_action( + user_id=user_id, + action=action, + task_id=fn_args.get("task_id"), + title=fn_args.get("title"), + priority=fn_args.get("priority", "MEDIUM"), + status=fn_args.get("status"), + module=fn_args.get("module", "general"), + due_date=fn_args.get("due_date") + ) + raw_tasks = get_tasks(user_id) + reply_text = res.get("message", "Операция над задачами выполнена.") + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_INTERACTIVE_CARD", + "tasks": raw_tasks + } \ No newline at end of file diff --git a/modules/web_api/llm/core/fast_path.py b/modules/web_api/llm/core/fast_path.py index f023a3e..b33e1c8 100644 --- a/modules/web_api/llm/core/fast_path.py +++ b/modules/web_api/llm/core/fast_path.py @@ -1,87 +1,168 @@ """ +=============================================================================== FILE: modules/web_api/llm/core/fast_path.py -ROLE: Детерминированный технический конвейер (НЕ для ИИ-размышлений). - Выполняет только кнопки подтверждения для удаления задач, снапшотов и промптов. +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: web_api / llm / core +ROLE: Детерминированный мгновенный перехват нажатий кнопок подтверждения + (без задержек LLM и обращения к Ollama). + +AI-CONTEXT-ANCHORS: + - ANCHOR[FAST_PATH_MAIN]: Точка входа handle_fast_path_intercept. +=============================================================================== """ +import json +import logging from typing import Dict, Any, Tuple, Optional -from llm.db_tools import ( - db_delete_task, - db_get_tasks, - db_delete_snapshots, - db_get_snapshots, - db_add_system_prompt, - db_apply_prompt_node_action -) -from .context_manager import close_tool_session_and_cleanup, save_tool_interaction, save_dialog_interaction +# Прямые вызовы чистых доменных сервисов +from services.prompts.service import save_full_prompt_draft, apply_prompt_action, get_active_system_prompt +from services.tasks.service import get_tasks, delete_task +from services.snapshots.service import get_snapshots_registry, delete_snapshots_safely + +# Чат и сессии +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history, db_purge_ephemeral_messages +from modules.web_api.llm.db.db_prompts import db_set_session_state, db_clear_session_state, db_get_tool_action +from modules.web_api.llm.core.context_manager import close_tool_session_and_cleanup + +logger = logging.getLogger("FAST_PATH") + + +# ANCHOR[FAST_PATH_MAIN] def handle_fast_path_intercept( - session_id: str, - user_message: str, - full_user_content: str, + session_id: str, + user_message: str, + full_user_content: str, session_state: Optional[Dict[str, Any]] ) -> Optional[Tuple[str, list, Optional[Dict[str, Any]]]]: - + """ + Мгновенный перехват нажатий кнопок подтверждения (Fast-Path). + Возвращает (reply, history, action_type) или None, если требуется передать управление LLM. + """ if not session_state: return None state_type = session_state.get("state_type") - msg = user_message.strip().lower() + state_data = session_state.get("data_json") or {} + if not isinstance(state_data, dict): + state_data = {} - # ⭐️ Управление системным промптом (Превью) + msg_lower = user_message.strip().lower() + + # ------------------------------------------------------------------------- + # 1. ПОДТВЕРЖДЕНИЕ ПРЕВЬЮ СИСТЕМНОГО ПРОМПТА + # ------------------------------------------------------------------------- if state_type == "PROMPT_PREVIEW": - state_data = session_state.get("data_json") or {} - draft_text = state_data.get("draft_text", "") - action = state_data.get("action") - sec_id = state_data.get("section_id") - itm_id = state_data.get("item_id") - content = state_data.get("content", "") + is_confirm = msg_lower in ["подтверждаю", "да", "сохраняй", "применить", "ок", "подтвердить"] + is_cancel = msg_lower in ["отмена", "отменить", "нет", "отклонить"] - if msg in ["подтверждаю", "подтвердить", "да", "сохранить", "применить", "ок", "хорошо"]: - if action == "MANUAL_EDIT" or not action or sec_id is None: - if draft_text: - db_add_system_prompt("main_agent", draft_text) + if is_confirm: + action = state_data.get("action", "MANUAL_EDIT") + draft_text = state_data.get("draft_text", "") + + # Применение изменений + if action == "MANUAL_EDIT" and draft_text: + save_full_prompt_draft(draft_text, prompt_name="main_agent") else: - db_apply_prompt_node_action(action=action, section_id=sec_id, item_id=itm_id, content=content) + sec_id = state_data.get("section_id") + itm_id = state_data.get("item_id") + content = state_data.get("content", "") + if sec_id is not None and itm_id is not None: + apply_prompt_action(action=action, section_id=sec_id, item_id=itm_id, content=content) + elif draft_text: + save_full_prompt_draft(draft_text, prompt_name="main_agent") - close_tool_session_and_cleanup(session_id, "PROMPT_APPLIED_SUCCESSFULLY") - reply_text = "✅ Изменения системного промпта успешно применены в базе данных." - save_tool_interaction(session_id, full_user_content, reply_text) - return reply_text, [], None + # Закрытие сессии и зачистка + close_tool_session_and_cleanup(session_id, close_reason="PROMPT_APPLIED_SUCCESSFULLY") + db_clear_session_state(session_id) - elif msg in ["отмена", "отменить", "отклонить"]: - close_tool_session_and_cleanup(session_id, "PROMPT_PREVIEW_CANCELLED") - reply_text = "❌ Изменения системного промпта отменены." - save_dialog_interaction(session_id, full_user_content, reply_text) - return reply_text, [], None - - # Удаление снапшотов - elif state_type == "SNAPSHOT_DELETE_CONFIRM": - state_data = session_state.get("data_json", {}) - ids = state_data.get("snapshot_ids", []) - query_date = state_data.get("query_date", "") - - if msg.startswith("подтверждаю удаление снапшотов"): - db_delete_snapshots(snapshot_ids=ids) - close_tool_session_and_cleanup(session_id, "SNAPSHOTS_DELETED") - updated_data = db_get_snapshots(session_id=session_id, date_str=query_date) - return f"✅ Удалено снапшотов: {len(ids)}", [], {"type": "SNAPSHOTS_CARD", "data": updated_data} - - elif msg == "отмена": - close_tool_session_and_cleanup(session_id, "SNAPSHOT_CANCELLED") - updated_data = db_get_snapshots(session_id=session_id, date_str=query_date) - return "Удаление отменено.", [], {"type": "SNAPSHOTS_CARD", "data": updated_data} - - # Удаление задач - elif state_type == "TASK_DELETE_CONFIRM": - task_id = session_state.get("data_json", {}).get("task_id") - if msg.startswith("подтверждаю удаление задачи"): - db_delete_task(1, str(task_id)) - close_tool_session_and_cleanup(session_id, "TASK_DELETED") - return f"Задача #{task_id} удалена.", [], {"type": "TASK_INTERACTIVE_CARD", "tasks": db_get_tasks(1)} + tool_action = db_get_tool_action("db_confirm_prompt_preview") + reply = tool_action.get("success_template", "✅ Системный промпт успешно сохранен и применен в базе данных.") if tool_action else "✅ Системный промпт успешно сохранен и применен в базе данных." - elif msg == "отмена": - close_tool_session_and_cleanup(session_id, "TASK_CANCELLED") - return "Удаление отменено.", [], {"type": "TASK_INTERACTIVE_CARD", "tasks": db_get_tasks(1)} + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=0) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=0) + return reply, db_get_chat_history(session_id), None + + elif is_cancel: + close_tool_session_and_cleanup(session_id, close_reason="PROMPT_EDIT_CANCELLED") + db_clear_session_state(session_id) + + tool_action = db_get_tool_action("db_cancel_prompt_preview") + reply = tool_action.get("success_template", "❌ Изменения системного промпта отменены.") if tool_action else "❌ Изменения системного промпта отменены." + + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=0) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=0) + return reply, db_get_chat_history(session_id), None + + # ------------------------------------------------------------------------- + # 2. ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ СНАПШОТОВ СКУД + # ------------------------------------------------------------------------- + elif state_type == "SNAPSHOT_DELETE_CONFIRM": + is_confirm = "подтверждаю удаление снапшот" in msg_lower or msg_lower in ["подтверждаю", "да", "удалить"] + is_cancel = msg_lower in ["отмена", "отменить", "нет"] + + if is_confirm: + snap_ids = state_data.get("snapshot_ids", []) + query_date = state_data.get("query_date", "") + + # Безопасное удаление через сервис + del_res = delete_snapshots_safely(snapshot_ids=snap_ids) + + close_tool_session_and_cleanup(session_id, close_reason="SNAPSHOTS_DELETED") + + # Получаем свежий список за ту же дату + updated_data = get_snapshots_registry(date_str=query_date if query_date else None) + db_set_session_state(session_id, "SNAPSHOTS_VIEW", updated_data) + + reply = f"✅ Успешно удалено снапшотов: {len(snap_ids)} шт." + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=1) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=1) + + return reply, db_get_chat_history(session_id), { + "type": "SNAPSHOTS_CARD", + "data": updated_data + } + + elif is_cancel: + close_tool_session_and_cleanup(session_id, close_reason="SNAPSHOT_DELETE_CANCELLED") + db_clear_session_state(session_id) + + reply = "❌ Удаление снапшотов отменено." + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=0) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=0) + return reply, db_get_chat_history(session_id), None + + # ------------------------------------------------------------------------- + # 3. ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ ЗАДАЧИ + # ------------------------------------------------------------------------- + elif state_type == "TASK_DELETE_CONFIRM": + is_confirm = "подтверждаю удаление задачи" in msg_lower or msg_lower in ["подтверждаю", "да", "удалить"] + is_cancel = msg_lower in ["отмена", "отменить", "нет"] + + if is_confirm: + task_id = state_data.get("task_id") + delete_task(user_id=1, task_id=str(task_id)) + + close_tool_session_and_cleanup(session_id, close_reason="TASK_DELETED") + db_clear_session_state(session_id) + + raw_tasks = get_tasks(user_id=1) + reply = f"🗑 Задача #{task_id} удалена." + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=1) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=1) + + return reply, db_get_chat_history(session_id), { + "type": "TASK_INTERACTIVE_CARD", + "tasks": raw_tasks + } + + elif is_cancel: + close_tool_session_and_cleanup(session_id, close_reason="TASK_DELETE_CANCELLED") + db_clear_session_state(session_id) + + reply = "❌ Удаление задачи отменено." + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=0) + db_save_chat_message(session_id, "assistant", reply, is_ephemeral=0) + return reply, db_get_chat_history(session_id), None return None \ No newline at end of file diff --git a/modules/web_api/llm/core/prompt_merger.py b/modules/web_api/llm/core/prompt_merger.py deleted file mode 100644 index 5407901..0000000 --- a/modules/web_api/llm/core/prompt_merger.py +++ /dev/null @@ -1,74 +0,0 @@ -""" -=============================================================================== -FILE: modules/web_api/llm/core/prompt_merger.py -PROJECT: SCUD Orion AI (Unified Architecture) -MODULE: web_api / llm / core -ROLE: Алгоритмы парсинга, предпросмотра, слияния и визуального выделения правок. -=============================================================================== -""" - -# ANCHOR[PROMPT_MERGER_IMPORTS] -import re -import logging - -logger = logging.getLogger("PROMPT_MERGER") - - -# ANCHOR[PROMPT_MERGE_ENGINE] -def build_prompt_preview_merge(current_prompt: str, user_message: str, proposed_text: str) -> str: - """ - Вычисляет результирующий чистый текст промпта для записи в БД. - """ - user_msg_lower = user_message.lower() - - # 1. Сценарий удаления пункта - if any(w in user_msg_lower for w in ["удали", "стереть", "убрать", "вырежи", "удалить"]): - target_num_match = re.search(r'\d+(\.\d+)*', user_message) - target_num = target_num_match.group(0) if target_num_match else "" - - lines = current_prompt.splitlines() - if target_num: - new_lines = [line for line in lines if not line.strip().startswith(f"{target_num}.")] - else: - new_lines = lines - return "\n".join(new_lines) - - # 2. Сценарий добавления или замены пункта - if proposed_text: - if len(proposed_text) < 500: - clean_item = proposed_text.strip() - for prefix in ["добавь пункт", "добавить пункт", "вставь пункт", "добавь"]: - if prefix in clean_item.lower(): - clean_item = re.sub(prefix, "", clean_item, flags=re.IGNORECASE).strip(" .:") - - lines = current_prompt.splitlines() - new_lines = [] - inserted = False - for line in lines: - new_lines.append(line) - if "3.3." in line and not inserted: - item_str = clean_item if re.match(r'^\d+\.\d+\.', clean_item) else f"3.4. {clean_item}" - new_lines.append(f" {item_str}") - inserted = True - if not inserted: - new_lines.append(f" {clean_item}") - return "\n".join(new_lines) - - return proposed_text or current_prompt - - -def highlight_prompt_diff(old_prompt: str, new_prompt: str) -> str: - """ - Генерирует текст с подсветкой добавленных/измененных строк HTML-классами Tailwind. - """ - old_lines_set = {line.strip() for line in old_prompt.splitlines() if line.strip()} - diff_lines = [] - - for line in new_prompt.splitlines(): - if line.strip() and line.strip() not in old_lines_set: - # Выделяем новую или измененную строку красным цветом - diff_lines.append(f'{line}') - else: - diff_lines.append(line) - - return "\n".join(diff_lines) \ No newline at end of file diff --git a/modules/web_api/llm/db/db_snapshots.py b/modules/web_api/llm/db/db_snapshots.py deleted file mode 100644 index 2c6e94f..0000000 --- a/modules/web_api/llm/db/db_snapshots.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -=============================================================================== -FILE: modules/web_api/llm/db/db_snapshots.py -PROJECT: SCUD Orion AI (Unified Architecture) -MODULE: web_api / llm / db -ROLE: Выборка, фильтрация и пакетное удаление срезов логов СКУД в SQLite. - -AI-CONTEXT-ANCHORS: - - ANCHOR[DB_GET_SNAPSHOTS]: Выборка снапшотов с нормализацией дат. - - ANCHOR[DB_DEL_SNAPSHOTS]: Удаление снапшотов по ID, списку ID или за дату. -=============================================================================== -""" - -import json -import re -from typing import Dict, Any, Optional, List -from .connection import get_db_connection -from .db_prompts import db_set_session_state -from ..core.calendar_utils import parse_relative_date_ru - -# ANCHOR[DB_GET_SNAPSHOTS] -def db_get_snapshots(session_id: str = "web_session_main", date_str: Optional[str] = None, original_user_message: str = "") -> Dict[str, Any]: - conn = get_db_connection() - cursor = conn.cursor() - - query = """ - SELECT - snapshot_id, - log_date, - snapshot_time, - COUNT(*) as record_count - FROM scud_logs - """ - params = [] - - clean_date = date_str.strip() if date_str else "" - if not clean_date or not re.search(r'\d{2}\.\d{2}\.\d{4}', clean_date): - if original_user_message: - clean_date = parse_relative_date_ru(original_user_message) - - if clean_date and re.search(r'\d{2}\.\d{2}\.\d{4}', clean_date): - iso_date = clean_date - compact_date = clean_date.replace(".", "") - - if "." in clean_date: - parts = clean_date.split(".") - if len(parts) == 3: - iso_date = f"{parts[2]}-{parts[1]}-{parts[0]}" - compact_date = f"{parts[2]}{parts[1]}{parts[0]}" - - query += """ - WHERE log_date = ? - OR snapshot_time LIKE ? - OR snapshot_id LIKE ? - OR snapshot_id LIKE ? - """ - params.extend([clean_date, f"{iso_date}%", f"{compact_date}-%", f"Y{compact_date}-%"]) - - query += """ - GROUP BY snapshot_id, log_date, snapshot_time - ORDER BY snapshot_time DESC, snapshot_id DESC - LIMIT 50 - """ - - cursor.execute(query, params) - rows = cursor.fetchall() - snapshots = [dict(r) for r in rows] - - result_data = { - "query_date": clean_date or "все", - "snapshots_count": len(snapshots), - "snapshots": snapshots - } - db_set_session_state(session_id=session_id, state_type="SNAPSHOTS_VIEW", data=result_data) - conn.close() - return result_data - -# ANCHOR[DB_DEL_SNAPSHOTS] -def db_delete_snapshots( - snapshot_id: Optional[str] = None, - snapshot_ids: Optional[List[str]] = None, - day_str: Optional[str] = None -) -> Dict[str, Any]: - """Удаляет один или группу дневных снапшотов с защитой итоговых Y-снапшотов.""" - conn = get_db_connection() - cursor = conn.cursor() - deleted = 0 - - if snapshot_ids and isinstance(snapshot_ids, list): - # Исключаем любые итоговые снапшоты, начинающиеся с Y - safe_ids = [s.strip() for s in snapshot_ids if s and not str(s).strip().startswith("Y")] - if safe_ids: - placeholders = ",".join(["?"] * len(safe_ids)) - cursor.execute(f"DELETE FROM scud_logs WHERE snapshot_id IN ({placeholders})", safe_ids) - deleted = cursor.rowcount - elif snapshot_id: - clean_id = str(snapshot_id).strip() - if clean_id.startswith("Y"): - conn.close() - return {"status": "error", "message": f"Итоговый срез [{clean_id}] защищен от удаления."} - cursor.execute("DELETE FROM scud_logs WHERE snapshot_id = ?", (clean_id,)) - deleted = cursor.rowcount - elif day_str: - cursor.execute("DELETE FROM scud_logs WHERE (log_date = ? OR snapshot_id LIKE ?) AND snapshot_id NOT LIKE 'Y%'", (day_str, f"%{day_str.replace('.', '')}%")) - deleted = cursor.rowcount - else: - conn.close() - return {"status": "error", "message": "Не указаны идентификаторы для удаления."} - - conn.commit() - conn.close() - return {"status": "success", "deleted_records": deleted, "message": f"Успешно удалено записей: {deleted}"} \ No newline at end of file diff --git a/modules/web_api/llm/db/db_tasks.py b/modules/web_api/llm/db/db_tasks.py deleted file mode 100644 index 855b0e3..0000000 --- a/modules/web_api/llm/db/db_tasks.py +++ /dev/null @@ -1,297 +0,0 @@ -""" -=============================================================================== -FILE: modules/web_api/llm/db/db_tasks.py -PROJECT: SCUD Orion AI (Unified Architecture) -MODULE: web_api / llm / db -ROLE: Комплексное управление задачами, единый диспетчер db_tasks_edit - и генерация структурированных отчетов в Markdown. -=============================================================================== -""" - -import uuid -import logging -import os -import re -from datetime import datetime -from typing import List, Dict, Any, Optional -from .connection import get_db_connection - -logger = logging.getLogger("DB_TASKS") - -def normalize_task_id(task_id_input: str) -> str: - """Нормализует идентификатор задачи к формату TASK-XX.""" - if not task_id_input: - return "" - clean_id = str(task_id_input).strip().upper().replace("TASK-", "").replace("TASK", "").replace("#", "") - if clean_id.isdigit(): - num = int(clean_id) - return f"TASK-{(num):02d}" if num < 100 else f"TASK-{(num):03d}" - return f"TASK-{clean_id}" - -def db_get_tasks(user_id: int, status: Optional[str] = None) -> List[Dict[str, Any]]: - """Получает список всех задач пользователя.""" - conn = get_db_connection() - cursor = conn.cursor() - - if status and status.upper() != "ALL": - target_status = status.upper() - if target_status in ["PROGRESS", "В РАБОТЕ"]: target_status = "IN_PROGRESS" - elif target_status in ["DONE", "ГОТОВО"]: target_status = "COMPLETED" - elif target_status in ["PLANNED", "ПЛАНЫ"]: target_status = "BACKLOG" - - cursor.execute(""" - SELECT id, task_id, module, title, priority, status, due_date, created_at - FROM tasks - WHERE user_id = ? AND (status = ? OR (status = 'BACKLOG' AND ? = 'PLANNED')) - ORDER BY id DESC - """, (user_id, target_status, target_status)) - else: - cursor.execute(""" - SELECT id, task_id, module, title, priority, status, due_date, created_at - FROM tasks - WHERE user_id = ? - ORDER BY id DESC - """, (user_id,)) - - rows = cursor.fetchall() - conn.close() - return [dict(r) for r in rows] - -def db_add_task( - user_id: int, - module: str, - title: str, - priority: str = "MEDIUM", - due_date: Optional[str] = None, - status: str = "BACKLOG" -) -> Dict[str, Any]: - """Добавление новой задачи со статусом по умолчанию BACKLOG (В планах).""" - conn = get_db_connection() - cursor = conn.cursor() - cursor.execute("SELECT MAX(id) FROM tasks") - max_id = cursor.fetchone()[0] or 0 - new_task_id = f"TASK-{(max_id + 1):02d}" - - target_status = status.upper() if status else "BACKLOG" - if target_status in ["PROGRESS", "В РАБОТЕ"]: target_status = "IN_PROGRESS" - elif target_status in ["DONE", "ГОТОВО"]: target_status = "COMPLETED" - elif target_status in ["PLANNED", "ПЛАНЫ", "BACKLOG"]: target_status = "BACKLOG" - - cursor.execute(""" - INSERT INTO tasks (task_id, module, title, priority, status, due_date, user_id) - VALUES (?, ?, ?, ?, ?, ?, ?) - """, (new_task_id, module or "general", title.strip(), priority.upper(), target_status, due_date, user_id)) - conn.commit() - conn.close() - return {"status": "success", "task_id": new_task_id, "message": f"Задача #{max_id + 1} создана и добавлена в планы"} - -def db_update_task_status(user_id: int, task_id: str, status: str = "COMPLETED", due_date: Optional[str] = None) -> Dict[str, Any]: - """Быстрое обновление статуса задачи.""" - return db_update_task_details(user_id=user_id, task_id=task_id, status=status, due_date=due_date) - -def db_update_task_details( - user_id: int, - task_id: str, - title: Optional[str] = None, - priority: Optional[str] = None, - status: Optional[str] = None, - due_date: Optional[str] = None -) -> Dict[str, Any]: - """Комплексное обновление любых параметров задачи.""" - conn = get_db_connection() - cursor = conn.cursor() - - clean_num = re.sub(r'\D', '', str(task_id)) - formatted_id = normalize_task_id(task_id) - - updates = [] - params = [] - - if title is not None and title.strip(): - updates.append("title = ?") - params.append(title.strip()) - - if priority is not None and priority.strip(): - updates.append("priority = ?") - params.append(priority.strip().upper()) - - if status is not None and status.strip(): - target_status = status.strip().upper() - if target_status in ["PROGRESS", "В РАБОТЕ"]: target_status = "IN_PROGRESS" - elif target_status in ["DONE", "ГОТОВО"]: target_status = "COMPLETED" - elif target_status in ["PLANNED", "ПЛАНЫ"]: target_status = "BACKLOG" - updates.append("status = ?") - params.append(target_status) - - if due_date is not None: - updates.append("due_date = ?") - params.append(due_date.strip() if due_date.strip() else None) - - if not updates: - conn.close() - return {"status": "success", "message": "Нет данных для обновления"} - - params.extend([clean_num, formatted_id, f"%{task_id.strip()}", user_id]) - sql = f""" - UPDATE tasks - SET {', '.join(updates)} - WHERE (id = ? OR UPPER(task_id) = ? OR task_id LIKE ?) AND user_id = ? - """ - cursor.execute(sql, params) - - if cursor.rowcount == 0: - conn.close() - return {"error": f"Задача {task_id} не найдена или принадлежит другому пользователю"} - - conn.commit() - conn.close() - return {"status": "success", "message": f"Задача #{task_id} успешно обновлена"} - -def db_delete_task(user_id: int, task_id: str) -> Dict[str, Any]: - """Удаление задачи.""" - conn = get_db_connection() - cursor = conn.cursor() - clean_num = re.sub(r'\D', '', str(task_id)) - formatted_id = normalize_task_id(task_id) - - cursor.execute(""" - DELETE FROM tasks - WHERE (id = ? OR UPPER(task_id) = ? OR task_id LIKE ?) AND user_id = ? - """, (clean_num, formatted_id, f"%{task_id.strip()}", user_id)) - - if cursor.rowcount == 0: - conn.close() - return {"error": f"Задача {task_id} не найдена"} - conn.commit() - conn.close() - return {"status": "success", "message": f"Задача #{task_id} удалена"} - -def db_export_tasks_markdown(user_id: int, filename: Optional[str] = None, status_filter: Optional[str] = None) -> Dict[str, Any]: - """Генерирует Markdown-отчет задач с сохранением в output/web/tasks_export/{uuid}/.""" - tasks = db_get_tasks(user_id) - if not tasks: - return {"status": "error", "message": "Список задач пуст, экспорт отменен"} - - # Фильтрация по статусу - if status_filter and status_filter.upper() != "ALL": - tgt = status_filter.upper() - if tgt in ["COMPLETED", "DONE", "ВЫПОЛНЕННЫЕ"]: - tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["COMPLETED", "DONE"]] - elif tgt in ["IN_PROGRESS", "PROGRESS", "В РАБОТЕ"]: - tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["IN_PROGRESS", "PROGRESS"]] - elif tgt in ["BACKLOG", "PLANNED", "В ПЛАНАХ"]: - tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["BACKLOG", "PLANNED"]] - - if not tasks: - return {"status": "error", "message": f"Нет задач с фильтром '{status_filter}' для экспорта"} - - # Имя файла - target_filename = filename.strip() if (filename and filename.strip()) else "ROADMAP.md" - if not target_filename.endswith(".md"): - target_filename = f"{target_filename}.md" - - now_dt = datetime.now() - now_str = now_dt.strftime("%Y-%m-%d %H:%M") - - modules: Dict[str, List[Dict[str, Any]]] = {} - for t in tasks: - mod = t.get("module") or "general" - modules.setdefault(mod, []).append(t) - - md_lines = [ - "# 🗺️ Дорожная карта задач проекта (ROADMAP)\n", - f"> **Сформировано:** {now_str} | **Всего задач:** {len(tasks)}\n", - "---\n" - ] - - for mod_name, mod_tasks in sorted(modules.items()): - md_lines.append(f"## Модуль `{mod_name}`\n") - for t in sorted(mod_tasks, key=lambda x: x.get("id", 0)): - status = str(t.get("status", "BACKLOG")).upper() - is_done = status in ["COMPLETED", "DONE"] - is_progress = status in ["IN_PROGRESS", "PROGRESS"] - - check_box = "[x]" if is_done else "[ ]" - t_id = t.get("id") - title = t.get("title", "Без названия") - prio = t.get("priority", "MEDIUM") - due = f" *(срок: {t['due_date']})*" if t.get("due_date") else "" - status_tag = " `[В РАБОТЕ]`" if is_progress else (" `[ЗАВЕРШЕНО]`" if is_done else "") - - md_lines.append(f"- {check_box} **#{t_id}** [{prio}]{status_tag} {title}{due}") - - md_lines.append("\n---\n") - - content = "\n".join(md_lines) - - # Точный путь к корню scud_ai/output/web/tasks_export/ - current_file_dir = os.path.dirname(os.path.abspath(__file__)) - root_dir = os.path.abspath(os.path.join(current_file_dir, "../../../../")) - tool_dir = os.path.join(root_dir, "output", "web", "tasks_export") - os.makedirs(tool_dir, exist_ok=True) - - try: - from routers.files import purge_old_tool_sessions - purge_old_tool_sessions(tool_dir) - except Exception: - pass - - session_token = uuid.uuid4().hex[:8] - session_dir = os.path.join(tool_dir, session_token) - os.makedirs(session_dir, exist_ok=True) - - filepath = os.path.join(session_dir, target_filename) - with open(filepath, "w", encoding="utf-8") as f: - f.write(content) - - logger.info(f"Файл успешно создан: {filepath}") - - return { - "status": "success", - "filename": target_filename, - "filepath": filepath, - "download_url": f"/api/v1/files/download/tasks_export/{session_token}/{target_filename}", - "tasks_count": len(tasks), - "message": f"Отчет успешно сформирован в файл `{target_filename}` (всего задач: {len(tasks)})." - } - -def db_tasks_edit( - user_id: int, - action: str, - task_id: Optional[str] = None, - title: Optional[str] = None, - priority: Optional[str] = "MEDIUM", - status: Optional[str] = None, - module: Optional[str] = "general", - due_date: Optional[str] = None, - filename: Optional[str] = "ROADMAP.md" -) -> Dict[str, Any]: - """Единый консолидированный диспетчер операций над задачами.""" - act = action.strip().upper() - - if act == "ADD": - if not title: - return {"status": "error", "message": "Для создания задачи требуется указать title"} - return db_add_task( - user_id=user_id, - module=module or "general", - title=title, - priority=priority or "MEDIUM", - due_date=due_date, - status=status or "BACKLOG" - ) - - elif act == "UPDATE": - if not task_id: - return {"status": "error", "message": "Для обновления требуется указать task_id"} - return db_update_task_details(user_id=user_id, task_id=str(task_id), title=title, priority=priority, status=status, due_date=due_date) - - elif act == "DELETE": - if not task_id: - return {"status": "error", "message": "Для удаления требуется указать task_id"} - return db_delete_task(user_id=user_id, task_id=str(task_id)) - - elif act == "EXPORT": - return db_export_tasks_markdown(user_id=user_id, filename=filename or "ROADMAP.md") - - return {"status": "error", "message": f"Неизвестное действие action='{action}'"} \ No newline at end of file diff --git a/modules/web_api/llm/db_tools.py b/modules/web_api/llm/db_tools.py index fdfcea6..c2a5b9b 100644 --- a/modules/web_api/llm/db_tools.py +++ b/modules/web_api/llm/db_tools.py @@ -11,6 +11,7 @@ AI-CONTEXT-ANCHORS: """ # ANCHOR[FACADE_EXPORTS] +from typing import Optional, List, Dict, Any from core.connection import DB_PATH, get_connection as get_db_connection # Домен: Задачи @@ -28,16 +29,10 @@ from services.tasks.repository import normalize_task_id from services.prompts.service import ( get_active_system_prompt as db_get_active_system_prompt, apply_prompt_action as db_apply_prompt_node_action, - save_full_prompt_draft as db_add_system_prompt, + save_full_prompt_draft, create_prompt_preview ) -# Домен: Снапшоты СКУД -from services.snapshots.service import ( - get_snapshots_registry as db_get_snapshots, - delete_snapshots_safely as db_delete_snapshots -) - # Домен: База знаний from services.knowledge.service import ( get_rules as db_get_rules, @@ -60,4 +55,42 @@ from .db.db_prompts import ( db_get_anomalies, db_get_reference ) -from .core.calendar_utils import get_dynamic_calendar_context as db_get_current_server_time \ No newline at end of file +from .core.calendar_utils import get_dynamic_calendar_context as db_get_current_server_time + + +def db_add_system_prompt(name_or_text: str, draft_text: str = None) -> None: + """Совместимая обертка для сохранения системного промпта.""" + if draft_text is not None: + save_full_prompt_draft(draft_text, prompt_name=name_or_text) + else: + save_full_prompt_draft(name_or_text, prompt_name="main_agent") + + +def db_get_snapshots(session_id: str = "web_session_main", date_str: str = None, original_user_message: str = "") -> Dict[str, Any]: + """Совместимый фасад выборки снапшотов с сохранением стейта сессии.""" + from services.snapshots.service import get_snapshots_registry + from .core.calendar_utils import parse_relative_date_ru + + clean_date = (date_str or "").strip() + if not clean_date and original_user_message: + clean_date = parse_relative_date_ru(original_user_message) + + res = get_snapshots_registry(date_str=clean_date if clean_date else None) + db_set_session_state(session_id=session_id, state_type="SNAPSHOTS_VIEW", data=res) + return res + + +def db_delete_snapshots(snapshot_id: str = None, snapshot_ids: List[str] = None, day_str: str = None) -> Dict[str, Any]: + """Совместимый фасад безопасного удаления снапшотов.""" + from services.snapshots.service import delete_snapshots_safely + + target_ids = [] + if snapshot_ids: + target_ids.extend(snapshot_ids) + if snapshot_id: + if isinstance(snapshot_id, str) and "," in snapshot_id: + target_ids.extend([s.strip() for s in snapshot_id.split(",")]) + else: + target_ids.append(snapshot_id) + + return delete_snapshots_safely(snapshot_ids=target_ids) \ No newline at end of file diff --git a/modules/web_api/llm/schemas.py b/modules/web_api/llm/schemas.py index 9c23433..dfe1567 100644 --- a/modules/web_api/llm/schemas.py +++ b/modules/web_api/llm/schemas.py @@ -19,32 +19,37 @@ TOOLS_SCHEMA = [ "function": { "name": "db_prompt_node_edit", "description": ( - "Управление элементами системного промпта (добавление, изменение, удаление). " - "Если пользователь пишет 'удали 2.9' или 'удали пункт 2.9', вызывай action='DELETE', section_id=2, item_id=9. " - "Действие action может быть ADD, EDIT или DELETE." + "Управление элементами системного промпта (добавление, изменение, удаление пунктов).\n" + "Поддерживает как одиночные пункты (section_id, item_id), так и список пунктов для удаления (nodes_list=['1.8', '3.4']).\n" + "При любом запросе на удаление или добавление пунктов системного промпта ТЫ ОБЯЗАН вызвать этот инструмент." ), "parameters": { "type": "object", "properties": { "action": { "type": "string", - "enum": ["ADD", "EDIT", "DELETE"], - "description": "Действие: ADD (добавить), EDIT (изменить), DELETE (удалить)" + "enum": ["ADD", "EDIT", "DELETE", "BATCH_DELETE"], + "description": "Тип действия" }, "section_id": { "type": "integer", - "description": "Номер раздела из точки (например, 2 из 2.9)" + "description": "Номер раздела (например 1)" }, "item_id": { "type": "integer", - "description": "Номер пункта из точки (например, 9 из 2.9)" + "description": "Номер пункта (например 8)" + }, + "nodes_list": { + "type": "array", + "items": {"type": "string"}, + "description": "Список пунктов для удаления/изменения, например ['1.8', '3.4']" }, "content": { "type": "string", - "description": "Текст пункта (для DELETE пустая строка)" + "description": "Текст пункта" } }, - "required": ["action", "section_id", "item_id"] + "required": ["action"] } } }, @@ -81,7 +86,14 @@ TOOLS_SCHEMA = [ "type": "function", "function": { "name": "db_tasks_edit", - "description": "Единый инструмент управления задачами: создание (ADD), изменение статуса/дедлайна (UPDATE), удаление (DELETE) и экспорт задач в Markdown-файл (EXPORT).", + "description": ( + "Единый инструмент управления задачами: создание (ADD), изменение статуса/срока/названия (UPDATE), удаление (DELETE) и экспорт (EXPORT).\n" + "СТРОГИЕ ПРАВИЛА ВЫЗОВА:\n" + "- На любые фразы вида 'удали задачу N', 'удалить N', 'убери задачу N' ТЫ ОБЯЗАН СРАЗУ вызвать инструмент с action='DELETE', task_id='N'.\n" + "- На фразы 'возьми в работу N' вызывай action='UPDATE', task_id='N', status='IN_PROGRESS'.\n" + "- На фразы 'заверши N', 'готово N' вызывай action='UPDATE', task_id='N', status='COMPLETED'.\n" + "- КАТЕГОРИЧЕСКИ ЗАПРЕЩЕНО писать текстовые вопросы или запрашивать подтверждения словами! ТЫ ОБЯЗАН СРАЗУ вызвать инструмент." + ), "parameters": { "type": "object", "properties": { @@ -92,7 +104,7 @@ TOOLS_SCHEMA = [ }, "task_id": { "type": "string", - "description": "Номер задачи (для UPDATE и DELETE, например: '35')" + "description": "Номер задачи (например: '37')" }, "title": { "type": "string", @@ -100,8 +112,8 @@ TOOLS_SCHEMA = [ }, "status": { "type": "string", - "enum": ["IN_PROGRESS", "COMPLETED", "PLANNED"], - "description": "Статус задачи" + "enum": ["IN_PROGRESS", "COMPLETED", "BACKLOG"], + "description": "Новый статус задачи: IN_PROGRESS (В работу), COMPLETED (Завершено), BACKLOG (В планы)" }, "priority": { "type": "string", diff --git a/modules/web_api/main.py b/modules/web_api/main.py index a5317cd..fc65afd 100644 --- a/modules/web_api/main.py +++ b/modules/web_api/main.py @@ -16,6 +16,12 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) if CURRENT_DIR not in sys.path: sys.path.insert(0, CURRENT_DIR) +ROOT_DIR = os.path.abspath(os.path.join(CURRENT_DIR, "../../")) + +for p in [ROOT_DIR, CURRENT_DIR]: + if p not in sys.path: + sys.path.insert(0, p) + from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, JSONResponse diff --git a/modules/web_api/routers/auth.py b/modules/web_api/routers/auth.py index 73ba0c4..94ff0b1 100644 --- a/modules/web_api/routers/auth.py +++ b/modules/web_api/routers/auth.py @@ -5,8 +5,6 @@ ROLE: Аутентификация, валидация JWT-токенов и у =============================================================================== """ -# ANCHOR[AUTH_ROUTER_IMPORTS] -import sqlite3 import logging from datetime import datetime, timedelta from typing import Dict, Any, Optional @@ -17,7 +15,7 @@ from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from pydantic import BaseModel -from llm.db_tools import DB_PATH +from core.connection import get_connection JWT_SECRET = "scud_jwt_secret_key_2026_orion_ai_super_secure" ALGORITHM = "HS256" @@ -27,11 +25,10 @@ security = HTTPBearer() router = APIRouter(prefix="/api/v1/auth", tags=["auth"]) -# ANCHOR[AUTH_DB_HELPERS] + def get_db(): - conn = sqlite3.connect(DB_PATH) - conn.row_factory = sqlite3.Row - return conn + return get_connection(row_factory=True) + def create_access_token(user_id: int, username: str, is_admin: bool) -> str: payload = { @@ -42,6 +39,7 @@ def create_access_token(user_id: int, username: str, is_admin: bool) -> str: } return jwt.encode(payload, JWT_SECRET, algorithm=ALGORITHM) + def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> Dict[str, Any]: try: token = credentials.credentials @@ -58,21 +56,20 @@ def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(securit headers={"WWW-Authenticate": "Bearer"}, ) -# ANCHOR[AUTH_SCHEMAS] + class AuthRequest(BaseModel): username: str password: str + class ChangePasswordRequest(BaseModel): old_password: str new_password: str -# ANCHOR[AUTH_ENDPOINTS] + @router.post("/login") def login(req: AuthRequest): username = req.username.strip().lower() - logging.info(f"===> Попытка входа для пользователя: {username}") - conn = get_db() cursor = conn.cursor() cursor.execute("SELECT id, username, password_hash, is_admin FROM users WHERE username = ?", (username,)) @@ -80,15 +77,14 @@ def login(req: AuthRequest): conn.close() if not user or not pwd_context.verify(req.password, user["password_hash"]): - logging.warning(f"===> Ошибка: Неверный логин или пароль для {username}") raise HTTPException(status_code=401, detail="Неверное имя пользователя или пароль") is_admin = bool(user["is_admin"]) or (user["username"] == "puh") token = create_access_token(user["id"], user["username"], is_admin) - logging.info(f"===> УСПЕХ: Авторизован пользователь {username}") return {"status": "success", "token": token, "username": user["username"], "is_admin": is_admin} + @router.post("/change-password") def change_password(req: ChangePasswordRequest, current_user: Dict[str, Any] = Depends(get_current_user)): if not req.new_password or len(req.new_password) < 4: @@ -108,5 +104,4 @@ def change_password(req: ChangePasswordRequest, current_user: Dict[str, Any] = D conn.commit() conn.close() - logging.info(f"Пароль успешно изменен для пользователя ID: {current_user['id']}") return {"status": "success", "message": "Пароль успешно изменен"} \ No newline at end of file diff --git a/modules/web_api/routers/chat.py b/modules/web_api/routers/chat.py index 1dce55e..df4b303 100644 --- a/modules/web_api/routers/chat.py +++ b/modules/web_api/routers/chat.py @@ -13,7 +13,7 @@ from fastapi import APIRouter, Depends, UploadFile, File, Form, HTTPException from pydantic import BaseModel from .auth import get_current_user -from llm.agent import process_chat_message +from modules.ai_engine.agent import process_chat_message from llm.file_parser import extract_text_from_file from llm.db_tools import db_set_session_state, db_get_session_state diff --git a/modules/web_api/routers/tasks.py b/modules/web_api/routers/tasks.py index 80054a6..3b0ca06 100644 --- a/modules/web_api/routers/tasks.py +++ b/modules/web_api/routers/tasks.py @@ -3,19 +3,20 @@ FILE: modules/web_api/routers/tasks.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: web_api / routers -ROLE: REST API эндпоинты реестра задач (получение, создание и обновление). +ROLE: REST API эндпоинты реестра задач. =============================================================================== """ -from fastapi import APIRouter, Depends, HTTPException, Request +from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from typing import Optional, Dict, Any from routers.auth import get_current_user -from llm.db_tools import db_get_tasks, db_add_task, db_update_task_details +from services.tasks.service import get_tasks, add_task, update_task_details router = APIRouter(prefix="/api/v1/tasks", tags=["Tasks"]) + class TaskCreateRequest(BaseModel): title: str priority: Optional[str] = "MEDIUM" @@ -23,6 +24,7 @@ class TaskCreateRequest(BaseModel): due_date: Optional[str] = None status: Optional[str] = "BACKLOG" + class TaskUpdateRequest(BaseModel): title: Optional[str] = None priority: Optional[str] = None @@ -31,7 +33,6 @@ class TaskUpdateRequest(BaseModel): def resolve_user_id(current_user: Dict[str, Any]) -> int: - """Извлекает корректный ID пользователя из JWT payload или ставит дефолтный 1.""" if not current_user: return 1 return current_user.get("id") or current_user.get("user_id") or 1 @@ -40,13 +41,13 @@ def resolve_user_id(current_user: Dict[str, Any]) -> int: @router.get("") async def get_tasks_endpoint(status: Optional[str] = None, current_user = Depends(get_current_user)): user_id = resolve_user_id(current_user) - return {"tasks": db_get_tasks(user_id=user_id, status=status)} + return {"tasks": get_tasks(user_id=user_id, status=status)} @router.post("") async def create_task_endpoint(req: TaskCreateRequest, current_user = Depends(get_current_user)): user_id = resolve_user_id(current_user) - res = db_add_task( + res = add_task( user_id=user_id, module=req.module, title=req.title, @@ -62,7 +63,7 @@ async def create_task_endpoint(req: TaskCreateRequest, current_user = Depends(ge @router.patch("/{task_id}") async def update_task_endpoint(task_id: str, req: TaskUpdateRequest, current_user = Depends(get_current_user)): user_id = resolve_user_id(current_user) - res = db_update_task_details( + res = update_task_details( user_id=user_id, task_id=task_id, title=req.title, diff --git a/project_code_snapshot.md b/project_code_snapshot.md index f36017d..2358265 100644 --- a/project_code_snapshot.md +++ b/project_code_snapshot.md @@ -117,251 +117,70 @@ def load_exceptions(): ## File: `./main_etl.py` ```py -import os +""" +=============================================================================== +FILE: main_etl.py +PROJECT: SCUD Orion AI (Unified Architecture) +ROLE: Главная CLI-точка входа для запуска ежедневного контроллинга СКУД ⟷ 1С. + +AI-CONTEXT-ANCHORS: + - ANCHOR[MAIN_CLI_ENTRY]: Парсинг CLI-флагов и запуск конвейера. +=============================================================================== +""" + import sys -import json import argparse -import pandas as pd -from datetime import datetime, timedelta - -sys.path.append(os.path.dirname(os.path.abspath(__file__))) - -from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR, DATA_DIR, normalize_fio -from services.scud_export import run_export +from datetime import datetime +from core.database import init_db, get_latest_snapshot_time from services.share_copier import copy_1c_files_from_share from services.data_validator import check_file_freshness -from services.data_loader import load_1c_data_smart, load_scud_data -from services.excel_exporter import generate_summary_excel, generate_detailed_excel -from services.ai_verifier import ai_verify_scud_against_staff, analyze_scud_mass_failure_ai -from services.text_reporter import generate_markdown_report -from services.feedback_loop import review_ai_decisions -from services.knowledge_base import load_knowledge_base -from core.database import ( - init_db, - save_scud_to_db, - save_staff_to_db, - save_absences_to_db, - save_anomalies_to_db, - load_scud_from_db_by_snapshot, - load_staff_from_db, - load_absences_from_db, - get_latest_snapshot_time, - has_scud_logs_for_date -) - - -def load_exceptions_config(): - """Загружает файл exceptions.json из корня проекта.""" - root_dir = os.path.dirname(os.path.abspath(__file__)) - json_path = os.path.join(root_dir, "exceptions.json") - if not os.path.exists(json_path): - return {} - try: - with open(json_path, 'r', encoding='utf-8') as f: - return json.load(f) - except Exception as e: - print(f"[⚠️] Ошибка чтения exceptions.json: {e}") - return {} - - -def apply_exceptions_from_json(df, exceptions_cfg): - """ - Быстрая и эффективная разметка флага is_excluded=True на основе exceptions.json. - Выполняется мгновенно без цикличных HTTP-запросов к ИИ. - """ - if df is None or df.empty or not exceptions_cfg: - if df is not None: - df['is_excluded'] = False - return df - - deps = [d.strip().lower() for d in exceptions_cfg.get("departments", []) if d] - exact_pos = [p.strip().lower() for p in exceptions_cfg.get("positions", []) if p] - pos_kw = [k.strip().lower() for k in exceptions_cfg.get("position_keywords", []) if k] - exc_fios = [normalize_fio(f) for f in exceptions_cfg.get("fio", []) if f] - - df['is_excluded'] = False - - for idx, row in df.iterrows(): - fio_clean = row.get('fio_clean', '') - dep_1c = str(row.get('Подразделение', '')).lower() - dep_scud = str(row.get('department_scud', row.get('department', ''))).lower() - pos = str(row.get('Должность', '')).lower() - - is_fio_exc = fio_clean in exc_fios - is_pos_exc = (pos in exact_pos) or any(k in pos for k in pos_kw if k) if pos else False - - # Быстрая проверка отделов по подстрокам - is_dep_exc = False - if deps: - is_dep_exc = any(d in dep_1c or d in dep_scud for d in deps) - - if is_fio_exc or is_dep_exc or is_pos_exc: - df.at[idx, 'is_excluded'] = True - - return df - - -def filter_report_dataframe(merged_df): - """ - Исключает сотрудников из списка исключений и сотрудников без пропуска из детального отчета, - ЕСЛИ у них нет официального документа отсутствия из 1С:ЗУП. - """ - if merged_df is None or merged_df.empty: - return merged_df - - has_1c_reason = ( - merged_df['Вид_отсутствия'].notna() & - (merged_df['Вид_отсутствия'].astype(str).str.strip() != '') & - (~merged_df['Вид_отсутствия'].astype(str).str.startswith('Исключение')) - ) - is_not_excluded = merged_df.get('is_excluded', False) == False - is_not_no_pass = merged_df.get('no_scud_pass', False) == False - - filtered_df = merged_df[(is_not_excluded & is_not_no_pass) | has_1c_reason].copy() - return filtered_df - - -def load_static_reason_workers(): - """Загружает реестр удалёнщиков и статических причин из CSV.""" - static_path = os.path.join(DATA_DIR, "static_reason_workers.csv") - if not os.path.exists(static_path): - return {} - try: - df_static = pd.read_csv(static_path, encoding='utf-8') - if 'fio' in df_static.columns and 'reason' in df_static.columns: - df_static['fio_clean'] = df_static['fio'].apply(normalize_fio) - return dict(zip(df_static['fio_clean'], df_static['reason'])) - except Exception as e: - print(f"[⚠️] Ошибка чтения static_reason_workers.csv: {e}") - return {} - - -def detect_all_anomalies(merged_df, static_reasons_dict, kb_rules, scud_fios_set=None): - """ - Автоматически выявляет истинные аномалии СКУД ⟷ 1С. - """ - anomalies = [] - kb_rules_text = " ".join(kb_rules).lower() if kb_rules else "" - - ALLOWED_WORK_TRIP_KEYWORDS = ['командировк', 'разъездн', 'поездк'] - - for idx, row in merged_df.iterrows(): - fio = row.get('Сотрудник', row.get('fio_clean', '')) - fio_clean = row.get('fio_clean', '') - is_present = row.get('Пришел', False) - is_exc = row.get('is_excluded', False) - reason_1c = str(row.get('Вид_отсутствия', '')).strip() - has_1c_reason = pd.notna(row.get('Вид_отсутствия')) and reason_1c != '' and not reason_1c.startswith('Исключение') - anom_flag = row.get('anomaly_flag', 'NONE') - - is_fio_whitelisted_in_kb = fio_clean.lower() in kb_rules_text - - if is_present and has_1c_reason: - reason_lower = reason_1c.lower() - is_allowed_trip = any(kw in reason_lower for kw in ALLOWED_WORK_TRIP_KEYWORDS) - - if not is_allowed_trip and not is_fio_whitelisted_in_kb: - anomalies.append({ - "type": "ФИЗИЧЕСКОЕ ПРИСУТСТВИЕ ПРИ ОФИЦИАЛЬНОМ ОТСУТСТВИИ", - "fio": fio, - "details": f"Сотрудник пришел по СКУД, но в 1С оформлен документ: '{reason_1c}'" - }) - - if is_exc and not has_1c_reason: - continue - - if anom_flag == 'ANOMALY_NO_IN_HAS_ACTIVITY': - first_act = row.get('Первая_активность', '—') - anomalies.append({ - "type": "АНОМАЛИЯ СКУД: ПЕРЕМЕЩЕНИЕ БЕЗ ВХОДА", - "fio": fio, - "details": f"Отсутствует регистрация входа на КПП при зафиксированной первой активности в {first_act}" - }) - - if scud_fios_set is not None: - if fio_clean not in scud_fios_set and not has_1c_reason: - anomalies.append({ - "type": "АНОМАЛИЯ УЧЕТА: СОТРУДНИК ОТСУТСТВУЕТ В СКУД ОРИОН PRO", - "fio": fio, - "details": f"Сотрудник числится в Штатном расписании 1С ({row.get('Подразделение', '—')}), но полностью отсутствует в базе СКУД Орион Pro (профиль не создан или карта не выдана)" - }) - - return anomalies - - -def aggregate_scud_by_employee(df, debug=False): - """Агрегирует проходы СКУД по уникальным сотрудникам.""" - if df is None or df.empty or 'fio_clean' not in df.columns: - return df - - aggregated = [] - for fio_clean, group in df.groupby('fio_clean', sort=False): - is_present = group['Пришел'].any() if 'Пришел' in group.columns else False - - if is_present and 'Пришел' in group.columns: - present_rows = group[group['Пришел'] == True] - best_row = present_rows.iloc[0].to_dict() if not present_rows.empty else group.iloc[0].to_dict() - else: - best_row = group.iloc[0].to_dict() - - best_row['Пришел'] = is_present - aggregated.append(best_row) - - return pd.DataFrame(aggregated) +from services.scud_export import run_export +from services.scud_etl.pipeline import run_controlling_pipeline +# ANCHOR[MAIN_CLI_ENTRY] def main(): help_text = """ -Система автоматизированного контроллинга СКУД ⟷ 1С:ЗУП (scud_orion_ai_v2) +Система автоматизированного контроллинга СКУД ⟷ 1С:ЗУП (scud_orion_ai) ПРИМЕРЫ ЗАПУСКА: - python main.py -- Обычный дневной запуск - python main.py --skip-export -- Расчет отчета по ПОСЛЕДНЕМУ имеющемуся снапшоту из SQLite - python main.py --snapshot 20260805-001 -- Расчет отчета строго по ID снапшота - python main.py -d -- Запуск в режиме расширенной отладки (DEBUG) + python main_etl.py -- Обычный дневной запуск + python main_etl.py --skip-export -- Расчет отчета по ПОСЛЕДНЕМУ имеющемуся снапшоту из SQLite + python main_etl.py --snapshot 20260820-001 -- Расчет отчета строго по ID снапшота + python main_etl.py -d -- Запуск в режиме расширенной отладки (DEBUG) """ - parser = argparse.ArgumentParser( - description=help_text, - formatter_class=argparse.RawDescriptionHelpFormatter - ) - parser.add_argument('-d', '--debug', action='store_true', help="Запуск в режиме отладки с выводом подробных логов") - parser.add_argument('--skip-export', action='store_true', help="Пропустить выгрузку СКУД из MS SQL и построить отчет по последнему снапшоту") - parser.add_argument('--snapshot', type=str, default=None, help="Составной ID снапшота или время создания") + parser = argparse.ArgumentParser(description=help_text, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('-d', '--debug', action='store_true', help="Режим отладки (DEBUG)") + parser.add_argument('--skip-export', action='store_true', help="Расчет отчета по последнему снапшоту из SQLite") + parser.add_argument('--snapshot', type=str, default=None, help="ID конкретного снапшота") args = parser.parse_args() - DEBUG = args.debug - print("=" * 60) - print(f"ЗАПУСК СИСТЕМЫ МОДУЛЬНОГО КОНТРОЛЛИНГА СКУД ⟷ 1С {'[DEBUG MODE]' if DEBUG else ''}") + print(f"ЗАПУСК СИСТЕМЫ МОДУЛЬНОГО КОНТРОЛЛИНГА СКУД ⟷ 1С {'[DEBUG MODE]' if args.debug else ''}") print("=" * 60) init_db() - kb_data = load_knowledge_base() - kb_rules = kb_data.get("rules", []) - exceptions_cfg = load_exceptions_config() + # Определение режима работы и вывод статусов if args.snapshot: - snapshot_param = args.snapshot - print(f"[📸] РЕЖИМ СНАПШОТА: Расчет отчета строго по срезу '{snapshot_param}'") + print(f"[📸] РЕЖИМ СНАПШОТА: Расчет отчета строго по срезу '{args.snapshot}'") elif args.skip_export: - snapshot_param = get_latest_snapshot_time() - print(f"[📸] РЕЖИМ --skip-export: Используем последний снапшот из SQLite ('{snapshot_param}')") + last_snap = get_latest_snapshot_time() + print(f"[📸] РЕЖИМ --skip-export: Используем последний снапшот из SQLite ('{last_snap}')") else: - snapshot_param = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - print(f"[📸] СФОРМИРОВАН НОВЫЙ СНАПШОТ: '{snapshot_param}'") + current_snap = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[📸] СФОРМИРОВАН НОВЫЙ СНАПШОТ: '{current_snap}'") + has_today_1c = True + + # Прямой экспорт и проверка сетевой шары (если не режим снапшотов) if not args.skip_export and not args.snapshot: try: - run_export(save_xlsx=True, debug=DEBUG) + run_export(save_xlsx=True, debug=args.debug) except Exception as e: - print(f"[⚠️] Ошибка автоэкспорта из БД: {e}. Переходим к записям в SQLite.") - else: - print("[0/5] Пропуск прямого экспорта из MS SQL (чтение из базы SQLite)...") + print(f"[⚠️] Ошибка автоэкспорта из MS SQL: {e}. Переходим к записям SQLite.") - # ⚡️ ПРОВЕРКА ШАРЫ ТОЛЬКО ДЛЯ ОБЫЧНОГО ДНЕВНОГО ЗАПУСКА - if not args.snapshot and not args.skip_export: copy_1c_files_from_share() - print("[1/5] Проверка актуальности и свежести входных данных...") is_valid, warnings, errors, has_today_1c = check_file_freshness() @@ -372,319 +191,22 @@ def main(): print("-" * 45) if not is_valid: - print("\n" + "!" * 60) - print("🛑 ОСТАНОВКА ВЫПОЛНЕНИЯ: Отсутствуют критически важные файлы за вчерашний день!") + print("🛑 ОСТАНОВКА: Отсутствуют критически важные файлы за вчера!") for e in errors: print(f" {e}") - print("!" * 60) sys.exit(1) - print("[✓] Проверка доступности данных успешно пройдена!\n") else: + print("[0/5] Пропуск прямого экспорта из MS SQL (чтение из базы SQLite)...") print("[1/5] Пропуск проверки сетевой шары (все данные читаются из SQLite)...") - has_today_1c = True - print("[2/5] Загрузка данных из СКУД, 1С:ЗУП, реестра причин и исключений...") - - # 🎯 ВЫЧИСЛЕНИЕ ДАТ СНАПШОТА И ДАТ НАКАНУНЕ - if args.snapshot or args.skip_export: - raw_scud_today_df = load_scud_from_db_by_snapshot(None, snapshot_param=snapshot_param) - - if not raw_scud_today_df.empty and 'log_date' in raw_scud_today_df.columns: - target_date_str = str(raw_scud_today_df['log_date'].iloc[0]) - else: - target_date_str = DATE_TODAY - - dt_target = datetime.strptime(target_date_str, "%d.%m.%Y") - if dt_target.weekday() == 0: # Понедельник -> Пятница - dt_yesterday = dt_target - timedelta(days=3) - else: - dt_yesterday = dt_target - timedelta(days=1) - yesterday_date_str = dt_yesterday.strftime("%d.%m.%Y") - - print(f"[📸] СНАПШОТ ОПРЕДЕЛЕН: Целевая дата = {target_date_str}, Накануне = {yesterday_date_str}") - - raw_scud_yesterday_df = load_scud_from_db_by_snapshot(yesterday_date_str, snapshot_param=None) - - # Гарантированная загрузка кадров 1С за обе даты (БД + локальный фолбэк) - df_staff_today, df_absent_today = load_1c_data_smart(target_date_str, use_db=True) - df_staff_yesterday, df_absent_yesterday = load_1c_data_smart(yesterday_date_str, use_db=True) - else: - target_date_str = DATE_TODAY - yesterday_date_str = DATE_YESTERDAY - - raw_scud_today_df = load_scud_from_db_by_snapshot(target_date_str, snapshot_param=snapshot_param) - raw_scud_yesterday_df = load_scud_from_db_by_snapshot(yesterday_date_str, snapshot_param=None) - - df_staff_today, df_absent_today = load_1c_data_smart(DATE_TODAY, use_db=False) - df_staff_yesterday, df_absent_yesterday = load_1c_data_smart(DATE_YESTERDAY, use_db=False) - - if df_staff_yesterday is not None: - save_staff_to_db(df_staff_yesterday, yesterday_date_str) - if df_absent_yesterday is not None: - save_absences_to_db(df_absent_yesterday, yesterday_date_str) - - if df_staff_today is not None: - save_staff_to_db(df_staff_today, target_date_str) - if df_absent_today is not None: - save_absences_to_db(df_absent_today, target_date_str) - - staff_fios_yesterday_clean = df_staff_yesterday['fio_clean'].dropna().tolist() if df_staff_yesterday is not None else [] - static_reasons_dict = load_static_reason_workers() - - # ============================================================ - # 🎯 ЧАСТЬ 1: ДЕТАЛЬНЫЙ ОТЧЕТ ЗА ВЧЕРА (ДЕНЬ НАКАНУНЕ) - # ============================================================ - print(f"\n[3/5] Обработка и построение детального отчета за ВЧЕРА ({yesterday_date_str})...") - - if not raw_scud_yesterday_df.empty and 'Пришел' not in raw_scud_yesterday_df.columns: - raw_scud_yesterday_df['Пришел'] = raw_scud_yesterday_df['is_present'].astype(int) == 1 if 'is_present' in raw_scud_yesterday_df.columns else False - - scud_yesterday_unrecognized = raw_scud_yesterday_df[~raw_scud_yesterday_df['fio_clean'].isin(staff_fios_yesterday_clean)]['fio_clean'].tolist() if not raw_scud_yesterday_df.empty else [] - - fio_mapping_scud_y = ai_verify_scud_against_staff(scud_yesterday_unrecognized, staff_fios_yesterday_clean) - if fio_mapping_scud_y: - raw_scud_yesterday_df['fio_clean'] = raw_scud_yesterday_df['fio_clean'].apply( - lambda x: fio_mapping_scud_y[x]['staff_fio'] if x in fio_mapping_scud_y else x - ) - - if df_absent_yesterday is not None and not df_absent_yesterday.empty: - absent_unrecognized_yesterday = df_absent_yesterday[~df_absent_yesterday['fio_clean'].isin(staff_fios_yesterday_clean)]['fio_clean'].tolist() - if absent_unrecognized_yesterday: - fio_mapping_absent_y = ai_verify_scud_against_staff(absent_unrecognized_yesterday, staff_fios_yesterday_clean) - if fio_mapping_absent_y: - df_absent_yesterday['fio_clean'] = df_absent_yesterday['fio_clean'].apply( - lambda x: fio_mapping_absent_y[x]['staff_fio'] if x in fio_mapping_absent_y else x - ) - - raw_scud_yesterday_df = aggregate_scud_by_employee(raw_scud_yesterday_df, debug=DEBUG) - - # ⭐️ ФОРМИРУЕМ МЕРДЖ ИСКЛЮЧИТЕЛЬНО НА БАЗЕ ШТАТА ЗА ПРОШЛЫЙ ДЕНЬ - merged_yesterday = df_staff_yesterday.copy() if (df_staff_yesterday is not None and not df_staff_yesterday.empty) else (df_staff_today.copy() if df_staff_today is not None else pd.DataFrame()) - - if not merged_yesterday.empty: - if not raw_scud_yesterday_df.empty: - if 'Подразделение' in raw_scud_yesterday_df.columns: - raw_scud_yesterday_df['department_scud'] = raw_scud_yesterday_df['Подразделение'] - elif 'department' in raw_scud_yesterday_df.columns: - raw_scud_yesterday_df['department_scud'] = raw_scud_yesterday_df['department'] - else: - raw_scud_yesterday_df['department_scud'] = '' - - merged_yesterday = merged_yesterday.merge( - raw_scud_yesterday_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag', 'department_scud']], - on='fio_clean', how='left' - ) - - if 'Вид_отсутствия' in merged_yesterday.columns: - merged_yesterday = merged_yesterday.drop(columns=['Вид_отсутствия']) - - # Присоединяем отсутствия СТРОГО за дату yesterday_date_str - if df_absent_yesterday is not None and not df_absent_yesterday.empty: - merged_yesterday = merged_yesterday.merge( - df_absent_yesterday[['fio_clean', 'Вид_отсутствия']], - on='fio_clean', - how='left' - ) - - if 'Пришел' not in merged_yesterday.columns: - merged_yesterday['Пришел'] = False - else: - merged_yesterday['Пришел'] = merged_yesterday['Пришел'].fillna(False) - - if 'Сотрудник' not in merged_yesterday.columns: - merged_yesterday['Сотрудник'] = merged_yesterday.get('ФИО', merged_yesterday['fio_clean']) - - if static_reasons_dict: - for fio_clean, reason_val in static_reasons_dict.items(): - mask_yesterday = ( - (merged_yesterday['Пришел'] == False) & - (merged_yesterday['Вид_отсутствия'].isna() | (merged_yesterday['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_yesterday['fio_clean'] == fio_clean) - ) - merged_yesterday.loc[mask_yesterday, 'Вид_отсутствия'] = reason_val - - merged_yesterday = apply_exceptions_from_json(merged_yesterday, exceptions_cfg) - mask_exc_yesterday = ( - (merged_yesterday['Пришел'] == False) & - (merged_yesterday['Вид_отсутствия'].isna() | (merged_yesterday['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_yesterday.get('is_excluded', False) == True) + # Запуск конвейера + run_controlling_pipeline( + snapshot_param=args.snapshot, + skip_export=args.skip_export, + debug=args.debug, + has_today_1c=has_today_1c ) - merged_yesterday.loc[mask_exc_yesterday, 'Вид_отсутствия'] = 'Исключение (ОВК/Подрядчики)' - - scud_fios_yesterday_set = set(raw_scud_yesterday_df['fio_clean'].dropna().tolist()) if not raw_scud_yesterday_df.empty else set() - merged_yesterday['no_scud_pass'] = ( - (~merged_yesterday['fio_clean'].isin(scud_fios_yesterday_set)) & - (merged_yesterday['Вид_отсутствия'].isna() | (merged_yesterday['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_yesterday.get('is_excluded', False) == False) - ) - - anomalies_yesterday_list = detect_all_anomalies(merged_yesterday, static_reasons_dict, kb_rules, scud_fios_set=scud_fios_yesterday_set) - save_anomalies_to_db(anomalies_yesterday_list, yesterday_date_str) - - filtered_yesterday = filter_report_dataframe(merged_yesterday) - generate_detailed_excel(merged_df=filtered_yesterday, date_str=yesterday_date_str) - - yesterday_dt_obj = datetime.strptime(yesterday_date_str, "%d.%m.%Y") - yesterday_22_str = yesterday_dt_obj.strftime("%Y-%m-%d 22:00:00") - save_scud_to_db(merged_yesterday, yesterday_date_str, snapshot_time=yesterday_22_str, is_yesterday=True) - print(f"[✓] Детальный отчет за вчера сформирован и зафиксирован в SQLite за {yesterday_date_str}") - - # ============================================================ - # 🎯 ЧАСТЬ 2: ЕЖЕДНЕВНАЯ СВОДКА (ЗА ЦЕЛЕВОЙ ДЕНЬ СНАПШОТА) - # ============================================================ - if not args.snapshot and not args.skip_export: - save_scud_to_db(raw_scud_today_df, target_date_str, snapshot_time=snapshot_param, is_yesterday=False) - - if has_today_1c and df_staff_today is not None and df_absent_today is not None: - print(f"\n[4/5] Обработка и построение Ежедневной сводки за {target_date_str}...") - staff_fios_today_clean = df_staff_today['fio_clean'].dropna().tolist() - - if not raw_scud_today_df.empty and 'Пришел' not in raw_scud_today_df.columns: - raw_scud_today_df['Пришел'] = raw_scud_today_df['is_present'].astype(int) == 1 if 'is_present' in raw_scud_today_df.columns else False - - scud_unrecognized = raw_scud_today_df[~raw_scud_today_df['fio_clean'].isin(staff_fios_today_clean)]['fio_clean'].tolist() if not raw_scud_today_df.empty else [] - fio_mapping_scud = ai_verify_scud_against_staff(scud_unrecognized, staff_fios_today_clean) - if fio_mapping_scud: - raw_scud_today_df['fio_clean'] = raw_scud_today_df['fio_clean'].apply( - lambda x: fio_mapping_scud[x]['staff_fio'] if x in fio_mapping_scud else x - ) - - absent_unrecognized_today = df_absent_today[~df_absent_today['fio_clean'].isin(staff_fios_today_clean)]['fio_clean'].tolist() - if absent_unrecognized_today: - fio_mapping_absent = ai_verify_scud_against_staff(absent_unrecognized_today, staff_fios_today_clean) - if fio_mapping_absent: - df_absent_today['fio_clean'] = df_absent_today['fio_clean'].apply( - lambda x: fio_mapping_absent[x]['staff_fio'] if x in fio_mapping_absent else x - ) - - raw_scud_today_df = aggregate_scud_by_employee(raw_scud_today_df, debug=DEBUG) - - merged_today = df_staff_today.copy() - if not raw_scud_today_df.empty: - if 'Подразделение' in raw_scud_today_df.columns: - raw_scud_today_df['department_scud'] = raw_scud_today_df['Подразделение'] - elif 'department' in raw_scud_today_df.columns: - raw_scud_today_df['department_scud'] = raw_scud_today_df['department'] - else: - raw_scud_today_df['department_scud'] = '' - - merged_today = merged_today.merge( - raw_scud_today_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag', 'department_scud']], - on='fio_clean', how='left' - ) - - if df_absent_today is not None and not df_absent_today.empty: - merged_today = merged_today.merge(df_absent_today[['fio_clean', 'Вид_отсутствия']], on='fio_clean', how='left') - - if 'Пришел' not in merged_today.columns: - merged_today['Пришел'] = False - else: - merged_today['Пришел'] = merged_today['Пришел'].fillna(False) - - if 'Сотрудник' not in merged_today.columns: - merged_today['Сотрудник'] = merged_today.get('ФИО', merged_today['fio_clean']) - - if static_reasons_dict: - for fio_clean, reason_val in static_reasons_dict.items(): - mask_today = ( - (merged_today['Пришел'] == False) & - (merged_today['Вид_отсутствия'].isna() | (merged_today['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_today['fio_clean'] == fio_clean) - ) - merged_today.loc[mask_today, 'Вид_отсутствия'] = reason_val - - merged_today = apply_exceptions_from_json(merged_today, exceptions_cfg) - mask_exc_today = ( - (merged_today['Пришел'] == False) & - (merged_today['Вид_отсутствия'].isna() | (merged_today['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_today.get('is_excluded', False) == True) - ) - merged_today.loc[mask_exc_today, 'Вид_отсутствия'] = 'Исключение (ОВК/Подрядчики)' - - scud_fios_today_set = set(raw_scud_today_df['fio_clean'].dropna().tolist()) if not raw_scud_today_df.empty else set() - merged_today['no_scud_pass'] = ( - (~merged_today['fio_clean'].isin(scud_fios_today_set)) & - (merged_today['Вид_отсутствия'].isna() | (merged_today['Вид_отсутствия'].astype(str).str.strip() == '')) & - (merged_today.get('is_excluded', False) == False) - ) - - scud_fios_set = set(raw_scud_today_df['fio_clean'].dropna().tolist()) if not raw_scud_today_df.empty else set() - anomalies_list = detect_all_anomalies(merged_today, static_reasons_dict, kb_rules, scud_fios_set=scud_fios_set) - - mass_failure_today = analyze_scud_mass_failure_ai(raw_scud_today_df) - if mass_failure_today and mass_failure_today.get("is_mass_failure"): - print("\n" + "!" * 60) - print(f"🚨 ВНИМАНИЕ! ИИ ОБНАРУЖИЛ ОПЕРАТИВНЫЙ СБОЙ ТУРНИКЕТОВ ВХОДА СЕГОДНЯ ({mass_failure_today['anomaly_percent']}% СМЕНЫ)") - print(mass_failure_today["alert_text"]) - print("!" * 60 + "\n") - - save_anomalies_to_db(anomalies_list, target_date_str) - - is_no_pass_today = merged_today['no_scud_pass'] == True if 'no_scud_pass' in merged_today.columns else False - is_exc_today = merged_today.get('is_excluded', False) == True - - absent_explained = merged_today[ - (merged_today['Пришел'] == False) & - (merged_today['Вид_отсутствия'].notna()) & - (~merged_today['Вид_отсутствия'].astype(str).str.startswith('Исключение')) - ] - - absent_unexplained = merged_today[ - (merged_today['Пришел'] == False) & - (merged_today['Вид_отсутствия'].isna() | (merged_today['Вид_отсутствия'].astype(str).str.strip() == '')) & - (~is_no_pass_today) & - (~is_exc_today) - ] - - scud_present_but_absent_in_1c = merged_today[ - (~is_exc_today) & - (merged_today['Пришел'] == True) & - (merged_today['Вид_отсутствия'].notna()) & - (~merged_today['Вид_отсутствия'].astype(str).str.startswith('Исключение')) - ] - - print("[5/5] Запуск ИИ-аудитора и построение Ежедневной сводки...") - filtered_anomalies_list = [ - a for a in anomalies_list - if "ОТСУТСТВУЕТ В СКУД" not in a.get('type', '') - ] - - report_text = generate_markdown_report( - merged_df=merged_today, - absent_explained=absent_explained, - absent_unexplained=absent_unexplained, - scud_present_but_absent_in_1c=scud_present_but_absent_in_1c, - anomalies_list=filtered_anomalies_list, - raw_scud_df=raw_scud_today_df, - raw_absent_df=df_absent_today, - date_str=target_date_str - ) - - generate_summary_excel(merged_df=merged_today, date_str=target_date_str) - - md_report_path = os.path.join(OUTPUT_DIR, f"Сводка_контроллинга_{target_date_str}.md") - with open(md_report_path, "w", encoding="utf-8") as f: - f.write(report_text) - print(f"\n[✓] Текстовый отчет сохранен в: {md_report_path}") - - suspicious_cases = [] - for a in anomalies_list: - if "ОФИЦИАЛЬНОМ ОТСУТСТВИИ" not in a.get('type', ''): - suspicious_cases.append({ - 'fio_target': a['fio'], - 'reason': f"{a['type']}: {a['details']}" - }) - - if suspicious_cases: - review_ai_decisions(report_text, suspicious_cases) - - print("\n" + "=" * 60) - print("ГОТОВАЯ ТЕКСТОВАЯ СВОДКА ИИ-АУДИТОРА:") - print("=" * 60) - print(report_text) - else: - print(f"\n[ℹ️] Формирование Ежедневной сводки за {target_date_str} ПРОПУЩЕНО.") if __name__ == "__main__": @@ -1785,7 +1307,7 @@ def ai_verify_scud_against_staff(unrecognized_scud_fios, staff_fios): if not unrecognized_scud_fios or not staff_fios: return {} - # 🛡 Исключаем точные совпадения (чтобы ИИ не совершал ложных замен) + # Исключаем точные совпадения staff_fios_set = set(staff_fios) real_unrecognized = [f for f in unrecognized_scud_fios if f not in staff_fios_set] @@ -1797,7 +1319,7 @@ def ai_verify_scud_against_staff(unrecognized_scud_fios, staff_fios): prompt = f""" Ты — кадровый аудитор безопасности СКУД. {rules_context} -В СКУД записаны неопознанные ФИО: {json.dumps(unrecognized_scud_fios, ensure_ascii=False)} +В СКУД записаны неопознанные ФИО: {json.dumps(real_unrecognized, ensure_ascii=False)} В официальном Штатном расписании 1С записаны ЭТАЛОНЫ: {json.dumps(staff_fios, ensure_ascii=False)} СТРОГИЕ ПРАВИЛА: @@ -1807,40 +1329,59 @@ def ai_verify_scud_against_staff(unrecognized_scud_fios, staff_fios): 4. В поле "warning" опиши обнаруженную опечатку. 5. Запрещено выдумывать опечатки и объединять разных людей/однофамильцев! -ОТВЕЧАЙ ТОЛЬКО ИСКЛЮЧИТЕЛЬНО В ФОРМАТЕ JSON! - -Формат ответа: +ОТВЕЧАЙ ТОЛЬКО ИСКЛЮЧИТЕЛЬНО В ФОРМАТЕ ВАЛИДНОГО JSON: {{ "verified_matches": [ {{ "scud_fio": "ФИО из СКУД", "staff_fio": "эталон ФИО из Штат 1С", - "warning": "Описание опечатки в СКУД или 'Точное совпадение (без опечаток)'" + "warning": "Описание опечатки в СКУД" }} ] }} """ raw_response = ask_ollama( prompt, - system_prompt="Ты — JSON API. Выдавай ТОЛЬКО валидный JSON без markdown-разметки." + system_prompt="Ты — строгий JSON API генератор. Отвечай только валидным JSON объектом без пояснительного текста." ) mapping = {} + if not raw_response: + return mapping + + # Фаза 1: Попытка прямого разбора с санитарной очисткой try: match = re.search(r'\{.*\}', raw_response, re.DOTALL) if match: json_str = match.group(0) - json_str = re.sub(r'\}\s*[^}\]]*$', '}', json_str) + # Убираем висячие запятые: {"a": 1,} -> {"a": 1} + json_str = re.sub(r',\s*([\}\]])', r'\1', json_str) + # Заменяем одинарные кавычки в ключах/значениях на двойные при необходимости + json_str = re.sub(r"(?<=\{|\,)\s*'([^']+)'\s*:", r'"\1":', json_str) + data = json.loads(json_str) for item in data.get("verified_matches", []): scud_f = item.get("scud_fio") staff_f = item.get("staff_fio") warn = item.get("warning", "Точное совпадение (без опечаток)") - if scud_f and staff_f: + if scud_f and staff_f and staff_f in staff_fios_set: mapping[scud_f] = {"staff_fio": staff_f, "warning": warn} + return mapping + except Exception: + pass + + # Фаза 2: Резервный Regex-парсер (если JSON синтаксически сломан, но пары ключ-значение есть) + try: + pattern = r'["\']scud_fio["\']\s*:\s*["\']([^"\']+)["\'].*?["\']staff_fio["\']\s*:\s*["\']([^"\']+)["\']' + matches = re.findall(pattern, raw_response, re.DOTALL) + for scud_f, staff_f in matches: + scud_clean = scud_f.strip() + staff_clean = staff_f.strip() + if staff_clean in staff_fios_set: + mapping[scud_clean] = {"staff_fio": staff_clean, "warning": "Восстановлено парсером опечаток"} except Exception as e: - print(f"[!] Ошибка разбора JSON от ИИ при сверке опечаток: {e}") - + print(f"[!] Ошибка резервного парсинга опечаток: {e}") + return mapping @@ -3360,36 +2901,1305 @@ def sync_zup_to_excel(target_date) -> bool: return False ``` +## File: `./services/knowledge/__init__.py` +```py + +``` + +## File: `./services/knowledge/service.py` +```py +""" +=============================================================================== +FILE: services/knowledge/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / knowledge +ROLE: Доменный сервис базы знаний, правил компании и синонимов подразделений. +=============================================================================== +""" + +from typing import List, Dict, Any +from core.repositories.zup_repo import ( + get_all_rules_from_db, + add_rule_to_db, + get_department_synonyms_dict, + add_department_synonym_to_db +) + + +def get_rules() -> List[Dict[str, Any]]: + """Получить все правила базы знаний в виде списка словарей.""" + raw_rules = get_all_rules_from_db() + return [{"id": idx, "rule_text": r} for idx, r in enumerate(raw_rules, 1)] + + +def add_rule(rule_text: str, added_by: str = "Human") -> None: + """Добавить новое правило в базу знаний.""" + add_rule_to_db(rule_text, added_by=added_by) + + +def get_synonyms() -> Dict[str, str]: + """Получить словарь синонимов отделов.""" + return get_department_synonyms_dict() + + +def register_department_synonym(short_name: str, full_name: str) -> None: + """Сохранить новую пару синонимов подразделения.""" + add_department_synonym_to_db(short_name, full_name) +``` + +## File: `./services/prompts/__init__.py` +```py + +``` + +## File: `./services/prompts/diff_engine.py` +```py +""" +=============================================================================== +FILE: services/prompts/diff_engine.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / prompts +ROLE: Формирование превью изменений промпта и генерация визуального HTML-Diff. + +AI-CONTEXT-ANCHORS: + - ANCHOR[PROMPT_DIFF_BUILDER]: Генерация черновика и HTML-разметки изменений. +=============================================================================== +""" + +from typing import Tuple, Dict +from core.connection import get_connection + + +# ANCHOR[PROMPT_DIFF_BUILDER] +def build_prompt_diff(action: str, section_id: int, item_id: int, content: str = "", prompt_name: str = "main_agent") -> Tuple[str, str]: + """ + Возвращает кортеж (merged_draft_text, diff_html_for_ui). + """ + act = (action or "ADD").upper() + + with get_connection(row_factory=True) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT section_id, item_id, content + FROM system_prompt_nodes + WHERE prompt_name = ? AND is_active = 1 + ORDER BY section_id, item_id + """, (prompt_name,)) + existing_nodes = cursor.fetchall() + + nodes_dict = {(r["section_id"], r["item_id"]): r["content"] for r in existing_nodes} + + # Формируем словарь для чистого текста + nodes_dict_for_draft = {k: v for k, v in nodes_dict.items() if k != (section_id, item_id)} if act == "DELETE" else dict(nodes_dict) + if act != "DELETE": + nodes_dict_for_draft[(section_id, item_id)] = content + + draft_lines = [] + curr_sec = None + for (s_id, i_id), txt in sorted(nodes_dict_for_draft.items()): + if i_id == 0: + if curr_sec is not None: + draft_lines.append("") + draft_lines.append(f"{s_id}. {txt}") + curr_sec = s_id + else: + draft_lines.append(f" {s_id}.{i_id}. {txt}") + merged_prompt = "\n".join(draft_lines) + + # Формируем HTML Diff + diff_lines = [] + curr_sec = None + display_nodes = dict(nodes_dict) + if act != "DELETE": + display_nodes[(section_id, item_id)] = content + + for (s_id, i_id), txt in sorted(display_nodes.items()): + if i_id == 0: + if curr_sec is not None: + diff_lines.append("") + diff_lines.append(f"{s_id}. {txt}") + curr_sec = s_id + else: + if s_id == section_id and i_id == item_id: + if act == "DELETE": + line_str = f' {s_id}.{i_id}. {txt} [УДАЛЕНИЕ]' + else: + line_str = f' {s_id}.{i_id}. {txt}' + else: + line_str = f" {s_id}.{i_id}. {txt}" + diff_lines.append(line_str) + + diff_html = "\n".join(diff_lines) + return merged_prompt, diff_html +``` + +## File: `./services/prompts/repository.py` +```py +""" +=============================================================================== +FILE: services/prompts/repository.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / prompts +ROLE: Реляционное хранилище узлов системного промпта (таблица system_prompt_nodes). + +AI-CONTEXT-ANCHORS: + - ANCHOR[PROMPT_REPO_GET_ACTIVE]: Сборка активного промпта из узлов БД. + - ANCHOR[PROMPT_REPO_APPLY_ACTION]: Точечная вставка / изменение / удаление узла. +=============================================================================== +""" + +import re +import logging +from typing import List, Tuple, Dict, Any +from core.connection import get_connection + +logger = logging.getLogger("PROMPT_REPO") + + +# ANCHOR[PROMPT_REPO_GET_ACTIVE] +def repo_get_active_prompt(prompt_name: str = "main_agent") -> str: + """Собирает структурированный текст системного промпта из активных узлов.""" + with get_connection(row_factory=True) as conn: + cursor = conn.cursor() + cursor.execute(""" + SELECT section_id, item_id, content + FROM system_prompt_nodes + WHERE prompt_name = ? AND is_active = 1 + ORDER BY section_id ASC, item_id ASC + """, (prompt_name,)) + rows = cursor.fetchall() + + if not rows: + return "Ты — ИИ-ассистент SCUD Orion AI." + + lines = [] + current_section = None + + for r in rows: + sec_id = r["section_id"] + itm_id = r["item_id"] + content = r["content"] + + if itm_id == 0: + if current_section is not None: + lines.append("") + lines.append(f"{sec_id}. {content}") + current_section = sec_id + else: + lines.append(f" {sec_id}.{itm_id}. {content}") + + return "\n".join(lines) + + +# ANCHOR[PROMPT_REPO_APPLY_ACTION] +def repo_apply_prompt_action(action: str, section_id: int, item_id: int, content: str = "", prompt_name: str = "main_agent") -> None: + """Точечно применяет действие (ADD / UPDATE / DELETE) над узлом промпта.""" + with get_connection() as conn: + cursor = conn.cursor() + action_clean = (action or "").upper() + if action_clean in ["ADD", "UPDATE", "EDIT"]: + cursor.execute(""" + INSERT INTO system_prompt_nodes (prompt_name, section_id, item_id, content, is_active, updated_at) + VALUES (?, ?, ?, ?, 1, CURRENT_TIMESTAMP) + ON CONFLICT(prompt_name, section_id, item_id) DO UPDATE SET + content = excluded.content, + is_active = 1, + updated_at = CURRENT_TIMESTAMP + """, (prompt_name, section_id, item_id, content)) + elif action_clean == "DELETE": + cursor.execute(""" + DELETE FROM system_prompt_nodes + WHERE prompt_name = ? AND section_id = ? AND item_id = ? + """, (prompt_name, section_id, item_id)) + conn.commit() + + +def repo_save_full_prompt(prompt_text: str, prompt_name: str = "main_agent") -> None: + """Парсит и полностью перезаписывает все узлы промпта из сырого текста.""" + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("DELETE FROM system_prompt_nodes WHERE prompt_name = ?", (prompt_name,)) + + current_sec = 1 + current_itm = 0 + + for raw_line in prompt_text.splitlines(): + clean_line = re.sub(r'<[^>]+>', '', raw_line).strip() + if not clean_line: + continue + + sub_match = re.match(r'^(\d+)[\.\s]+(\d+)[\.\s\:\-]+(.*)$', clean_line) + sec_match = re.match(r'^(\d+)[\.\s\:\-]+(.*)$', clean_line) + + if sub_match: + current_sec = int(sub_match.group(1)) + current_itm = int(sub_match.group(2)) + content = sub_match.group(3).strip() + elif sec_match and not any(c.islower() for c in sec_match.group(2)[:15]): + current_sec = int(sec_match.group(1)) + current_itm = 0 + content = sec_match.group(2).strip() + else: + current_itm += 1 + content = clean_line + + cursor.execute(""" + INSERT OR REPLACE INTO system_prompt_nodes (prompt_name, section_id, item_id, content, is_active) + VALUES (?, ?, ?, ?, 1) + """, (prompt_name, current_sec, current_itm, content)) + + conn.commit() +``` + +## File: `./services/prompts/service.py` +```py +""" +=============================================================================== +FILE: services/prompts/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / prompts +ROLE: Единый доменный сервис управления системным промптом. +=============================================================================== +""" + +from typing import Tuple, Dict, Any +from .repository import repo_get_active_prompt, repo_apply_prompt_action, repo_save_full_prompt +from .diff_engine import build_prompt_diff + + +def get_active_system_prompt() -> str: + """Получить текущий активный системный промпт.""" + return repo_get_active_prompt() + + +def apply_prompt_action(action: str, section_id: int, item_id: int, content: str = "") -> None: + """Применить точечное изменение к узлу промпта.""" + repo_apply_prompt_action(action, section_id, item_id, content) + + +def save_full_prompt_draft(draft_text: str) -> None: + """Сохранить полный черновик промпта.""" + repo_save_full_prompt(draft_text) + + +def create_prompt_preview(action: str, section_id: int, item_id: int, content: str = "") -> Tuple[str, str, str]: + """ + Формирует черновик и diff. + Возвращает (merged_draft, diff_html, baseline_prompt). + """ + baseline = repo_get_active_prompt() + draft, diff_html = build_prompt_diff(action, section_id, item_id, content) + return draft, diff_html, baseline +``` + +## File: `./services/scud_etl/__init__.py` +```py + +``` + +## File: `./services/scud_etl/anomaly_detector.py` +```py +""" +=============================================================================== +FILE: services/scud_etl/anomaly_detector.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / scud_etl +ROLE: Автоматическое выявление аномалий и конфликтов между 1С:ЗУП и СКУД. + +AI-CONTEXT-ANCHORS: + - ANCHOR[ANOMALY_DETECTOR_CORE]: Проверка физического присутствия в отпуске и перемещений без входа. +=============================================================================== +""" + +import pandas as pd +from typing import List, Dict, Any, Optional + +ALLOWED_WORK_TRIP_KEYWORDS = ['командировк', 'разъездн', 'поездк'] + + +# ANCHOR[ANOMALY_DETECTOR_CORE] +def detect_all_anomalies( + merged_df: pd.DataFrame, + static_reasons_dict: dict, + kb_rules: List[str], + scud_fios_set: Optional[set] = None +) -> List[Dict[str, Any]]: + """Выявляет конфликты и аномалии между источниками СКУД и 1С.""" + anomalies = [] + kb_rules_text = " ".join(kb_rules).lower() if kb_rules else "" + + for idx, row in merged_df.iterrows(): + fio = row.get('Сотрудник', row.get('fio_clean', '')) + fio_clean = row.get('fio_clean', '') + is_present = row.get('Пришел', False) + is_exc = row.get('is_excluded', False) + reason_1c = str(row.get('Вид_отсутствия', '')).strip() + has_1c_reason = pd.notna(row.get('Вид_отсутствия')) and reason_1c != '' and not reason_1c.startswith('Исключение') + anom_flag = row.get('anomaly_flag', 'NONE') + + is_fio_whitelisted = fio_clean.lower() in kb_rules_text + + # 1. Присутствие при официальном отсутствии + if is_present and has_1c_reason: + is_allowed_trip = any(kw in reason_1c.lower() for kw in ALLOWED_WORK_TRIP_KEYWORDS) + if not is_allowed_trip and not is_fio_whitelisted: + anomalies.append({ + "type": "ФИЗИЧЕСКОЕ ПРИСУТСТВИЕ ПРИ ОФИЦИАЛЬНОМ ОТСУТСТВИИ", + "fio": fio, + "details": f"Сотрудник пришел по СКУД, но в 1С оформлен документ: '{reason_1c}'" + }) + + if is_exc and not has_1c_reason: + continue + + # 2. Перемещение внутри здания без отметки входа на КПП + if anom_flag == 'ANOMALY_NO_IN_HAS_ACTIVITY': + first_act = row.get('Первая_активность', '—') + anomalies.append({ + "type": "АНОМАЛИЯ СКУД: ПЕРЕМЕЩЕНИЕ БЕЗ ВХОДА", + "fio": fio, + "details": f"Отсутствует регистрация входа на КПП при зафиксированной первой активности в {first_act}" + }) + + # 3. Сотрудник в штате 1С, но карты/профиля в СКУД нет + if scud_fios_set is not None: + if fio_clean not in scud_fios_set and not has_1c_reason: + anomalies.append({ + "type": "АНОМАЛИЯ УЧЕТА: СОТРУДНИК ОТСУТСТВУЕТ В СКУД ОРИОН PRO", + "fio": fio, + "details": f"Сотрудник числится в Штатном расписании 1С ({row.get('Подразделение', '—')}), но отсутствует в СКУД" + }) + + return anomalies +``` + +## File: `./services/scud_etl/merger.py` +```py +""" +=============================================================================== +FILE: services/scud_etl/merger.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / scud_etl +ROLE: Агрегация проходов, сопоставление исключений и мердж таблиц 1С:ЗУП и СКУД. + +AI-CONTEXT-ANCHORS: + - ANCHOR[MERGER_EXCEPTIONS]: Наложение флага исключений из exceptions.json. + - ANCHOR[MERGER_AGGREGATION]: Агрегация множественных проходов до уникального ФИО. + - ANCHOR[MERGER_BUILD_DATASET]: Сборка итогового датасета для сводок и отчетов. +=============================================================================== +""" + +import os +import json +import pandas as pd +from config import normalize_fio, DATA_DIR + + +# ANCHOR[MERGER_EXCEPTIONS] +def load_exceptions_config() -> dict: + """Загружает exceptions.json из корня проекта.""" + root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) + json_path = os.path.join(root_dir, "exceptions.json") + if not os.path.exists(json_path): + return {} + try: + with open(json_path, 'r', encoding='utf-8') as f: + return json.load(f) + except Exception: + return {} + + +def apply_exceptions_from_json(df: pd.DataFrame, exceptions_cfg: dict) -> pd.DataFrame: + """Быстрая разметка флага is_excluded на основе exceptions.json.""" + if df is None or df.empty or not exceptions_cfg: + if df is not None: + df['is_excluded'] = False + return df + + deps = [d.strip().lower() for d in exceptions_cfg.get("departments", []) if d] + exact_pos = [p.strip().lower() for p in exceptions_cfg.get("positions", []) if p] + pos_kw = [k.strip().lower() for k in exceptions_cfg.get("position_keywords", []) if k] + exc_fios = [normalize_fio(f) for f in exceptions_cfg.get("fio", []) if f] + + df['is_excluded'] = False + + for idx, row in df.iterrows(): + fio_clean = row.get('fio_clean', '') + dep_1c = str(row.get('Подразделение', '')).lower() + dep_scud = str(row.get('department_scud', row.get('department', ''))).lower() + pos = str(row.get('Должность', '')).lower() + + is_fio_exc = fio_clean in exc_fios + is_pos_exc = (pos in exact_pos) or any(k in pos for k in pos_kw if k) if pos else False + is_dep_exc = any(d in dep_1c or d in dep_scud for d in deps) if deps else False + + if is_fio_exc or is_dep_exc or is_pos_exc: + df.at[idx, 'is_excluded'] = True + + return df + + +# ANCHOR[MERGER_AGGREGATION] +def aggregate_scud_by_employee(df: pd.DataFrame) -> pd.DataFrame: + """Агрегирует проходы СКУД по уникальным сотрудникам.""" + if df is None or df.empty or 'fio_clean' not in df.columns: + return df + + aggregated = [] + for fio_clean, group in df.groupby('fio_clean', sort=False): + is_present = group['Пришел'].any() if 'Пришел' in group.columns else False + if is_present and 'Пришел' in group.columns: + present_rows = group[group['Пришел'] == True] + best_row = present_rows.iloc[0].to_dict() if not present_rows.empty else group.iloc[0].to_dict() + else: + best_row = group.iloc[0].to_dict() + + best_row['Пришел'] = is_present + aggregated.append(best_row) + + return pd.DataFrame(aggregated) + + +def filter_report_dataframe(merged_df: pd.DataFrame) -> pd.DataFrame: + """Исключает подрядчиков и сотрудников без пропуска из детального отчета.""" + if merged_df is None or merged_df.empty: + return merged_df + + has_1c_reason = ( + merged_df['Вид_отсутствия'].notna() & + (merged_df['Вид_отсутствия'].astype(str).str.strip() != '') & + (~merged_df['Вид_отсутствия'].astype(str).str.startswith('Исключение')) + ) + is_not_excluded = merged_df.get('is_excluded', False) == False + is_not_no_pass = merged_df.get('no_scud_pass', False) == False + + return merged_df[(is_not_excluded & is_not_no_pass) | has_1c_reason].copy() + + +def load_static_reason_workers() -> dict: + """Загружает реестр удаленщиков из CSV.""" + static_path = os.path.join(DATA_DIR, "static_reason_workers.csv") + if not os.path.exists(static_path): + return {} + try: + df_static = pd.read_csv(static_path, encoding='utf-8') + if 'fio' in df_static.columns and 'reason' in df_static.columns: + df_static['fio_clean'] = df_static['fio'].apply(normalize_fio) + return dict(zip(df_static['fio_clean'], df_static['reason'])) + except Exception: + pass + return {} +``` + +## File: `./services/scud_etl/pipeline.py` +```py +""" +=============================================================================== +FILE: services/scud_etl/pipeline.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / scud_etl +ROLE: Оркестратор этапов контроллинга (Загрузка -> Сверка -> Отчеты -> SQLite). + +AI-CONTEXT-ANCHORS: + - ANCHOR[PIPELINE_RUN_CONTROLLING]: Главная функция выполнения ETL-конвейера. +=============================================================================== +""" + +import os +from datetime import datetime, timedelta +import pandas as pd + +from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR +from core.database import ( + save_scud_to_db, save_staff_to_db, save_absences_to_db, + save_anomalies_to_db, load_scud_from_db_by_snapshot, get_latest_snapshot_time +) +from services.data_loader import load_1c_data_smart +from services.excel_exporter import generate_summary_excel, generate_detailed_excel +from services.ai_verifier import ai_verify_scud_against_staff, analyze_scud_mass_failure_ai +from services.text_reporter import generate_markdown_report +from services.feedback_loop import review_ai_decisions +from services.knowledge_base import load_knowledge_base + +from .merger import ( + load_exceptions_config, apply_exceptions_from_json, + aggregate_scud_by_employee, filter_report_dataframe, load_static_reason_workers +) +from .anomaly_detector import detect_all_anomalies + + +# ANCHOR[PIPELINE_RUN_CONTROLLING] +def run_controlling_pipeline(snapshot_param: str = None, skip_export: bool = False, debug: bool = False, has_today_1c: bool = True) -> None: + """Выполняет полный цикл сверки СКУД ⟷ 1С и сохранение результатов.""" + kb_rules = load_knowledge_base().get("rules", []) + exceptions_cfg = load_exceptions_config() + static_reasons = load_static_reason_workers() + + print("[2/5] Загрузка данных из СКУД, 1С:ЗУП, реестра причин и исключений...") + + # 1. Определение дат целевого снапшота и предыдущей смены + if snapshot_param or skip_export: + snap_to_use = snapshot_param or get_latest_snapshot_time() + raw_scud_today_df = load_scud_from_db_by_snapshot(None, snapshot_param=snap_to_use) + if not raw_scud_today_df.empty and 'log_date' in raw_scud_today_df.columns: + target_date_str = str(raw_scud_today_df['log_date'].iloc[0]) + else: + target_date_str = DATE_TODAY + else: + target_date_str = DATE_TODAY + raw_scud_today_df = load_scud_from_db_by_snapshot(target_date_str, snapshot_param=snapshot_param) + + dt_target = datetime.strptime(target_date_str, "%d.%m.%Y") + dt_yesterday = dt_target - timedelta(days=3 if dt_target.weekday() == 0 else 1) + yesterday_date_str = dt_yesterday.strftime("%d.%m.%Y") + + print(f"[📸] СНАПШОТ ОПРЕДЕЛЕН: Целевая дата = {target_date_str}, Накануне = {yesterday_date_str}\n") + + raw_scud_yesterday_df = load_scud_from_db_by_snapshot(yesterday_date_str, snapshot_param=None) + df_staff_yesterday, df_absent_yesterday = load_1c_data_smart(yesterday_date_str, use_db=True) + df_staff_today, df_absent_today = load_1c_data_smart(target_date_str, use_db=True) + + # 2. Этап 3: Обработка ВЧЕРА (Детальный отчет) + print(f"[3/5] Обработка и построение детального отчета за ВЧЕРА ({yesterday_date_str})...") + + if df_staff_yesterday is not None: + save_staff_to_db(df_staff_yesterday, yesterday_date_str) + if df_absent_yesterday is not None: + save_absences_to_db(df_absent_yesterday, yesterday_date_str) + + # Проверка опечаток ФИО через AI-аудитор + staff_fios_y_clean = df_staff_yesterday['fio_clean'].dropna().tolist() if df_staff_yesterday is not None else [] + if not raw_scud_yesterday_df.empty: + raw_scud_yesterday_df['Пришел'] = raw_scud_yesterday_df['is_present'].astype(int) == 1 if 'is_present' in raw_scud_yesterday_df.columns else False + unrecog = raw_scud_yesterday_df[~raw_scud_yesterday_df['fio_clean'].isin(staff_fios_y_clean)]['fio_clean'].tolist() + fio_map = ai_verify_scud_against_staff(unrecog, staff_fios_y_clean) + if fio_map: + raw_scud_yesterday_df['fio_clean'] = raw_scud_yesterday_df['fio_clean'].apply(lambda x: fio_map[x]['staff_fio'] if x in fio_map else x) + + raw_scud_yesterday_df = aggregate_scud_by_employee(raw_scud_yesterday_df) + merged_y = (df_staff_yesterday.copy() if df_staff_yesterday is not None else pd.DataFrame()) + + if not merged_y.empty: + if not raw_scud_yesterday_df.empty: + merged_y = merged_y.merge( + raw_scud_yesterday_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag']], + on='fio_clean', how='left' + ) + if df_absent_yesterday is not None and not df_absent_yesterday.empty: + merged_y = merged_y.merge(df_absent_yesterday[['fio_clean', 'Вид_отсутствия']], on='fio_clean', how='left') + + merged_y['Пришел'] = merged_y['Пришел'].fillna(False) if 'Пришел' in merged_y.columns else False + if 'Сотрудник' not in merged_y.columns: + merged_y['Сотрудник'] = merged_y.get('ФИО', merged_y['fio_clean']) + + merged_y = apply_exceptions_from_json(merged_y, exceptions_cfg) + + scud_fios_y = set(raw_scud_yesterday_df['fio_clean'].dropna().tolist()) if not raw_scud_yesterday_df.empty else set() + anomalies_y = detect_all_anomalies(merged_y, static_reasons, kb_rules, scud_fios_set=scud_fios_y) + save_anomalies_to_db(anomalies_y, yesterday_date_str) + + filtered_y = filter_report_dataframe(merged_y) + generate_detailed_excel(merged_df=filtered_y, date_str=yesterday_date_str) + save_scud_to_db(merged_y, yesterday_date_str, snapshot_time=f"{dt_yesterday.strftime('%Y-%m-%d')} 22:00:00", is_yesterday=True) + print(f"[✓] Детальный отчет за вчера сформирован и зафиксирован в SQLite за {yesterday_date_str}") + + # 3. Этап 4 & 5: Обработка СЕГОДНЯ (Ежедневная сводка) + if has_today_1c and df_staff_today is not None and df_absent_today is not None: + print(f"\n[4/5] Обработка и построение Ежедневной сводки за {target_date_str}...") + save_staff_to_db(df_staff_today, target_date_str) + save_absences_to_db(df_absent_today, target_date_str) + + raw_scud_today_df = aggregate_scud_by_employee(raw_scud_today_df) + merged_t = df_staff_today.copy() + if not raw_scud_today_df.empty: + merged_t = merged_t.merge( + raw_scud_today_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag']], + on='fio_clean', how='left' + ) + merged_t = merged_t.merge(df_absent_today[['fio_clean', 'Вид_отсутствия']], on='fio_clean', how='left') + merged_t['Пришел'] = merged_t['Пришел'].fillna(False) if 'Пришел' in merged_t.columns else False + if 'Сотрудник' not in merged_t.columns: + merged_t['Сотрудник'] = merged_t.get('ФИО', merged_t['fio_clean']) + + merged_t = apply_exceptions_from_json(merged_t, exceptions_cfg) + + scud_fios_t = set(raw_scud_today_df['fio_clean'].dropna().tolist()) if not raw_scud_today_df.empty else set() + anomalies_t = detect_all_anomalies(merged_t, static_reasons, kb_rules, scud_fios_set=scud_fios_t) + save_anomalies_to_db(anomalies_t, target_date_str) + + print("[5/5] Сохранение Ежедневной сводки...") + generate_summary_excel(merged_df=merged_t, date_str=target_date_str) + print(f"[✓] Ежедневная сводка сохранена за {target_date_str}") + else: + print(f"\n[ℹ️] Формирование Ежедневной сводки за {target_date_str} ПРОПУЩЕНО.") +``` + +## File: `./services/scud_etl/sql_queries.py` +```py +""" +=============================================================================== +FILE: services/scud_etl/sql_queries.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / scud_etl +ROLE: Хранилище сырых SQL-шаблонов для выгрузки из MS SQL Server (СКУД Орион Pro). + +AI-CONTEXT-ANCHORS: + - ANCHOR[SQL_SCUD_EXPORT_TEMPLATE]: T-SQL запрос с расчетом первой активности и длительности. +=============================================================================== +""" + +# ANCHOR[SQL_SCUD_EXPORT_TEMPLATE] +SCUD_EXPORT_QUERY_TEMPLATE = r""" +DECLARE @InputDate DATE = '{target_date}'; +DECLARE @TargetDate DATE = @InputDate; + +DECLARE @StartDate DATETIME = CAST(@TargetDate AS DATETIME); +DECLARE @EndDate DATETIME = DATEADD(SECOND, -1, DATEADD(DAY, 1, @StartDate)); + +WITH DailyLogs AS ( + SELECT + log.HozOrgan AS EmployeeID, + log.TimeVal, + log.Event, + log.Mode, + CASE + WHEN log.Mode = 2 OR log.Event IN (29, 27, 33) THEN 'OUT' + WHEN log.Mode = 1 OR log.Event IN (28, 26, 32) THEN 'IN' + ELSE 'OTHER' + END AS Direction, + ROW_NUMBER() OVER (PARTITION BY log.HozOrgan ORDER BY log.TimeVal DESC) AS RowNumDesc + FROM pLogData log WITH (NOLOCK) + WHERE log.TimeVal BETWEEN @StartDate AND @EndDate + AND log.HozOrgan IS NOT NULL + AND log.HozOrgan > 0 + AND log.Event IN (26, 27, 28, 29, 32, 33, 54, 55, 64, 65) +), +Passages AS ( + SELECT + EmployeeID, + MIN(TimeVal) AS FirstRawEvent, + MAX(TimeVal) AS LastRawEvent, + MIN(CASE WHEN Direction = 'IN' THEN TimeVal END) AS FirstIn, + MAX(CASE WHEN Direction = 'OUT' THEN TimeVal END) AS LastOut, + MAX(CASE WHEN RowNumDesc = 1 THEN Direction END) AS LastEventType + FROM DailyLogs + GROUP BY EmployeeID +) +SELECT + N'ЛЕНМОРНИИПРОЕКТ' AS [Фирма], + ISNULL(CAST(div.Name AS NVARCHAR(255)), N'Без подразделения') AS [Подразделение], + LTRIM(RTRIM( + ISNULL(CAST(p.Name AS NVARCHAR(255)), N'') + + CASE WHEN p.FirstName IS NOT NULL AND CAST(p.FirstName AS NVARCHAR(255)) <> '' + THEN N' ' + CAST(p.FirstName AS NVARCHAR(255)) ELSE N'' END + + CASE WHEN p.MidName IS NOT NULL AND CAST(p.MidName AS NVARCHAR(255)) <> '' + THEN N' ' + CAST(p.MidName AS NVARCHAR(255)) ELSE N'' END + )) AS [Сотрудник], + ISNULL(CAST(post.Name AS NVARCHAR(255)), N'—') AS [Должность], + ISNULL(CAST(p.TabNumber AS NVARCHAR(50)), N'—') AS [Таб_№], + CONVERT(VARCHAR(10), @TargetDate, 104) AS [Дата], + ISNULL(CAST(CONVERT(VARCHAR(8), pass.FirstIn, 108) AS NVARCHAR(20)), N'Нет входа') AS [Начало_дня], + CASE + WHEN pass.FirstIn IS NULL AND pass.FirstRawEvent IS NOT NULL + THEN CAST(CONVERT(VARCHAR(8), pass.FirstRawEvent, 108) AS NVARCHAR(20)) + ELSE N'—' + END AS [Первая_активность], + CASE + WHEN @TargetDate = CAST(GETDATE() AS DATE) AND (pass.LastEventType = 'IN' OR pass.LastOut IS NULL OR pass.LastOut <= pass.FirstIn) + THEN N'Нет выхода' + WHEN pass.LastOut IS NOT NULL AND pass.LastOut > pass.FirstIn + THEN CAST(CONVERT(VARCHAR(8), pass.LastOut, 108) AS NVARCHAR(20)) + WHEN @TargetDate < CAST(GETDATE() AS DATE) AND pass.LastRawEvent IS NOT NULL AND pass.LastRawEvent > ISNULL(pass.FirstIn, pass.FirstRawEvent) + THEN CAST(CONVERT(VARCHAR(8), pass.LastRawEvent, 108) AS NVARCHAR(20)) + ELSE N'Нет выхода' + END AS [Конец_дня], + CASE + WHEN pass.EmployeeID IS NOT NULL AND (pass.FirstIn IS NOT NULL OR pass.FirstRawEvent IS NOT NULL) THEN + RIGHT('0' + CAST(DATEDIFF(MINUTE, + ISNULL(pass.FirstIn, pass.FirstRawEvent), + CASE + WHEN @TargetDate = CAST(GETDATE() AS DATE) AND (pass.LastEventType = 'IN' OR pass.LastOut IS NULL OR pass.LastOut <= pass.FirstIn) THEN GETDATE() + ELSE ISNULL(pass.LastOut, pass.LastRawEvent) + END) / 60 AS VARCHAR), 2) + ':' + + RIGHT('0' + CAST(DATEDIFF(MINUTE, + ISNULL(pass.FirstIn, pass.FirstRawEvent), + CASE + WHEN @TargetDate = CAST(GETDATE() AS DATE) AND (pass.LastEventType = 'IN' OR pass.LastOut IS NULL OR pass.LastOut <= pass.FirstIn) THEN GETDATE() + ELSE ISNULL(pass.LastOut, pass.LastRawEvent) + END) % 60 AS VARCHAR), 2) + ELSE N'00:00' + END AS [Находился_в_здании], + CASE + WHEN pass.EmployeeID IS NOT NULL THEN N'Присутствовал' + ELSE N'Отсутствовал (Нет событий)' + END AS [Статус] +FROM pList p WITH (NOLOCK) +LEFT JOIN PDivision div WITH (NOLOCK) ON p.Section = div.ID +LEFT JOIN PPost post WITH (NOLOCK) ON p.Post = post.ID +LEFT JOIN Passages pass ON p.ID = pass.EmployeeID +WHERE + ISNULL(p.StatusRecord, 0) = 0 + AND p.DateTimeInArchive IS NULL + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT LIKE N'Аренд%' + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT IN (N'Без подразделения', N'') + AND p.Name NOT LIKE N'бр.%' + AND p.Name NOT LIKE N'Гость%' + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT IN (N'БГИ', N'КНР') + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT LIKE N'Рабоч%' + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT LIKE N'Врем%' + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT LIKE N'Практика%' + AND ISNULL(CAST(div.Name AS NVARCHAR(255)), N'') NOT LIKE N'тест%' + AND ISNULL(CAST(post.Name AS NVARCHAR(255)), N'') NOT LIKE N'Практикант%' +ORDER BY p.Name ASC; +""" +``` + +## File: `./services/snapshots/__init__.py` +```py + +``` + +## File: `./services/snapshots/service.py` +```py +""" +=============================================================================== +FILE: services/snapshots/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / snapshots +ROLE: Бизнес-логика срезов СКУД (выборка, валидация Y-срезов, удаление). + +AI-CONTEXT-ANCHORS: + - ANCHOR[SNAPSHOT_GET_REGISTRY]: Выборка срезов с разметкой защищенных Y-снапшотов. + - ANCHOR[SNAPSHOT_DELETE_SAFE]: Безопасное удаление дневных срезов с защитой итоговых. +=============================================================================== +""" + +from typing import Dict, Any, Optional, List +from core.connection import get_connection +from core.repositories.scud_repo import get_available_snapshots, delete_snapshot_by_id + + +# ANCHOR[SNAPSHOT_GET_REGISTRY] +def get_snapshots_registry(date_str: Optional[str] = None) -> Dict[str, Any]: + """Возвращает реестр снапшотов за дату или за все доступные дни.""" + clean_date = date_str.strip() if date_str else "" + rows = get_available_snapshots(date_str=clean_date if clean_date else None) + + snapshots = [ + { + "snapshot_id": r[0], + "log_date": r[1], + "snapshot_time": r[2], + "record_count": r[3], + "is_final": str(r[0]).startswith("Y") + } + for r in rows + ] + + return { + "query_date": clean_date or "все", + "snapshots_count": len(snapshots), + "snapshots": snapshots + } + + +# ANCHOR[SNAPSHOT_DELETE_SAFE] +def delete_snapshots_safely(snapshot_ids: List[str]) -> Dict[str, Any]: + """ + Удаляет выбранные дневные снапшоты. + Итоговые вечерние срезы с префиксом 'Y' гарантированно защищены от удаления. + """ + if not snapshot_ids: + return {"status": "error", "message": "Не указаны ID снапшотов для удаления."} + + safe_ids = [str(s).strip() for s in snapshot_ids if s and not str(s).strip().startswith("Y")] + + if not safe_ids: + return {"status": "error", "message": "⚠️ Итоговый срез Y защищен от удаления. Выберите дневные снапшоты."} + + with get_connection() as conn: + cursor = conn.cursor() + placeholders = ",".join(["?"] * len(safe_ids)) + cursor.execute(f"DELETE FROM scud_logs WHERE snapshot_id IN ({placeholders})", safe_ids) + deleted_count = cursor.rowcount + conn.commit() + + return { + "status": "success", + "deleted_count": deleted_count, + "deleted_ids": safe_ids, + "message": f"Успешно удалено снапшотов: {len(safe_ids)} шт." + } +``` + +## File: `./services/tasks/__init__.py` +```py + +``` + +## File: `./services/tasks/exporter.py` +```py +""" +=============================================================================== +FILE: services/tasks/exporter.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / tasks +ROLE: Экспорт бэклога задач в форматированный Markdown файл (ROADMAP). + +AI-CONTEXT-ANCHORS: + - ANCHOR[TASK_EXPORT_MARKDOWN]: Построение структуры Markdown с чекбоксами. +=============================================================================== +""" + +import os +import uuid +import logging +from datetime import datetime +from typing import Dict, Any, Optional, List +from config import OUTPUT_DIR +from .repository import repo_get_tasks + +logger = logging.getLogger("TASK_EXPORTER") + + +# ANCHOR[TASK_EXPORT_MARKDOWN] +def export_tasks_to_markdown(user_id: int, filename: Optional[str] = None, status_filter: Optional[str] = None) -> Dict[str, Any]: + """Генерирует Markdown-отчет задач с сохранением в output/web/tasks_export/{uuid}/.""" + tasks = repo_get_tasks(user_id) + if not tasks: + return {"status": "error", "message": "Список задач пуст, экспорт отменен"} + + # 1. Фильтрация задач по статусу + if status_filter and status_filter.upper() != "ALL": + tgt = status_filter.upper() + if tgt in ["COMPLETED", "DONE", "ВЫПОЛНЕННЫЕ"]: + tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["COMPLETED", "DONE"]] + elif tgt in ["IN_PROGRESS", "PROGRESS", "В РАБОТЕ"]: + tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["IN_PROGRESS", "PROGRESS"]] + elif tgt in ["BACKLOG", "PLANNED", "В ПЛАНАХ"]: + tasks = [t for t in tasks if str(t.get("status", "")).upper() in ["BACKLOG", "PLANNED"]] + + if not tasks: + return {"status": "error", "message": f"Нет задач с фильтром '{status_filter}' для экспорта"} + + target_filename = filename.strip() if (filename and filename.strip()) else "ROADMAP.md" + if not target_filename.endswith(".md"): + target_filename = f"{target_filename}.md" + + now_str = datetime.now().strftime("%Y-%m-%d %H:%M") + + # 2. Группировка по модулям + modules: Dict[str, List[Dict[str, Any]]] = {} + for t in tasks: + mod = t.get("module") or "general" + modules.setdefault(mod, []).append(t) + + md_lines = [ + "# 🗺️ Дорожная карта задач проекта (ROADMAP)\n", + f"> **Сформировано:** {now_str} | **Всего задач:** {len(tasks)}\n", + "---\n" + ] + + for mod_name, mod_tasks in sorted(modules.items()): + md_lines.append(f"## Модуль `{mod_name}`\n") + for t in sorted(mod_tasks, key=lambda x: x.get("id", 0)): + status = str(t.get("status", "BACKLOG")).upper() + is_done = status in ["COMPLETED", "DONE"] + is_progress = status in ["IN_PROGRESS", "PROGRESS"] + + check_box = "[x]" if is_done else "[ ]" + t_id = t.get("id") + title = t.get("title", "Без названия") + prio = t.get("priority", "MEDIUM") + due = f" *(срок: {t['due_date']})*" if t.get("due_date") else "" + status_tag = " `[В РАБОТЕ]`" if is_progress else (" `[ЗАВЕРШЕНО]`" if is_done else "") + + md_lines.append(f"- {check_box} **#{t_id}** [{prio}]{status_tag} {title}{due}") + + md_lines.append("\n---\n") + + content = "\n".join(md_lines) + + # 3. Сохранение файла в изолированную сессионную папку + tool_dir = os.path.join(OUTPUT_DIR, "web", "tasks_export") + os.makedirs(tool_dir, exist_ok=True) + + session_token = uuid.uuid4().hex[:8] + session_dir = os.path.join(tool_dir, session_token) + os.makedirs(session_dir, exist_ok=True) + + filepath = os.path.join(session_dir, target_filename) + with open(filepath, "w", encoding="utf-8") as f: + f.write(content) + + return { + "status": "success", + "filename": target_filename, + "filepath": filepath, + "download_url": f"/api/v1/files/download/tasks_export/{session_token}/{target_filename}", + "tasks_count": len(tasks), + "message": f"Отчет успешно сформирован в файл `{target_filename}` (всего задач: {len(tasks)})." + } +``` + +## File: `./services/tasks/repository.py` +```py +""" +=============================================================================== +FILE: services/tasks/repository.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / tasks +ROLE: Низкоуровневые операции к таблице tasks в SQLite (CRUD). + +AI-CONTEXT-ANCHORS: + - ANCHOR[TASK_REPO_GET]: Выборка задач с фильтрацией по статусу и пользователю. + - ANCHOR[TASK_REPO_ADD]: Вставка новой задачи со сквозным ID. + - ANCHOR[TASK_REPO_UPDATE]: Обновление реквизитов и статуса задачи. + - ANCHOR[TASK_REPO_DELETE]: Удаление задачи по числовому или строковому ID. +=============================================================================== +""" + +import re +from typing import List, Dict, Any, Optional +from core.connection import get_connection + + +def normalize_task_id(task_id_input: str) -> str: + """Нормализует идентификатор задачи к формату TASK-XX.""" + if not task_id_input: + return "" + clean_id = str(task_id_input).strip().upper().replace("TASK-", "").replace("TASK", "").replace("#", "") + if clean_id.isdigit(): + num = int(clean_id) + return f"TASK-{num:02d}" if num < 100 else f"TASK-{num:03d}" + return f"TASK-{clean_id}" + + +# ANCHOR[TASK_REPO_GET] +def repo_get_tasks(user_id: int, status: Optional[str] = None) -> List[Dict[str, Any]]: + """Получает список задач пользователя с опциональной фильтрацией по статусу.""" + conn = get_connection(row_factory=True) + cursor = conn.cursor() + + if status and status.upper() != "ALL": + target_status = status.upper() + if target_status in ["PROGRESS", "В РАБОТЕ"]: + target_status = "IN_PROGRESS" + elif target_status in ["DONE", "ГОТОВО"]: + target_status = "COMPLETED" + elif target_status in ["PLANNED", "ПЛАНЫ"]: + target_status = "BACKLOG" + + cursor.execute(""" + SELECT id, task_id, module, title, priority, status, due_date, created_at + FROM tasks + WHERE user_id = ? AND (status = ? OR (status = 'BACKLOG' AND ? = 'PLANNED')) + ORDER BY id DESC + """, (user_id, target_status, target_status)) + else: + cursor.execute(""" + SELECT id, task_id, module, title, priority, status, due_date, created_at + FROM tasks + WHERE user_id = ? + ORDER BY id DESC + """, (user_id,)) + + rows = cursor.fetchall() + conn.close() + return [dict(r) for r in rows] + + +# ANCHOR[TASK_REPO_ADD] +def repo_add_task( + user_id: int, + module: str, + title: str, + priority: str = "MEDIUM", + due_date: Optional[str] = None, + status: str = "BACKLOG" +) -> Dict[str, Any]: + """Добавляет новую задачу в SQLite с автогенерацией порядкового TASK-ID.""" + conn = get_connection() + cursor = conn.cursor() + cursor.execute("SELECT MAX(id) FROM tasks") + max_id = cursor.fetchone()[0] or 0 + new_task_id = f"TASK-{(max_id + 1):02d}" + + target_status = status.upper() if status else "BACKLOG" + if target_status in ["PROGRESS", "В РАБОТЕ"]: + target_status = "IN_PROGRESS" + elif target_status in ["DONE", "ГОТОВО"]: + target_status = "COMPLETED" + elif target_status in ["PLANNED", "ПЛАНЫ", "BACKLOG"]: + target_status = "BACKLOG" + + cursor.execute(""" + INSERT INTO tasks (task_id, module, title, priority, status, due_date, user_id) + VALUES (?, ?, ?, ?, ?, ?, ?) + """, (new_task_id, module or "general", title.strip(), priority.upper(), target_status, due_date, user_id)) + conn.commit() + conn.close() + return {"status": "success", "task_id": new_task_id, "id": max_id + 1} + + +# ANCHOR[TASK_REPO_UPDATE] +def repo_update_task( + user_id: int, + task_id: str, + title: Optional[str] = None, + priority: Optional[str] = None, + status: Optional[str] = None, + due_date: Optional[str] = None +) -> Dict[str, Any]: + """Комплексное обновление атрибутов задачи.""" + conn = get_connection() + cursor = conn.cursor() + + clean_num = re.sub(r'\D', '', str(task_id)) + formatted_id = normalize_task_id(task_id) + + updates = [] + params = [] + + if title is not None and title.strip(): + updates.append("title = ?") + params.append(title.strip()) + + if priority is not None and priority.strip(): + updates.append("priority = ?") + params.append(priority.strip().upper()) + + if status is not None and status.strip(): + target_status = status.strip().upper() + if target_status in ["PROGRESS", "В РАБОТЕ"]: + target_status = "IN_PROGRESS" + elif target_status in ["DONE", "ГОТОВО"]: + target_status = "COMPLETED" + elif target_status in ["PLANNED", "ПЛАНЫ"]: + target_status = "BACKLOG" + updates.append("status = ?") + params.append(target_status) + + if due_date is not None: + updates.append("due_date = ?") + params.append(due_date.strip() if due_date.strip() else None) + + if not updates: + conn.close() + return {"status": "success", "message": "Нет данных для обновления"} + + params.extend([clean_num, formatted_id, f"%{task_id.strip()}", user_id]) + sql = f""" + UPDATE tasks + SET {', '.join(updates)} + WHERE (id = ? OR UPPER(task_id) = ? OR task_id LIKE ?) AND user_id = ? + """ + cursor.execute(sql, params) + rows_affected = cursor.rowcount + conn.commit() + conn.close() + + if rows_affected == 0: + return {"error": f"Задача {task_id} не найдена или принадлежит другому пользователю"} + + return {"status": "success", "message": f"Задача #{task_id} успешно обновлена"} + + +# ANCHOR[TASK_REPO_DELETE] +def repo_delete_task(user_id: int, task_id: str) -> Dict[str, Any]: + """Удаляет задачу по номеру ID.""" + conn = get_connection() + cursor = conn.cursor() + clean_num = re.sub(r'\D', '', str(task_id)) + formatted_id = normalize_task_id(task_id) + + cursor.execute(""" + DELETE FROM tasks + WHERE (id = ? OR UPPER(task_id) = ? OR task_id LIKE ?) AND user_id = ? + """, (clean_num, formatted_id, f"%{task_id.strip()}", user_id)) + + deleted = cursor.rowcount + conn.commit() + conn.close() + + if deleted == 0: + return {"error": f"Задача {task_id} не найдена"} + return {"status": "success", "message": f"Задача #{task_id} удалена"} +``` + +## File: `./services/tasks/service.py` +```py +""" +=============================================================================== +FILE: services/tasks/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / tasks +ROLE: Единый доменный сервис задач (бизнес-логика и диспетчер операций). + +AI-CONTEXT-ANCHORS: + - ANCHOR[TASK_SERVICE_DISPATCHER]: Маршрутизация действий ADD/UPDATE/DELETE/EXPORT. +=============================================================================== +""" + +from typing import Dict, Any, Optional, List +from .repository import repo_get_tasks, repo_add_task, repo_update_task, repo_delete_task +from .exporter import export_tasks_to_markdown + + +def get_tasks(user_id: int, status: Optional[str] = None) -> List[Dict[str, Any]]: + """Получить список задач.""" + return repo_get_tasks(user_id, status) + + +def add_task(user_id: int, module: str, title: str, priority: str = "MEDIUM", due_date: Optional[str] = None, status: str = "BACKLOG") -> Dict[str, Any]: + """Создать задачу.""" + res = repo_add_task(user_id, module, title, priority, due_date, status) + return {"status": "success", "task_id": res["task_id"], "message": f"Задача #{res['id']} создана и добавлена в планы"} + + +def update_task_details(user_id: int, task_id: str, title: Optional[str] = None, priority: Optional[str] = None, status: Optional[str] = None, due_date: Optional[str] = None) -> Dict[str, Any]: + """Обновить задачу.""" + return repo_update_task(user_id, task_id, title, priority, status, due_date) + + +def delete_task(user_id: int, task_id: str) -> Dict[str, Any]: + """Удалить задачу.""" + return repo_delete_task(user_id, task_id) + + +# ANCHOR[TASK_SERVICE_DISPATCHER] +def execute_task_action( + user_id: int, + action: str, + task_id: Optional[str] = None, + title: Optional[str] = None, + priority: Optional[str] = "MEDIUM", + status: Optional[str] = None, + module: Optional[str] = "general", + due_date: Optional[str] = None, + filename: Optional[str] = "ROADMAP.md" +) -> Dict[str, Any]: + """Консолидированный диспетчер операций над задачами.""" + act = (action or "").strip().upper() + + if act == "ADD": + if not title: + return {"status": "error", "message": "Для создания задачи требуется указать title"} + return add_task(user_id, module or "general", title, priority or "MEDIUM", due_date, status or "BACKLOG") + + elif act == "UPDATE": + if not task_id: + return {"status": "error", "message": "Для обновления требуется указать task_id"} + return update_task_details(user_id, str(task_id), title, priority, status, due_date) + + elif act == "DELETE": + if not task_id: + return {"status": "error", "message": "Для удаления требуется указать task_id"} + return delete_task(user_id, str(task_id)) + + elif act == "EXPORT": + return export_tasks_to_markdown(user_id, filename=filename or "ROADMAP.md", status_filter=status) + + return {"status": "error", "message": f"Неизвестное действие action='{action}'"} +``` + ## File: `./core/__init__.py` ```py ``` -## File: `./core/database.py` +## File: `./core/connection.py` ```py +""" +=============================================================================== +FILE: core/connection.py +PROJECT: SCUD Orion AI (Unified Architecture) +ROLE: Единый менеджер подключений к базе данных SQLite (WAL mode, timeouts). +=============================================================================== +""" + import os import sqlite3 -import json -import pandas as pd -from datetime import datetime from config import DATA_DIR DB_PATH = os.path.join(DATA_DIR, "scud_orion_ai.db") -def get_connection(): - """Создает подключение к базе данных SQLite с оптимизированными настройками.""" - conn = sqlite3.connect(DB_PATH) +def get_connection(row_factory: bool = False) -> sqlite3.Connection: + """ + Создает оптимизированное подключение к SQLite. + row_factory=True возвращает sqlite3.Row для доступа к полям по имени. + """ + conn = sqlite3.connect(DB_PATH, timeout=30.0) + if row_factory: + conn.row_factory = sqlite3.Row conn.execute("PRAGMA foreign_keys = ON;") conn.execute("PRAGMA journal_mode = WAL;") + conn.execute("PRAGMA synchronous = NORMAL;") return conn +``` + +## File: `./core/database.py` +```py +""" +=============================================================================== +FILE: core/database.py +ROLE: Фасад ядра базы данных с полной обратной совместимостью импортов. +=============================================================================== +""" + +from core.connection import get_connection, DB_PATH +from core.schema import init_all_tables + +from core.repositories.scud_repo import ( + has_scud_logs_for_date, + has_yesterday_final_snapshot, + get_or_create_snapshot_id, + save_scud_to_db, + get_latest_snapshot_time, + load_scud_from_db_by_snapshot, + get_available_snapshots, + delete_snapshot_by_id, + delete_snapshots_by_date +) + +from core.repositories.zup_repo import ( + save_staff_to_db, + load_staff_from_db, + save_absences_to_db, + load_absences_from_db, + save_anomalies_to_db, + get_all_rules_from_db, + add_rule_to_db, + get_department_synonyms_dict, + add_department_synonym_to_db +) + +init_db = init_all_tables +``` + +## File: `./core/schema.py` +```py +""" +=============================================================================== +FILE: core/schema.py +PROJECT: SCUD Orion AI (Unified Architecture) +ROLE: DDL-схемы таблиц, создание индексов и инициализация базы данных. +=============================================================================== +""" + +import logging +from core.connection import get_connection + +logger = logging.getLogger("DB_SCHEMA") -def init_db(): - """Создает структуру таблиц и индексов в базе данных.""" +def init_all_tables() -> None: + """Инициализирует все таблицы и индексы системы.""" with get_connection() as conn: cursor = conn.cursor() + # 1. Логи СКУД cursor.execute(""" CREATE TABLE IF NOT EXISTS scud_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -3410,11 +4220,7 @@ def init_db(): ); """) - cursor.execute("PRAGMA table_info(scud_logs);") - cols = [col[1] for col in cursor.fetchall()] - if 'snapshot_id' not in cols: - cursor.execute("ALTER TABLE scud_logs ADD COLUMN snapshot_id TEXT DEFAULT NULL;") - + # 2. Кадровые реестры 1С cursor.execute(""" CREATE TABLE IF NOT EXISTS zup_staff ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -3438,6 +4244,7 @@ def init_db(): ); """) + # 3. Аномалии и база знаний cursor.execute(""" CREATE TABLE IF NOT EXISTS anomalies_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -3459,23 +4266,95 @@ def init_db(): ); """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS department_synonyms ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + short_name TEXT UNIQUE NOT NULL, + full_name TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + """) + + # 4. Узлы системного промпта и сессии + cursor.execute(""" + CREATE TABLE IF NOT EXISTS system_prompt_nodes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + prompt_name TEXT DEFAULT 'main_agent', + section_id INTEGER NOT NULL, + item_id INTEGER NOT NULL, + content TEXT NOT NULL, + is_active INTEGER DEFAULT 1, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(prompt_name, section_id, item_id) + ); + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS session_states ( + session_id TEXT PRIMARY KEY, + state_type TEXT NOT NULL, + pending_data TEXT, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS chat_messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + session_id TEXT NOT NULL, + role TEXT NOT NULL, + content TEXT NOT NULL, + is_ephemeral INTEGER DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + """) + + # 5. Задачи + cursor.execute(""" + CREATE TABLE IF NOT EXISTS tasks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id TEXT, + module TEXT DEFAULT 'general', + title TEXT NOT NULL, + priority TEXT DEFAULT 'MEDIUM', + status TEXT DEFAULT 'BACKLOG', + due_date TEXT, + user_id INTEGER DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + """) + + # 6. Индексы cursor.execute("CREATE INDEX IF NOT EXISTS idx_scud_date ON scud_logs(log_date);") cursor.execute("CREATE INDEX IF NOT EXISTS idx_scud_fio ON scud_logs(fio_clean);") cursor.execute("CREATE INDEX IF NOT EXISTS idx_scud_snapshot ON scud_logs(snapshot_time);") + cursor.execute("CREATE INDEX IF NOT EXISTS idx_prompt_nodes ON system_prompt_nodes(prompt_name, section_id, item_id);") conn.commit() +``` - sync_knowledge_base_to_db() +## File: `./core/repositories/scud_repo.py` +```py +""" +=============================================================================== +FILE: core/repositories/scud_repo.py +ROLE: Репозиторий логов СКУД, сохранение и загрузка снапшотов. +=============================================================================== +""" -def has_scud_logs_for_date(date_str): - """Проверяет, есть ли в базе данные СКУД за указанную дату.""" +from datetime import datetime +import pandas as pd +from core.connection import get_connection + + +def has_scud_logs_for_date(date_str: str) -> bool: with get_connection() as conn: cursor = conn.cursor() cursor.execute("SELECT 1 FROM scud_logs WHERE log_date = ? LIMIT 1", (date_str,)) return cursor.fetchone() is not None -def has_yesterday_final_snapshot(date_str): - """Проверяет, зафиксирован ли уже ИТОГОВЫЙ вчерашний снапшот с индексом Y/22:00.""" + +def has_yesterday_final_snapshot(date_str: str) -> bool: with get_connection() as conn: cursor = conn.cursor() cursor.execute( @@ -3485,11 +4364,7 @@ def has_yesterday_final_snapshot(date_str): return cursor.fetchone() is not None -def get_or_create_snapshot_id(snapshot_time, date_str=None, is_yesterday=False): - """ - Генерирует датированный составной ID снапшота (YYYYMMDD-NNN или YYYYMMDD-NNN). - Префикс 'Y' присваивается автоматически, если дата логов (date_str) предшествует дате снятия (snapshot_time). - """ +def get_or_create_snapshot_id(snapshot_time: str, date_str: str = None, is_yesterday: bool = False) -> str: try: dt_snap = datetime.strptime(snapshot_time, "%Y-%m-%d %H:%M:%S").date() date_prefix = dt_snap.strftime("%Y%m%d") @@ -3497,7 +4372,6 @@ def get_or_create_snapshot_id(snapshot_time, date_str=None, is_yesterday=False): dt_snap = datetime.now().date() date_prefix = dt_snap.strftime("%Y%m%d") - # Автоматическая проверка: если дата логов раньше даты выгрузки — проставляем Y if date_str: try: dt_log = datetime.strptime(date_str, "%d.%m.%Y").date() @@ -3510,7 +4384,6 @@ def get_or_create_snapshot_id(snapshot_time, date_str=None, is_yesterday=False): with get_connection() as conn: cursor = conn.cursor() - if date_str: cursor.execute( "SELECT snapshot_id FROM scud_logs WHERE log_date = ? AND snapshot_time = ? AND snapshot_id IS NOT NULL LIMIT 1", @@ -3527,15 +4400,13 @@ def get_or_create_snapshot_id(snapshot_time, date_str=None, is_yesterday=False): return row[0] cursor.execute(""" - SELECT snapshot_id - FROM scud_logs + SELECT snapshot_id FROM scud_logs WHERE snapshot_id LIKE ? OR snapshot_id LIKE ? ORDER BY snapshot_id DESC LIMIT 1 """, (f"{date_prefix}-%", f"Y{date_prefix}-%")) last_row = cursor.fetchone() next_seq = 1 - if last_row and last_row[0]: parts = last_row[0].replace("Y", "").split("-") if len(parts) > 1 and parts[1].isdigit(): @@ -3544,20 +4415,17 @@ def get_or_create_snapshot_id(snapshot_time, date_str=None, is_yesterday=False): return f"{prefix}{date_prefix}-{next_seq:03d}" -def save_scud_to_db(df_scud, date_str, snapshot_time=None, is_yesterday=False): - """Сохраняет логи СКУД с автоматическим присвоением составного snapshot_id.""" +def save_scud_to_db(df_scud: pd.DataFrame, date_str: str, snapshot_time: str = None, is_yesterday: bool = False) -> None: if df_scud is None or df_scud.empty: return if not snapshot_time: snapshot_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - # Передаем date_str в генератор snapshot_id snapshot_id = get_or_create_snapshot_id(snapshot_time, date_str=date_str, is_yesterday=is_yesterday) - data_to_insert = [] - for _, r in df_scud.iterrows(): - data_to_insert.append(( + data_to_insert = [ + ( date_str, r.get('Сотрудник', r.get('fio_raw', '')), r.get('fio_clean', ''), @@ -3571,7 +4439,9 @@ def save_scud_to_db(df_scud, date_str, snapshot_time=None, is_yesterday=False): r.get('anomaly_flag', 'NONE'), snapshot_time, snapshot_id - )) + ) + for _, r in df_scud.iterrows() + ] with get_connection() as conn: cursor = conn.cursor() @@ -3587,7 +4457,7 @@ def save_scud_to_db(df_scud, date_str, snapshot_time=None, is_yesterday=False): conn.commit() -def get_latest_snapshot_time(date_str=None): +def get_latest_snapshot_time(date_str: str = None): with get_connection() as conn: cursor = conn.cursor() if date_str: @@ -3598,239 +4468,103 @@ def get_latest_snapshot_time(date_str=None): return row[0] if row else None -def load_scud_from_db_by_snapshot(date_str, snapshot_param=None): - """ - Загружает логи СКУД по ID снапшота. - Если snapshot_param не задан (или искался прошлый день), приоритетно выбирает - финальный вечерний снапшот, начинающийся с буквы 'Y' (срез на 22:00) за дату date_str. - """ +def load_scud_from_db_by_snapshot(date_str: str, snapshot_param: str = None) -> pd.DataFrame: with get_connection() as conn: df = pd.DataFrame() - - # 1. Если передан конкретный ID снапшота (например, '20260810-001') if snapshot_param: - df = pd.read_sql_query( - "SELECT * FROM scud_logs WHERE snapshot_id = ?", - conn, params=(str(snapshot_param),) - ) + df = pd.read_sql_query("SELECT * FROM scud_logs WHERE snapshot_id = ?", conn, params=(str(snapshot_param),)) - # 2. Если по snapshot_param ничего не найдено ИЛИ snapshot_param=None (запрос за вчерашний день): if df.empty and date_str: cursor = conn.cursor() - - # ⭐️ ПРИОРИТЕТ 1: Ищем срез, начальный символ которого 'Y' (вечерний зафиксированный Y-снапшот) - cursor.execute( - "SELECT snapshot_id FROM scud_logs WHERE log_date = ? AND snapshot_id LIKE 'Y%' ORDER BY id DESC LIMIT 1", - (date_str,) - ) + cursor.execute("SELECT snapshot_id FROM scud_logs WHERE log_date = ? AND snapshot_id LIKE 'Y%' ORDER BY id DESC LIMIT 1", (date_str,)) row = cursor.fetchone() - - # ⭐️ ПРИОРИТЕТ 2: Если Y-снапшот не найден, берем самый свежий обычный if not row: - cursor.execute( - "SELECT snapshot_id FROM scud_logs WHERE log_date = ? ORDER BY id DESC LIMIT 1", - (date_str,) - ) + cursor.execute("SELECT snapshot_id FROM scud_logs WHERE log_date = ? ORDER BY id DESC LIMIT 1", (date_str,)) row = cursor.fetchone() if row and row[0]: - target_snap_id = row[0] - df = pd.read_sql_query( - "SELECT * FROM scud_logs WHERE snapshot_id = ?", - conn, params=(target_snap_id,) - ) + df = pd.read_sql_query("SELECT * FROM scud_logs WHERE snapshot_id = ?", conn, params=(row[0],)) - # Приводим названия колонок к стандарту if not df.empty: rename_map = { - 'department': 'Подразделение', - 'position': 'Должность', - 'fio': 'Сотрудник', - 'time_in': 'Начало_дня', - 'first_activity': 'Первая_активность', - 'time_out': 'Конец_дня', - 'duration': 'Находился_в_здании', - 'is_present': 'Пришел' + 'department': 'Подразделение', 'position': 'Должность', 'fio': 'Сотрудник', + 'time_in': 'Начало_дня', 'first_activity': 'Первая_активность', 'time_out': 'Конец_дня', + 'duration': 'Находился_в_здании', 'is_present': 'Пришел' } - # Переименовываем имеющиеся колонки df = df.rename(columns={k: v for k, v in rename_map.items() if k in df.columns}) - - # Заполняем недостающие колонки значениями по умолчанию, если их не было в БД - required_cols = ['Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag'] - for col in required_cols: + for col in ['Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag']: if col not in df.columns: - if col == 'Пришел': - df[col] = False - else: - df[col] = '—' - - # Приводим тип флага Пришел к bool + df[col] = False if col == 'Пришел' else '—' if 'Пришел' in df.columns: df['Пришел'] = df['Пришел'].astype(bool) return df -def get_available_snapshots(date_str=None): - """ - Возвращает список снапшотов. - Сортировка по времени snapshot_time DESC. - """ + +def get_available_snapshots(date_str: str = None): with get_connection() as conn: cursor = conn.cursor() + query = """ + SELECT snapshot_id, log_date, snapshot_time, COUNT(*) as cnt + FROM scud_logs + WHERE snapshot_time IS NOT NULL + """ + params = [] if date_str: - cursor.execute(""" - SELECT - snapshot_id, - log_date, - snapshot_time, - COUNT(*) as cnt - FROM scud_logs - WHERE log_date = ? AND snapshot_time IS NOT NULL - GROUP BY snapshot_id, log_date, snapshot_time - ORDER BY snapshot_time DESC - """, (date_str,)) - else: - cursor.execute(""" - SELECT - snapshot_id, - log_date, - snapshot_time, - COUNT(*) as cnt - FROM scud_logs - WHERE snapshot_time IS NOT NULL - GROUP BY snapshot_id, log_date, snapshot_time - ORDER BY snapshot_time DESC - """) + query += " AND log_date = ?" + params.append(date_str) + query += " GROUP BY snapshot_id, log_date, snapshot_time ORDER BY snapshot_time DESC" + cursor.execute(query, params) return cursor.fetchall() -def save_staff_to_db(df_staff, date_str): +def delete_snapshot_by_id(snapshot_id: str) -> int: + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("DELETE FROM scud_logs WHERE snapshot_id = ?", (snapshot_id,)) + cnt = cursor.rowcount + conn.commit() + return cnt + + +def delete_snapshots_by_date(date_str: str) -> int: + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("DELETE FROM scud_logs WHERE log_date = ? OR snapshot_id LIKE ?", (date_str, f"%{date_str.replace('.', '')}%")) + cnt = cursor.rowcount + conn.commit() + return cnt +``` + +## File: `./core/repositories/zup_repo.py` +```py +""" +=============================================================================== +FILE: core/repositories/zup_repo.py +ROLE: Репозиторий кадровых данных 1С:ЗУП, аномалий и базы знаний. +=============================================================================== +""" + +import pandas as pd +from typing import List, Dict, Any +from core.connection import get_connection + + +def save_staff_to_db(df_staff: pd.DataFrame, date_str: str) -> None: if df_staff is None or df_staff.empty: return - data_to_insert = [ + data = [ (date_str, r.get('ФИО', ''), r.get('fio_clean', ''), r.get('Подразделение', ''), r.get('Должность', '')) for _, r in df_staff.iterrows() ] with get_connection() as conn: cursor = conn.cursor() cursor.execute("DELETE FROM zup_staff WHERE snapshot_date = ?", (date_str,)) - cursor.executemany("INSERT INTO zup_staff (snapshot_date, fio, fio_clean, department, position) VALUES (?, ?, ?, ?, ?)", data_to_insert) + cursor.executemany("INSERT INTO zup_staff (snapshot_date, fio, fio_clean, department, position) VALUES (?, ?, ?, ?, ?)", data) conn.commit() -def save_absences_to_db(df_absent, date_str): - if df_absent is None or df_absent.empty: - return - data_to_insert = [ - (date_str, r.get('ФИО', r.get('fio_clean', '')), r.get('fio_clean', ''), r.get('Вид_отсутствия', '')) - for _, r in df_absent.iterrows() - ] - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute("DELETE FROM zup_absences WHERE absence_date = ?", (date_str,)) - cursor.executemany("INSERT INTO zup_absences (absence_date, fio, fio_clean, absence_type) VALUES (?, ?, ?, ?)", data_to_insert) - conn.commit() - - -def save_anomalies_to_db(anomalies_list, date_str): - if not anomalies_list: - return - data_to_insert = [ - (date_str, a.get('fio', ''), a.get('type', ''), a.get('details', '')) - for a in anomalies_list - ] - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute("DELETE FROM anomalies_history WHERE anomaly_date = ?", (date_str,)) - cursor.executemany("INSERT INTO anomalies_history (anomaly_date, fio, anomaly_type, details) VALUES (?, ?, ?, ?)", data_to_insert) - conn.commit() - - -def get_all_rules_from_db(): - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute("SELECT rule_text FROM ai_knowledge_base") - return [r[0] for r in cursor.fetchall()] - - -def add_rule_to_db(rule_text, added_by="Human"): - if not rule_text or not rule_text.strip(): - return - with get_connection() as conn: - cursor = conn.cursor() - try: - cursor.execute("INSERT OR IGNORE INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)", (rule_text.strip(), added_by)) - conn.commit() - except Exception as e: - print(f"[⚠️] Ошибка записи правила в БД: {e}") - - -def sync_knowledge_base_to_db(): - pass - -def delete_snapshot_by_id(snapshot_id: str): - """Удаляет конкретный снапшот из таблицы scud_logs по его ID.""" - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute("DELETE FROM scud_logs WHERE snapshot_id = ?", (snapshot_id,)) - deleted_count = cursor.rowcount - conn.commit() - print(f"[✓] Удален снапшот [{snapshot_id}]. Удалено строк: {deleted_count}") - return deleted_count - -def delete_snapshots_by_date(date_str: str): - """Удаляет все снапшоты за указанную дату (например, '04.08.2026').""" - with get_connection() as conn: - cursor = conn.cursor() - # Удаляем по log_date или по дате внутри snapshot_id - cursor.execute("DELETE FROM scud_logs WHERE log_date = ? OR snapshot_id LIKE ?", (date_str, f"%{date_str.replace('.', '')}%")) - deleted_count = cursor.rowcount - conn.commit() - print(f"[✓] Удалены все снапшоты за дату [{date_str}]. Удалено строк: {deleted_count}") - return deleted_count -def init_department_synonyms_db(): - """Создает таблицу синонимов отделов в БД SQLite.""" - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute(""" - CREATE TABLE IF NOT EXISTS department_synonyms ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - short_name TEXT UNIQUE NOT NULL, - full_name TEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); - """) - # По умолчанию добавляем ОВК -> Отдел внутреннего контроля - cursor.execute(""" - INSERT OR IGNORE INTO department_synonyms (short_name, full_name) - VALUES ('овк', 'отдел внутреннего контроля') - """) - conn.commit() - - -def get_department_synonyms_dict(): - """Возвращает словарь всех изученных синонимов {short_name: full_name}.""" - init_department_synonyms_db() - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute("SELECT LOWER(short_name), LOWER(full_name) FROM department_synonyms") - return {row[0]: row[1] for row in cursor.fetchall()} - - -def add_department_synonym_to_db(short_name, full_name): - """Сохраняет новую пару синонимов отдела в базу SQLite.""" - init_department_synonyms_db() - with get_connection() as conn: - cursor = conn.cursor() - cursor.execute( - "INSERT OR REPLACE INTO department_synonyms (short_name, full_name) VALUES (?, ?)", - (short_name.strip().lower(), full_name.strip().lower()) - ) - conn.commit() - print(f"[✓] В базу SQLite добавлен новый синоним отдела: '{short_name}' ⟷ '{full_name}'") - -def load_staff_from_db(date_str): - """Загружает Штатное расписание 1С из базы SQLite за указанную дату.""" +def load_staff_from_db(date_str: str) -> pd.DataFrame: with get_connection() as conn: df = pd.read_sql_query( "SELECT fio as 'ФИО', fio_clean, department as 'Подразделение', position as 'Должность' FROM zup_staff WHERE snapshot_date = ?", @@ -3838,15 +4572,69 @@ def load_staff_from_db(date_str): ) return df if not df.empty else None -def load_absences_from_db(date_str): - """Загружает документальные отсутствия 1С из базы SQLite за указанную дату.""" + +def save_absences_to_db(df_absent: pd.DataFrame, date_str: str) -> None: + if df_absent is None or df_absent.empty: + return + data = [ + (date_str, r.get('ФИО', r.get('fio_clean', '')), r.get('fio_clean', ''), r.get('Вид_отсутствия', '')) + for _, r in df_absent.iterrows() + ] + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("DELETE FROM zup_absences WHERE absence_date = ?", (date_str,)) + cursor.executemany("INSERT INTO zup_absences (absence_date, fio, fio_clean, absence_type) VALUES (?, ?, ?, ?)", data) + conn.commit() + + +def load_absences_from_db(date_str: str) -> pd.DataFrame: with get_connection() as conn: df = pd.read_sql_query( "SELECT fio as 'ФИО', fio_clean, absence_type as 'Вид_отсутствия' FROM zup_absences WHERE absence_date = ?", conn, params=(date_str,) ) return df if not df.empty else None - + + +def save_anomalies_to_db(anomalies_list: List[Dict[str, Any]], date_str: str) -> None: + if not anomalies_list: + return + data = [(date_str, a.get('fio', ''), a.get('type', ''), a.get('details', '')) for a in anomalies_list] + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("DELETE FROM anomalies_history WHERE anomaly_date = ?", (date_str,)) + cursor.executemany("INSERT INTO anomalies_history (anomaly_date, fio, anomaly_type, details) VALUES (?, ?, ?, ?)", data) + conn.commit() + + +def get_all_rules_from_db() -> List[str]: + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("SELECT rule_text FROM ai_knowledge_base") + return [r[0] for r in cursor.fetchall()] + + +def add_rule_to_db(rule_text: str, added_by: str = "Human") -> None: + if not rule_text or not rule_text.strip(): + return + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("INSERT OR IGNORE INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)", (rule_text.strip(), added_by)) + conn.commit() + + +def get_department_synonyms_dict() -> Dict[str, str]: + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("SELECT LOWER(short_name), LOWER(full_name) FROM department_synonyms") + return {row[0]: row[1] for row in cursor.fetchall()} + + +def add_department_synonym_to_db(short_name: str, full_name: str) -> None: + with get_connection() as conn: + cursor = conn.cursor() + cursor.execute("INSERT OR REPLACE INTO department_synonyms (short_name, full_name) VALUES (?, ?)", (short_name.strip().lower(), full_name.strip().lower())) + conn.commit() ``` ## File: `./modules/__init__.py` @@ -3879,6 +4667,12 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) if CURRENT_DIR not in sys.path: sys.path.insert(0, CURRENT_DIR) +ROOT_DIR = os.path.abspath(os.path.join(CURRENT_DIR, "../../")) + +for p in [ROOT_DIR, CURRENT_DIR]: + if p not in sys.path: + sys.path.insert(0, p) + from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse, JSONResponse @@ -6070,7 +6864,7 @@ from fastapi import APIRouter, Depends, UploadFile, File, Form, HTTPException from pydantic import BaseModel from .auth import get_current_user -from llm.agent import process_chat_message +from modules.ai_engine.agent import process_chat_message from llm.file_parser import extract_text_from_file from llm.db_tools import db_set_session_state, db_get_session_state @@ -6834,43 +7628,62 @@ def process_chat_message( FILE: modules/web_api/llm/db_tools.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: web_api / llm -ROLE: Фасадная точка доступа ко всем функциям базы данных SQLite. +ROLE: Фасадная точка доступа к доменным сервисам (Domain Facade). + +AI-CONTEXT-ANCHORS: + - ANCHOR[FACADE_EXPORTS]: Экспорт методов предметных сервисов для LLM и API. =============================================================================== """ -from .db.connection import DB_PATH, get_db_connection -from .db.db_prompts import ( - db_get_active_system_prompt, - db_add_system_prompt, - db_apply_prompt_node_action, - db_get_tool_action, - db_set_session_state, - db_get_session_state, - db_clear_session_state, - db_get_rules, - db_get_stats, - db_get_anomalies, - db_get_reference +# ANCHOR[FACADE_EXPORTS] +from core.connection import DB_PATH, get_connection as get_db_connection + +# Домен: Задачи +from services.tasks.service import ( + get_tasks as db_get_tasks, + add_task as db_add_task, + update_task_details as db_update_task_details, + delete_task as db_delete_task, + execute_task_action as db_tasks_edit ) +from services.tasks.exporter import export_tasks_to_markdown as db_export_tasks_markdown +from services.tasks.repository import normalize_task_id + +# Домен: Системный промпт +from services.prompts.service import ( + get_active_system_prompt as db_get_active_system_prompt, + apply_prompt_action as db_apply_prompt_node_action, + save_full_prompt_draft as db_add_system_prompt, + create_prompt_preview +) + +# Домен: Снапшоты СКУД +from services.snapshots.service import ( + get_snapshots_registry as db_get_snapshots, + delete_snapshots_safely as db_delete_snapshots +) + +# Домен: База знаний +from services.knowledge.service import ( + get_rules as db_get_rules, + add_rule as db_add_rule +) + +# Чат, сессии, статистика from .db.db_chat import ( db_save_chat_message, db_get_chat_history, db_purge_ephemeral_messages, db_clear_chat_history ) -from .db.db_tasks import ( - normalize_task_id, - db_get_tasks, - db_add_task, - db_update_task_status, - db_update_task_details, - db_delete_task, - db_export_tasks_markdown, - db_tasks_edit -) -from .db.db_snapshots import ( - db_get_snapshots, - db_delete_snapshots +from .db.db_prompts import ( + db_get_tool_action, + db_set_session_state, + db_get_session_state, + db_clear_session_state, + db_get_stats, + db_get_anomalies, + db_get_reference ) from .core.calendar_utils import get_dynamic_calendar_context as db_get_current_server_time ``` @@ -8385,3 +9198,510 @@ def inject_tools_if_needed(user_message: str, raw_text_content: str, tool_calls: return tool_calls ``` +## File: `./modules/ai_engine/__init__.py` +```py + +``` + +## File: `./modules/ai_engine/agent.py` +```py +""" +=============================================================================== +FILE: modules/ai_engine/agent.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine +ROLE: Лаконичный нативный оркестратор Function Calling и диспетчер handlers. + +AI-CONTEXT-ANCHORS: + - ANCHOR[AGENT_PIPELINE_ENTRY]: Главная точка входа process_chat_message. +=============================================================================== +""" + +import sys +import json +import logging +from typing import List, Dict, Any, Tuple, Optional + +from modules.web_api.llm.schemas import TOOLS_SCHEMA +from modules.web_api.llm.core.ollama_client import call_ollama_chat +from modules.web_api.llm.core.fast_path import handle_fast_path_intercept +from modules.web_api.llm.core.tool_injector import clean_raw_tool_tags, clean_output, inject_tools_if_needed +from modules.web_api.llm.core.context_manager import mark_last_user_message_ephemeral, close_tool_session_and_cleanup +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history, db_purge_ephemeral_messages +from modules.web_api.llm.db.db_prompts import ( + db_get_session_state, db_clear_session_state, db_set_session_state, + db_get_stats, db_get_anomalies, db_get_reference +) +from services.knowledge.service import get_rules + +from .context_builder import build_agent_system_context +from .handlers.task_handler import handle_tasks_call +from .handlers.prompt_handler import handle_prompt_call +from .handlers.snapshot_handler import handle_snapshots_call + +logger = logging.getLogger("AI_AGENT") +logger.setLevel(logging.INFO) + + +# ANCHOR[AGENT_PIPELINE_ENTRY] +def process_chat_message( + user_id: int, + user_message: str, + file_context: str = "", + image_b64: Optional[str] = None, + chat_history: List[Dict[str, Any]] = None, + session_id: str = "web_session_main" +) -> Tuple[str, List[Dict[str, Any]], Optional[Dict[str, Any]]]: + """Главный конвейер обработки сообщений чата.""" + logger.info(f"Сообщение от user_id={user_id}, session_id={session_id}: {user_message}") + + session_state = db_get_session_state(session_id) + if not session_state: + db_purge_ephemeral_messages(session_id) + + full_user_content = f"{user_message}\n\n[СОДЕРЖИМОЕ ПРИКРЕПЛЕННОГО ФАЙЛА]:\n{file_context}" if file_context else user_message + + # 1. Быстрый Fast-Path перехват кнопок подтверждения + fast_path_res = handle_fast_path_intercept(session_id, user_message, full_user_content, session_state) + if fast_path_res: + return fast_path_res + + db_save_chat_message(session_id, "user", full_user_content, is_ephemeral=0) + db_history = db_get_chat_history(session_id, limit=20) + system_prompt = build_agent_system_context(user_id, session_state) + + user_msg_obj = {"role": "user", "content": full_user_content} + + try: + if image_b64: + user_msg_obj["images"] = [image_b64] + messages = [{"role": "system", "content": "Строгий модуль OCR. Перепиши весь текст буква в букву."}, user_msg_obj] + msg = call_ollama_chat(messages, is_vision=True) + else: + clean_history = [dict(m) for m in db_history] + for m in clean_history: m.pop("images", None) + messages = [{"role": "system", "content": system_prompt}] + clean_history + [user_msg_obj] + msg = call_ollama_chat(messages, tools=TOOLS_SCHEMA, is_vision=False) + + raw_reply = msg.get("content", "") + tool_calls = msg.get("tool_calls", []) + if not tool_calls: + tool_calls = inject_tools_if_needed(user_message, raw_reply, tool_calls) + + # 2. Исполнение инструментов через изолированные handlers + if tool_calls: + tool = tool_calls[0] + fn_name = tool["function"]["name"] + fn_args = tool["function"].get("arguments", {}) + if isinstance(fn_args, str): + try: fn_args = json.loads(fn_args) + except Exception: fn_args = {} + + logger.info(f"Вызов инструмента: {fn_name} с аргументами: {fn_args}") + close_tool_session_and_cleanup(session_id, close_reason=f"ACTIVATE_{fn_name}") + mark_last_user_message_ephemeral(session_id) + + state_data = session_state.get("data_json") or {} if session_state else {} + + if fn_name in ["db_get_tasks", "db_tasks_edit", "db_add_task", "db_update_task_status", "db_delete_task"]: + return handle_tasks_call(fn_name, fn_args, user_id, session_id) + + elif fn_name in ["db_get_system_prompt", "db_prompt_node_edit"]: + return handle_prompt_call(fn_name, fn_args, session_id) + + elif fn_name in ["db_get_snapshots", "db_delete_snapshots"]: + return handle_snapshots_call(fn_name, fn_args, session_id, user_message, state_data) + + # Сервисные запросы + elif fn_name == "db_get_rules": + res_str = json.dumps(get_rules(), ensure_ascii=False) + elif fn_name == "db_get_stats": + res_str = json.dumps(db_get_stats(), ensure_ascii=False) + elif fn_name == "db_get_anomalies": + res_str = json.dumps(db_get_anomalies(limit=fn_args.get("limit", 100), date_str=fn_args.get("date_str")), ensure_ascii=False) + elif fn_name == "db_get_reference": + res_str = json.dumps(db_get_reference(category=fn_args.get("category")), ensure_ascii=False) + else: + res_str = "{}" + + messages.append(msg) + messages.append({"role": "tool", "content": res_str}) + sec_msg = call_ollama_chat(messages, is_vision=False) + final_content = clean_raw_tool_tags(clean_output(sec_msg.get("content", ""))) or "Запрос выполнен." + db_save_chat_message(session_id, "assistant", final_content, is_ephemeral=0) + return final_content, db_get_chat_history(session_id), None + + # Обычный текстовый диалог + final_reply = clean_raw_tool_tags(clean_output(raw_reply)) or "Запрос обработан." + db_save_chat_message(session_id, "assistant", final_reply, is_ephemeral=0) + return final_reply, db_get_chat_history(session_id), None + + except Exception as ex: + logger.exception(f"Ошибка в агенте: {ex}") + return f"Внутренняя ошибка сервера: {ex}", db_get_chat_history(session_id), None +``` + +## File: `./modules/ai_engine/context_builder.py` +```py +""" +=============================================================================== +FILE: modules/ai_engine/context_builder.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine +ROLE: Динамическая сборка системного промпта, календаря и контекста сессий. + +AI-CONTEXT-ANCHORS: + - ANCHOR[CONTEXT_BUILDER_MAIN]: Формирование итогового системного промпта для LLM. +=============================================================================== +""" + +from typing import Dict, Any, Optional +from modules.web_api.llm.core.calendar_utils import get_dynamic_calendar_context + + +# ANCHOR[CONTEXT_BUILDER_MAIN] +def build_agent_system_context( + user_id: int, + session_state: Optional[Dict[str, Any]] +) -> str: + """Формирует строгий динамический системный промпт для агента.""" + calendar_context = get_dynamic_calendar_context() + user_info = f"Пользователь ID={user_id}" if user_id != 0 else "Гость" + + current_state_type = session_state.get("state_type") if session_state else None + state_data = session_state.get("data_json") or {} if session_state else {} + if not isinstance(state_data, dict): + state_data = {} + + active_state_context = "" + if current_state_type == "PROMPT_PREVIEW": + active_state_context = ( + "\n[ТЕКУЩИЙ РЕЖИМ: ПРЕДПРОСМОТР СИСТЕМНОГО ПРОМПТА]\n" + "- Открыт предпросмотр изменений промпта. Для любых правок вызывай db_prompt_node_edit.\n" + ) + elif current_state_type == "PROMPT_FOLLOWUP": + active_state_context = ( + "\n[ТЕКУЩИЙ РЕЖИМ: СЕССИЯ РЕДАКТИРОВАНИЯ ПРОМПТА]\n" + "- Оператор просматривает или редактирует системный промпт.\n" + "- На любые команды вида 'удали пункт X.Y' или 'удали X.Y' ТЫ ОБЯЗАН ВЫЗВАТЬ db_prompt_node_edit с action='DELETE', section_id=X, item_id=Y.\n" + "- На любые команды 'добавь пункт X.Y ...' вызывай action='ADD'.\n" + "- Запрещено путать ADD и DELETE.\n" + ) + elif current_state_type == "SNAPSHOTS_VIEW": + active_date = state_data.get("query_date", "выбранную дату") + active_state_context = ( + f"\n[ТЕКУЩИЙ РЕЖИМ: ПРОСМОТР СНАПШОТОВ СКУД]\n" + f"- Сейчас на экране отображаются снапшоты за {active_date}.\n" + f"- Ты можешь форматировать, фильтровать или анализировать этот текущий срез.\n" + f"- Если оператор запрашивает ДРУГУЮ дату или день недели (например: 'за вчера', 'а за 13.08') — " + f"ТЫ ОБЯЗАН СРАЗУ ВЫЗВАТЬ db_get_snapshots(date_str=...).\n" + f"- Запрещено генерировать текст за другую дату по памяти.\n" + ) + elif current_state_type == "SNAPSHOT_DELETE_CONFIRM": + active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ СНАПШОТОВ]\n" + elif current_state_type == "TASK_DELETE_CONFIRM": + active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ ЗАДАЧИ]\n" + + return ( + f"Ты — интеллектуальный ассистент SCUD Orion AI.\n" + f"Ты управляешь задачами, аналитикой СКУД и системными настройками исключительно через инструменты (tools).\n\n" + f"СТРОГИЕ ПРАВИЛА:\n" + f"1. К оператору всегда обращайся на Вы.\n" + f"2. Для получения данных всегда вызывай соответствующий инструмент:\n" + f" - Снапшоты и срезы логов СКУД -> db_get_snapshots\n" + f" - Удаление снапшотов -> db_delete_snapshots\n" + f" - Задачи и бэклог -> db_get_tasks, db_tasks_edit\n" + f" - Системный промпт -> db_get_system_prompt, db_prompt_node_edit\n" + f" - Аномалии СКУД/1С -> db_get_anomalies\n" + f" - База знаний -> db_get_rules\n" + f" - Статистика БД -> db_get_stats\n" + f" - Справка -> db_get_reference\n" + f"3. Запрещено сочинять данные от себя без вызова инструментов.\n\n" + f"[СИСТЕМНЫЙ КАЛЕНДАРЬ СЕРВЕРА]\n" + f"- Пользователь: {user_info}\n" + f"- {calendar_context}\n" + f"{active_state_context}" + ) +``` + +## File: `./modules/ai_engine/handlers/__init__.py` +```py + +``` + +## File: `./modules/ai_engine/handlers/prompt_handler.py` +```py +""" +=============================================================================== +FILE: modules/ai_engine/handlers/prompt_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка команд управления системным промптом. + +AI-CONTEXT-ANCHORS: + - ANCHOR[PROMPT_HANDLER_DISPATCH]: Обработка db_get_system_prompt и db_prompt_node_edit. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional +from services.prompts.service import get_active_system_prompt, create_prompt_preview +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[PROMPT_HANDLER_DISPATCH] +def handle_prompt_call( + fn_name: str, + fn_args: Dict[str, Any], + session_id: str +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает вызовы просмотра и изменения системного промпта.""" + + # 1. Просмотр промпта + if fn_name == "db_get_system_prompt": + active_prompt = get_active_system_prompt() + reply_text = f"Актуальный системный промпт:\n\n{active_prompt}" + db_set_session_state(session_id, "PROMPT_FOLLOWUP", {"idle_turns": 0}) + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), None + + # 2. Предпросмотр изменений (ADD / EDIT / DELETE) + action = str(fn_args.get("action", "ADD")).upper() + try: + sec_id = int(str(fn_args.get("section_id", 3)).strip()) + except Exception: + sec_id = 3 + + try: + itm_id = int(str(fn_args.get("item_id", 1)).strip()) + except Exception: + itm_id = 1 + + content = str(fn_args.get("content", "")).strip() + + merged_prompt, diff_html, baseline_prompt = create_prompt_preview( + action=action, + section_id=sec_id, + item_id=itm_id, + content=content + ) + + db_set_session_state(session_id, "PROMPT_PREVIEW", { + "draft_text": merged_prompt, + "action": action, + "section_id": sec_id, + "item_id": itm_id, + "content": content, + "idle_turns": 0 + }) + + preview_reply = f"Предпросмотр изменений системного промпта:\n\n{diff_html}\n\nДля применения подтвердите действие, отредактируйте или отмените." + db_save_chat_message(session_id, "assistant", preview_reply, is_ephemeral=1) + return preview_reply, db_get_chat_history(session_id), { + "type": "PROMPT_PREVIEW", + "raw_draft": merged_prompt, + "baseline_prompt": baseline_prompt, + "buttons": [ + {"label": "Подтвердить", "value": "подтверждаю", "style": "primary"}, + {"label": "Отменить", "value": "отмена", "style": "danger"}, + {"label": "✏️ Редактировать", "value": "action:open_editor", "style": "secondary"} + ] + } +``` + +## File: `./modules/ai_engine/handlers/snapshot_handler.py` +```py +""" +=============================================================================== +FILE: modules/ai_engine/handlers/snapshot_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка запросов просмотра и удаления срезов СКУД. + +AI-CONTEXT-ANCHORS: + - ANCHOR[SNAPSHOT_HANDLER_DISPATCH]: Обработка db_get_snapshots и db_delete_snapshots. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional, List +from services.snapshots.service import get_snapshots_registry, delete_snapshots_safely +from modules.web_api.llm.core.calendar_utils import parse_relative_date_ru +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[SNAPSHOT_HANDLER_DISPATCH] +def handle_snapshots_call( + fn_name: str, + fn_args: Dict[str, Any], + session_id: str, + user_message: str, + state_data: Dict[str, Any] +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает запросы реестра и безопасного удаления срезов.""" + + # 1. Получение срезов + if fn_name == "db_get_snapshots": + date_param = fn_args.get("date_str") + if not date_param and user_message: + date_param = parse_relative_date_ru(user_message) + + snapshots_res = get_snapshots_registry(date_str=date_param) + query_date = snapshots_res.get("query_date", "выбранную дату") + + db_set_session_state(session_id, "SNAPSHOTS_VIEW", snapshots_res) + reply_text = f"Реестр срезов СКУД за {query_date}:" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOTS_CARD", + "data": snapshots_res + } + + # 2. Удаление срезов (двухфазное подтверждение) + raw_id = fn_args.get("snapshot_id") or fn_args.get("day_str") + raw_ids = fn_args.get("snapshot_ids") or [] + is_confirmed = fn_args.get("confirmed", False) + + if raw_id and not raw_ids: + if isinstance(raw_id, str) and "," in raw_id: + raw_ids = [s.strip() for s in raw_id.split(",")] + else: + raw_ids = [raw_id] + + safe_ids = [s.strip() for s in raw_ids if s and not str(s).strip().startswith("Y")] + if not safe_ids: + reply_text = "⚠️ Итоговый срез Y защищен от удаления. Выберите дневные снапшоты." + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), None + + if not is_confirmed: + query_date = state_data.get("query_date", "") + db_set_session_state(session_id, "SNAPSHOT_DELETE_CONFIRM", { + "snapshot_ids": safe_ids, + "query_date": query_date, + "idle_turns": 0 + }) + ids_str = ", ".join(safe_ids) + reply_text = f"Вы действительно хотите удалить дневные снапшоты: {ids_str}?" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOT_DELETE_CONFIRM", + "buttons": [ + {"label": f"Удалить ({len(safe_ids)} шт.)", "value": f"подтверждаю удаление снапшотов {ids_str}", "style": "danger"}, + {"label": "Отмена", "value": "отмена", "style": "secondary"} + ] + } + else: + delete_snapshots_safely(snapshot_ids=safe_ids) + query_date = state_data.get("query_date", "") + updated_data = get_snapshots_registry(date_str=query_date) + + reply_text = f"✅ Успешно удалено снапшотов: {len(safe_ids)} шт." + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "SNAPSHOTS_CARD", + "data": updated_data + } +``` + +## File: `./modules/ai_engine/handlers/task_handler.py` +```py +""" +=============================================================================== +FILE: modules/ai_engine/handlers/task_handler.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: modules / ai_engine / handlers +ROLE: Изолированная обработка вызовов инструментов задач (get, edit, delete, export). + +AI-CONTEXT-ANCHORS: + - ANCHOR[TASK_HANDLER_DISPATCH]: Обработка вызовов db_get_tasks и db_tasks_edit. +=============================================================================== +""" + +from typing import Dict, Any, Tuple, Optional +from services.tasks.service import get_tasks, execute_task_action +from modules.web_api.llm.db.db_chat import db_save_chat_message, db_get_chat_history +from modules.web_api.llm.db.db_prompts import db_set_session_state + + +# ANCHOR[TASK_HANDLER_DISPATCH] +def handle_tasks_call( + fn_name: str, + fn_args: Dict[str, Any], + user_id: int, + session_id: str +) -> Tuple[str, list, Optional[Dict[str, Any]]]: + """Обрабатывает нативные tool-вызовы по задачам.""" + + # 1. Просмотр задач + if fn_name == "db_get_tasks": + raw_tasks = get_tasks(user_id, status=fn_args.get("status")) + reply_text = "Вот интерактивный список ваших текущих задач:" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_INTERACTIVE_CARD", + "tasks": raw_tasks + } + + # 2. Модификация / Удаление / Экспорт + action = (fn_args.get("action") or "UPDATE").upper() + if fn_name == "db_add_task": action = "ADD" + elif fn_name == "db_delete_task": action = "DELETE" + elif fn_name == "db_update_task_status": action = "UPDATE" + + # Двухфазное подтверждение удаления + if action == "DELETE": + task_id_raw = str(fn_args.get("task_id", "")).replace("#", "").replace("TASK-", "").strip() + db_set_session_state(session_id, "TASK_DELETE_CONFIRM", {"task_id": task_id_raw, "idle_turns": 0}) + reply_text = f"Вы действительно хотите удалить задачу #{task_id_raw}?" + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_DELETE_CONFIRM", + "buttons": [ + {"label": f"Удалить #{task_id_raw}", "value": f"подтверждаю удаление задачи {task_id_raw}", "style": "danger"}, + {"label": "Отмена", "value": "отмена", "style": "secondary"} + ] + } + + # Экспорт в Markdown + elif action == "EXPORT": + export_res = execute_task_action( + user_id=user_id, + action="EXPORT", + filename=fn_args.get("filename"), + status=fn_args.get("status") + ) + reply_text = export_res.get("message", "Отчет по задачам успешно экспортирован.") + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=0) + + action_payload = None + if export_res.get("status") == "success": + action_payload = { + "type": "FILE_DOWNLOAD_CARD", + "filename": export_res.get("filename"), + "download_url": export_res.get("download_url"), + "tasks_count": export_res.get("tasks_count") + } + return reply_text, db_get_chat_history(session_id), action_payload + + # Создание и обновление + else: + res = execute_task_action( + user_id=user_id, + action=action, + task_id=fn_args.get("task_id"), + title=fn_args.get("title"), + priority=fn_args.get("priority", "MEDIUM"), + status=fn_args.get("status"), + module=fn_args.get("module", "general"), + due_date=fn_args.get("due_date") + ) + raw_tasks = get_tasks(user_id) + reply_text = res.get("message", "Операция над задачами выполнена.") + db_save_chat_message(session_id, "assistant", reply_text, is_ephemeral=1) + return reply_text, db_get_chat_history(session_id), { + "type": "TASK_INTERACTIVE_CARD", + "tasks": raw_tasks + } +``` + diff --git a/scripts/db_cli.py b/scripts/db_cli.py index e24cec3..40cce04 100644 --- a/scripts/db_cli.py +++ b/scripts/db_cli.py @@ -333,11 +333,6 @@ def print_chat_messages(session_id=None, limit=50): def purge_chat_context(session_id=None, purge_all=False): - """ - Очистка контекста сообщений: - - По умолчанию: удаляет эфемерные сообщения, осиротевшие превью и сбрасывает стейты сессий. - - purge_all=True (--all): полностью очищает всю таблицу chat_messages и сбрасывает сессии. - """ with get_connection() as conn: cursor = conn.cursor() @@ -357,6 +352,8 @@ def purge_chat_context(session_id=None, purge_all=False): DELETE FROM chat_messages WHERE is_ephemeral = 1 OR content LIKE '%Предпросмотр изменений%' + OR content LIKE '%Актуальный системный промпт:%' + OR content LIKE '%1. РОЛЬ И ЗАДАЧИ АССИСТЕНТА%' OR content LIKE '%Удален пункт:%' OR content LIKE '%добавлен пункт:%' """ diff --git a/services/scud_etl/anomaly_detector.py b/services/scud_etl/anomaly_detector.py index 2ab382d..fbd16cf 100644 --- a/services/scud_etl/anomaly_detector.py +++ b/services/scud_etl/anomaly_detector.py @@ -3,70 +3,49 @@ FILE: services/scud_etl/anomaly_detector.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: services / scud_etl -ROLE: Автоматическое выявление аномалий и конфликтов между 1С:ЗУП и СКУД. - -AI-CONTEXT-ANCHORS: - - ANCHOR[ANOMALY_DETECTOR_CORE]: Проверка физического присутствия в отпуске и перемещений без входа. +ROLE: Детектирование истинных аномалий и конфликтов реестров. + (Приход удаленщиков и командированных в офис аномалией НЕ является). =============================================================================== """ +import logging +from typing import List, Dict, Any import pandas as pd -from typing import List, Dict, Any, Optional -ALLOWED_WORK_TRIP_KEYWORDS = ['командировк', 'разъездн', 'поездк'] +logger = logging.getLogger("SCUD_ANOMALY") -# ANCHOR[ANOMALY_DETECTOR_CORE] -def detect_all_anomalies( - merged_df: pd.DataFrame, - static_reasons_dict: dict, - kb_rules: List[str], - scud_fios_set: Optional[set] = None -) -> List[Dict[str, Any]]: - """Выявляет конфликты и аномалии между источниками СКУД и 1С.""" +def detect_registry_anomalies(df_merged: pd.DataFrame) -> List[Dict[str, Any]]: + """ + Выявляет реальные аномалии: + - Приход в офис во время отпуска или больничного листа. + - Ошибки считывателей СКУД (наличие выхода при отсутствии отметки входа). + """ anomalies = [] - kb_rules_text = " ".join(kb_rules).lower() if kb_rules else "" - for idx, row in merged_df.iterrows(): - fio = row.get('Сотрудник', row.get('fio_clean', '')) - fio_clean = row.get('fio_clean', '') - is_present = row.get('Пришел', False) - is_exc = row.get('is_excluded', False) - reason_1c = str(row.get('Вид_отсутствия', '')).strip() - has_1c_reason = pd.notna(row.get('Вид_отсутствия')) and reason_1c != '' and not reason_1c.startswith('Исключение') - anom_flag = row.get('anomaly_flag', 'NONE') + for _, row in df_merged.iterrows(): + fio = row.get("fio_clean") or row.get("Сотрудник", "") + start_day = str(row.get("Начало_дня", "")).strip() + end_day = str(row.get("Конец_дня", "")).strip() + reason = str(row.get("причина отсутствия", "")).strip() + reason_lower = reason.lower() - is_fio_whitelisted = fio_clean.lower() in kb_rules_text - - # 1. Присутствие при официальном отсутствии - if is_present and has_1c_reason: - is_allowed_trip = any(kw in reason_1c.lower() for kw in ALLOWED_WORK_TRIP_KEYWORDS) - if not is_allowed_trip and not is_fio_whitelisted: + # 1. Приход в офис при отпуске / больничном + if start_day != "Нет входа" and reason and reason != "nan": + # Удаленная работа и командировки разрешены для работы в офисе + if not ("удален" in reason_lower or "дистанцион" in reason_lower or "командировк" in reason_lower or "поездк" in reason_lower): anomalies.append({ - "type": "ФИЗИЧЕСКОЕ ПРИСУТСТВИЕ ПРИ ОФИЦИАЛЬНОМ ОТСУТСТВИИ", "fio": fio, - "details": f"Сотрудник пришел по СКУД, но в 1С оформлен документ: '{reason_1c}'" + "type": "PHYSICAL_PRESENCE_DURING_ABSENCE", + "description": f"Сотрудник пришел по СКУД ({start_day}), но в 1С оформлен документ: '{reason}'." }) - if is_exc and not has_1c_reason: - continue - - # 2. Перемещение внутри здания без отметки входа на КПП - if anom_flag == 'ANOMALY_NO_IN_HAS_ACTIVITY': - first_act = row.get('Первая_активность', '—') + # 2. Аномалия оборудования (есть выход без входа) + if start_day == "Нет входа" and end_day != "Нет выхода": anomalies.append({ - "type": "АНОМАЛИЯ СКУД: ПЕРЕМЕЩЕНИЕ БЕЗ ВХОДА", "fio": fio, - "details": f"Отсутствует регистрация входа на КПП при зафиксированной первой активности в {first_act}" + "type": "SCUD_EQUIPMENT_ANOMALY", + "description": f"Отсутствует отметка утреннего входа при наличии выхода ({end_day})." }) - # 3. Сотрудник в штате 1С, но карты/профиля в СКУД нет - if scud_fios_set is not None: - if fio_clean not in scud_fios_set and not has_1c_reason: - anomalies.append({ - "type": "АНОМАЛИЯ УЧЕТА: СОТРУДНИК ОТСУТСТВУЕТ В СКУД ОРИОН PRO", - "fio": fio, - "details": f"Сотрудник числится в Штатном расписании 1С ({row.get('Подразделение', '—')}), но отсутствует в СКУД" - }) - return anomalies \ No newline at end of file diff --git a/services/scud_etl/merger.py b/services/scud_etl/merger.py index c168984..bfd9707 100644 --- a/services/scud_etl/merger.py +++ b/services/scud_etl/merger.py @@ -3,112 +3,110 @@ FILE: services/scud_etl/merger.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: services / scud_etl -ROLE: Агрегация проходов, сопоставление исключений и мердж таблиц 1С:ЗУП и СКУД. - -AI-CONTEXT-ANCHORS: - - ANCHOR[MERGER_EXCEPTIONS]: Наложение флага исключений из exceptions.json. - - ANCHOR[MERGER_AGGREGATION]: Агрегация множественных проходов до уникального ФИО. - - ANCHOR[MERGER_BUILD_DATASET]: Сборка итогового датасета для сводок и отчетов. +ROLE: Агрегация реестров СКУД и 1С, наложение исключений, нормализация кодов + подразделений и расчет сходящегося баланса присутствия. =============================================================================== """ -import os -import json +import logging +from typing import Dict, Any, List import pandas as pd -from config import normalize_fio, DATA_DIR + +# Используем правильные имена функций из services/knowledge/service.py +from services.knowledge.service import get_department_synonyms_dict, get_rules + +logger = logging.getLogger("SCUD_MERGER") -# ANCHOR[MERGER_EXCEPTIONS] -def load_exceptions_config() -> dict: - """Загружает exceptions.json из корня проекта.""" - root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) - json_path = os.path.join(root_dir, "exceptions.json") - if not os.path.exists(json_path): - return {} - try: - with open(json_path, 'r', encoding='utf-8') as f: - return json.load(f) - except Exception: - return {} +def merge_scud_and_1c( + df_scud: pd.DataFrame, + df_staff_1c: pd.DataFrame, + df_absences_1c: pd.DataFrame +) -> pd.DataFrame: + """ + Объединяет реестры СКУД и 1С:ЗУП: + - Применяет исключения (уборщики, ОВК и др.). + - Устанавливает короткие аббревиатуры подразделений (КО, ОАН, РУК и др.). + - Привязывает кадровые документы отсутствий из 1С. + """ + # Получаем словарь синонимов + synonyms = get_department_synonyms_dict() + + df_res = df_scud.copy() + if "Сотрудник" in df_res.columns: + df_res["fio_clean"] = df_res["Сотрудник"].astype(str).str.strip() + + # 1. Фильтрация системных исключений + # Загружаем исключения из базы знаний или задаем системный фильтр + excluded_depts = {"ОВК", "Отдел вневедомственного контроля", "Служба уборки", "Клининг"} + excluded_positions = {"Уборщик", "Уборщица", "Дворник"} + + if not df_res.empty: + if "Подразделение" in df_res.columns: + df_res = df_res[~df_res["Подразделение"].astype(str).isin(excluded_depts)] + if "Должность" in df_res.columns: + df_res = df_res[~df_res["Должность"].astype(str).isin(excluded_positions)] + + # 2. Трансляция подразделений в короткие аббревиатуры СКУД + if "Подразделение" in df_res.columns: + df_res["Подразделение"] = df_res["Подразделение"].apply( + lambda d: synonyms.get(d, d) + ) + + # 3. Привязка документов отсутствий из 1С + absences_map = {} + if not df_absences_1c.empty and "Сотрудник" in df_absences_1c.columns and "Причина" in df_absences_1c.columns: + for _, row in df_absences_1c.iterrows(): + fio = str(row["Сотрудник"]).strip() + reason = str(row["Причина"]).strip() + absences_map[fio] = reason + + df_res["причина отсутствия"] = df_res["fio_clean"].map(absences_map) + + return df_res -def apply_exceptions_from_json(df: pd.DataFrame, exceptions_cfg: dict) -> pd.DataFrame: - """Быстрая разметка флага is_excluded на основе exceptions.json.""" - if df is None or df.empty or not exceptions_cfg: - if df is not None: - df['is_excluded'] = False - return df +def calculate_summary_metrics(df_merged: pd.DataFrame) -> Dict[str, Any]: + """ + Расчет строго сходящегося баланса присутствия: + A (Итого на работе) + B (Удаленная работа) + C (Официально отсутствуют) + D (Неизвестно) = N (Всего) + """ + total_staff = len(df_merged) - deps = [d.strip().lower() for d in exceptions_cfg.get("departments", []) if d] - exact_pos = [p.strip().lower() for p in exceptions_cfg.get("positions", []) if p] - pos_kw = [k.strip().lower() for k in exceptions_cfg.get("position_keywords", []) if k] - exc_fios = [normalize_fio(f) for f in exceptions_cfg.get("fio", []) if f] + # 1. Все, кто физически пришел в офис по СКУД (включая удаленщиков, пришедших в офис) + came_to_office_mask = df_merged["Начало_дня"].astype(str).str.strip().ne("Нет входа") + working_in_office = df_merged[came_to_office_mask] + working_in_office_count = len(working_in_office) - df['is_excluded'] = False + # 2. Все, кто сегодня НЕ пришел в офис + not_came_mask = ~came_to_office_mask + df_not_came = df_merged[not_came_mask] - for idx, row in df.iterrows(): - fio_clean = row.get('fio_clean', '') - dep_1c = str(row.get('Подразделение', '')).lower() - dep_scud = str(row.get('department_scud', row.get('department', ''))).lower() - pos = str(row.get('Должность', '')).lower() + # 3. Из непришедших выделяем удаленщиков (работают из дома) + reason_series = df_not_came["причина отсутствия"].astype(str).str.lower() + is_remote_mask = reason_series.str.contains("удален|дистанцион", regex=True, na=False) + + remote_home = df_not_came[is_remote_mask] + remote_home_count = len(remote_home) - is_fio_exc = fio_clean in exc_fios - is_pos_exc = (pos in exact_pos) or any(k in pos for k in pos_kw if k) if pos else False - is_dep_exc = any(d in dep_1c or d in dep_scud for d in deps) if deps else False + # 4. Из оставшихся непришедших выделяем официальные отсутствия (отпуск, больничный, командировка и т.д.) + df_remaining_absent = df_not_came[~is_remote_mask] + has_doc_mask = df_remaining_absent["причина отсутствия"].notna() & \ + df_remaining_absent["причина отсутствия"].ne("") & \ + df_remaining_absent["причина отсутствия"].ne("nan") + + official_absent = df_remaining_absent[has_doc_mask] + official_absent_count = len(official_absent) - if is_fio_exc or is_dep_exc or is_pos_exc: - df.at[idx, 'is_excluded'] = True + # 5. Оставшиеся непришедшие без документов — истинно неизвестные + unknown = df_remaining_absent[~has_doc_mask] + unknown_count = len(unknown) - return df - - -# ANCHOR[MERGER_AGGREGATION] -def aggregate_scud_by_employee(df: pd.DataFrame) -> pd.DataFrame: - """Агрегирует проходы СКУД по уникальным сотрудникам.""" - if df is None or df.empty or 'fio_clean' not in df.columns: - return df - - aggregated = [] - for fio_clean, group in df.groupby('fio_clean', sort=False): - is_present = group['Пришел'].any() if 'Пришел' in group.columns else False - if is_present and 'Пришел' in group.columns: - present_rows = group[group['Пришел'] == True] - best_row = present_rows.iloc[0].to_dict() if not present_rows.empty else group.iloc[0].to_dict() - else: - best_row = group.iloc[0].to_dict() - - best_row['Пришел'] = is_present - aggregated.append(best_row) - - return pd.DataFrame(aggregated) - - -def filter_report_dataframe(merged_df: pd.DataFrame) -> pd.DataFrame: - """Исключает подрядчиков и сотрудников без пропуска из детального отчета.""" - if merged_df is None or merged_df.empty: - return merged_df - - has_1c_reason = ( - merged_df['Вид_отсутствия'].notna() & - (merged_df['Вид_отсутствия'].astype(str).str.strip() != '') & - (~merged_df['Вид_отсутствия'].astype(str).str.startswith('Исключение')) - ) - is_not_excluded = merged_df.get('is_excluded', False) == False - is_not_no_pass = merged_df.get('no_scud_pass', False) == False - - return merged_df[(is_not_excluded & is_not_no_pass) | has_1c_reason].copy() - - -def load_static_reason_workers() -> dict: - """Загружает реестр удаленщиков из CSV.""" - static_path = os.path.join(DATA_DIR, "static_reason_workers.csv") - if not os.path.exists(static_path): - return {} - try: - df_static = pd.read_csv(static_path, encoding='utf-8') - if 'fio' in df_static.columns and 'reason' in df_static.columns: - df_static['fio_clean'] = df_static['fio'].apply(normalize_fio) - return dict(zip(df_static['fio_clean'], df_static['reason'])) - except Exception: - pass - return {} \ No newline at end of file + return { + "total_staff": total_staff, + "working_in_office_count": working_in_office_count, + "remote_home_count": remote_home_count, + "official_absent_count": official_absent_count, + "unknown_count": unknown_count, + "unknown_list": unknown[["fio_clean", "Подразделение", "Должность"]].to_dict(orient="records") if not unknown.empty else [] + } \ No newline at end of file diff --git a/services/scud_etl/pipeline.py b/services/scud_etl/pipeline.py index 6c118b5..f0f783f 100644 --- a/services/scud_etl/pipeline.py +++ b/services/scud_etl/pipeline.py @@ -3,137 +3,64 @@ FILE: services/scud_etl/pipeline.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: services / scud_etl -ROLE: Оркестратор этапов контроллинга (Загрузка -> Сверка -> Отчеты -> SQLite). - -AI-CONTEXT-ANCHORS: - - ANCHOR[PIPELINE_RUN_CONTROLLING]: Главная функция выполнения ETL-конвейера. +ROLE: Оркестрация выборки снапшотов из SQLite и загрузки кадровых файлов 1С. =============================================================================== """ import os -from datetime import datetime, timedelta +import json +import logging +from typing import Optional import pandas as pd -from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR -from core.database import ( - save_scud_to_db, save_staff_to_db, save_absences_to_db, - save_anomalies_to_db, load_scud_from_db_by_snapshot, get_latest_snapshot_time -) -from services.data_loader import load_1c_data_smart -from services.excel_exporter import generate_summary_excel, generate_detailed_excel -from services.ai_verifier import ai_verify_scud_against_staff, analyze_scud_mass_failure_ai -from services.text_reporter import generate_markdown_report -from services.feedback_loop import review_ai_decisions -from services.knowledge_base import load_knowledge_base +from core.connection import get_connection -from .merger import ( - load_exceptions_config, apply_exceptions_from_json, - aggregate_scud_by_employee, filter_report_dataframe, load_static_reason_workers -) -from .anomaly_detector import detect_all_anomalies +logger = logging.getLogger("SCUD_PIPELINE") -# ANCHOR[PIPELINE_RUN_CONTROLLING] -def run_controlling_pipeline(snapshot_param: str = None, skip_export: bool = False, debug: bool = False, has_today_1c: bool = True) -> None: - """Выполняет полный цикл сверки СКУД ⟷ 1С и сохранение результатов.""" - kb_rules = load_knowledge_base().get("rules", []) - exceptions_cfg = load_exceptions_config() - static_reasons = load_static_reason_workers() +def load_best_snapshot_for_date(date_str: str, prefer_final_y: bool = True) -> pd.DataFrame: + """ + Извлекает срез за дату из SQLite. Для отчета за вчера строго ищет + финальный вечерний срез Y (с зафиксированными выходами за 22:00:00). + """ + with get_connection(row_factory=True) as conn: + cursor = conn.cursor() + + if prefer_final_y: + cursor.execute(""" + SELECT raw_data_json + FROM scud_snapshots + WHERE (snapshot_date = ? OR date_str = ?) AND (snapshot_id LIKE 'Y%' OR snapshot_time LIKE '22:00%') + ORDER BY id DESC LIMIT 1 + """, (date_str, date_str)) + row = cursor.fetchone() + if row and row["raw_data_json"]: + data = json.loads(row["raw_data_json"]) + return pd.DataFrame(data) - print("[2/5] Загрузка данных из СКУД, 1С:ЗУП, реестра причин и исключений...") + cursor.execute(""" + SELECT raw_data_json + FROM scud_snapshots + WHERE snapshot_date = ? OR date_str = ? + ORDER BY id DESC LIMIT 1 + """, (date_str, date_str)) + row = cursor.fetchone() + if row and row["raw_data_json"]: + data = json.loads(row["raw_data_json"]) + return pd.DataFrame(data) - # 1. Определение дат целевого снапшота и предыдущей смены - if snapshot_param or skip_export: - snap_to_use = snapshot_param or get_latest_snapshot_time() - raw_scud_today_df = load_scud_from_db_by_snapshot(None, snapshot_param=snap_to_use) - if not raw_scud_today_df.empty and 'log_date' in raw_scud_today_df.columns: - target_date_str = str(raw_scud_today_df['log_date'].iloc[0]) - else: - target_date_str = DATE_TODAY - else: - target_date_str = DATE_TODAY - raw_scud_today_df = load_scud_from_db_by_snapshot(target_date_str, snapshot_param=snapshot_param) + return pd.DataFrame() - dt_target = datetime.strptime(target_date_str, "%d.%m.%Y") - dt_yesterday = dt_target - timedelta(days=3 if dt_target.weekday() == 0 else 1) - yesterday_date_str = dt_yesterday.strftime("%d.%m.%Y") - print(f"[📸] СНАПШОТ ОПРЕДЕЛЕН: Целевая дата = {target_date_str}, Накануне = {yesterday_date_str}\n") +def load_1c_files_for_date(date_str: str) -> tuple[pd.DataFrame, pd.DataFrame]: + """ + Загружает файлы Штат_*.xlsx и Отсутствия_*.xlsx за указанную дату из data/1c/. + """ + formatted_date = date_str.replace(".", "_") + staff_file = f"data/1c/Штат_{formatted_date}.xlsx" + absences_file = f"data/1c/Отсутствия_{formatted_date}.xlsx" - raw_scud_yesterday_df = load_scud_from_db_by_snapshot(yesterday_date_str, snapshot_param=None) - df_staff_yesterday, df_absent_yesterday = load_1c_data_smart(yesterday_date_str, use_db=True) - df_staff_today, df_absent_today = load_1c_data_smart(target_date_str, use_db=True) + df_staff = pd.read_excel(staff_file) if os.path.exists(staff_file) else pd.DataFrame() + df_absences = pd.read_excel(absences_file) if os.path.exists(absences_file) else pd.DataFrame() - # 2. Этап 3: Обработка ВЧЕРА (Детальный отчет) - print(f"[3/5] Обработка и построение детального отчета за ВЧЕРА ({yesterday_date_str})...") - - if df_staff_yesterday is not None: - save_staff_to_db(df_staff_yesterday, yesterday_date_str) - if df_absent_yesterday is not None: - save_absences_to_db(df_absent_yesterday, yesterday_date_str) - - # Проверка опечаток ФИО через AI-аудитор - staff_fios_y_clean = df_staff_yesterday['fio_clean'].dropna().tolist() if df_staff_yesterday is not None else [] - if not raw_scud_yesterday_df.empty: - raw_scud_yesterday_df['Пришел'] = raw_scud_yesterday_df['is_present'].astype(int) == 1 if 'is_present' in raw_scud_yesterday_df.columns else False - unrecog = raw_scud_yesterday_df[~raw_scud_yesterday_df['fio_clean'].isin(staff_fios_y_clean)]['fio_clean'].tolist() - fio_map = ai_verify_scud_against_staff(unrecog, staff_fios_y_clean) - if fio_map: - raw_scud_yesterday_df['fio_clean'] = raw_scud_yesterday_df['fio_clean'].apply(lambda x: fio_map[x]['staff_fio'] if x in fio_map else x) - - raw_scud_yesterday_df = aggregate_scud_by_employee(raw_scud_yesterday_df) - merged_y = (df_staff_yesterday.copy() if df_staff_yesterday is not None else pd.DataFrame()) - - if not merged_y.empty: - if not raw_scud_yesterday_df.empty: - merged_y = merged_y.merge( - raw_scud_yesterday_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag']], - on='fio_clean', how='left' - ) - if df_absent_yesterday is not None and not df_absent_yesterday.empty: - merged_y = merged_y.merge(df_absent_yesterday[['fio_clean', 'Вид_отсутствия']], on='fio_clean', how='left') - - merged_y['Пришел'] = merged_y['Пришел'].fillna(False) if 'Пришел' in merged_y.columns else False - if 'Сотрудник' not in merged_y.columns: - merged_y['Сотрудник'] = merged_y.get('ФИО', merged_y['fio_clean']) - - merged_y = apply_exceptions_from_json(merged_y, exceptions_cfg) - - scud_fios_y = set(raw_scud_yesterday_df['fio_clean'].dropna().tolist()) if not raw_scud_yesterday_df.empty else set() - anomalies_y = detect_all_anomalies(merged_y, static_reasons, kb_rules, scud_fios_set=scud_fios_y) - save_anomalies_to_db(anomalies_y, yesterday_date_str) - - filtered_y = filter_report_dataframe(merged_y) - generate_detailed_excel(merged_df=filtered_y, date_str=yesterday_date_str) - save_scud_to_db(merged_y, yesterday_date_str, snapshot_time=f"{dt_yesterday.strftime('%Y-%m-%d')} 22:00:00", is_yesterday=True) - print(f"[✓] Детальный отчет за вчера сформирован и зафиксирован в SQLite за {yesterday_date_str}") - - # 3. Этап 4 & 5: Обработка СЕГОДНЯ (Ежедневная сводка) - if has_today_1c and df_staff_today is not None and df_absent_today is not None: - print(f"\n[4/5] Обработка и построение Ежедневной сводки за {target_date_str}...") - save_staff_to_db(df_staff_today, target_date_str) - save_absences_to_db(df_absent_today, target_date_str) - - raw_scud_today_df = aggregate_scud_by_employee(raw_scud_today_df) - merged_t = df_staff_today.copy() - if not raw_scud_today_df.empty: - merged_t = merged_t.merge( - raw_scud_today_df[['fio_clean', 'Пришел', 'Начало_дня', 'Первая_активность', 'Конец_дня', 'Находился_в_здании', 'anomaly_flag']], - on='fio_clean', how='left' - ) - merged_t = merged_t.merge(df_absent_today[['fio_clean', 'Вид_отсутствия']], on='fio_clean', how='left') - merged_t['Пришел'] = merged_t['Пришел'].fillna(False) if 'Пришел' in merged_t.columns else False - if 'Сотрудник' not in merged_t.columns: - merged_t['Сотрудник'] = merged_t.get('ФИО', merged_t['fio_clean']) - - merged_t = apply_exceptions_from_json(merged_t, exceptions_cfg) - - scud_fios_t = set(raw_scud_today_df['fio_clean'].dropna().tolist()) if not raw_scud_today_df.empty else set() - anomalies_t = detect_all_anomalies(merged_t, static_reasons, kb_rules, scud_fios_set=scud_fios_t) - save_anomalies_to_db(anomalies_t, target_date_str) - - print("[5/5] Сохранение Ежедневной сводки...") - generate_summary_excel(merged_df=merged_t, date_str=target_date_str) - print(f"[✓] Ежедневная сводка сохранена за {target_date_str}") - else: - print(f"\n[ℹ️] Формирование Ежедневной сводки за {target_date_str} ПРОПУЩЕНО.") \ No newline at end of file + return df_staff, df_absences \ No newline at end of file diff --git a/services/snapshots/service.py b/services/snapshots/service.py new file mode 100644 index 0000000..b3c174f --- /dev/null +++ b/services/snapshots/service.py @@ -0,0 +1,69 @@ +""" +=============================================================================== +FILE: services/snapshots/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / snapshots +ROLE: Бизнес-логика срезов СКУД (выборка, валидация Y-срезов, удаление). + +AI-CONTEXT-ANCHORS: + - ANCHOR[SNAPSHOT_GET_REGISTRY]: Выборка срезов с разметкой защищенных Y-снапшотов. + - ANCHOR[SNAPSHOT_DELETE_SAFE]: Безопасное удаление дневных срезов с защитой итоговых. +=============================================================================== +""" + +from typing import Dict, Any, Optional, List +from core.connection import get_connection +from core.repositories.scud_repo import get_available_snapshots, delete_snapshot_by_id + + +# ANCHOR[SNAPSHOT_GET_REGISTRY] +def get_snapshots_registry(date_str: Optional[str] = None) -> Dict[str, Any]: + """Возвращает реестр снапшотов за дату или за все доступные дни.""" + clean_date = date_str.strip() if date_str else "" + rows = get_available_snapshots(date_str=clean_date if clean_date else None) + + snapshots = [ + { + "snapshot_id": r[0], + "log_date": r[1], + "snapshot_time": r[2], + "record_count": r[3], + "is_final": str(r[0]).startswith("Y") + } + for r in rows + ] + + return { + "query_date": clean_date or "все", + "snapshots_count": len(snapshots), + "snapshots": snapshots + } + + +# ANCHOR[SNAPSHOT_DELETE_SAFE] +def delete_snapshots_safely(snapshot_ids: List[str]) -> Dict[str, Any]: + """ + Удаляет выбранные дневные снапшоты. + Итоговые вечерние срезы с префиксом 'Y' гарантированно защищены от удаления. + """ + if not snapshot_ids: + return {"status": "error", "message": "Не указаны ID снапшотов для удаления."} + + safe_ids = [str(s).strip() for s in snapshot_ids if s and not str(s).strip().startswith("Y")] + + if not safe_ids: + return {"status": "error", "message": "⚠️ Итоговый срез Y защищен от удаления. Выберите дневные снапшоты."} + + with get_connection() as conn: + cursor = conn.cursor() + placeholders = ",".join(["?"] * len(safe_ids)) + cursor.execute(f"DELETE FROM scud_logs WHERE snapshot_id IN ({placeholders})", safe_ids) + deleted_count = cursor.rowcount + conn.commit() + + return { + "status": "success", + "deleted_count": deleted_count, + "deleted_ids": safe_ids, + "message": f"Успешно удалено снапшотов: {len(safe_ids)} шт." + } \ No newline at end of file diff --git a/services/text_reporter/__init__.py b/services/text_reporter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/text_reporter/service.py b/services/text_reporter/service.py new file mode 100644 index 0000000..a031c8e --- /dev/null +++ b/services/text_reporter/service.py @@ -0,0 +1,49 @@ +""" +=============================================================================== +FILE: services/text_reporter/service.py +PROJECT: SCUD Orion AI (Unified Architecture) +MODULE: services / text_reporter +ROLE: Формирование текстовой сводки ИИ-аудитора для вывода в консоль и сохранения в MD. +=============================================================================== +""" + +from typing import Dict, Any, List + + +def format_controlling_summary_markdown( + target_date: str, + metrics: Dict[str, Any], + anomalies: List[Dict[str, Any]] +) -> str: + """Генерирует Markdown-текст ежедневной сводки контроллинга.""" + lines = [ + f"**Сводка контроллинга СКУД и 1С:ЗУП на {target_date}**\n", + f"- Всего сотрудников по штату: **{metrics['total_staff']}**", + f"- Итого на работе (в офисе): **{metrics['working_in_office_count']}**", + f"- Удаленная работа (из дома): **{metrics['remote_home_count']}**", + f"- Официально отсутствуют: **{metrics['official_absent_count']}**", + f"- Неизвестно (истинно неотмеченные): **{metrics['unknown_count']}** чел.", + f"- Выявлено аномалий/конфликтов реестров: **{len(anomalies)}** шт.\n" + ] + + # Блок аномалий + lines.append(f"#### 🚨 Выявленные ИИ аномалии и конфликты источников ({len(anomalies)}):") + if anomalies: + for idx, a in enumerate(anomalies, 1): + lines.append(f"{idx}. {a['fio']}: {a['description']}") + else: + lines.append("Конфликтов и аномалий реестров не обнаружено.") + lines.append("") + + # Блок неизвестных + unknown_list = metrics.get("unknown_list", []) + lines.append(f"#### ❓ Неизвестные случаи ({len(unknown_list)}):") + if unknown_list: + for idx, u in enumerate(unknown_list, 1): + dept = u.get("Подразделение") or "—" + pos = u.get("Должность") or "—" + lines.append(f"{idx}. {u.get('fio_clean')} — {dept}, {pos}") + else: + lines.append("Все отсутствия подтверждены документами.") + + return "\n".join(lines) \ No newline at end of file