- Unify API: lib/api.ts uses /api/v1, inbox uses /api/inbox (rewrites) - Remove localhost refs: openapi, inbox page - Add rewrites: /api/inbox|tmc -> inbox-server, /api/v1 -> FastAPI - Add stub routes: knowledge/insights, recommendations, search, log-error - Transfer from PAPA: prompts (inspection, tmc), scripts, supabase, data/tmc-requests - Fix inbox-server: ORDER BY created_at, package.json - Remove redundant app/api/inbox/files route (rewrites handle it) - knowledge/ in gitignore (large PDFs) Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
from __future__ import annotations
|
||
|
||
from datetime import datetime, timezone
|
||
|
||
from apscheduler.schedulers.background import BackgroundScheduler
|
||
from apscheduler.triggers.interval import IntervalTrigger
|
||
from fastapi import FastAPI
|
||
from sqlalchemy.orm import Session
|
||
|
||
from app.core.config import settings
|
||
from app.db.session import SessionLocal
|
||
from app.models import CertApplication, CertApplicationStatus
|
||
from app.services.notifications import notify
|
||
from app.services.risk_scanner import scan_risks
|
||
|
||
_scheduler: BackgroundScheduler | None = None
|
||
|
||
|
||
def _check_remark_deadlines():
|
||
now = datetime.now(timezone.utc)
|
||
db: Session = SessionLocal()
|
||
try:
|
||
q = db.query(CertApplication).filter(
|
||
CertApplication.status == CertApplicationStatus.REMARKS,
|
||
CertApplication.remarks_deadline_at.isnot(None),
|
||
CertApplication.remarks_deadline_at < now,
|
||
)
|
||
for app in q.all():
|
||
app.status = CertApplicationStatus.EXPIRED
|
||
db.commit()
|
||
# notify applicant
|
||
notify(
|
||
db,
|
||
recipient_user_id=app.created_by_user_id,
|
||
title=f"Заявка {app.number}: срок устранения замечаний истек",
|
||
body=f"Срок {settings.remark_deadline_days} дней истек {app.remarks_deadline_at.isoformat()}. Заявка переведена в статус EXPIRED.",
|
||
)
|
||
finally:
|
||
db.close()
|
||
|
||
|
||
def _scan_risks():
|
||
"""Сканирует риски по всем ВС."""
|
||
db: Session = SessionLocal()
|
||
try:
|
||
scan_risks(db)
|
||
except Exception as e:
|
||
# Логируем ошибку, но не падаем
|
||
print(f"Ошибка сканирования рисков: {e}")
|
||
finally:
|
||
db.close()
|
||
|
||
|
||
def start_scheduler(app: FastAPI):
|
||
global _scheduler
|
||
if _scheduler is not None:
|
||
return
|
||
_scheduler = BackgroundScheduler()
|
||
# In prod align with ops; here check every 10 minutes.
|
||
_scheduler.add_job(_check_remark_deadlines, trigger=IntervalTrigger(minutes=10), id="remark_deadlines")
|
||
# Сканирование рисков каждый час
|
||
_scheduler.add_job(_scan_risks, trigger=IntervalTrigger(hours=1), id="risk_scan")
|
||
_scheduler.start()
|
||
|
||
@app.on_event("shutdown")
|
||
def _shutdown():
|
||
if _scheduler:
|
||
_scheduler.shutdown(wait=False)
|