feat: add v3 extraction storage and structured parsing
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user