E4 (B21): отправка зон в КОНТУР по операции (контракт B20)
- contour_operation_id в PATCH /operations/{id} (mapping на операцию КОНТУРа).
- backend/routers/contour.py: POST /{id}/send-to-contour — последний анализ
(search_models → legacy analysis_log) → SearchZones[] GeoJSON-сектора
направлений (±22.5°, probability по приоритету) → POST {CONTOUR_API_URL}/
api/v1/vector/zones?operation_id=... (Bearer CONTOUR_TOKEN). Все шаги
аудируются (contour_send_ok/failed). GET /{id}/areas-checked — прокси
проверенных квадратов (inbound к B17).
- env: CONTOUR_API_URL (дефолт CT130:8000), CONTOUR_TOKEN (в secrets).
- case_id-фильтр в GET /operations.
- UI: панель «КОНТУР» на странице анализа: ввод/сохранение UUID операции
КОНТУРа, кнопка «Отправить зоны в КОНТУР» со статусом результата.
- Тесты E4 (4): build B20-payload (полигон замкнут, probability 0..1,
operation_id в query, Bearer), недостающий contour_id 400, отказ КОНТУРа
→ 502 + аудит, геометрия сектора.
226 passed, 5 skipped.
This commit is contained in:
@@ -38,6 +38,7 @@ class OperationUpdate(BaseModel):
|
||||
title: Optional[str] = None
|
||||
status: Optional[str] = None
|
||||
unit_id: Optional[str] = None
|
||||
contour_operation_id: Optional[str] = None # UUID операции в КОНТУРе
|
||||
|
||||
|
||||
def _op_scope(db: Session, user: User) -> list | None:
|
||||
@@ -63,6 +64,7 @@ def _get_operation_checked(db: Session, user: User, operation_id: str) -> Search
|
||||
@router.get('')
|
||||
def list_operations(
|
||||
status_filter: Optional[str] = Query(default=None, alias='status'),
|
||||
case_id: Optional[str] = Query(default=None),
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict[str, Any]:
|
||||
@@ -72,6 +74,9 @@ def list_operations(
|
||||
query = query.filter(SearchOperation.unit_id.in_(scope))
|
||||
if status_filter:
|
||||
query = query.filter(SearchOperation.status == status_filter)
|
||||
if case_id:
|
||||
import uuid as uuid_mod
|
||||
query = query.filter(SearchOperation.case_id == uuid_mod.UUID(case_id))
|
||||
ops = query.order_by(SearchOperation.updated_at.desc()).all()
|
||||
from backend.models import User as UserModel
|
||||
users_by_id = {}
|
||||
@@ -199,6 +204,13 @@ def update_operation(
|
||||
changes['unit'] = (str(op.unit_id) if op.unit_id else None, payload.unit_id)
|
||||
op.unit_id = new_unit
|
||||
|
||||
if payload.contour_operation_id is not None:
|
||||
new_contour = uuid_mod.UUID(payload.contour_operation_id)
|
||||
if new_contour != op.contour_operation_id:
|
||||
changes['contour_operation_id'] = (str(op.contour_operation_id) if op.contour_operation_id else None,
|
||||
payload.contour_operation_id)
|
||||
op.contour_operation_id = new_contour
|
||||
|
||||
if payload.status is not None and payload.status != op.status:
|
||||
allowed = ALLOWED_TRANSITIONS.get(op.status, set())
|
||||
if payload.status not in allowed:
|
||||
|
||||
Reference in New Issue
Block a user