from __future__ import annotations from datetime import datetime from typing import Any import uuid from sqlalchemy import ( Boolean, DateTime, ForeignKey, Index, Integer, JSON, String, 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 FormInstanceIdentity(Base, TimestampMixin): __tablename__ = "form_instance_identities" __table_args__ = ( UniqueConstraint( "tenant_id", "instance_id", name="uq_form_instance_identity", ), Index( "ix_form_instance_owner", "tenant_id", "created_by", "definition_id", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) definition_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) definition_revision: Mapped[str] = mapped_column( String(255), nullable=False, index=True ) created_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) class FormInstanceRevision(Base, TimestampMixin): __tablename__ = "form_instance_revisions" __table_args__ = ( UniqueConstraint( "tenant_id", "instance_id", "revision", name="uq_form_instance_revision", ), Index( "ix_form_instance_current", "tenant_id", "instance_id", "superseded_at", ), Index( "ix_form_instance_catalog", "tenant_id", "status", "recorded_at", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) identity_id: Mapped[str] = mapped_column( ForeignKey("form_instance_identities.id", ondelete="RESTRICT"), nullable=False, index=True, ) revision: Mapped[int] = mapped_column(Integer, nullable=False) previous_revision_id: Mapped[str | None] = mapped_column( ForeignKey("form_instance_revisions.id", ondelete="RESTRICT"), nullable=True, index=True, ) status: Mapped[str] = mapped_column(String(30), nullable=False, index=True) recorded_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) superseded_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, index=True ) snapshot: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False) changed_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) class FormInstanceEvent(Base, TimestampMixin): __tablename__ = "form_instance_events" __table_args__ = ( UniqueConstraint( "tenant_id", "event_id", name="uq_form_instance_event", ), UniqueConstraint( "tenant_id", "idempotency_key", name="uq_form_instance_idempotency", ), Index( "ix_form_instance_event_history", "tenant_id", "instance_id", "occurred_at", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) instance_revision: Mapped[int] = mapped_column(Integer, nullable=False) event_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) event_type: Mapped[str] = mapped_column(String(120), nullable=False, index=True) status: Mapped[str] = mapped_column(String(30), nullable=False, index=True) occurred_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) actor_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) request_sha256: Mapped[str] = mapped_column(String(64), nullable=False) payload: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False) class FormHandoffEffect(Base, TimestampMixin): __tablename__ = "form_handoff_effects" __table_args__ = ( UniqueConstraint( "tenant_id", "effect_id", name="uq_form_handoff_effect", ), UniqueConstraint( "tenant_id", "idempotency_key", name="uq_form_handoff_idempotency", ), UniqueConstraint( "tenant_id", "provider_key", name="uq_form_handoff_provider_key", ), Index( "ix_form_handoff_instance_state", "tenant_id", "instance_id", "state", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) effect_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) instance_revision: Mapped[int] = mapped_column(Integer, nullable=False) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) provider_key: Mapped[str] = mapped_column(String(255), nullable=False) request_sha256: Mapped[str] = mapped_column(String(64), nullable=False) binding_kind: Mapped[str] = mapped_column(String(30), nullable=False, index=True) binding_reference: Mapped[str] = mapped_column(String(500), nullable=False) provider_capability: Mapped[str] = mapped_column(String(120), nullable=False) state: Mapped[str] = mapped_column(String(30), nullable=False, index=True) attempt_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) requested_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) resolved_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, index=True ) target_ref: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True) href: Mapped[str | None] = mapped_column(String(2000), nullable=True) evidence: Mapped[list[dict[str, Any]]] = mapped_column( JSON, default=list, nullable=False ) last_error: Mapped[str | None] = mapped_column(String(2000), nullable=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormIntakeProfile(Base, TimestampMixin): __tablename__ = "form_intake_profiles" __table_args__ = ( UniqueConstraint( "tenant_id", "profile_id", name="uq_form_intake_profile", ), UniqueConstraint("public_id", name="uq_form_intake_public_id"), Index( "ix_form_intake_definition", "tenant_id", "definition_id", "definition_revision", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) profile_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) public_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True) definition_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) definition_revision: Mapped[str] = mapped_column( String(255), nullable=False, index=True ) mode: Mapped[str] = mapped_column(String(30), nullable=False, index=True) enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) revision: Mapped[int] = mapped_column(Integer, default=1, nullable=False) custodian_ref: Mapped[str] = mapped_column(String(255), nullable=False) draft_ttl_seconds: Mapped[int] = mapped_column(Integer, nullable=False) invitation_ttl_seconds: Mapped[int] = mapped_column(Integer, nullable=False) rate_limit_per_minute: Mapped[int] = mapped_column(Integer, nullable=False) rate_window_started_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) rate_window_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False) created_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) updated_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormIntakeSession(Base, TimestampMixin): __tablename__ = "form_intake_sessions" __table_args__ = ( UniqueConstraint( "tenant_id", "session_id", name="uq_form_intake_session", ), UniqueConstraint("token_sha256", name="uq_form_intake_token"), UniqueConstraint( "tenant_id", "idempotency_key", name="uq_form_intake_session_idempotency", ), Index( "ix_form_intake_session_state", "tenant_id", "profile_id", "status", "expires_at", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) session_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) profile_id: Mapped[str] = mapped_column( ForeignKey("form_intake_profiles.id", ondelete="RESTRICT"), nullable=False, index=True, ) token_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True) mode: Mapped[str] = mapped_column(String(30), nullable=False, index=True) status: Mapped[str] = mapped_column(String(30), nullable=False, index=True) instance_id: Mapped[str | None] = mapped_column( String(255), nullable=True, index=True ) actor_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) request_sha256: Mapped[str] = mapped_column(String(64), nullable=False) expires_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) started_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) submitted_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) revoked_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) created_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormAssistedConfirmation(Base, TimestampMixin): __tablename__ = "form_assisted_confirmations" __table_args__ = ( UniqueConstraint( "tenant_id", "confirmation_id", name="uq_form_assisted_confirmation", ), UniqueConstraint( "tenant_id", "idempotency_key", name="uq_form_assisted_confirmation_idempotency", ), Index( "ix_form_assisted_confirmation_instance", "tenant_id", "instance_id", "instance_revision", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) confirmation_id: Mapped[str] = mapped_column( String(36), nullable=False, index=True ) intake_session_id: Mapped[str] = mapped_column( ForeignKey("form_intake_sessions.id", ondelete="RESTRICT"), nullable=False, index=True, ) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) instance_revision: Mapped[int] = mapped_column(Integer, nullable=False) outcome: Mapped[str] = mapped_column(String(30), nullable=False, index=True) method: Mapped[str] = mapped_column(String(30), nullable=False, index=True) confirmed_by_ref: Mapped[str] = mapped_column(String(255), nullable=False) operator_actor_id: Mapped[str] = mapped_column( String(255), nullable=False, index=True ) confirmed_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) payload_sha256: Mapped[str] = mapped_column(String(64), nullable=False) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) request_sha256: Mapped[str] = mapped_column(String(64), nullable=False) correction_note: Mapped[str | None] = mapped_column(String(1000), nullable=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormStatusAccessPolicy(Base, TimestampMixin): __tablename__ = "form_status_access_policies" __table_args__ = ( UniqueConstraint( "tenant_id", "policy_id", name="uq_form_status_access_policy", ), UniqueConstraint( "tenant_id", "definition_id", "definition_revision", name="uq_form_status_access_definition", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) policy_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) definition_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) definition_revision: Mapped[str] = mapped_column( String(255), nullable=False, index=True ) mode: Mapped[str] = mapped_column(String(30), nullable=False, index=True) enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) revision: Mapped[int] = mapped_column(Integer, default=1, nullable=False) email_field_key: Mapped[str | None] = mapped_column(String(255), nullable=True) token_ttl_seconds: Mapped[int] = mapped_column(Integer, nullable=False) request_limit_per_hour: Mapped[int] = mapped_column(Integer, nullable=False) created_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) updated_by: Mapped[str] = mapped_column(String(255), nullable=False, index=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormStatusAccessGrant(Base, TimestampMixin): __tablename__ = "form_status_access_grants" __table_args__ = ( UniqueConstraint( "tenant_id", "grant_id", name="uq_form_status_access_grant", ), UniqueConstraint("tracking_id", name="uq_form_status_tracking_id"), UniqueConstraint( "tenant_id", "instance_id", name="uq_form_status_access_instance", ), Index( "ix_form_status_access_policy_state", "tenant_id", "policy_id", "revoked_at", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) grant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) policy_id: Mapped[str] = mapped_column( ForeignKey("form_status_access_policies.id", ondelete="RESTRICT"), nullable=False, index=True, ) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) tracking_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True) mode: Mapped[str] = mapped_column(String(30), nullable=False, index=True) applicant_actor_id: Mapped[str | None] = mapped_column( String(255), nullable=True, index=True ) recipient_email_sha256: Mapped[str | None] = mapped_column( String(64), nullable=True ) token_ttl_seconds: Mapped[int] = mapped_column(Integer, nullable=False) request_limit_per_hour: Mapped[int] = mapped_column(Integer, nullable=False) request_window_started_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) request_window_count: Mapped[int] = mapped_column( Integer, default=0, nullable=False ) issued_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) last_accessed_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) revoked_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, index=True ) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormStatusAccessToken(Base, TimestampMixin): __tablename__ = "form_status_access_tokens" __table_args__ = ( UniqueConstraint( "tenant_id", "token_id", name="uq_form_status_access_token", ), UniqueConstraint("token_sha256", name="uq_form_status_access_token_digest"), Index( "ix_form_status_access_token_state", "tenant_id", "grant_id", "expires_at", "revoked_at", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) token_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) grant_id: Mapped[str] = mapped_column( ForeignKey("form_status_access_grants.id", ondelete="RESTRICT"), nullable=False, index=True, ) token_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True) issued_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) expires_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) revoked_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, index=True ) last_used_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True ) notification_id: Mapped[str | None] = mapped_column(String(255), nullable=True) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) class FormAcknowledgement(Base, TimestampMixin): __tablename__ = "form_acknowledgements" __table_args__ = ( UniqueConstraint( "tenant_id", "acknowledgement_id", name="uq_form_acknowledgement", ), UniqueConstraint( "tenant_id", "idempotency_key", name="uq_form_acknowledgement_idempotency", ), Index( "ix_form_acknowledgement_instance", "tenant_id", "instance_id", "instance_revision", ), ) id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True) acknowledgement_id: Mapped[str] = mapped_column( String(36), nullable=False, index=True ) instance_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) instance_revision: Mapped[int] = mapped_column(Integer, nullable=False) statement_id: Mapped[str] = mapped_column(String(255), nullable=False) statement_version: Mapped[str] = mapped_column(String(255), nullable=False) actor_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True) accepted_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, index=True ) payload_sha256: Mapped[str] = mapped_column(String(64), nullable=False) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) request_sha256: Mapped[str] = mapped_column(String(64), nullable=False) details: Mapped[dict[str, Any]] = mapped_column( "metadata", JSON, default=dict, nullable=False ) __all__ = [ "FormAcknowledgement", "FormAssistedConfirmation", "FormInstanceEvent", "FormHandoffEffect", "FormIntakeProfile", "FormIntakeSession", "FormInstanceIdentity", "FormInstanceRevision", "FormStatusAccessGrant", "FormStatusAccessPolicy", "FormStatusAccessToken", ]