use axum::Extension; use axum::extract::{FromRef, Path, Query, State}; use axum::response::Json; use validator::Validate; use erp_core::error::AppError; use erp_core::rbac::require_permission; use erp_core::types::{ApiResponse, PaginatedResponse, Pagination, TenantContext}; use uuid::Uuid; use crate::dto::{CompleteTaskReq, DelegateTaskReq, TaskResp}; use crate::service::task_service::TaskService; use crate::workflow_state::WorkflowState; /// GET /api/v1/workflow/tasks/pending pub async fn list_pending_tasks( State(state): State, Extension(ctx): Extension, Query(pagination): Query, ) -> Result>>, AppError> where WorkflowState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "workflow.approve")?; let (tasks, total) = TaskService::list_pending(ctx.tenant_id, ctx.user_id, &pagination, &state.db).await?; let page = pagination.page.unwrap_or(1); let page_size = pagination.limit(); let total_pages = total.div_ceil(page_size); Ok(Json(ApiResponse::ok(PaginatedResponse { data: tasks, total, page, page_size, total_pages, }))) } /// GET /api/v1/workflow/tasks/completed pub async fn list_completed_tasks( State(state): State, Extension(ctx): Extension, Query(pagination): Query, ) -> Result>>, AppError> where WorkflowState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "workflow.approve")?; let (tasks, total) = TaskService::list_completed(ctx.tenant_id, ctx.user_id, &pagination, &state.db).await?; let page = pagination.page.unwrap_or(1); let page_size = pagination.limit(); let total_pages = total.div_ceil(page_size); Ok(Json(ApiResponse::ok(PaginatedResponse { data: tasks, total, page, page_size, total_pages, }))) } /// POST /api/v1/workflow/tasks/{id}/complete pub async fn complete_task( State(state): State, Extension(ctx): Extension, Path(id): Path, Json(req): Json, ) -> Result>, AppError> where WorkflowState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "workflow.approve")?; req.validate().map_err(|e| AppError::Validation(e.to_string()))?; let resp = TaskService::complete( id, ctx.tenant_id, ctx.user_id, &req, &state.db, &state.event_bus, ) .await?; Ok(Json(ApiResponse::ok(resp))) } /// POST /api/v1/workflow/tasks/{id}/delegate pub async fn delegate_task( State(state): State, Extension(ctx): Extension, Path(id): Path, Json(req): Json, ) -> Result>, AppError> where WorkflowState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "workflow.delegate")?; req.validate().map_err(|e| AppError::Validation(e.to_string()))?; let resp = TaskService::delegate(id, ctx.tenant_id, ctx.user_id, &req, &state.db).await?; Ok(Json(ApiResponse::ok(resp))) }