from datetime import date from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.application.delivery import ReportDeliveryService from app.core.background.task_queue import ( enqueue_attendance_summary_push, enqueue_daily_brief_push, enqueue_lifecycle_report, enqueue_project_weekly_push, enqueue_risk_progress_push, enqueue_work_daily_push, enqueue_work_weekly_push, ) from app.core.database import get_db from app.core.security import ApiPrincipal, require_api_key, require_operations_enabled from app.modules.reports.constants import ReportPushKey from app.modules.reports.schemas import ( LifecycleRunRequest, PushReportRequest, ReportResponse, WorkReportGenerateRequest, ) from app.modules.reports.services import ReportService router = APIRouter(dependencies=[Depends(require_api_key)]) @router.get("/daily-brief", response_model=ReportResponse) def daily_brief( db: Session = Depends(get_db), ) -> dict: return ReportService(db).daily_brief() @router.get("/project-weekly", response_model=ReportResponse) def project_weekly( db: Session = Depends(get_db), ) -> dict: return ReportService(db).project_weekly() @router.get("/risk-progress") def risk_progress( db: Session = Depends(get_db), ) -> dict: return ReportService(db).risk_progress() @router.get("/project-lifecycle") def project_lifecycle_report( project_code: str | None = None, owner: str | None = None, period_start: date | None = None, period_end: date | None = None, include_ai: bool = False, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return ReportService(db).project_lifecycle_report( project_code=project_code, owner=owner, period_start=period_start, period_end=period_end, include_ai=include_ai, actor=principal.actor, ) @router.get("/enterprise-analytics") def enterprise_analytics( project_code: str | None = None, owner: str | None = None, period_start: date | None = None, period_end: date | None = None, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return ReportService(db).enterprise_analytics( project_code=project_code, owner=owner, period_start=period_start, period_end=period_end, actor=principal.actor, ) @router.get("/attendance-summary") def attendance_summary( work_date: date | None = None, db: Session = Depends(get_db), ) -> dict: return ReportService(db).attendance_summary(work_date) @router.get("/personnel-lifecycle") def personnel_lifecycle_report( department: str | None = None, employee_code: str | None = None, project_code: str | None = None, period_start: date | None = None, period_end: date | None = None, db: Session = Depends(get_db), ) -> dict: return ReportService(db).personnel_lifecycle_report( department=department, employee_code=employee_code, project_code=project_code, period_start=period_start, period_end=period_end, ) @router.get("/project-finance-needs") def project_finance_needs_report( project_code: str | None = None, department: str | None = None, as_of: date | None = None, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return ReportService(db).project_finance_needs_report( project_code=project_code, department=department, as_of=as_of, include_ai=False, actor=principal.actor, ) @router.post("/lifecycle/enqueue") def enqueue_lifecycle( payload: LifecycleRunRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: require_operations_enabled() return enqueue_lifecycle_report( report_type=payload.report_type, receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, force=payload.force, actor=principal.actor, ) @router.get("/push-runs") def list_push_runs( status: str | None = None, limit: int = 100, db: Session = Depends(get_db), ) -> dict: return {ReportPushKey.ITEMS: ReportService(db).list_push_runs(status_filter=status, limit=limit)} @router.get("/push-runs/{code}") def get_push_run( code: str, db: Session = Depends(get_db), ) -> dict: return ReportService(db).get_push_run(code) @router.post("/work-reports/generate") def generate_work_report( payload: WorkReportGenerateRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: if payload.persist: require_operations_enabled() return ReportService(db).generate_work_report( report_type=payload.report_type, reporter=payload.reporter, department=payload.department, project_code=payload.project_code, period_start=payload.period_start, period_end=payload.period_end, persist=payload.persist, actor=principal.actor, ) @router.post("/daily-brief/push") def push_daily_brief( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.daily_brief() return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/project-weekly/push") def push_project_weekly( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.project_weekly() return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/attendance-summary/push") def push_attendance_summary( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.attendance_summary() return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/risk-progress/push") def push_risk_progress( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.risk_progress() return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/work-daily/push") def push_work_daily( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.work_daily_report(reporter=principal.actor, actor=principal.actor) return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/work-weekly/push") def push_work_weekly( payload: PushReportRequest, db: Session = Depends(get_db), principal: ApiPrincipal = Depends(require_api_key), ) -> dict: service = ReportService(db) report = service.work_weekly_report(reporter=principal.actor, actor=principal.actor) return ReportDeliveryService(db).push_report( report, payload.receive_id, payload.receive_id_type, principal.actor, ) @router.post("/daily-brief/enqueue") def enqueue_daily_brief( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_daily_brief_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, ) @router.post("/project-weekly/enqueue") def enqueue_project_weekly( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_project_weekly_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, ) @router.post("/attendance-summary/enqueue") def enqueue_attendance_summary( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_attendance_summary_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, ) @router.post("/risk-progress/enqueue") def enqueue_risk_progress( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_risk_progress_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, ) @router.post("/work-daily/enqueue") def enqueue_work_daily( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_work_daily_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, ) @router.post("/work-weekly/enqueue") def enqueue_work_weekly( payload: PushReportRequest, principal: ApiPrincipal = Depends(require_api_key), ) -> dict: return enqueue_work_weekly_push( receive_id=payload.receive_id, receive_id_type=payload.receive_id_type, actor=principal.actor, )