This commit is contained in:
@@ -2,6 +2,7 @@ import enum
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import String, Integer, ForeignKey, DateTime, Enum, Boolean
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
@@ -75,4 +76,30 @@ class Ticket(Base):
|
||||
)
|
||||
|
||||
seat: Mapped["Seat"] = relationship(back_populates="ticket")
|
||||
user: Mapped["User"] = relationship(back_populates="tickets")
|
||||
user: Mapped["User"] = relationship(back_populates="tickets")
|
||||
|
||||
|
||||
class ActionLog(Base):
|
||||
"""Audit trail: every mutating request is recorded here by AuditLogMiddleware."""
|
||||
|
||||
__tablename__ = "action_logs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
|
||||
# nullable — anonymous / unauthenticated requests (e.g. /api/auth/register)
|
||||
user_id: Mapped[int | None] = mapped_column(Integer, nullable=True, index=True)
|
||||
|
||||
# "POST /api/tickets/book", "DELETE /api/seats/42", etc.
|
||||
action: Mapped[str] = mapped_column(String, nullable=False, index=True)
|
||||
|
||||
# request.client.host or X-Forwarded-For (behind Traefik)
|
||||
ip_address: Mapped[str | None] = mapped_column(String, nullable=True)
|
||||
|
||||
# Optional structured payload (response body excerpt, error detail, …)
|
||||
details: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
default=lambda: datetime.now(timezone.utc),
|
||||
index=True,
|
||||
)
|
||||
Reference in New Issue
Block a user