gendesign/backend/app/workers/tasks/mv_sales_tracker_refresh.py
bot-backend 2cf6261005
Some checks failed
CI / changes (push) Successful in 9s
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Failing after 1m49s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Failing after 1m39s
CI / backend-tests (push) Failing after 8m57s
CI / backend-tests (pull_request) Failing after 9m6s
chore(sql): renumber sales-tracker MV migration 161→164 (avoid collision)
2026-06-17 22:36:39 +03:00

52 lines
1.9 KiB
Python

"""Celery task: refresh the sales-tracker MVs (Issue #61).
Scheduled via hardcoded beat entry in workers/beat_schedule.py:
'mv-sales-tracker-refresh-weekly' — weekly on Monday at 04:30 MSK.
Refreshes (both CONCURRENTLY, non-blocking):
- mv_sales_tracker_velocity_by_district (Site Finder Velocity Score, 4th criterion)
- mv_sales_tracker_absorption_curves (recommend_mix + sellout forecast foundation)
Both MVs are built from the Объектив sales-tracker ("шахматки") snapshots
(objective_lots / objective_lots_history). Source data refreshes via the
objective_sync beat job, so a weekly MV refresh keeps the aggregates current.
MV-source migration: data/sql/164_mv_sales_tracker_velocity_absorption.sql.
"""
from __future__ import annotations
import logging
from typing import Any
from app.core.db import SessionLocal
from app.services.site_finder.sales_tracker_mv_refresh import refresh_sales_tracker_mvs
from app.workers.celery_app import celery_app
logger = logging.getLogger(__name__)
@celery_app.task(
bind=True,
name="tasks.mv_sales_tracker_refresh.refresh_sales_tracker_mvs",
max_retries=2,
)
def refresh_sales_tracker_mvs_task(self: Any) -> dict[str, Any]:
"""REFRESH both sales-tracker MVs (#61).
Both MVs are refreshed CONCURRENTLY (non-blocking, require their UNIQUE
indexes created by migration 161); the service falls back to non-concurrent
if an MV is found unpopulated (first-run edge case).
Returns result dict for the Celery task result store / logging.
"""
db = SessionLocal()
try:
counts = refresh_sales_tracker_mvs(db, concurrently=True)
logger.info("refresh_sales_tracker_mvs: completed, rows=%s", counts)
return {"status": "ok", "rows": counts}
except Exception as e:
logger.exception("refresh_sales_tracker_mvs failed: %s", e)
raise
finally:
db.close()