@startuml Crowd Reports System title Система отчетов Crowd actor User participant "CrowdReport API" as api database "reports.user_reports" as queue_db participant "Report Builder Worker" as worker participant "OverallStatsReport" as overall participant "QueueStatsReport" as queues participant "WorkTimeReport" as worktime database "crowd.measurements" as measurements_db database "crowd.detected_queues" as queues_db participant "Excel Generator" as excel participant "Storage (S3)" as storage == Создание отчета == User -> api: POST /crowd_reports?op=CREATE api -> api: QueryEnricher._populate_sources() note right: zones.id = ['zone1', 'zone2'] api -> queue_db: insert task (status='in_queue') api -> User: report created == Обработка очереди == loop continuous worker -> queue_db: find_one_and_update(status='in_queue') alt task found queue_db -> worker: report task worker -> worker: setup_context(report) alt overall_stats_report worker -> overall: make_report() overall -> measurements_db: aggregate({'zones.id': {'$in': [...]}}) measurements_db -> overall: measurements data else queue_stats_report worker -> queues: make_report() queues -> queues_db: find({'zone_id': {'$in': [...]}}) queues_db -> queues: queues data else work_time_report worker -> worktime: make_report() worktime -> measurements_db: find + schedule analysis measurements_db -> worktime: filtered data end worker -> excel: generate XLSX excel -> worker: Excel file worker -> storage: save_to_s3() worker -> queue_db: update(status='done') else no tasks worker -> worker: sleep(SLEEP_INTERVAL) end end == Получение результата == User -> api: GET /crowd_reports/{id} api -> queue_db: find report alt status='done' queue_db -> api: report with download_url api -> User: report ready else status='in_progress' api -> User: report in progress else status='failed' api -> User: report failed end @enduml