- 新增后台用车服务配置模块,支持维护服务简介、优势与使用流程 - 新增需求线索管理页面,支持筛选、查看与更新用车线索状态 - 新增小程序用车需求页面,优化登录路径与回跳逻辑 - 优化车型卡片跳转与用车需求提交功能 - 新增服务端API与数据处理逻辑,完善权限校验 - 更新全站配置与API文档,新增相关测试用例
378 lines
20 KiB
Python
378 lines
20 KiB
Python
from datetime import datetime, timezone
|
|
from uuid import uuid4
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
|
|
from sqlalchemy.dialects.postgresql import ARRAY, JSONB
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
from .database import Base
|
|
|
|
|
|
def utc_now() -> datetime:
|
|
return datetime.now(timezone.utc).replace(tzinfo=None)
|
|
|
|
|
|
def new_id() -> str:
|
|
return str(uuid4())
|
|
|
|
|
|
class AdminUser(Base):
|
|
__tablename__ = "AdminUser"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
email: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
name: Mapped[str] = mapped_column(String, nullable=False)
|
|
passwordHash: Mapped[str] = mapped_column(String, nullable=False)
|
|
role: Mapped[str] = mapped_column(String, default="admin", nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
auditLogs: Mapped[list["AuditLog"]] = relationship(back_populates="actor")
|
|
assignedLeads: Mapped[list["Lead"]] = relationship(back_populates="assignedUser", foreign_keys="Lead.assignedUserId")
|
|
|
|
|
|
class MediaAsset(Base):
|
|
__tablename__ = "MediaAsset"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
url: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
name: Mapped[str | None] = mapped_column(String)
|
|
mimeType: Mapped[str | None] = mapped_column(String)
|
|
sizeBytes: Mapped[int | None] = mapped_column(Integer)
|
|
group: Mapped[str | None] = mapped_column(String)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class HeroSlide(Base):
|
|
__tablename__ = "HeroSlide"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
kicker: Mapped[str | None] = mapped_column(String)
|
|
actionLabel: Mapped[str | None] = mapped_column(String)
|
|
image: Mapped[str] = mapped_column(String, nullable=False)
|
|
targetType: Mapped[str | None] = mapped_column(String)
|
|
targetValue: Mapped[str | None] = mapped_column(String)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class DestinationHero(Base):
|
|
__tablename__ = "DestinationHero"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
kicker: Mapped[str | None] = mapped_column(String)
|
|
image: Mapped[str | None] = mapped_column(String)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class VehicleOption(Base):
|
|
__tablename__ = "VehicleOption"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
description: Mapped[str | None] = mapped_column(Text)
|
|
image: Mapped[str | None] = mapped_column(String)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class VehicleServiceConfig(Base):
|
|
__tablename__ = "VehicleServiceConfig"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
introTitle: Mapped[str] = mapped_column(String, nullable=False)
|
|
intro: Mapped[str] = mapped_column(Text, nullable=False)
|
|
serviceSections: Mapped[list[dict[str, str]]] = mapped_column(JSONB, default=list, nullable=False)
|
|
advantages: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
processSteps: Mapped[list[dict[str, str]]] = mapped_column(JSONB, default=list, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class HomeExperience(Base):
|
|
__tablename__ = "HomeExperience"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
badge: Mapped[str] = mapped_column(String, nullable=False)
|
|
category: Mapped[str] = mapped_column(String, nullable=False)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
englishTitle: Mapped[str] = mapped_column(String, nullable=False)
|
|
image: Mapped[str] = mapped_column(String, nullable=False)
|
|
demandKeyword: Mapped[str] = mapped_column(String, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class HomeTeamBuilding(Base):
|
|
__tablename__ = "HomeTeamBuilding"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
tag: Mapped[str] = mapped_column(String, nullable=False)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
description: Mapped[str] = mapped_column(Text, nullable=False)
|
|
image: Mapped[str] = mapped_column(String, nullable=False)
|
|
demandKeyword: Mapped[str] = mapped_column(String, nullable=False)
|
|
detailSubtitle: Mapped[str] = mapped_column(String, default="", nullable=False)
|
|
detailParagraphs: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class HomeWildArchive(Base):
|
|
__tablename__ = "HomeWildArchive"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
image: Mapped[str] = mapped_column(String, nullable=False)
|
|
images: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
demandKeyword: Mapped[str] = mapped_column(String, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class HomeWanfaRecommendation(Base):
|
|
__tablename__ = "HomeWanfaRecommendation"
|
|
__table_args__ = (
|
|
UniqueConstraint("categoryId", name="uq_HomeWanfaRecommendation_categoryId"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
categoryId: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("WanfaCategory.id", ondelete="RESTRICT"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
category: Mapped["WanfaCategory"] = relationship(back_populates="recommendations")
|
|
|
|
|
|
class WanfaCategory(Base):
|
|
__tablename__ = "WanfaCategory"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
label: Mapped[str] = mapped_column(String, nullable=False)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
routes: Mapped[list["WanfaRoute"]] = relationship(
|
|
back_populates="category",
|
|
order_by="WanfaRoute.sortOrder.asc()",
|
|
)
|
|
recommendations: Mapped[list[HomeWanfaRecommendation]] = relationship(back_populates="category")
|
|
|
|
|
|
class WanfaRoute(Base):
|
|
__tablename__ = "WanfaRoute"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
categoryId: Mapped[str] = mapped_column(
|
|
String,
|
|
ForeignKey("WanfaCategory.id", ondelete="RESTRICT"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
subtitle: Mapped[str] = mapped_column(Text, nullable=False)
|
|
image: Mapped[str] = mapped_column(String, nullable=False)
|
|
routeCount: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
demandKeyword: Mapped[str] = mapped_column(String, nullable=False)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
category: Mapped[WanfaCategory] = relationship(back_populates="routes")
|
|
|
|
|
|
class DetailRecord(Base):
|
|
__tablename__ = "DetailRecord"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
key: Mapped[str] = mapped_column(String, nullable=False, unique=True)
|
|
eyebrow: Mapped[str] = mapped_column(String, nullable=False)
|
|
duration: Mapped[str] = mapped_column(String, nullable=False)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
subtitle: Mapped[str] = mapped_column(Text, nullable=False)
|
|
intro: Mapped[str] = mapped_column(Text, nullable=False)
|
|
highlights: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
included: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
excluded: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
notes: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
gallery: Mapped[list[str]] = mapped_column(JSONB, default=list, nullable=False)
|
|
conciergeAdvisorId: Mapped[str | None] = mapped_column(String, nullable=True)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class ConciergeAdvisor(Base):
|
|
__tablename__ = "ConciergeAdvisor"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
avatar: Mapped[str] = mapped_column(String, nullable=False)
|
|
name: Mapped[str] = mapped_column(String, nullable=False)
|
|
role: Mapped[str] = mapped_column(String, nullable=False)
|
|
details: Mapped[list[dict[str, str]]] = mapped_column(JSONB, default=list, nullable=False)
|
|
qrImage: Mapped[str] = mapped_column(String, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False, index=True)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class DemandHero(Base):
|
|
__tablename__ = "DemandHero"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
kicker: Mapped[str | None] = mapped_column(String)
|
|
description: Mapped[str | None] = mapped_column(Text)
|
|
steps: Mapped[list[str]] = mapped_column(ARRAY(String), default=list, nullable=False)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class DemandFeatureCard(Base):
|
|
__tablename__ = "DemandFeatureCard"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
description: Mapped[str | None] = mapped_column(Text)
|
|
sortOrder: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class DemandForm(Base):
|
|
__tablename__ = "DemandForm"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
destinationLabel: Mapped[str] = mapped_column(String, default="目的地/玩法", nullable=False)
|
|
destinationPlaceholder: Mapped[str | None] = mapped_column(String)
|
|
phoneLabel: Mapped[str] = mapped_column(String, default="联系方式", nullable=False)
|
|
phonePlaceholder: Mapped[str | None] = mapped_column(String)
|
|
noteLabel: Mapped[str] = mapped_column(String, default="补充说明", nullable=False)
|
|
notePlaceholder: Mapped[str | None] = mapped_column(String)
|
|
submitLabel: Mapped[str] = mapped_column(String, default="提交出行需求", nullable=False)
|
|
chips: Mapped[list[str]] = mapped_column(ARRAY(String), default=list, nullable=False)
|
|
isActive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
|
|
class Lead(Base):
|
|
__tablename__ = "Lead"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
leadType: Mapped[str] = mapped_column(String, default="general", nullable=False, index=True)
|
|
contactName: Mapped[str | None] = mapped_column(String)
|
|
customerId: Mapped[str | None] = mapped_column(String, ForeignKey("Customer.id", ondelete="SET NULL"), index=True)
|
|
destination: Mapped[str | None] = mapped_column(String)
|
|
phone: Mapped[str] = mapped_column(String, nullable=False)
|
|
travelDate: Mapped[datetime | None] = mapped_column(DateTime)
|
|
peopleCount: Mapped[int | None] = mapped_column(Integer)
|
|
budgetMin: Mapped[int | None] = mapped_column(Integer)
|
|
budgetMax: Mapped[int | None] = mapped_column(Integer)
|
|
note: Mapped[str | None] = mapped_column(Text)
|
|
vehicleDemand: Mapped[dict | None] = mapped_column(JSONB)
|
|
sourcePage: Mapped[str | None] = mapped_column(String)
|
|
status: Mapped[str] = mapped_column(String, default="new", nullable=False)
|
|
assignedUserId: Mapped[str | None] = mapped_column(String, ForeignKey("AdminUser.id", ondelete="SET NULL"))
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
assignedUser: Mapped[AdminUser | None] = relationship(back_populates="assignedLeads", foreign_keys=[assignedUserId])
|
|
followups: Mapped[list["LeadFollowup"]] = relationship(back_populates="lead", cascade="all, delete-orphan")
|
|
|
|
|
|
class LeadFollowup(Base):
|
|
__tablename__ = "LeadFollowup"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
leadId: Mapped[str] = mapped_column(String, ForeignKey("Lead.id", ondelete="CASCADE"), nullable=False)
|
|
content: Mapped[str] = mapped_column(Text, nullable=False)
|
|
nextAt: Mapped[datetime | None] = mapped_column(DateTime)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
|
|
lead: Mapped[Lead] = relationship(back_populates="followups")
|
|
|
|
|
|
class Customer(Base):
|
|
__tablename__ = "Customer"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
phone: Mapped[str] = mapped_column(String, unique=True, nullable=False)
|
|
name: Mapped[str | None] = mapped_column(String)
|
|
wechat: Mapped[str | None] = mapped_column(String)
|
|
note: Mapped[str | None] = mapped_column(Text)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
orders: Mapped[list["Order"]] = relationship(back_populates="customer")
|
|
|
|
|
|
class Order(Base):
|
|
__tablename__ = "Order"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
customerId: Mapped[str | None] = mapped_column(String, ForeignKey("Customer.id", ondelete="SET NULL"))
|
|
status: Mapped[str] = mapped_column(String, default="draft", nullable=False)
|
|
travelDate: Mapped[datetime | None] = mapped_column(DateTime)
|
|
amount: Mapped[int | None] = mapped_column(Integer)
|
|
note: Mapped[str | None] = mapped_column(Text)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
updatedAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, onupdate=utc_now, nullable=False)
|
|
|
|
customer: Mapped[Customer | None] = relationship(back_populates="orders")
|
|
|
|
|
|
class SiteVersion(Base):
|
|
__tablename__ = "SiteVersion"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
title: Mapped[str] = mapped_column(String, nullable=False)
|
|
status: Mapped[str] = mapped_column(String, default="draft", nullable=False)
|
|
snapshot: Mapped[dict | list] = mapped_column(JSONB, nullable=False)
|
|
publishedAt: Mapped[datetime | None] = mapped_column(DateTime)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
|
|
|
|
class AuditLog(Base):
|
|
__tablename__ = "AuditLog"
|
|
|
|
id: Mapped[str] = mapped_column(String, primary_key=True, default=new_id)
|
|
actorId: Mapped[str | None] = mapped_column(String, ForeignKey("AdminUser.id", ondelete="SET NULL"))
|
|
action: Mapped[str] = mapped_column(String, nullable=False)
|
|
entity: Mapped[str] = mapped_column(String, nullable=False)
|
|
entityId: Mapped[str | None] = mapped_column(String)
|
|
before: Mapped[dict | list | None] = mapped_column(JSONB)
|
|
after: Mapped[dict | list | None] = mapped_column(JSONB)
|
|
createdAt: Mapped[datetime] = mapped_column(DateTime, default=utc_now, nullable=False)
|
|
|
|
actor: Mapped[AdminUser | None] = relationship(back_populates="auditLogs")
|