Нормализовать переводы строк в LF
Решение по TD-STYLE-ANALYZERS: LF — инструменты проекта (Python/Node) пишут LF, CRLF-.sh не работают на Linux CI (sh scripts/ci.sh), большинство файлов уже были LF. Добавлен .gitattributes (* text=auto eol=lf, бинарные исключения), .editorconfig переведён на lf, 1029 файлов конвертированы, git add --renormalize. Из индекса убраны закравшиеся archive/**/__pycache__/*.pyc.
This commit is contained in:
@@ -1,74 +1,74 @@
|
||||
"""Мониторинг пайплайна — вкладка «Обработка» (очередь и отсев)."""
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ..auth import current_login
|
||||
from ..services import processing as processing_svc
|
||||
|
||||
router = APIRouter(prefix="/api/pipeline", tags=["processing"])
|
||||
|
||||
|
||||
class ReturnBody(BaseModel):
|
||||
reason: str = ""
|
||||
|
||||
|
||||
@router.get("/stats")
|
||||
def stats(_: str = Depends(current_login)) -> dict:
|
||||
"""Сводка: размер очереди (new/ai) и число записей в отсеве."""
|
||||
return processing_svc.stats()
|
||||
|
||||
|
||||
@router.get("/queue")
|
||||
def queue(limit: int = 100, _: str = Depends(current_login)) -> dict:
|
||||
"""Сырые сообщения, ожидающие обработки (этап 1 или ИИ)."""
|
||||
q = processing_svc.queue_counts()
|
||||
return {
|
||||
"items": processing_svc.list_queue(limit),
|
||||
"counts": q,
|
||||
"rejected": processing_svc.rejected_count(),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/rejected")
|
||||
def rejected(
|
||||
q: str = "",
|
||||
offset: int = 0,
|
||||
limit: int = 100,
|
||||
_: str = Depends(current_login),
|
||||
) -> dict:
|
||||
"""Отсев: что и почему не прошло пайплайн (полнотекстовый поиск по q)."""
|
||||
return processing_svc.list_rejected(q, offset, limit)
|
||||
|
||||
|
||||
@router.post("/rejected/clear")
|
||||
def rejected_clear(_: str = Depends(current_login)) -> dict:
|
||||
"""Ручная полная очистка отсева (безвозвратно)."""
|
||||
cleared = processing_svc.clear_all()
|
||||
return {"ok": True, "cleared": cleared}
|
||||
|
||||
|
||||
@router.delete("/rejected/{rej_id}")
|
||||
def rejected_delete(rej_id: str, _: str = Depends(current_login)) -> dict:
|
||||
processing_svc.delete_one(rej_id)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.post("/rejected/{rej_id}/return")
|
||||
def rejected_return(rej_id: str, body: ReturnBody, _: str = Depends(current_login)) -> dict:
|
||||
"""Вернуть отсеянное сообщение в обработку.
|
||||
|
||||
Для возвращённого сообщения причины отсева (стоп-лист, резюме, тип,
|
||||
без суммы, устарело, ML/ИИ-спам) игнорируются: оно уходит на ML/ИИ
|
||||
и создаёт карточку. ML обучается на действии (снятие «спама»), а решение
|
||||
ИИ по возвращённому сообщению снова учит ML. Запись в отсеве помечается
|
||||
«возвращено» с указанной пользователем причиной.
|
||||
"""
|
||||
try:
|
||||
out = processing_svc.return_to_queue(rej_id, body.reason)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(404, "Запись не найдена") from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(400, str(exc)) from exc
|
||||
return out
|
||||
"""Мониторинг пайплайна — вкладка «Обработка» (очередь и отсев)."""
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ..auth import current_login
|
||||
from ..services import processing as processing_svc
|
||||
|
||||
router = APIRouter(prefix="/api/pipeline", tags=["processing"])
|
||||
|
||||
|
||||
class ReturnBody(BaseModel):
|
||||
reason: str = ""
|
||||
|
||||
|
||||
@router.get("/stats")
|
||||
def stats(_: str = Depends(current_login)) -> dict:
|
||||
"""Сводка: размер очереди (new/ai) и число записей в отсеве."""
|
||||
return processing_svc.stats()
|
||||
|
||||
|
||||
@router.get("/queue")
|
||||
def queue(limit: int = 100, _: str = Depends(current_login)) -> dict:
|
||||
"""Сырые сообщения, ожидающие обработки (этап 1 или ИИ)."""
|
||||
q = processing_svc.queue_counts()
|
||||
return {
|
||||
"items": processing_svc.list_queue(limit),
|
||||
"counts": q,
|
||||
"rejected": processing_svc.rejected_count(),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/rejected")
|
||||
def rejected(
|
||||
q: str = "",
|
||||
offset: int = 0,
|
||||
limit: int = 100,
|
||||
_: str = Depends(current_login),
|
||||
) -> dict:
|
||||
"""Отсев: что и почему не прошло пайплайн (полнотекстовый поиск по q)."""
|
||||
return processing_svc.list_rejected(q, offset, limit)
|
||||
|
||||
|
||||
@router.post("/rejected/clear")
|
||||
def rejected_clear(_: str = Depends(current_login)) -> dict:
|
||||
"""Ручная полная очистка отсева (безвозвратно)."""
|
||||
cleared = processing_svc.clear_all()
|
||||
return {"ok": True, "cleared": cleared}
|
||||
|
||||
|
||||
@router.delete("/rejected/{rej_id}")
|
||||
def rejected_delete(rej_id: str, _: str = Depends(current_login)) -> dict:
|
||||
processing_svc.delete_one(rej_id)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.post("/rejected/{rej_id}/return")
|
||||
def rejected_return(rej_id: str, body: ReturnBody, _: str = Depends(current_login)) -> dict:
|
||||
"""Вернуть отсеянное сообщение в обработку.
|
||||
|
||||
Для возвращённого сообщения причины отсева (стоп-лист, резюме, тип,
|
||||
без суммы, устарело, ML/ИИ-спам) игнорируются: оно уходит на ML/ИИ
|
||||
и создаёт карточку. ML обучается на действии (снятие «спама»), а решение
|
||||
ИИ по возвращённому сообщению снова учит ML. Запись в отсеве помечается
|
||||
«возвращено» с указанной пользователем причиной.
|
||||
"""
|
||||
try:
|
||||
out = processing_svc.return_to_queue(rej_id, body.reason)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(404, "Запись не найдена") from exc
|
||||
except ValueError as exc:
|
||||
raise HTTPException(400, str(exc)) from exc
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user