Integrate Obfuscator file picker into Contracts
Deploy contracts-flask / validate (push) Canceled after 0s
Deploy contracts-flask / validate (push) Canceled after 0s
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
+44
-36
@@ -1,7 +1,7 @@
|
||||
"""API blueprint — groups, documents, supplements, sync, cleanup, spec-current, chat."""
|
||||
from flask import Blueprint, request, jsonify
|
||||
from db import documents, supplements, spec_current
|
||||
from db.connection import execute, query
|
||||
from db.connection import execute, query, transaction
|
||||
from services.grouping import group_documents, apply_groups
|
||||
from config import LLM_URL, LLM_KEY, LLM_MODEL
|
||||
import httpx
|
||||
@@ -38,47 +38,65 @@ def api_document(doc_id):
|
||||
|
||||
@api_bp.route("/api/documents/<doc_id>", methods=["DELETE"])
|
||||
def api_document_delete(doc_id):
|
||||
if not documents.get(doc_id):
|
||||
return jsonify(ok=False, error="not found"), 404
|
||||
with transaction():
|
||||
contract_ids = _delete_document(doc_id)
|
||||
_delete_orphan_contracts(contract_ids)
|
||||
return jsonify(ok=True)
|
||||
|
||||
|
||||
def _delete_document(doc_id):
|
||||
supps = query("SELECT id, contract_id FROM supplements WHERE document_id = %s", (doc_id,))
|
||||
for s in (supps or []):
|
||||
contract_ids = {row["contract_id"] for row in supps}
|
||||
for supp in supps:
|
||||
execute(
|
||||
"""DELETE FROM spec_current WHERE contract_id = %s
|
||||
AND last_event_id IN (SELECT id FROM spec_events WHERE supplement_id = %s)""",
|
||||
(s["contract_id"], s["id"]),
|
||||
(supp["contract_id"], supp["id"]),
|
||||
)
|
||||
execute("DELETE FROM spec_events WHERE supplement_id = %s", (s["id"],))
|
||||
execute("DELETE FROM supplements WHERE id = %s", (s["id"],))
|
||||
execute("DELETE FROM spec_events WHERE supplement_id = %s", (supp["id"],))
|
||||
execute("DELETE FROM supplements WHERE id = %s", (supp["id"],))
|
||||
execute("DELETE FROM documents WHERE id = %s", (doc_id,))
|
||||
return jsonify(ok=True)
|
||||
return contract_ids
|
||||
|
||||
|
||||
def _delete_orphan_contracts(contract_ids):
|
||||
for contract_id in contract_ids:
|
||||
remaining = query(
|
||||
"SELECT id FROM supplements WHERE contract_id = %s LIMIT 1",
|
||||
(contract_id,),
|
||||
)
|
||||
if not remaining:
|
||||
execute("DELETE FROM contracts WHERE id = %s", (contract_id,))
|
||||
|
||||
|
||||
# ── Sync ─────────────────────────────────────────────────────────
|
||||
|
||||
@api_bp.route("/api/sync", methods=["POST"])
|
||||
def api_sync():
|
||||
"""Удалить документы, не входящие в keep_ids."""
|
||||
body = request.get_json()
|
||||
keep_ids = set(body.get("keep_ids", []))
|
||||
"""Remove documents absent from keep_ids in the specified batch only."""
|
||||
body = request.get_json(silent=True) or {}
|
||||
batch_id = body.get("batch_id")
|
||||
keep_ids = body.get("keep_ids", [])
|
||||
if not isinstance(batch_id, str) or not batch_id.strip():
|
||||
return jsonify(ok=False, error="batch_id required"), 400
|
||||
if not isinstance(keep_ids, list) or any(not isinstance(doc_id, str) for doc_id in keep_ids):
|
||||
return jsonify(ok=False, error="keep_ids must be a list of document IDs"), 400
|
||||
if len(keep_ids) > 1000:
|
||||
return jsonify(ok=False, error="too many keep_ids (max 1000)"), 400
|
||||
|
||||
docs = query("SELECT id FROM documents", ())
|
||||
docs = query("SELECT id FROM documents WHERE batch_id = %s", (batch_id,))
|
||||
deleted = 0
|
||||
for d in (docs or []):
|
||||
if d["id"] in keep_ids:
|
||||
continue
|
||||
supps = query("SELECT id, contract_id FROM supplements WHERE document_id = %s", (d["id"],))
|
||||
for s in (supps or []):
|
||||
execute(
|
||||
"""DELETE FROM spec_current WHERE contract_id = %s
|
||||
AND last_event_id IN (SELECT id FROM spec_events WHERE supplement_id = %s)""",
|
||||
(s["contract_id"], s["id"]),
|
||||
)
|
||||
execute("DELETE FROM spec_events WHERE supplement_id = %s", (s["id"],))
|
||||
execute("DELETE FROM supplements WHERE id = %s", (s["id"],))
|
||||
execute("DELETE FROM documents WHERE id = %s", (d["id"],))
|
||||
deleted += 1
|
||||
|
||||
execute("DELETE FROM contracts WHERE id NOT IN (SELECT DISTINCT contract_id FROM supplements)")
|
||||
contract_ids = set()
|
||||
keep_ids = set(keep_ids)
|
||||
with transaction():
|
||||
for doc in docs:
|
||||
if doc["id"] in keep_ids:
|
||||
continue
|
||||
contract_ids.update(_delete_document(doc["id"]))
|
||||
deleted += 1
|
||||
_delete_orphan_contracts(contract_ids)
|
||||
return jsonify(ok=True, deleted=deleted)
|
||||
|
||||
|
||||
@@ -170,13 +188,3 @@ def chat():
|
||||
return jsonify(OK=True, ANSWER=answer)
|
||||
except Exception as e:
|
||||
return jsonify(OK=False, ERROR=f"LLM error: {e}")
|
||||
|
||||
|
||||
# ── Cleanup (атомарное удаление БД) ──────────────────────────────
|
||||
|
||||
@api_bp.route("/api/cleanup", methods=["POST"])
|
||||
def api_cleanup():
|
||||
"""Полная очистка: os.remove(DB) + init новой. Данные гарантированно стёрты."""
|
||||
from db.connection import cleanup_db
|
||||
cleanup_db()
|
||||
return jsonify(ok=True, message="all data cleaned")
|
||||
|
||||
Reference in New Issue
Block a user