gendesign/backend/app/schemas/job_settings.py
lekss361 2fee7739e8 feat(jobs): centralized job_settings API + DB-driven beat schedule
- JobSetting ORM model (JSONB extra_config) + Pydantic schemas
- GET/PUT /api/v1/admin/jobs/settings + /{job_type} (X-Admin-Token auth)
- celery_app.py builds beat_schedule from job_settings DB (env fallback
  retained for safety on first deploy / DB unreachable)
- nspd_geo task reads rate_ms from job_settings when per-job row has
  no override
- enqueue/resume geo jobs route to queue_name from job_settings
- Worker container: --queues=celery,scrape_kn,geo (one container,
  three named queues — kn sweep no longer blocks nspd_geo)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:38:13 +03:00

34 lines
1,011 B
Python

"""Pydantic v2 схемы для job_settings API."""
from datetime import datetime
from pydantic import BaseModel, Field
class JobSettingRead(BaseModel):
job_type: str
enabled: bool
queue_name: str
cron_schedule: str | None
rate_ms: int | None
max_retries: int
max_concurrency: int
extra_config: dict
updated_at: datetime
updated_by: str | None
description: str | None
model_config = {"from_attributes": True}
class JobSettingUpdate(BaseModel):
"""PATCH-style: передавать только изменяемые поля. Непереданные — без изменений."""
enabled: bool | None = None
queue_name: str | None = None
# Пустая строка → NULL (manual-only режим).
cron_schedule: str | None = None
rate_ms: int | None = Field(None, ge=0)
max_retries: int | None = Field(None, ge=0, le=10)
max_concurrency: int | None = Field(None, ge=1, le=20)
extra_config: dict | None = None