61 lines
3.0 KiB
Python
61 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
from typing import Any
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Index, Integer, JSON, String, Text, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from govoplan_core.db.base import Base, TimestampMixin
|
|
|
|
|
|
def new_uuid() -> str:
|
|
return str(uuid.uuid4())
|
|
|
|
|
|
class AuditLog(Base, TimestampMixin):
|
|
__tablename__ = "audit_log"
|
|
__table_args__ = (
|
|
Index("ix_audit_log_scope_created_at", "scope", "created_at"),
|
|
Index("ix_audit_log_tenant_scope_created_at", "tenant_id", "scope", "created_at"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
|
|
scope: Mapped[str] = mapped_column(String(20), default="tenant", nullable=False, index=True)
|
|
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
|
|
user_id: Mapped[str | None] = mapped_column(ForeignKey("access_users.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
api_key_id: Mapped[str | None] = mapped_column(ForeignKey("access_api_keys.id", ondelete="SET NULL"), nullable=True, index=True)
|
|
action: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
|
|
object_type: Mapped[str | None] = mapped_column(String(100), index=True)
|
|
object_id: Mapped[str | None] = mapped_column(String(100), index=True)
|
|
details: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
class AuditOutboxEvent(Base, TimestampMixin):
|
|
__tablename__ = "audit_outbox_events"
|
|
__table_args__ = (
|
|
UniqueConstraint("event_id", name="uq_audit_outbox_events_event_id"),
|
|
Index("ix_audit_outbox_events_status_next_attempt_at", "status", "next_attempt_at"),
|
|
Index("ix_audit_outbox_events_event_type", "event_type"),
|
|
Index("ix_audit_outbox_events_correlation_id", "correlation_id"),
|
|
)
|
|
|
|
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
|
|
event_id: Mapped[str] = mapped_column(String(36), nullable=False)
|
|
event_type: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
module_id: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
correlation_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
causation_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
classification: Mapped[str] = mapped_column(String(40), nullable=False, default="internal")
|
|
payload: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
status: Mapped[str] = mapped_column(String(20), nullable=False, default="pending", index=True)
|
|
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
next_attempt_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
dispatched_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
__all__ = ["AuditLog", "AuditOutboxEvent", "new_uuid"]
|