ivideon: add face_report generated diagram

This commit is contained in:
t0xa 2026-01-19 16:05:02 +03:00
parent 742f87567d
commit 8141aaa323

View file

@ -0,0 +1,96 @@
@startuml
title Создание отчёта о рабочем времени (face_work_time_json)
actor Client
participant "face/api" as API
database "MongoDB\nuser_reports" as ReportsDB
participant "report_checker\n(Worker)" as Checker
participant "reporter.py" as Reporter
participant "WorkTimeJsonReport" as WorkTime
participant "data_loader" as DataLoader
database "MongoDB\nface_events" as EventsDB
database "MongoDB\nfaces" as FacesDB
participant "tools.py" as Tools
database "Redis" as Redis
== 1. Создание задачи на отчёт ==
Client -> API: POST /reports\n(type=face_work_time_json)
API -> API: FaceReport.create()\nvalidate options, build query
API -> ReportsDB: insert(status='in_queue')
API --> Client: {success: true, id: report_id}
== 2. Обработка отчёта воркером ==
loop каждые SLEEP_INTERVAL секунд
Checker -> ReportsDB: find_one_and_update\n(status='in_queue' → 'in_progress')
end
Checker -> Checker: ProcessPoolExecutor\ncreate_report_sync(report)
note right: Новый процесс\nс asyncio.run()
Checker -> Reporter: create_report(report)
Reporter -> Reporter: @with_context\nустановить контекст пользователя
Reporter -> Reporter: Выбрать класс из REGISTRY\n(face_work_time_json → WorkTimeJsonReport)
Reporter -> WorkTime: make_report()
== 3. Загрузка данных ==
WorkTime -> DataLoader: get_events(query)
DataLoader -> EventsDB: find(query)\n[best_shot_time, face_id, camera_id]
EventsDB --> DataLoader: events[]
DataLoader --> WorkTime: events
WorkTime -> DataLoader: get_faces(galleries, events,\ncameras_in, cameras_out, tz)
loop для каждого события
DataLoader -> DataLoader: result[face_id] = GroupedFace(face_id)
DataLoader -> DataLoader: group.handle(best_shot_time, direction)
end
DataLoader -> DataLoader: _get_faces_without_events()\n(лица из галерей без событий)
DataLoader -> FacesDB: find(_id NOT IN face_ids,\ngallery IN galleries)
FacesDB --> DataLoader: faces_without_events
DataLoader -> DataLoader: face_ids = events + faces_without_events
== 4. Обогащение данных фотографиями ==
DataLoader -> DataLoader: _get_faces_data(face_ids)
DataLoader -> FacesDB: find(_id IN face_ids)\n[person, photos, description, gallery_id]
FacesDB --> DataLoader: faces_data[]
loop для каждого face
DataLoader -> DataLoader: _get_photo(face_data)
alt photos пустой или None
DataLoader --> DataLoader: return None
note right #pink: **ПРИЧИНА 1**\nphotos отсутствует
else photos есть
DataLoader -> DataLoader: найти default фото\nили первое из списка
DataLoader -> Tools: get_thumb_url(photo)
alt есть thumbnails.thumbnail_200.url
Tools --> DataLoader: url
else есть thumbnails.thumbnail_200.obj_ref
Tools -> Tools: storage.generate_presigned_url()
Tools --> DataLoader: presigned_url
else нет thumbnail_200
Tools --> DataLoader: None
note right #pink: **ПРИЧИНА 2**\nнет thumbnail_200
end
end
DataLoader -> DataLoader: face.photo = photo_url
end
DataLoader --> WorkTime: List[GroupedFace]
== 5. Генерация и сохранение ==
WorkTime -> WorkTime: _generate(query, faces, tz, schedule)
note right: Формирует JSON:\n[name, photo, face_id, ...]
WorkTime -> Redis: setex(key, json, TTL=1 day)
WorkTime -> ReportsDB: update(status='done',\n_redis_key=key)
== 6. Получение результата ==
Client -> API: GET /reports/{id}/json
API -> ReportsDB: find(_id=id)
API -> Redis: get(_redis_key)
Redis --> API: json_data
API --> Client: {summary: {...}, details: {...}}
@enduml