| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- from datetime import UTC, date, datetime
- from sqlalchemy import (
- JSON,
- BigInteger,
- Column,
- Date,
- ForeignKey,
- Index,
- String,
- Table,
- Text,
- UniqueConstraint,
- )
- from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
- from app.infrastructure.mysql.types import UTCDateTime
- def utc_now() -> datetime:
- return datetime.now(UTC)
- class CoreBase(DeclarativeBase):
- pass
- admin_user_roles = Table(
- "admin_user_roles",
- CoreBase.metadata,
- Column("admin_user_id", String(26), ForeignKey("admin_users.id"), primary_key=True),
- Column("role_id", String(26), ForeignKey("roles.id"), primary_key=True),
- )
- role_permissions = Table(
- "role_permissions",
- CoreBase.metadata,
- Column("role_id", String(26), ForeignKey("roles.id"), primary_key=True),
- Column(
- "permission_id",
- String(26),
- ForeignKey("permissions.id"),
- primary_key=True,
- ),
- )
- class H5UserRecord(CoreBase):
- __tablename__ = "h5_users"
- __table_args__ = (
- Index("ix_h5_users_status_created", "status", "created_at"),
- Index("ix_h5_users_source", "source_code"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- mobile: Mapped[str] = mapped_column(String(32), unique=True, nullable=False)
- mobile_masked: Mapped[str] = mapped_column(String(32), nullable=False)
- display_name: Mapped[str] = mapped_column(String(64), nullable=False)
- region_code: Mapped[str | None] = mapped_column(String(12))
- status: Mapped[str] = mapped_column(String(32), nullable=False, default="ACTIVE")
- source_code: Mapped[str] = mapped_column(String(64), nullable=False, default="DIRECT")
- last_login_at: Mapped[datetime | None] = mapped_column(UTCDateTime())
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- updated_at: Mapped[datetime] = mapped_column(
- UTCDateTime(), nullable=False, default=utc_now, onupdate=utc_now
- )
- version: Mapped[int] = mapped_column(nullable=False, default=1)
- class PermissionRecord(CoreBase):
- __tablename__ = "permissions"
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- code: Mapped[str] = mapped_column(String(128), unique=True, nullable=False)
- name: Mapped[str] = mapped_column(String(64), nullable=False)
- resource: Mapped[str] = mapped_column(String(64), nullable=False)
- action: Mapped[str] = mapped_column(String(32), nullable=False)
- class RoleRecord(CoreBase):
- __tablename__ = "roles"
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- code: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
- name: Mapped[str] = mapped_column(String(64), nullable=False)
- data_scope: Mapped[str] = mapped_column(String(32), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False, default="ACTIVE")
- permissions: Mapped[list[PermissionRecord]] = relationship(
- secondary=role_permissions,
- lazy="selectin",
- )
- class AdminUserRecord(CoreBase):
- __tablename__ = "admin_users"
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- username: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
- password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
- display_name: Mapped[str] = mapped_column(String(64), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False, default="ACTIVE")
- roles: Mapped[list[RoleRecord]] = relationship(
- secondary=admin_user_roles,
- lazy="selectin",
- )
- class AuthSessionRecord(CoreBase):
- __tablename__ = "auth_sessions"
- __table_args__ = (
- Index(
- "ix_auth_sessions_subject",
- "subject_type",
- "subject_id",
- "revoked_at",
- ),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- subject_type: Mapped[str] = mapped_column(String(16), nullable=False)
- subject_id: Mapped[str] = mapped_column(String(26), nullable=False)
- refresh_jti_hash: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
- expires_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- revoked_at: Mapped[datetime | None] = mapped_column(UTCDateTime())
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class SalespersonRecord(CoreBase):
- __tablename__ = "salespersons"
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- admin_user_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("admin_users.id"),
- unique=True,
- nullable=False,
- )
- salesperson_code: Mapped[str] = mapped_column(
- String(32),
- unique=True,
- nullable=False,
- )
- name: Mapped[str] = mapped_column(String(64), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- created_at: Mapped[datetime] = mapped_column(
- UTCDateTime(),
- nullable=False,
- default=utc_now,
- )
- class PromotionCodeRecord(CoreBase):
- __tablename__ = "promotion_codes"
- __table_args__ = (Index("ix_promotion_codes_salesperson", "salesperson_id", "status"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- code: Mapped[str] = mapped_column(String(32), unique=True, nullable=False)
- salesperson_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("salespersons.id"),
- nullable=False,
- )
- channel: Mapped[str] = mapped_column(String(32), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- created_at: Mapped[datetime] = mapped_column(
- UTCDateTime(),
- nullable=False,
- default=utc_now,
- )
- class LeadAttributionRecord(CoreBase):
- __tablename__ = "lead_attributions"
- __table_args__ = (Index("ix_lead_attributions_salesperson", "salesperson_id", "last_touch_at"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- h5_user_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("h5_users.id"),
- unique=True,
- nullable=False,
- )
- salesperson_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("salespersons.id"),
- nullable=False,
- )
- promotion_code_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("promotion_codes.id"),
- nullable=False,
- )
- source_code: Mapped[str] = mapped_column(String(32), nullable=False)
- visit_count: Mapped[int] = mapped_column(nullable=False, default=1)
- first_touch_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- last_touch_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- class OrderAttributionRecord(CoreBase):
- __tablename__ = "order_attributions"
- __table_args__ = (
- Index("ix_order_attributions_salesperson", "salesperson_id", "attributed_at"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- order_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("enrollment_orders.id"),
- unique=True,
- nullable=False,
- )
- h5_user_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("h5_users.id"),
- nullable=False,
- )
- salesperson_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("salespersons.id"),
- nullable=False,
- )
- promotion_code_id: Mapped[str] = mapped_column(
- String(26),
- ForeignKey("promotion_codes.id"),
- nullable=False,
- )
- source_code: Mapped[str] = mapped_column(String(32), nullable=False)
- amount_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- attributed_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- class ProductRecord(CoreBase):
- __tablename__ = "products"
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_code: Mapped[str] = mapped_column(String(32), unique=True, nullable=False)
- name: Mapped[str] = mapped_column(String(128), nullable=False)
- category: Mapped[str] = mapped_column(String(32), nullable=False)
- summary: Mapped[str] = mapped_column(String(500), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- class ProductVersionRecord(CoreBase):
- __tablename__ = "product_versions"
- __table_args__ = (
- UniqueConstraint("product_id", "version_no", name="uq_product_version"),
- Index("ix_product_versions_availability", "status", "effective_from", "effective_to"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_id: Mapped[str] = mapped_column(String(26), ForeignKey("products.id"), nullable=False)
- version_no: Mapped[str] = mapped_column(String(32), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- effective_from: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- effective_to: Mapped[datetime | None] = mapped_column(UTCDateTime())
- rule_version: Mapped[str] = mapped_column(String(32), nullable=False, default="eligibility-v1")
- rate_version: Mapped[str] = mapped_column(String(32), nullable=False, default="rate-v1")
- terms_summary: Mapped[str] = mapped_column(Text, nullable=False, default="")
- plans: Mapped[list["PlanRecord"]] = relationship(
- back_populates="product_version",
- cascade="all, delete-orphan",
- lazy="selectin",
- )
- class PlanRecord(CoreBase):
- __tablename__ = "plans"
- __table_args__ = (
- UniqueConstraint("product_version_id", "plan_code", name="uq_plan_version_code"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_version_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("product_versions.id"), nullable=False
- )
- plan_code: Mapped[str] = mapped_column(String(32), nullable=False)
- name: Mapped[str] = mapped_column(String(128), nullable=False)
- summary: Mapped[str] = mapped_column(String(500), nullable=False, default="")
- status: Mapped[str] = mapped_column(String(32), nullable=False, default="ACTIVE")
- premium_cents: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
- coverage_amount_cents: Mapped[int] = mapped_column(
- BigInteger, nullable=False, default=0
- )
- min_age: Mapped[int] = mapped_column(nullable=False, default=0)
- max_age: Mapped[int] = mapped_column(nullable=False, default=100)
- product_version: Mapped[ProductVersionRecord] = relationship(back_populates="plans")
- class ProductChangeLogRecord(CoreBase):
- __tablename__ = "product_change_logs"
- __table_args__ = (
- Index("ix_product_change_logs_product_created", "product_id", "created_at"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("products.id"), nullable=False
- )
- version_id: Mapped[str | None] = mapped_column(String(26))
- action: Mapped[str] = mapped_column(String(32), nullable=False)
- actor_id: Mapped[str] = mapped_column(String(26), nullable=False)
- actor_name: Mapped[str] = mapped_column(String(64), nullable=False)
- detail_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- class EligibilityRuleRecord(CoreBase):
- __tablename__ = "eligibility_rules"
- __table_args__ = (
- UniqueConstraint("product_version_id", "rule_code", name="uq_eligibility_rule"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_version_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("product_versions.id"), nullable=False
- )
- rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
- rule_type: Mapped[str] = mapped_column(String(32), nullable=False)
- operator: Mapped[str] = mapped_column(String(16), nullable=False)
- parameters_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- failure_code: Mapped[str] = mapped_column(String(64), nullable=False)
- failure_message: Mapped[str] = mapped_column(String(255), nullable=False)
- class RateTableRecord(CoreBase):
- __tablename__ = "rate_tables"
- __table_args__ = (
- UniqueConstraint("product_version_id", "rate_code", name="uq_rate_code"),
- Index(
- "ix_rate_lookup",
- "product_version_id",
- "plan_id",
- "region_group",
- "min_age",
- "max_age",
- "effective_from",
- ),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- product_version_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("product_versions.id"), nullable=False
- )
- plan_id: Mapped[str] = mapped_column(String(26), ForeignKey("plans.id"), nullable=False)
- rate_code: Mapped[str] = mapped_column(String(64), nullable=False)
- min_age: Mapped[int] = mapped_column(nullable=False)
- max_age: Mapped[int] = mapped_column(nullable=False)
- region_group: Mapped[str] = mapped_column(String(32), nullable=False)
- occupation_group: Mapped[str] = mapped_column(String(32), nullable=False)
- premium_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- currency: Mapped[str] = mapped_column(String(3), nullable=False, default="CNY")
- effective_from: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- effective_to: Mapped[datetime | None] = mapped_column(UTCDateTime())
- class QuoteRecord(CoreBase):
- __tablename__ = "quotes"
- __table_args__ = (Index("ix_quotes_user_status", "h5_user_id", "status", "expires_at"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- h5_user_id: Mapped[str] = mapped_column(String(26), ForeignKey("h5_users.id"), nullable=False)
- product_id: Mapped[str] = mapped_column(String(26), ForeignKey("products.id"), nullable=False)
- product_version_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("product_versions.id"), nullable=False
- )
- plan_id: Mapped[str] = mapped_column(String(26), ForeignKey("plans.id"), nullable=False)
- insured_age: Mapped[int] = mapped_column(nullable=False)
- insured_region_code: Mapped[str] = mapped_column(String(12), nullable=False)
- occupation_code: Mapped[str] = mapped_column(String(32), nullable=False)
- relationship: Mapped[str] = mapped_column(String(32), nullable=False)
- premium_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- currency: Mapped[str] = mapped_column(String(3), nullable=False)
- rule_version: Mapped[str] = mapped_column(String(32), nullable=False)
- rate_version: Mapped[str] = mapped_column(String(32), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- expires_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class EnrollmentDraftRecord(CoreBase):
- __tablename__ = "enrollment_drafts"
- __table_args__ = (Index("ix_drafts_user_status", "h5_user_id", "status", "created_at"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- h5_user_id: Mapped[str] = mapped_column(String(26), ForeignKey("h5_users.id"), nullable=False)
- quote_id: Mapped[str] = mapped_column(String(26), ForeignKey("quotes.id"), nullable=False)
- applicant_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- insured_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- contact_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- expires_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class UserConfirmationRecord(CoreBase):
- __tablename__ = "user_confirmations"
- __table_args__ = (Index("ix_confirmations_subject", "draft_id", "status"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- h5_user_id: Mapped[str] = mapped_column(String(26), ForeignKey("h5_users.id"), nullable=False)
- draft_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("enrollment_drafts.id"), nullable=False
- )
- token_hash: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- expires_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class EnrollmentOrderRecord(CoreBase):
- __tablename__ = "enrollment_orders"
- __table_args__ = (
- UniqueConstraint(
- "h5_user_id",
- "idempotency_key",
- name="uq_orders_user_idempotency",
- ),
- Index("ix_orders_user_status", "h5_user_id", "status", "created_at"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- order_no: Mapped[str] = mapped_column(String(40), unique=True, nullable=False)
- h5_user_id: Mapped[str] = mapped_column(String(26), ForeignKey("h5_users.id"), nullable=False)
- quote_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("quotes.id"), unique=True, nullable=False
- )
- draft_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("enrollment_drafts.id"), nullable=False
- )
- confirmation_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("user_confirmations.id"), unique=True, nullable=False
- )
- idempotency_key: Mapped[str] = mapped_column(String(64), nullable=False)
- product_id: Mapped[str] = mapped_column(String(26), nullable=False)
- product_version_id: Mapped[str] = mapped_column(String(26), nullable=False)
- plan_id: Mapped[str] = mapped_column(String(26), nullable=False)
- applicant_snapshot_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- insured_snapshot_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- amount_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- currency: Mapped[str] = mapped_column(String(3), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class PaymentTransactionRecord(CoreBase):
- __tablename__ = "payment_transactions"
- __table_args__ = (
- UniqueConstraint(
- "order_id",
- "idempotency_key",
- name="uq_payments_order_idempotency",
- ),
- Index("ix_payments_order_status", "order_id", "status"),
- )
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- payment_no: Mapped[str] = mapped_column(String(40), unique=True, nullable=False)
- order_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("enrollment_orders.id"), nullable=False
- )
- h5_user_id: Mapped[str] = mapped_column(String(26), nullable=False)
- transaction_type: Mapped[str] = mapped_column(String(16), nullable=False)
- provider: Mapped[str] = mapped_column(String(32), nullable=False)
- idempotency_key: Mapped[str] = mapped_column(String(64), nullable=False)
- amount_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- currency: Mapped[str] = mapped_column(String(3), nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- provider_transaction_no: Mapped[str | None] = mapped_column(String(64), unique=True)
- succeeded_at: Mapped[datetime | None] = mapped_column(UTCDateTime())
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False, default=utc_now)
- class PolicyRecord(CoreBase):
- __tablename__ = "policies"
- __table_args__ = (Index("ix_policies_user_status", "h5_user_id", "status", "coverage_end"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- policy_no: Mapped[str] = mapped_column(String(40), unique=True, nullable=False)
- order_id: Mapped[str] = mapped_column(
- String(26), ForeignKey("enrollment_orders.id"), unique=True, nullable=False
- )
- h5_user_id: Mapped[str] = mapped_column(String(26), nullable=False)
- product_id: Mapped[str] = mapped_column(String(26), nullable=False)
- product_version_id: Mapped[str] = mapped_column(String(26), nullable=False)
- plan_id: Mapped[str] = mapped_column(String(26), nullable=False)
- premium_cents: Mapped[int] = mapped_column(BigInteger, nullable=False)
- currency: Mapped[str] = mapped_column(String(3), nullable=False)
- coverage_start: Mapped[date] = mapped_column(Date, nullable=False)
- coverage_end: Mapped[date] = mapped_column(Date, nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- issued_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- class OutboxEventRecord(CoreBase):
- __tablename__ = "outbox_events"
- __table_args__ = (Index("ix_outbox_dispatch", "status", "created_at"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- aggregate_type: Mapped[str] = mapped_column(String(32), nullable=False)
- aggregate_id: Mapped[str] = mapped_column(String(26), nullable=False)
- event_type: Mapped[str] = mapped_column(String(128), nullable=False)
- payload_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
- class AsyncTaskRecord(CoreBase):
- __tablename__ = "async_tasks"
- __table_args__ = (Index("ix_async_tasks_claim", "status", "created_at"),)
- id: Mapped[str] = mapped_column(String(26), primary_key=True)
- task_type: Mapped[str] = mapped_column(String(128), nullable=False)
- business_key: Mapped[str] = mapped_column(String(128), nullable=False)
- idempotency_key: Mapped[str] = mapped_column(String(128), unique=True, nullable=False)
- payload_json: Mapped[dict[str, object]] = mapped_column(JSON, nullable=False)
- status: Mapped[str] = mapped_column(String(32), nullable=False)
- attempt_count: Mapped[int] = mapped_column(nullable=False, default=0)
- created_at: Mapped[datetime] = mapped_column(UTCDateTime(), nullable=False)
|