v2.0.2: fix SQLite — UUID in all INSERTs, now()→datetime, ::jsonb cleanup
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
"""Конфигурация приложения — все настройки в одном месте."""
|
||||
import os
|
||||
|
||||
VERSION = "2.0.1"
|
||||
VERSION = "2.0.2"
|
||||
|
||||
LLM_URL = os.getenv("LLM_API_URL", "https://api.aillm.ru/v1/chat/completions")
|
||||
LLM_KEY = os.getenv("LLM_API_KEY", "")
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"""Contracts CRUD."""
|
||||
from db.connection import query, execute, execute_returning
|
||||
import uuid
|
||||
from db.connection import query, execute
|
||||
|
||||
|
||||
def insert(number, client=""):
|
||||
return execute_returning(
|
||||
"INSERT INTO contracts (number, client) VALUES (%s, %s) RETURNING *",
|
||||
(number, client),
|
||||
cid = str(uuid.uuid4())
|
||||
execute(
|
||||
"INSERT INTO contracts (id, number, client) VALUES (%s, %s, %s)",
|
||||
(cid, number, client),
|
||||
)
|
||||
return get(cid)
|
||||
|
||||
|
||||
def get(contract_id):
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
"""Documents CRUD."""
|
||||
import uuid
|
||||
from db.connection import query, execute, execute_returning
|
||||
|
||||
|
||||
def insert(filename, mime_type, original_bytes, status="uploaded", batch_id=None, zip_source=None, content_hash=None):
|
||||
"""Insert document, return row dict."""
|
||||
return execute_returning(
|
||||
"""INSERT INTO documents (filename, mime_type, original_bytes, status, batch_id, zip_source, content_hash)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING *""",
|
||||
(filename, mime_type, original_bytes, status, batch_id, zip_source, content_hash),
|
||||
doc_id = str(uuid.uuid4())
|
||||
execute(
|
||||
"""INSERT INTO documents (id, filename, mime_type, original_bytes, status, batch_id, zip_source, content_hash)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(doc_id, filename, mime_type, original_bytes, status, batch_id, zip_source, content_hash),
|
||||
)
|
||||
return get(doc_id)
|
||||
|
||||
|
||||
def get(doc_id):
|
||||
|
||||
+12
-9
@@ -1,5 +1,6 @@
|
||||
"""Prompts CRUD."""
|
||||
from db.connection import query, execute, execute_returning
|
||||
import uuid
|
||||
from db.connection import query, execute
|
||||
|
||||
|
||||
def _serialize(row):
|
||||
@@ -46,8 +47,8 @@ def seed_defaults():
|
||||
"ТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---"
|
||||
)
|
||||
execute(
|
||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||
("extract", "default-v1", extract_body, True, "Авто-создан из llm_prompt.py _build_initial"),
|
||||
"INSERT INTO prompts (id, role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s, %s)",
|
||||
(str(uuid.uuid4()), "extract", "default-v1", extract_body, True, "Авто-создан из llm_prompt.py _build_initial"),
|
||||
)
|
||||
|
||||
if "diff" not in existing_roles:
|
||||
@@ -75,8 +76,8 @@ def seed_defaults():
|
||||
"ТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---"
|
||||
)
|
||||
execute(
|
||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||
("diff", "default-v1", diff_body, True, "Авто-создан из llm_prompt.py _build_diff"),
|
||||
"INSERT INTO prompts (id, role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s, %s)",
|
||||
(str(uuid.uuid4()), "diff", "default-v1", diff_body, True, "Авто-создан из llm_prompt.py _build_diff"),
|
||||
)
|
||||
_ensure_classify_prompt()
|
||||
|
||||
@@ -97,11 +98,13 @@ def save_new_version(role, name, body, notes="", is_active=True):
|
||||
"""Save new prompt version. Deactivates all others for this role, inserts new one."""
|
||||
if is_active:
|
||||
execute("UPDATE prompts SET is_active=false WHERE role=%s", (role,))
|
||||
return execute_returning(
|
||||
"""INSERT INTO prompts (role, name, body, is_active, notes)
|
||||
VALUES (%s, %s, %s, %s, %s) RETURNING *""",
|
||||
(role, name, body, is_active, notes),
|
||||
pid = str(uuid.uuid4())
|
||||
execute(
|
||||
"""INSERT INTO prompts (id, role, name, body, is_active, notes)
|
||||
VALUES (%s, %s, %s, %s, %s, %s)""",
|
||||
(pid, role, name, body, is_active, notes),
|
||||
)
|
||||
return get(pid)
|
||||
|
||||
|
||||
def activate(prompt_id):
|
||||
|
||||
+20
-20
@@ -40,11 +40,11 @@ def apply_ops(contract_id, supplement_id, document_id, ops, prompt_id, raw_llm_r
|
||||
continue
|
||||
name_hash = _hash(name, nr.get("date_start"))
|
||||
execute(
|
||||
"""INSERT INTO spec_events (contract_id, supplement_id, seq, action, target_hash,
|
||||
"""INSERT INTO spec_events (id, contract_id, supplement_id, seq, action, target_hash,
|
||||
new_values, comment, status, prompt_version, source_document_id, raw_llm_response)
|
||||
VALUES (%s, %s, %s, 'ADD', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
VALUES (%s, %s, %s, %s, 'ADD', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
(
|
||||
contract_id, supplement_id, seq, name_hash,
|
||||
str(uuid.uuid4()), contract_id, supplement_id, seq, name_hash,
|
||||
json.dumps(nr, ensure_ascii=False),
|
||||
op.get("comment", ""), prompt_id, document_id,
|
||||
json.dumps(raw_llm_response, ensure_ascii=False),
|
||||
@@ -62,11 +62,11 @@ def apply_ops(contract_id, supplement_id, document_id, ops, prompt_id, raw_llm_r
|
||||
seq += 1
|
||||
continue
|
||||
execute(
|
||||
"""INSERT INTO spec_events (contract_id, supplement_id, seq, action, target_hash,
|
||||
"""INSERT INTO spec_events (id, contract_id, supplement_id, seq, action, target_hash,
|
||||
new_values, comment, status, prompt_version, source_document_id, raw_llm_response)
|
||||
VALUES (%s, %s, %s, 'UPDATE', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
VALUES (%s, %s, %s, %s, 'UPDATE', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
(
|
||||
contract_id, supplement_id, seq, th,
|
||||
str(uuid.uuid4()), contract_id, supplement_id, seq, th,
|
||||
json.dumps(nv, ensure_ascii=False),
|
||||
op.get("comment", ""), prompt_id, document_id,
|
||||
json.dumps(raw_llm_response, ensure_ascii=False),
|
||||
@@ -83,11 +83,11 @@ def apply_ops(contract_id, supplement_id, document_id, ops, prompt_id, raw_llm_r
|
||||
seq += 1
|
||||
continue
|
||||
execute(
|
||||
"""INSERT INTO spec_events (contract_id, supplement_id, seq, action, target_hash,
|
||||
"""INSERT INTO spec_events (id, contract_id, supplement_id, seq, action, target_hash,
|
||||
new_values, comment, status, prompt_version, source_document_id, raw_llm_response)
|
||||
VALUES (%s, %s, %s, 'DELETE', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
VALUES (%s, %s, %s, %s, 'DELETE', %s, %s, %s, 'applied', %s, %s, %s)""",
|
||||
(
|
||||
contract_id, supplement_id, seq, th,
|
||||
str(uuid.uuid4()), contract_id, supplement_id, seq, th,
|
||||
json.dumps({}), op.get("comment", ""),
|
||||
prompt_id, document_id,
|
||||
json.dumps(raw_llm_response, ensure_ascii=False),
|
||||
@@ -100,11 +100,11 @@ def apply_ops(contract_id, supplement_id, document_id, ops, prompt_id, raw_llm_r
|
||||
elif action == "UNRESOLVED":
|
||||
# Log but don't apply
|
||||
execute(
|
||||
"""INSERT INTO spec_events (contract_id, supplement_id, seq, action, target_hash,
|
||||
"""INSERT INTO spec_events (id, contract_id, supplement_id, seq, action, target_hash,
|
||||
new_values, comment, status, prompt_version, source_document_id, raw_llm_response)
|
||||
VALUES (%s, %s, %s, 'UNRESOLVED', %s, %s, %s, 'unresolved', %s, %s, %s)""",
|
||||
VALUES (%s, %s, %s, %s, 'UNRESOLVED', %s, %s, %s, 'unresolved', %s, %s, %s)""",
|
||||
(
|
||||
contract_id, supplement_id, seq,
|
||||
str(uuid.uuid4()), contract_id, supplement_id, seq,
|
||||
op.get("target_hash", ""),
|
||||
json.dumps(op.get("new_values", {}), ensure_ascii=False),
|
||||
op.get("reason", op.get("comment", "")),
|
||||
@@ -125,11 +125,11 @@ def apply_ops(contract_id, supplement_id, document_id, ops, prompt_id, raw_llm_r
|
||||
def _log_unresolved(contract_id, supplement_id, seq, op, prompt_id, document_id, raw_llm_response, reason):
|
||||
"""Log an op as UNRESOLVED instead of silently ignoring it."""
|
||||
execute(
|
||||
"""INSERT INTO spec_events (contract_id, supplement_id, seq, action, target_hash,
|
||||
"""INSERT INTO spec_events (id, contract_id, supplement_id, seq, action, target_hash,
|
||||
new_values, comment, status, prompt_version, source_document_id, raw_llm_response)
|
||||
VALUES (%s, %s, %s, 'UNRESOLVED', %s, %s, %s, 'unresolved', %s, %s, %s)""",
|
||||
VALUES (%s, %s, %s, %s, 'UNRESOLVED', %s, %s, %s, 'unresolved', %s, %s, %s)""",
|
||||
(
|
||||
contract_id, supplement_id, seq,
|
||||
str(uuid.uuid4()), contract_id, supplement_id, seq,
|
||||
op.get("target_hash", ""),
|
||||
json.dumps(op.get("new_values", op.get("new_row", {})) or {}, ensure_ascii=False),
|
||||
reason,
|
||||
@@ -159,16 +159,16 @@ def _upsert_spec_current(contract_id, name_hash, row):
|
||||
)
|
||||
if existing:
|
||||
execute(
|
||||
"""UPDATE spec_current SET name=%s, price=%s, qty=%s, sum=%s, date_start=%s, updated_at=now()
|
||||
"""UPDATE spec_current SET name=%s, price=%s, qty=%s, sum=%s, date_start=%s, updated_at=datetime('now')
|
||||
WHERE contract_id=%s AND name_hash=%s""",
|
||||
(row.get("name"), row.get("price"), row.get("qty"), row.get("sum"),
|
||||
row.get("date_start"), contract_id, name_hash),
|
||||
)
|
||||
else:
|
||||
execute(
|
||||
"""INSERT INTO spec_current (contract_id, name_hash, name, price, qty, sum, date_start)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s)""",
|
||||
(contract_id, name_hash, row.get("name"), row.get("price"),
|
||||
"""INSERT INTO spec_current (id, contract_id, name_hash, name, price, qty, sum, date_start)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(str(uuid.uuid4()), contract_id, name_hash, row.get("name"), row.get("price"),
|
||||
row.get("qty"), row.get("sum"), row.get("date_start")),
|
||||
)
|
||||
|
||||
@@ -182,7 +182,7 @@ def _update_spec_current(contract_id, name_hash, new_values):
|
||||
sets.append(f"{field} = %s")
|
||||
params.append(new_values[field])
|
||||
if sets:
|
||||
sets.append("updated_at = now()")
|
||||
sets.append("updated_at = datetime('now')")
|
||||
params.extend([contract_id, name_hash])
|
||||
execute(
|
||||
f"UPDATE spec_current SET {', '.join(sets)} WHERE contract_id = %s AND name_hash = %s",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
"""Supplements CRUD."""
|
||||
from db.connection import query, execute, execute_returning
|
||||
import uuid
|
||||
from db.connection import query, execute
|
||||
|
||||
|
||||
def insert(contract_id, document_id, supp_type="additional"):
|
||||
return execute_returning(
|
||||
"""INSERT INTO supplements (contract_id, document_id, type)
|
||||
VALUES (%s, %s, %s) RETURNING *""",
|
||||
(contract_id, document_id, supp_type),
|
||||
sid = str(uuid.uuid4())
|
||||
execute(
|
||||
"""INSERT INTO supplements (id, contract_id, document_id, type)
|
||||
VALUES (%s, %s, %s, %s)""",
|
||||
(sid, contract_id, document_id, supp_type),
|
||||
)
|
||||
return get(sid)
|
||||
|
||||
|
||||
def list_by_contract(contract_id):
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<body>
|
||||
<div class="topbar">
|
||||
<img src="/static/logo.svg" alt="Nubes">
|
||||
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v2.0.1</span></span>
|
||||
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v2.0.2</span></span>
|
||||
<div id="pipelineStepper" style="display:flex;gap:8px;font-size:11px;align-items:center;color:var(--muted);">
|
||||
<span id="stepUpload">○ Загрузка</span><span>→</span>
|
||||
<span id="stepClassify">○ Классификация</span><span>→</span>
|
||||
|
||||
Reference in New Issue
Block a user