Files
govoplan-forms-runtime/src/govoplan_forms_runtime/backend/db/models.py
T

542 lines
21 KiB
Python

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",
]