sandbox/ivideon/puml/faces/report_creation.puml

96 lines
3.9 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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