feat: 添加数据库迁移脚本并更新Dockerfile配置 - 在Dockerfile中添加alembic配置文件和目录的复制指令 - 更新alembic/env.py注册新的模块模型:events、workflows、writebacks - 生成完整的初始数据库schema迁移脚本,包含以下表: - approval_requests, attendance_records, audit_logs, domain_events - expenses, feishu_event_receipts, fund_accounts, legacy_sync_runs - official_writeback_runs, performance_metrics, policies, procurements - projects, report_push_runs, risk_event_actions, risk_events - standards, suppliers, work_reports, work_tasks, workflow_actions - workflow_instances等21个数据表结构定义 - 在API路由器中添加新模块的路由:events、workflows、writebacks、observability ```
92 lines
2.2 KiB
Python
92 lines
2.2 KiB
Python
from enum import StrEnum
|
|
|
|
from app.modules.business.constants import RiskLevel
|
|
|
|
|
|
class RiskSummaryKey(StrEnum):
|
|
RISK_LEVEL = "risk_level"
|
|
RISK_SCORE = "risk_score"
|
|
OVERDUE_TASKS = "overdue_tasks"
|
|
DELAYED_PROJECTS = "delayed_projects"
|
|
OVER_BUDGET_PROJECTS = "over_budget_projects"
|
|
FUND_RISKS = "fund_risks"
|
|
SUPPLIER_RISKS = "supplier_risks"
|
|
OPEN_EVENTS = "open_events"
|
|
|
|
|
|
class RiskGenerationResultKey(StrEnum):
|
|
CREATED = "created"
|
|
UPDATED = "updated"
|
|
SKIPPED = "skipped"
|
|
ITEMS = "items"
|
|
ACTION = "action"
|
|
RISK_EVENT = "risk_event"
|
|
|
|
|
|
class RiskGenerationAction(StrEnum):
|
|
CREATED = "created"
|
|
UPDATED = "updated"
|
|
SKIPPED = "skipped"
|
|
|
|
|
|
class RiskEventPayloadKey(StrEnum):
|
|
CODE = "code"
|
|
TITLE = "title"
|
|
RISK_TYPE = "risk_type"
|
|
RISK_LEVEL = "risk_level"
|
|
STATUS = "status"
|
|
SOURCE_DOMAIN = "source_domain"
|
|
SOURCE_RECORD_ID = "source_record_id"
|
|
PROJECT_CODE = "project_code"
|
|
OWNER = "owner"
|
|
DUE_DATE = "due_date"
|
|
DETECTED_AT = "detected_at"
|
|
DESCRIPTION = "description"
|
|
MITIGATION = "mitigation"
|
|
EVIDENCE = "evidence"
|
|
|
|
|
|
class RiskEventActionValue(StrEnum):
|
|
ASSIGN = "assign"
|
|
COMMENT = "comment"
|
|
RESOLVE = "resolve"
|
|
CLOSE = "close"
|
|
REOPEN = "reopen"
|
|
|
|
|
|
class RiskEventActionKey(StrEnum):
|
|
ACTION = "action"
|
|
RISK_EVENT = "risk_event"
|
|
ACTION_RECORD = "action_record"
|
|
ITEMS = "items"
|
|
FROM_STATUS = "from_status"
|
|
TO_STATUS = "to_status"
|
|
COMMENT = "comment"
|
|
PAYLOAD = "payload"
|
|
ASSIGNED_TO = "assigned_to"
|
|
REVIEW_SUMMARY = "review_summary"
|
|
|
|
|
|
class RiskErrorDetail(StrEnum):
|
|
RISK_EVENT_NOT_FOUND = "Risk event not found"
|
|
|
|
|
|
RISK_SCORE_WEIGHTS = {
|
|
RiskSummaryKey.OVERDUE_TASKS: 1,
|
|
RiskSummaryKey.DELAYED_PROJECTS: 3,
|
|
RiskSummaryKey.OVER_BUDGET_PROJECTS: 4,
|
|
RiskSummaryKey.FUND_RISKS: 5,
|
|
RiskSummaryKey.SUPPLIER_RISKS: 3,
|
|
RiskSummaryKey.OPEN_EVENTS: 2,
|
|
}
|
|
RISK_LEVEL_HIGH_THRESHOLD = 15
|
|
RISK_LEVEL_MEDIUM_THRESHOLD = 5
|
|
|
|
|
|
def risk_level_for_score(score: int) -> RiskLevel:
|
|
if score >= RISK_LEVEL_HIGH_THRESHOLD:
|
|
return RiskLevel.HIGH
|
|
if score >= RISK_LEVEL_MEDIUM_THRESHOLD:
|
|
return RiskLevel.MEDIUM
|
|
return RiskLevel.LOW
|