Files

186 lines
9.3 KiB
Python

"""场外基金运营独立持久化模型。"""
from datetime import date, datetime
from decimal import Decimal
from typing import Any
from sqlalchemy import (
JSON,
BigInteger,
Date,
DateTime,
Integer,
Numeric,
String,
Text,
UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column
from app.model.base import Base
class OffsiteFundMail(Base):
__tablename__ = "offsite_fund_mail"
__table_args__ = (
UniqueConstraint("imap_uid", "message_id", name="uk_offsite_mail_source"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
mail_id: Mapped[str] = mapped_column(String(16), unique=True, nullable=False)
imap_uid: Mapped[str] = mapped_column(String(64), nullable=False)
message_id: Mapped[str] = mapped_column(String(255), nullable=False)
received_date: Mapped[date] = mapped_column(Date, nullable=False)
sender: Mapped[str] = mapped_column(String(255), nullable=False)
return_path: Mapped[str | None] = mapped_column(String(255))
auth_result: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
original_eml_path: Mapped[str] = mapped_column(String(500), nullable=False)
status: Mapped[str] = mapped_column(String(32), nullable=False, default="received")
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(String(500))
next_retry_at: Mapped[datetime | None] = mapped_column(DateTime)
last_attempt_at: Mapped[datetime | None] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteMailCursor(Base):
"""场外收件箱 UID 游标和处理租约。"""
__tablename__ = "offsite_mail_cursor"
__table_args__ = (
UniqueConstraint("mailbox", "folder", name="uk_offsite_mail_cursor_scope"),
)
id: Mapped[int] = mapped_column(
BigInteger().with_variant(Integer, "sqlite"), primary_key=True
)
mailbox: Mapped[str] = mapped_column(String(255), nullable=False)
folder: Mapped[str] = mapped_column(String(64), nullable=False, default="INBOX")
last_uid: Mapped[str] = mapped_column(String(64), nullable=False, default="0")
status: Mapped[str] = mapped_column(String(32), nullable=False, default="idle")
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
blocked_uid: Mapped[str | None] = mapped_column(String(64))
blocked_message_id: Mapped[str | None] = mapped_column(String(255))
last_error: Mapped[str | None] = mapped_column(String(500))
next_retry_at: Mapped[datetime | None] = mapped_column(DateTime)
lease_id: Mapped[str | None] = mapped_column(String(64))
lease_until: Mapped[datetime | None] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteFundAttachment(Base):
__tablename__ = "offsite_fund_attachment"
__table_args__ = (
UniqueConstraint("file_hash", "mail_id", name="uk_offsite_attachment_hash"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
attachment_id: Mapped[str] = mapped_column(String(24), unique=True, nullable=False)
mail_id: Mapped[str] = mapped_column(String(16), nullable=False)
filename: Mapped[str] = mapped_column(String(255), nullable=False)
file_hash: Mapped[str] = mapped_column(String(128), nullable=False)
media_type: Mapped[str] = mapped_column(String(128), nullable=False)
size_bytes: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
document_type: Mapped[str] = mapped_column(String(24), nullable=False)
original_file_path: Mapped[str] = mapped_column(String(500), nullable=False)
ocr_text: Mapped[str] = mapped_column(Text, nullable=False)
extracted_fields: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
field_confidence: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
page_evidence: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
status: Mapped[str] = mapped_column(String(32), nullable=False, default="recognized")
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteFundDocument(Base):
__tablename__ = "offsite_fund_document"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
task_id: Mapped[str] = mapped_column(String(24), unique=True, nullable=False)
mail_id: Mapped[str] = mapped_column(String(16), nullable=False)
attachment_id: Mapped[str] = mapped_column(String(24), nullable=False)
document_type: Mapped[str] = mapped_column(String(24), nullable=False)
fund_code: Mapped[str | None] = mapped_column(String(32))
fund_name: Mapped[str | None] = mapped_column(String(255))
account_identifier: Mapped[str | None] = mapped_column(String(128))
investor_name: Mapped[str | None] = mapped_column(String(128))
application_no: Mapped[str | None] = mapped_column(String(128))
application_date: Mapped[date | None] = mapped_column(Date)
raw_application_date: Mapped[str | None] = mapped_column(String(64))
agency: Mapped[str | None] = mapped_column(String(128))
subscription_amount_yuan: Mapped[Decimal | None] = mapped_column(Numeric(20, 4))
redemption_shares: Mapped[Decimal | None] = mapped_column(Numeric(20, 4))
operator_decision: Mapped[str] = mapped_column(String(16), nullable=False, default="未处理")
status: Mapped[str] = mapped_column(String(32), nullable=False, default="planned")
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteExecutionPlanTask(Base):
__tablename__ = "offsite_execution_plan_task"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
stage: Mapped[str] = mapped_column(String(16), nullable=False)
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
title: Mapped[str] = mapped_column(String(128), nullable=False)
depends_on: Mapped[list[Any]] = mapped_column(JSON, nullable=False)
input_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
output_json: Mapped[dict[str, Any] | None] = mapped_column(JSON)
status: Mapped[str] = mapped_column(String(16), nullable=False, default="待执行")
error_message: Mapped[str | None] = mapped_column(String(500))
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteRuleResult(Base):
__tablename__ = "offsite_rule_result"
__table_args__ = (
UniqueConstraint("task_id", "rule_code", name="uk_offsite_rule_task"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
rule_name: Mapped[str] = mapped_column(String(128), nullable=False)
result: Mapped[str] = mapped_column(String(16), nullable=False)
document_value: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
database_value: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
calculation: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteQueryRecord(Base):
__tablename__ = "offsite_query_record"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
natural_language_request: Mapped[str] = mapped_column(Text, nullable=False)
script_path: Mapped[str] = mapped_column(String(500), nullable=False)
result_summary: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
status: Mapped[str] = mapped_column(String(24), nullable=False)
error_message: Mapped[str | None] = mapped_column(String(500))
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class OffsiteNotification(Base):
__tablename__ = "offsite_notification"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
notification_type: Mapped[str] = mapped_column(String(32), nullable=False)
business_key: Mapped[str] = mapped_column(String(64), nullable=False)
receiver_id: Mapped[str] = mapped_column(String(64), nullable=False)
operator_id: Mapped[str] = mapped_column(String(64), nullable=False)
agent_draft: Mapped[str] = mapped_column(Text, nullable=False)
final_content: Mapped[str] = mapped_column(Text, nullable=False)
payload: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
status: Mapped[str] = mapped_column(String(16), nullable=False, default="待发送")
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
provider_message_id: Mapped[str | None] = mapped_column(String(128))
failure_reason: Mapped[str | None] = mapped_column(String(500))
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
sent_at: Mapped[datetime | None] = mapped_column(DateTime)
updated_at: Mapped[datetime | None] = mapped_column(DateTime)