"""CRUD для очереди исключений и сохранения решений оператора.""" import json import uuid from db.connection import execute, query def add_exception(batch_id, dossier_id, document_id, service_item_id, severity, stage, title, source_quote="", options=None): """Добавить конкретную нерешённую задачу и вернуть её запись.""" exception_id = str(uuid.uuid4()) options_json = json.dumps(options or [], ensure_ascii=False, default=str) execute( """INSERT INTO exceptions_queue (id, batch_id, dossier_id, document_id, service_item_id, severity, stage, title, source_quote, options_json) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (exception_id, batch_id, dossier_id, document_id, service_item_id, severity, stage, title, source_quote or "", options_json), ) return get_exception(exception_id) def get_exception(exception_id): """Получить исключение по ID и декодировать варианты решения.""" rows = query("SELECT * FROM exceptions_queue WHERE id = %s", (exception_id,)) if not rows: return None result = dict(rows[0]) try: result["options"] = json.loads(result.get("options_json") or "[]") except (TypeError, json.JSONDecodeError): result["options"] = [] try: result["resolution"] = json.loads(result.get("resolution_json") or "null") except (TypeError, json.JSONDecodeError): result["resolution"] = None return result def list_exceptions(batch_id=None, dossier_id=None, status=None): """Список исключений с необязательными фильтрами batch/dossier/status.""" clauses = [] params = [] for field, value in (("batch_id", batch_id), ("dossier_id", dossier_id), ("status", status)): if value is not None: clauses.append(f"{field} = %s") params.append(value) where = f" WHERE {' AND '.join(clauses)}" if clauses else "" rows = query( f"SELECT id FROM exceptions_queue{where} ORDER BY created_at, id", params, ) return [get_exception(row["id"]) for row in rows] def resolve_exception(exception_id, resolution): """Сохранить решение без удаления исходной причины и цитаты. Пересчёт зависимых данных выполняет сервисный слой; CRUD отвечает только за аудируемую фиксацию решения человека. """ resolution_json = json.dumps(resolution, ensure_ascii=False, default=str) changed = execute( """UPDATE exceptions_queue SET resolution_json = %s, status = 'RESOLVED', resolved_at = datetime('now') WHERE id = %s AND status = 'OPEN'""", (resolution_json, exception_id), ) return get_exception(exception_id) if changed else None