feat(верификация): рабочая очередь с пагинацией + /skip

- автодогрузка порций + кнопка «Загрузить ещё»; разбор сверху по уверенности
- POST /skip фиксирует пропуск (таблица skipped_item), очередь его исключает

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-27 10:58:10 +05:00
parent 1ff5d93cd8
commit 89928511ba
2 changed files with 29 additions and 4 deletions
+14 -1
View File
@@ -36,6 +36,8 @@ app.add_middleware(
def db() -> sqlite3.Connection:
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
# Отложенные оператором позиции (чтобы пропущенное не возвращалось в начало очереди).
conn.execute("CREATE TABLE IF NOT EXISTS skipped_item (item_id INTEGER PRIMARY KEY)")
return conn
@@ -155,6 +157,7 @@ def unmatched(limit: int = 50, offset: int = 0):
JOIN partner p ON pi.partner_id = p.partner_id
LEFT JOIN service s ON pi.suggested_service_id = s.service_id
WHERE pi.service_id IS NULL AND pi.is_active = 1
AND pi.item_id NOT IN (SELECT item_id FROM skipped_item)
ORDER BY pi.suggested_score DESC, pi.item_id
LIMIT ? OFFSET ?"""
with db() as conn:
@@ -184,12 +187,22 @@ def unmatched(limit: int = 50, offset: int = 0):
def unmatched_count():
with db() as conn:
n = conn.execute(
"SELECT COUNT(*) FROM price_item WHERE service_id IS NULL AND is_active = 1"
"""SELECT COUNT(*) FROM price_item
WHERE service_id IS NULL AND is_active = 1
AND item_id NOT IN (SELECT item_id FROM skipped_item)"""
).fetchone()[0]
learned = conn.execute("SELECT COUNT(*) FROM learned_synonym").fetchone()[0]
return {"remaining": n, "learned_synonyms": learned}
@app.post("/skip", summary="Отложить позицию (пропустить в очереди верификации)")
def skip_item(item_id: int):
with db() as conn:
conn.execute("INSERT OR IGNORE INTO skipped_item (item_id) VALUES (?)", [item_id])
conn.commit()
return {"item_id": item_id, "status": "skipped"}
@app.post("/match", summary="Ручное сопоставление позиции (с дообучением)")
def manual_match(item_id: int, service_id: str):
with db() as conn: