gendesign/backend/app/workers/celery_app.py
lekss361 ac870b0c58
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m49s
Deploy / build-worker (push) Successful in 3m33s
Deploy / deploy (push) Successful in 1m34s
fix(ptica): скраб ПДн перед отправкой в мониторинг + честная подпись НДС в отчётах (#2457) (#2749)
PII scrub wired to BOTH channels (before_send AND before_send_transaction) in app/main.py and app/workers/celery_app.py.

Before: Celery had no before_send at all, and before_send_transaction was URL-only while glitchtip_traces_sample_rate defaults to 0.05 - the Starlette integration puts request.data on transaction scope exactly as on error scope, so lead bodies leaked through the transaction channel.

Keys: full MERA set (client_name/client_phone/client_email/phone/email/name) plus company/message from PilotRequestInput.

VAT label: 'NDS (parking)' -> 'NDS (parking + commercial)' in DOCX/HTML exporters - financial.py computes VAT over parking AND non-residential.
2026-08-06 18:47:35 +00:00

110 lines
4.7 KiB
Python
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.

"""Celery app — single source of truth для Celery configuration.
Beat schedule build → app/workers/beat_schedule.py.
Worker lifecycle hooks (process_init, worker_ready) → app/workers/lifecycle.py.
"""
import logging
import os
import sentry_sdk
from celery import Celery
from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.httpx import HttpxIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from app.core.config import settings
from app.observability.sentry_scrub import scrub_event
logger = logging.getLogger(__name__)
# SDK инициализируется в обоих процессах (FastAPI-сервер и Celery-воркер),
# чтобы события из тасков попадали в GlitchTip. SDK безопасен для двойного
# вызова — повторный sentry_sdk.init() в одном процессе заменяет клиента.
if settings.glitchtip_dsn:
# before_send И before_send_transaction — ОБА на scrub_event (#2457-review,
# см. app/main.py и sentry_scrub.py module docstring): до этого фикса worker
# вообще не скрабил error-события (тут before_send не было), а
# before_send_transaction был на голом scrub_sensitive_query (только URL) —
# оба канала пропускали PII.
sentry_sdk.init(
dsn=settings.glitchtip_dsn,
environment=settings.environment,
release=os.getenv("GIT_SHA") or os.getenv("SENTRY_RELEASE") or "unknown",
traces_sample_rate=settings.glitchtip_traces_sample_rate,
profiles_sample_rate=0.0,
send_default_pii=False,
before_send=scrub_event,
before_send_transaction=scrub_event,
integrations=[
CeleryIntegration(monitor_beat_tasks=True),
SqlalchemyIntegration(),
HttpxIntegration(),
LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
],
)
logger.info(
"GlitchTip SDK initialised in Celery worker (env=%s)",
settings.environment,
)
celery_app = Celery(
"gendesign",
broker=settings.redis_url,
backend=settings.redis_url,
include=[
"app.workers.tasks.scrape_kn",
"app.workers.tasks.scrape_kn_catalog_objects",
"app.workers.tasks.scrape_kn_catalog_flats",
"app.workers.tasks.refresh_analytics",
"app.workers.tasks.scrape_objective",
"app.workers.tasks.objective_etl",
"app.workers.tasks.nspd_geo",
"app.workers.tasks.nspd_sync",
"app.workers.tasks.poi_sync",
"app.workers.tasks.noise_sync",
"app.workers.tasks.utility_infrastructure_sync",
"app.workers.tasks.pzz_sync",
"app.workers.tasks.scrape_cadastre",
"app.workers.tasks.ekburg_permits_sync",
"app.workers.tasks.cbr_macro_sync",
"app.workers.tasks.rosstat_macro_sync",
"app.workers.tasks.refresh_quarter_price_index",
"app.workers.tasks.etl_newbuilding_crossload",
"app.workers.tasks.supply_layers_refresh",
"app.workers.tasks.location_refresh",
"app.workers.tasks.forecast",
"app.workers.tasks.full_report",
"app.workers.tasks.ird_harvest",
"app.workers.tasks.ekb_krt_sync",
"app.workers.tasks.gknspecial_harvest",
"app.workers.tasks.opportunity_harvest",
"app.workers.tasks.planning_harvest",
"app.workers.tasks.zone_regulation_refresh",
"app.workers.tasks.backfill_zone_regulations",
"app.workers.tasks.reservation_ingest",
"app.workers.tasks.genplan_zones_sync",
"app.workers.tasks.ekb_ppt_tep_sync",
"app.workers.tasks.krt_geometry_sync",
"app.workers.tasks.okn_objects_sync",
"app.workers.tasks.pat_subzones_load",
"app.workers.tasks.izyatie_ocr_ingest",
"app.workers.tasks.developer_registry_refresh",
"app.workers.tasks.refresh_layout_velocity",
"app.workers.tasks.riasurt_sverdl_harvest",
"app.workers.tasks.mv_sales_tracker_refresh",
"app.workers.tasks.scrape_freshness_check",
"app.workers.tasks.connection_capacity_sync",
"app.workers.tasks.gisogd_permits_sync",
],
)
celery_app.conf.timezone = "Europe/Moscow"
# Apply beat schedule (DB → fallback → hardcoded entries)
from app.workers.beat_schedule import build_beat_schedule # noqa: E402
celery_app.conf.beat_schedule = build_beat_schedule()
# Register lifecycle hooks (import for side-effect — signal decorator registration)
from app.workers import lifecycle # noqa: E402, F401