65 lines
2.4 KiB
Python
65 lines
2.4 KiB
Python
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(),
|
|
)
|