Phase A (P1 production blockers): - A1: Apply IP rate limiting to public routes (login/refresh) - A2: Publish domain events for workflow instance state transitions (completed/suspended/resumed/terminated) via outbox pattern - A3: Replace hardcoded nil UUID default tenant with dynamic DB lookup - A4: Add GET /api/v1/audit-logs query endpoint with pagination - A5: Enhance CORS wildcard warning for production environments Phase B (P2 functional gaps): - B1: Remove dead erp-common crate (zero references in codebase) - B2: Refactor 5 settings pages to use typed API modules instead of direct client calls; create api/themes.ts; delete dead errors.ts - B3: Add resume/suspend buttons to InstanceMonitor page - B4: Remove unused EventHandler trait from erp-core - B5: Handle task.completed events in message module (send notifications) - B6: Wire TimeoutChecker as 60s background task - B7: Auto-skip ServiceTask nodes instead of crashing the process - B8: Remove empty register_routes() from ErpModule trait and modules
56 lines
1.9 KiB
Rust
56 lines
1.9 KiB
Rust
// 超时检查框架
|
|
//
|
|
// TimeoutChecker 定期扫描 tasks 表中已超时但仍处于 pending 状态的任务,
|
|
// 以便触发自动完成或升级逻辑(后续迭代实现)。
|
|
|
|
use chrono::Utc;
|
|
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
|
use uuid::Uuid;
|
|
|
|
use crate::entity::task;
|
|
use crate::error::WorkflowResult;
|
|
|
|
/// 超时检查服务。
|
|
pub struct TimeoutChecker;
|
|
|
|
impl TimeoutChecker {
|
|
/// 查询指定租户下已超时但未完成的任务列表。
|
|
///
|
|
/// 返回 due_date < now 且 status = 'pending' 的任务 ID。
|
|
pub async fn find_overdue_tasks(
|
|
tenant_id: Uuid,
|
|
db: &sea_orm::DatabaseConnection,
|
|
) -> WorkflowResult<Vec<Uuid>> {
|
|
let now = Utc::now();
|
|
let overdue = task::Entity::find()
|
|
.filter(task::Column::TenantId.eq(tenant_id))
|
|
.filter(task::Column::Status.eq("pending"))
|
|
.filter(task::Column::DueDate.lt(now))
|
|
.filter(task::Column::DeletedAt.is_null())
|
|
.all(db)
|
|
.await
|
|
.map_err(|e| crate::error::WorkflowError::Validation(e.to_string()))?;
|
|
|
|
Ok(overdue.iter().map(|t| t.id).collect())
|
|
}
|
|
|
|
/// 查询所有租户中已超时但未完成的任务列表。
|
|
///
|
|
/// 返回 due_date < now 且 status = 'pending' 的任务 ID。
|
|
/// 用于后台定时任务的全量扫描。
|
|
pub async fn find_all_overdue_tasks(
|
|
db: &sea_orm::DatabaseConnection,
|
|
) -> WorkflowResult<Vec<Uuid>> {
|
|
let now = Utc::now();
|
|
let overdue = task::Entity::find()
|
|
.filter(task::Column::Status.eq("pending"))
|
|
.filter(task::Column::DueDate.lt(now))
|
|
.filter(task::Column::DeletedAt.is_null())
|
|
.all(db)
|
|
.await
|
|
.map_err(|e| crate::error::WorkflowError::Validation(e.to_string()))?;
|
|
|
|
Ok(overdue.iter().map(|t| t.id).collect())
|
|
}
|
|
}
|