"""育种审计日志 数据模型(§3.10;写操作全程可追溯切面)""" from sqlalchemy import ForeignKey, Integer, String from sqlalchemy.orm import Mapped, mapped_column from app.core.base_model import MappedBase, ModelMixin, UserMixin class AuditLogModel(ModelMixin, UserMixin, MappedBase): """审计日志。 entity_type=业务表名(__tablename__);CREATE 记录级 / UPDATE 字段级(每变更字段一行)/ DELETE 记录级 / IMPORT 汇总级。operator_id→bre_personnel 仅当育种人员姓名与操作用户名 一致时填充(默认只填 created_id→sys_user)。 """ __tablename__ = "bre_audit_log" __table_args__ = () # 表无 status 列,不生成 ModelMixin 的 status 索引 entity_type: Mapped[str | None] = mapped_column( String(32), index=True, nullable=True, comment="实体类型(业务表名)", default=None ) entity_id: Mapped[int | None] = mapped_column( Integer, index=True, nullable=True, comment="实体ID", default=None ) action: Mapped[str | None] = mapped_column( String(32), index=True, nullable=True, comment="操作类型(CREATE/UPDATE/DELETE/IMPORT)", default=None ) field_name: Mapped[str | None] = mapped_column( String(64), nullable=True, comment="变更字段名(UPDATE 字段级)", default=None ) old_value: Mapped[str | None] = mapped_column( String(512), nullable=True, comment="旧值", default=None ) new_value: Mapped[str | None] = mapped_column( String(512), nullable=True, comment="新值", default=None ) operator_id: Mapped[int | None] = mapped_column( Integer, ForeignKey("bre_personnel.id", ondelete="CASCADE"), nullable=True, comment="操作人(育种人员,命中 personnel.name==username 才填)", default=None, )