Files
X-Financial/server/src/app/models/approval_action.py

65 lines
2.4 KiB
Python
Raw Normal View History

from __future__ import annotations
import uuid
from datetime import datetime
from typing import Any
from sqlalchemy import CheckConstraint, DateTime, Index, String, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.types import JSON
from app.db.base_class import Base
class ApprovalActionLedger(Base):
"""审批类写动作的持久化幂等账本。"""
__tablename__ = "approval_action_ledgers"
__table_args__ = (
CheckConstraint(
"action IN ('approve', 'return', 'pay')",
name="ck_approval_action_ledger_action",
),
CheckConstraint(
"(completed_at IS NULL AND result_status IS NULL "
"AND result_approval_stage IS NULL) OR "
"(completed_at IS NOT NULL AND result_status IS NOT NULL "
"AND result_approval_stage IS NOT NULL)",
name="ck_approval_action_ledger_completion",
),
UniqueConstraint(
"tenant_id",
"actor_id",
"request_id",
name="uq_approval_action_ledger_request",
),
Index(
"ix_approval_action_ledger_claim_action",
"tenant_id",
"claim_id",
"action",
),
)
id: Mapped[str] = mapped_column(
String(36),
primary_key=True,
default=lambda: str(uuid.uuid4()),
)
tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
actor_id: Mapped[str] = mapped_column(String(120), nullable=False)
request_id: Mapped[str] = mapped_column(String(120), nullable=False)
claim_id: Mapped[str] = mapped_column(String(36), nullable=False)
action: Mapped[str] = mapped_column(String(20), nullable=False)
payload_fingerprint: Mapped[str] = mapped_column(String(80), nullable=False)
expected_status: Mapped[str] = mapped_column(String(30), nullable=False)
expected_approval_stage: Mapped[str] = mapped_column(String(50), nullable=False)
result_status: Mapped[str | None] = mapped_column(String(30), nullable=True)
result_approval_stage: Mapped[str | None] = mapped_column(String(50), nullable=True)
response_json: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True)
completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
)