from __future__ import annotations from fastapi import APIRouter, Form, Request from fastapi.responses import RedirectResponse from app.core.db.common import CommonSessionLocal from app.core.http_responses import ui_access_denied from app.core.security.csrf import get_or_create_csrf_token, validate_csrf from app.core.security.session_auth import get_current_user from app.core.templating import templates from app.modules.core.rbac.deps import get_user_permissions, get_user_roles from app.modules.manager_dashboard.service import ( build_manager_dashboard_payload, can_access_manager_dashboard, get_manager_review_workspace, get_next_manager_review_task_id, ) from app.modules.services.execution import apply_task_review router = APIRouter(prefix="/manager", tags=["manager-dashboard-v2-ui"]) VALID_TABS = { "overview": "modules/manager_dashboard/templates/manager_dashboard/partials/overview.html", "team-work": "modules/manager_dashboard/templates/manager_dashboard/partials/team_work.html", "due-calendar": "modules/manager_dashboard/templates/manager_dashboard/partials/due_calendar.html", "review-queue": "modules/manager_dashboard/templates/manager_dashboard/partials/review_queue.html", "client-pending": "modules/manager_dashboard/templates/manager_dashboard/partials/client_pending.html", "documents": "modules/manager_dashboard/templates/manager_dashboard/partials/documents.html", "escalations": "modules/manager_dashboard/templates/manager_dashboard/partials/escalations.html", "reports": "modules/manager_dashboard/templates/manager_dashboard/partials/reports.html", "wizards": "modules/manager_dashboard/templates/manager_dashboard/partials/wizards.html", } def _ctx(request: Request, db, current_user, *, active_tab: str = "overview"): payload = build_manager_dashboard_payload(db, request, current_user) return { "request": request, "current_user": current_user, "current_user_roles": get_user_roles(db, current_user.id), "current_user_permissions": get_user_permissions(db, current_user.id), "csrf_token": get_or_create_csrf_token(request), "title": "Manager Dashboard", "active_tab": active_tab, **payload, } @router.get("/dashboard") def dashboard(request: Request, tab: str = "overview"): db = CommonSessionLocal() try: current_user = get_current_user(request, db=db) if not current_user: return RedirectResponse(url="/login", status_code=303) if not can_access_manager_dashboard(db, current_user): return ui_access_denied() active_tab = tab if tab in VALID_TABS else "overview" return templates.TemplateResponse( "modules/manager_dashboard/templates/manager_dashboard/dashboard.html", _ctx(request, db, current_user, active_tab=active_tab), ) finally: db.close() @router.get("/dashboard/tab/{tab_name}") def dashboard_tab(request: Request, tab_name: str): db = CommonSessionLocal() try: current_user = get_current_user(request, db=db) if not current_user: return RedirectResponse(url="/login", status_code=303) if not can_access_manager_dashboard(db, current_user): return ui_access_denied() active_tab = tab_name if tab_name in VALID_TABS else "overview" return templates.TemplateResponse( VALID_TABS[active_tab], _ctx(request, db, current_user, active_tab=active_tab), ) finally: db.close() @router.get("/reviews/engagements/{subscription_id}") def manager_review_workspace(request: Request, subscription_id: int, task_id: int | None = None): db = CommonSessionLocal() try: current_user = get_current_user(request, db=db) if not current_user: return RedirectResponse(url="/login", status_code=303) if not can_access_manager_dashboard(db, current_user): return ui_access_denied() workspace = get_manager_review_workspace( db, request, current_user, subscription_id=subscription_id, active_task_id=task_id, ) if not workspace: return RedirectResponse(url="/manager/dashboard?tab=review-queue", status_code=303) return templates.TemplateResponse( "modules/manager_dashboard/templates/manager_dashboard/manager_review_workspace.html", { "request": request, "current_user": current_user, "current_user_roles": get_user_roles(db, current_user.id), "current_user_permissions": get_user_permissions(db, current_user.id), "csrf_token": get_or_create_csrf_token(request), "title": "Manager Engagement Review", "workspace": workspace, }, ) finally: db.close() @router.post("/reviews/engagements/{subscription_id}/tasks/{task_id}") def manager_review_task_submit( request: Request, subscription_id: int, task_id: int, decision: str = Form("reviewed"), review_note: str = Form(""), workflow_action: str = Form("save"), csrf_token: str = Form(...), ): validate_csrf(request, csrf_token) db = CommonSessionLocal() try: current_user = get_current_user(request, db=db) if not current_user: return RedirectResponse(url="/login", status_code=303) if not can_access_manager_dashboard(db, current_user): return ui_access_denied() workspace = get_manager_review_workspace( db, request, current_user, subscription_id=subscription_id, active_task_id=task_id, ) if not workspace: return RedirectResponse(url="/manager/dashboard?tab=review-queue", status_code=303) active = workspace.get("active_task") or {} if int(active.get("id") or 0) != int(task_id): return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?review_error=task", status_code=303) if active.get("is_locked") or workspace.get("is_locked"): return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?task_id={task_id}&review_error=locked", status_code=303) if active.get("review_state") not in {"pending_review", "reviewed", "rework"}: return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?task_id={task_id}&review_error=not_ready", status_code=303) # Reload the ORM object from the scoped workspace query result. from app.modules.services.models import ClientServiceTaskInstance from sqlalchemy import select task = db.execute( select(ClientServiceTaskInstance).where( ClientServiceTaskInstance.id == int(task_id), ClientServiceTaskInstance.subscription_id == int(subscription_id), ) ).scalar_one_or_none() if not task: return RedirectResponse(url="/manager/dashboard?tab=review-queue", status_code=303) try: apply_task_review( db, task=task, review_level="manager", decision=decision, note=review_note, user_id=current_user.id, ) db.commit() except ValueError: db.rollback() return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?task_id={task_id}&review_error=validation", status_code=303) if workflow_action == "save_next": refreshed = get_manager_review_workspace(db, request, current_user, subscription_id=subscription_id) next_id = get_next_manager_review_task_id(refreshed, task_id) if refreshed else None if next_id: return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?task_id={next_id}&reviewed=1", status_code=303) return RedirectResponse(url=f"/manager/reviews/engagements/{subscription_id}?task_id={task_id}&reviewed=1", status_code=303) finally: db.close()