Finance-Accounts/ar-aging-app/backend/app/api/routes/processing.py

45 lines
1.8 KiB
Python

"""Start processing (background) and poll status/progress."""
from __future__ import annotations
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
from sqlalchemy.orm import Session as OrmSession
from ...db import models
from ...services.jobs import run_processing
from ..deps import db_dep, get_session_or_404, session_dict
router = APIRouter(prefix="/api/sessions", tags=["processing"])
@router.post("/{session_id}/process")
def start_processing(session_id: int, background: BackgroundTasks,
db: OrmSession = Depends(db_dep)) -> dict:
s = get_session_or_404(session_id, db)
if s.month_end_date is None:
raise HTTPException(400, "Set the month-end date before processing.")
valid_files = db.query(models.SessionFile).filter(
models.SessionFile.session_id == session_id).all()
if not valid_files:
raise HTTPException(400, "Upload at least one file before processing.")
if any(f.status == "invalid" for f in valid_files):
raise HTTPException(400, "One or more files failed validation; fix them before processing.")
if s.status == "processing":
raise HTTPException(409, "Already processing.")
s.status = "processing"
s.progress_stage = "Queued"
s.progress_pct = 0.0
s.error = ""
db.commit()
background.add_task(run_processing, session_id)
return {"started": True, "session_id": session_id}
@router.get("/{session_id}/status")
def status(session_id: int, db: OrmSession = Depends(db_dep)) -> dict:
s = get_session_or_404(session_id, db)
return {
"status": s.status, "stage": s.progress_stage, "pct": s.progress_pct,
"rows_done": s.progress_rows_done, "rows_total": s.progress_rows_total,
"eta_seconds": s.eta_seconds, "error": s.error, "session": session_dict(s),
}