from __future__ import annotations import uuid from datetime import datetime from typing import Any from sqlalchemy import DateTime, Integer, String, Text, UniqueConstraint from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column from api.models.base import Base, new_uuid class WriteIdempotencyKey(Base): __tablename__ = "write_idempotency_keys" __table_args__ = ( UniqueConstraint("key", name="uq_write_idempotency_keys_key"), ) id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=new_uuid) key: Mapped[str] = mapped_column(String(200), nullable=False, index=True) method: Mapped[str] = mapped_column(String(10), nullable=False) path: Mapped[str] = mapped_column(Text, nullable=False) route_class: Mapped[str] = mapped_column(String(30), nullable=False) request_hash: Mapped[str] = mapped_column(String(64), nullable=False) response_status: Mapped[int] = mapped_column(Integer, nullable=False) response_body: Mapped[Any] = mapped_column(JSONB, nullable=True) source_host: Mapped[str | None] = mapped_column(String(200), nullable=True) source_agent: Mapped[str | None] = mapped_column(String(100), nullable=True) first_seen_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) last_seen_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)