E3 (B21): операции мультипоиска — статусная машина, скоуп, дашборд

- Модель search_operations: title, case_id (unique — операция на карточку),
  status (planned/active/paused/completed/archived, CheckConstraint),
  unit_id, contour_operation_id (заготовка B20-E4), created_by, closed_at.
- Alembic 009_e3_operations.
- backend/routers/operations.py: POST (создание; unit по умолчанию =
  подразделение создателя; скоуп-проверка), GET список (скоуп-фильтр),
  GET /{id} (403 вне скоупа), GET /summary (active/total/completed_24h),
  PATCH (title/unit/status со статусной машиной: planned→active⇄paused→
  completed→archived; недопустимые переходы 400; completed ставит closed_at).
  Всё с аудитом operation_create/operation_update.
- Скоуп: unit_id ∈ visible_unit_ids (своё+подчинённые); РЦУ РЧС — все.
- Тесты E3 (12): создание с юнитом/дефолт/дубль кейса/cross-unit 403,
  скоуп списков, статусная машина, summary, аудит, cross-scope 403.
222 passed, 5 skipped.
This commit is contained in:
2026-09-09 21:29:33 +03:00
parent e694ad1a05
commit 808ef93a52
5 changed files with 549 additions and 0 deletions
+2
View File
@@ -9,6 +9,7 @@ from fastapi.middleware.cors import CORSMiddleware
from backend.database import init_db
from backend.routers.admin import router as admin_router
from backend.routers.admin_users import router as admin_users_router
from backend.routers.operations import router as operations_router
from backend.routers.analyze import router as analyze_router
from backend.routers.auth import router as auth_router
from backend.routers.cases import router as cases_router
@@ -55,6 +56,7 @@ app.include_router(closed_cases_router)
app.include_router(stats_router)
app.include_router(admin_router)
app.include_router(admin_users_router)
app.include_router(operations_router)
app.include_router(water_router)
app.include_router(geocode_router)