Files
company-ai-platform/app/modules/business/constants.py
JiuContinent 19e59e83cc ```
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
```
2026-07-08 14:08:03 +08:00

165 lines
3.7 KiB
Python

from enum import StrEnum
class StatusValue(StrEnum):
INITIATED = "立项"
TODO = "待办"
DRAFT = "草稿"
POLICY_DRAFT = "草案"
VALID = "有效"
APPROVING = "审批中"
PENDING_APPROVAL = "待审批"
PENDING = "pending"
ACCEPTED = "验收"
COMPLETED_CN = "已完成"
DONE_CN = "完成"
REVIEWED = "复盘"
ARCHIVED = "归档"
CLOSED_CN = "关闭"
CLOSED = "closed"
RESOLVED = "resolved"
DONE = "done"
COMPLETED = "completed"
GENERATED = "已生成"
UNKNOWN = "未知"
PAID = "已付款"
UNPAID = "未付款"
UNDELIVERED = "未到货"
INVOICE_NOT_RECEIVED = "未收票"
NORMAL = "normal"
NORMAL_CN = "正常"
LATE = "迟到"
LEAVE_EARLY = "早退"
MISSING_PUNCH = "缺卡"
ABSENT = "旷工"
ABNORMAL = "异常"
OPEN = "open"
RUNNING = "running"
RUNNING_CN = "执行中"
DRY_RUN = "dry_run"
class RiskLevel(StrEnum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class PriorityValue(StrEnum):
P2 = "P2"
class SourceSystem(StrEnum):
INTERNAL = "internal"
LEGACY_MYSQL = "legacy_mysql"
class AccountType(StrEnum):
BANK = "bank"
class VersionValue(StrEnum):
V1_0 = "v1.0"
class BusinessDomain(StrEnum):
PROJECTS = "projects"
TASKS = "tasks"
PROCUREMENTS = "procurements"
EXPENSES = "expenses"
FUND_ACCOUNTS = "fund-accounts"
POLICIES = "policies"
STANDARDS = "standards"
PERFORMANCE_METRICS = "performance-metrics"
SUPPLIERS = "suppliers"
ATTENDANCE_RECORDS = "attendance-records"
WORK_REPORTS = "work-reports"
RISK_EVENTS = "risk-events"
LEGACY_SYNC_RUNS = "legacy-sync-runs"
class BusinessResponseKey(StrEnum):
DOMAINS = "domains"
DOMAIN = "domain"
TOTAL = "total"
ITEMS = "items"
DATA = "data"
class BusinessPayloadKey(StrEnum):
DATA = "data"
APPROVAL_TICKET_ID = "approval_ticket_id"
class BusinessField(StrEnum):
ID = "id"
STATUS = "status"
class BusinessErrorDetail(StrEnum):
RECORD_NOT_FOUND = "Record not found"
HIGH_RISK_APPROVAL_REQUIRED = "High-risk domain change requires approval_ticket_id"
UNKNOWN_FIELD_TEMPLATE = "Unknown field '{field}'"
READ_ONLY_FIELD_TEMPLATE = "Field '{field}' is read-only"
INVALID_FIELD_VALUE_TEMPLATE = "Invalid value for field '{field}'"
class RiskEventType(StrEnum):
OVERDUE_TASK = "overdue_task"
DELAYED_PROJECT = "delayed_project"
OVER_BUDGET_PROJECT = "over_budget_project"
FUND_SAFETY_LINE = "fund_safety_line"
SUPPLIER_RISK = "supplier_risk"
DONE_STATUSES = frozenset(
{
StatusValue.DONE_CN,
StatusValue.COMPLETED_CN,
StatusValue.CLOSED_CN,
StatusValue.DONE,
StatusValue.COMPLETED,
StatusValue.CLOSED,
}
)
PENDING_APPROVAL_STATUSES = frozenset(
{
StatusValue.DRAFT,
StatusValue.APPROVING,
StatusValue.PENDING_APPROVAL,
StatusValue.PENDING,
}
)
PROJECT_CLOSED_STATUSES = frozenset(
{
StatusValue.ACCEPTED,
StatusValue.COMPLETED_CN,
StatusValue.REVIEWED,
StatusValue.ARCHIVED,
StatusValue.CLOSED_CN,
StatusValue.CLOSED,
}
)
ATTENDANCE_ABNORMAL_STATUSES = frozenset(
{
StatusValue.LATE,
StatusValue.LEAVE_EARLY,
StatusValue.MISSING_PUNCH,
StatusValue.ABSENT,
StatusValue.ABNORMAL,
}
)
SUPPLIER_RISK_LEVELS = frozenset({RiskLevel.MEDIUM, RiskLevel.HIGH})
CLOSED_RISK_STATUSES = frozenset({StatusValue.CLOSED, StatusValue.RESOLVED})
GENERATED_RISK_EVENT_TYPES = frozenset(
{
RiskEventType.OVERDUE_TASK,
RiskEventType.DELAYED_PROJECT,
RiskEventType.OVER_BUDGET_PROJECT,
RiskEventType.FUND_SAFETY_LINE,
RiskEventType.SUPPLIER_RISK,
}
)