diff --git a/backend/app/workers/beat_schedule.py b/backend/app/workers/beat_schedule.py index 79606f6e..4b2d672d 100644 --- a/backend/app/workers/beat_schedule.py +++ b/backend/app/workers/beat_schedule.py @@ -246,21 +246,23 @@ def build_beat_schedule() -> dict: "options": {"queue": "celery"}, } - # #105 Phase 4: ЕКБ РНС/РВЭ — ежемесячно 1-го числа в 05:00 МСК (02:00 UTC) + # #105 Phase 4: ЕКБ РНС/РВЭ — ежемесячно 1-го числа в 05:00 МСК. + # Celery conf.timezone=Europe/Moscow → crontab трактуется в МСК (#1233). schedule["ekburg-permits-monthly"] = { "task": "tasks.ekburg_permits_sync.refresh_all", - "schedule": _parse_cron("0 2 1 * *"), + "schedule": _parse_cron("0 5 1 * *"), "options": {"queue": "celery"}, } - # ПЗЗ территориальных зон ЕКБ из PKK6 ArcGIS — ежемесячно 1-го числа в 03:00 МСК (00:00 UTC). + # ПЗЗ территориальных зон ЕКБ из PKK6 ArcGIS — ежемесячно 1-го числа в 03:00 МСК. + # Celery conf.timezone=Europe/Moscow → crontab трактуется в МСК (#1233). # PKK6 нестабилен под нагрузкой, но данные ПЗЗ меняются редко — раз в месяц достаточно. # Task: tasks/pzz_sync.py → sync_pzz_zones_ekb. # Admin trigger: POST /api/v1/admin/scrape/pzz-sync. # Ref: issue #233 (pzz_zones_ekb = 0 rows, задача никогда не запускалась автоматически). schedule["pzz-sync-monthly"] = { "task": "tasks.pzz_sync.sync_pzz_zones_ekb", - "schedule": _parse_cron("0 0 1 * *"), + "schedule": _parse_cron("0 3 1 * *"), "options": {"queue": "celery"}, } @@ -280,13 +282,14 @@ def build_beat_schedule() -> dict: # "options": {"queue": "celery"}, # } - # Quarter price index refresh (#762) — monthly on the 5th at 05:00 MSK (02:00 UTC). + # Quarter price index refresh (#762) — monthly on the 5th at 05:00 MSK. + # Celery conf.timezone=Europe/Moscow → crontab трактуется в МСК (#1233). # Chains: mv_quarter_price_per_m2 → mv_quarter_price_index (in order, both CONCURRENTLY). # Runs 1 h after refresh-ekb-districts-medians (04:00 MSK) so deals data is settled. # Not in job_settings (technical infra task, no UI config needed). schedule["refresh-quarter-price-index"] = { "task": "tasks.refresh_quarter_price_index.refresh_quarter_price_index_chain", - "schedule": _parse_cron("0 2 5 * *"), # 02:00 UTC = 05:00 MSK, 5th of month + "schedule": _parse_cron("0 5 5 * *"), # 05:00 MSK, 5th of month "options": {"queue": "celery"}, } @@ -295,14 +298,15 @@ def build_beat_schedule() -> dict: # (#260) теперь возвращают полноценные dumps (territorial_zones, ЗОУИТ, risk # zones, engineering structures) вместо 0-3 features из single-pixel WMS. # - # Schedule: Mon 04:00 МСК (01:00 UTC). batch_size=50 ограничивает fanout per + # Schedule: Mon 04:00 МСК (Celery conf.timezone=Europe/Moscow → crontab в МСК, #1233). + # batch_size=50 ограничивает fanout per # tick — при 11k+ кварталов в cad_quarters_geom полный backfill займёт # несколько недель, но защищает от WAF rate-limit burst. # max_age_days=90 — refresh свежее квартала; новые / отсутствующие dumps # тоже попадают через harvest_stale_quarters (берёт NULL fetched_at). schedule["nspd-harvest-stale-quarters"] = { "task": "tasks.nspd_sync.harvest_stale_quarters", - "schedule": _parse_cron("0 1 * * mon"), # 01:00 UTC = 04:00 МСК + "schedule": _parse_cron("0 4 * * mon"), # 04:00 МСК "kwargs": {"region_code": 66, "max_age_days": 90, "batch_size": 50}, "options": {"queue": "celery"}, }