"""Dify-owned control-plane persistence for the KnowledgeFS product. These models intentionally have no dependency on Dify Dataset or Document models. KnowledgeFS data-plane objects remain owned by KnowledgeFS; these rows only describe Dify authorization, registration, and durable lifecycle intent. """ from __future__ import annotations from datetime import datetime from enum import StrEnum from typing import NotRequired, TypedDict import sqlalchemy as sa from sqlalchemy import DateTime, Index, String, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column from .base import DefaultFieldsDCMixin, TypeBase from .types import EnumText, LongText, StringUUID KnowledgeFSAllowedActions = list[str] class KnowledgeFSCommandEnvelope(TypedDict): schema_version: int idempotency_key: str expected_revision: int class KnowledgeFSModelSelectionIntentPayload(TypedDict): pluginId: str provider: str model: str class KnowledgeFSRerankIntentPayload(TypedDict): enabled: bool model: NotRequired[KnowledgeFSModelSelectionIntentPayload] class KnowledgeFSScoreThresholdIntentPayload(TypedDict): enabled: bool stage: str value: NotRequired[float] class KnowledgeFSRetrievalProfileIntentPayload(TypedDict): defaultMode: str reasoningModel: KnowledgeFSModelSelectionIntentPayload rerank: KnowledgeFSRerankIntentPayload scoreThreshold: KnowledgeFSScoreThresholdIntentPayload topK: int class KnowledgeFSProvisionCommandPayload(KnowledgeFSCommandEnvelope): provisioning_key: str name: str icon: str | None description: str | None slug: str model_intent: NotRequired[KnowledgeFSModelSelectionIntentPayload] profile_intent: NotRequired[KnowledgeFSRetrievalProfileIntentPayload] class KnowledgeFSMetadataUpdateCommandPayload(KnowledgeFSCommandEnvelope): metadata: dict[str, object] class KnowledgeFSDeleteCommandPayload(KnowledgeFSCommandEnvelope): knowledge_space_id: str | None provisioning_key: str class KnowledgeFSRevokeCommandPayload(KnowledgeFSCommandEnvelope): event_id: str grant_id: str knowledge_space_id: str principal: str reason_code: str revoke_sequence: int class KnowledgeFSRepairCommandPayload(KnowledgeFSCommandEnvelope): repair_reason: str KnowledgeFSCommandPayload = ( KnowledgeFSProvisionCommandPayload | KnowledgeFSMetadataUpdateCommandPayload | KnowledgeFSDeleteCommandPayload | KnowledgeFSRevokeCommandPayload | KnowledgeFSRepairCommandPayload ) class KnowledgeFSCapabilityAuthzRevisionSummary(TypedDict): membership_epoch: int space_acl_epoch: int external_access_epoch: int credential_revision: int | None class KnowledgeFSCapabilityClaimsSummary(TypedDict): action: str actor: str authz_revision: KnowledgeFSCapabilityAuthzRevisionSummary caller_kind: str content_policy_revision: int content_scope_ids: list[str] control_space_id: str expires_at: str grant_id: str issued_at: str namespace_id: str operation_id: str resource_id: str resource_parent_id: str | None resource_type: str subject: str class KnowledgeFSCapabilityReservationSummary(TypedDict): """Sanitized, exact input bound before a capability can be signed.""" action: str actor: str authz_revision: KnowledgeFSCapabilityAuthzRevisionSummary caller_kind: str content_policy_revision: int content_scope_ids: list[str] control_space_id: str grant_id: str namespace_id: str operation_id: str resource_id: str resource_parent_id: str | None resource_type: str subject: str trace_id: str class KnowledgeFSControlSpaceVisibility(StrEnum): ONLY_ME = "only_me" ALL_TEAM_MEMBERS = "all_team_members" PARTIAL_MEMBERS = "partial_members" class KnowledgeFSControlSpaceState(StrEnum): PROVISIONING = "provisioning" ACTIVE = "active" DELETING = "deleting" DELETED = "deleted" ERROR = "error" class KnowledgeFSControlSpacePermissionRole(StrEnum): OWNER = "owner" EDITOR = "editor" VIEWER = "viewer" class KnowledgeFSControlSpacePermissionStatus(StrEnum): ACTIVE = "active" REVOKED = "revoked" class KnowledgeFSApiCredentialStatus(StrEnum): ACTIVE = "active" REVOKED = "revoked" EXPIRED = "expired" class KnowledgeFSAppSpaceJoinType(StrEnum): AGENT = "agent" WORKFLOW = "workflow" class KnowledgeFSAppSpaceJoinStatus(StrEnum): ACTIVE = "active" REVOKED = "revoked" class KnowledgeFSCapabilityIssuanceReservationStatus(StrEnum): RESERVED = "reserved" ISSUED = "issued" FAILED = "failed" class KnowledgeFSLifecycleOperation(StrEnum): PROVISION = "provision" METADATA_UPDATE = "metadata_update" DELETE = "delete" REVOKE = "revoke" REPAIR = "repair" class KnowledgeFSLifecycleOutboxStatus(StrEnum): PENDING = "pending" PROCESSING = "processing" SUCCEEDED = "succeeded" RETRY = "retry" DEAD_LETTER = "dead_letter" class KnowledgeFSControlSpace(DefaultFieldsDCMixin, TypeBase): """Dify product resource registered to at most one KnowledgeFS Space.""" __tablename__ = "knowledge_fs_control_spaces" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_control_space_pkey"), UniqueConstraint("tenant_id", "id", name="kfs_control_space_tenant_id_uq"), UniqueConstraint("provisioning_key", name="kfs_control_space_provisioning_key_uq"), sa.ForeignKeyConstraint( ["tenant_id"], ["tenants.id"], name="kfs_control_space_workspace_fk", ondelete="RESTRICT", ), Index( "kfs_control_space_tenant_space_uq", "tenant_id", "knowledge_space_id", unique=True, postgresql_where=sa.text("knowledge_space_id IS NOT NULL"), ), Index("kfs_control_space_state_updated_idx", "state", "updated_at"), Index("kfs_control_space_tenant_state_updated_idx", "tenant_id", "state", "updated_at"), Index("kfs_control_space_tenant_owner_state_idx", "tenant_id", "owner_account_id", "state"), sa.CheckConstraint( "resource_version >= 0", name=sa.schema.conv("kfs_control_space_resource_version_ck"), ), sa.CheckConstraint("attempt_count >= 0", name=sa.schema.conv("kfs_control_space_attempt_count_ck")), sa.CheckConstraint( "state != 'active' OR knowledge_space_id IS NOT NULL", name=sa.schema.conv("kfs_control_space_active_registration_ck"), ), sa.CheckConstraint( "deletion_irreversible_at IS NULL OR state IN ('deleting', 'deleted', 'error')", name=sa.schema.conv("kfs_control_space_irreversible_state_ck"), ), sa.CheckConstraint( "knowledge_space_revision >= 0", name=sa.schema.conv("kfs_control_space_remote_revision_ck"), ), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) owner_account_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provisioning_key: Mapped[str] = mapped_column(String(255), nullable=False) knowledge_space_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) knowledge_space_revision: Mapped[int] = mapped_column( sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0, ) visibility: Mapped[KnowledgeFSControlSpaceVisibility] = mapped_column( EnumText(KnowledgeFSControlSpaceVisibility, length=32), nullable=False, server_default=sa.text("'only_me'"), default=KnowledgeFSControlSpaceVisibility.ONLY_ME, ) lifecycle_operation_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) state: Mapped[KnowledgeFSControlSpaceState] = mapped_column( EnumText(KnowledgeFSControlSpaceState, length=32), nullable=False, server_default=sa.text("'provisioning'"), default=KnowledgeFSControlSpaceState.PROVISIONING, ) resource_version: Mapped[int] = mapped_column( sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0, ) attempt_count: Mapped[int] = mapped_column( sa.Integer, nullable=False, server_default=sa.text("0"), default=0, ) last_attempt_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) last_error_code: Mapped[str | None] = mapped_column(String(255), nullable=True, default=None) last_error_message: Mapped[str | None] = mapped_column(LongText, nullable=True, default=None) last_synced_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) deletion_irreversible_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) class KnowledgeFSControlSpacePermission(DefaultFieldsDCMixin, TypeBase): """Account-level product authorization for one control-space.""" __tablename__ = "knowledge_fs_control_space_permissions" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_control_space_permission_pkey"), UniqueConstraint( "tenant_id", "control_space_id", "account_id", name="kfs_control_space_permission_identity_uq", ), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_control_space_permission_space_fk", ondelete="RESTRICT", ), Index("kfs_control_space_permission_account_idx", "tenant_id", "account_id", "status"), sa.CheckConstraint( "revision >= 0", name=sa.schema.conv("kfs_control_space_permission_revision_ck"), ), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) account_id: Mapped[str] = mapped_column(StringUUID, nullable=False) role: Mapped[KnowledgeFSControlSpacePermissionRole] = mapped_column( EnumText(KnowledgeFSControlSpacePermissionRole, length=32), nullable=False ) status: Mapped[KnowledgeFSControlSpacePermissionStatus] = mapped_column( EnumText(KnowledgeFSControlSpacePermissionStatus, length=32), nullable=False, server_default=sa.text("'active'"), default=KnowledgeFSControlSpacePermissionStatus.ACTIVE, ) revision: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) granted_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) revoked_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) class KnowledgeFSExternalAccessPolicy(DefaultFieldsDCMixin, TypeBase): """Fail-closed caller-channel policy for a control-space.""" __tablename__ = "knowledge_fs_external_access_policies" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_external_access_policy_pkey"), UniqueConstraint("tenant_id", "control_space_id", name="kfs_external_access_policy_space_uq"), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_external_access_policy_space_fk", ondelete="RESTRICT", ), sa.CheckConstraint("revision >= 0", name=sa.schema.conv("kfs_external_access_policy_revision_ck")), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) service_api_enabled: Mapped[bool] = mapped_column( sa.Boolean, nullable=False, server_default=sa.text("false"), default=False ) agent_enabled: Mapped[bool] = mapped_column( sa.Boolean, nullable=False, server_default=sa.text("false"), default=False ) workflow_enabled: Mapped[bool] = mapped_column( sa.Boolean, nullable=False, server_default=sa.text("false"), default=False ) mcp_enabled: Mapped[bool] = mapped_column( sa.Boolean, nullable=False, server_default=sa.text("false"), default=False ) revision: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) updated_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) class KnowledgeFSApiCredential(DefaultFieldsDCMixin, TypeBase): """Hashed, resource-bound KnowledgeFS API credential metadata.""" __tablename__ = "knowledge_fs_api_credentials" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_api_credential_pkey"), UniqueConstraint("credential_hash", name="kfs_api_credential_hash_uq"), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_api_credential_space_fk", ondelete="RESTRICT", ), Index("kfs_api_credential_tenant_space_status_idx", "tenant_id", "control_space_id", "status"), Index("kfs_api_credential_tenant_prefix_idx", "tenant_id", "credential_prefix"), sa.CheckConstraint("revision >= 0", name=sa.schema.conv("kfs_api_credential_revision_ck")), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) credential_hash: Mapped[str] = mapped_column(String(255), nullable=False) credential_prefix: Mapped[str] = mapped_column(String(32), nullable=False) credential_last4: Mapped[str] = mapped_column(String(4), nullable=False) principal: Mapped[str] = mapped_column(String(255), nullable=False) allowed_actions: Mapped[KnowledgeFSAllowedActions] = mapped_column(sa.JSON, nullable=False) status: Mapped[KnowledgeFSApiCredentialStatus] = mapped_column( EnumText(KnowledgeFSApiCredentialStatus, length=32), nullable=False, server_default=sa.text("'active'"), default=KnowledgeFSApiCredentialStatus.ACTIVE, ) revision: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) last_used_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) created_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) revoked_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) revoke_reason: Mapped[str | None] = mapped_column(String(255), nullable=True, default=None) class AppKnowledgeFSSpaceJoin(DefaultFieldsDCMixin, TypeBase): """Explicit Agent or Workflow app authorization for a control-space.""" __tablename__ = "app_knowledge_fs_space_joins" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="app_kfs_space_join_pkey"), UniqueConstraint( "tenant_id", "app_id", "control_space_id", "join_type", name="app_kfs_space_join_identity_uq", ), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="app_kfs_space_join_space_fk", ondelete="RESTRICT", ), Index("app_kfs_space_join_app_status_idx", "tenant_id", "app_id", "status"), sa.CheckConstraint("revision >= 0", name=sa.schema.conv("app_kfs_space_join_revision_ck")), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) app_id: Mapped[str] = mapped_column(StringUUID, nullable=False) join_type: Mapped[KnowledgeFSAppSpaceJoinType] = mapped_column( EnumText(KnowledgeFSAppSpaceJoinType, length=32), nullable=False ) status: Mapped[KnowledgeFSAppSpaceJoinStatus] = mapped_column( EnumText(KnowledgeFSAppSpaceJoinStatus, length=32), nullable=False, server_default=sa.text("'active'"), default=KnowledgeFSAppSpaceJoinStatus.ACTIVE, ) revision: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) created_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) revoked_by_account_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) class KnowledgeFSAuthorizationRevision(DefaultFieldsDCMixin, TypeBase): """Monotonic authorization epochs included in future Capability claims.""" __tablename__ = "knowledge_fs_authorization_revisions" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_authorization_revision_pkey"), UniqueConstraint("tenant_id", "control_space_id", name="kfs_authorization_revision_space_uq"), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_authorization_revision_space_fk", ondelete="RESTRICT", ), sa.CheckConstraint( "membership_epoch >= 0", name=sa.schema.conv("kfs_authorization_membership_epoch_ck"), ), sa.CheckConstraint( "space_acl_epoch >= 0", name=sa.schema.conv("kfs_authorization_space_acl_epoch_ck"), ), sa.CheckConstraint( "external_access_epoch >= 0", name=sa.schema.conv("kfs_authorization_external_access_epoch_ck"), ), sa.CheckConstraint( "content_policy_revision >= 0", name=sa.schema.conv("kfs_authorization_content_policy_revision_ck"), ), sa.CheckConstraint( "revoke_sequence >= 0", name=sa.schema.conv("kfs_authorization_revoke_sequence_ck"), ), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) membership_epoch: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) space_acl_epoch: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) external_access_epoch: Mapped[int] = mapped_column( sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0 ) content_policy_revision: Mapped[int] = mapped_column( sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0 ) revoke_sequence: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) class KnowledgeFSCapabilityIssuanceAudit(DefaultFieldsDCMixin, TypeBase): """Sanitized durable evidence for a Capability v2 issuance.""" __tablename__ = "knowledge_fs_capability_issuance_audits" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_capability_issuance_audit_pkey"), UniqueConstraint("jti_hash", name="kfs_capability_issuance_audit_jti_hash_uq"), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_capability_issuance_audit_space_fk", ondelete="RESTRICT", ), Index( "kfs_capability_issuance_audit_space_created_idx", "tenant_id", "control_space_id", "created_at", ), Index("kfs_capability_issuance_audit_trace_idx", "tenant_id", "trace_id"), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) trace_id: Mapped[str] = mapped_column(String(128), nullable=False) jti_hash: Mapped[str] = mapped_column(String(80), nullable=False) claims_summary: Mapped[KnowledgeFSCapabilityClaimsSummary] = mapped_column(sa.JSON, nullable=False) class KnowledgeFSCapabilityIssuanceReservation(DefaultFieldsDCMixin, TypeBase): """Durable authorization fence written before signing starts. The summary intentionally excludes bearer tokens, signing material, and raw JTI values. Revocation producers scan these rows as well as completed issuance audits, closing the authorization-to-signing race without holding a database transaction across signing. """ __tablename__ = "knowledge_fs_capability_issuance_reservations" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_capability_issuance_reservation_pkey"), UniqueConstraint( "tenant_id", "grant_id", name="kfs_capability_issuance_reservation_grant_uq", ), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_capability_issuance_reservation_space_fk", ondelete="RESTRICT", ), Index( "kfs_capability_issuance_reservation_subject_idx", "tenant_id", "control_space_id", "subject", "caller_kind", ), Index( "kfs_capability_issuance_reservation_trace_idx", "tenant_id", "trace_id", ), sa.CheckConstraint( "row_version >= 0", name=sa.schema.conv("kfs_capability_issuance_reservation_version_ck"), ), sa.CheckConstraint( "(status = 'reserved' AND issued_at IS NULL AND token_expires_at IS NULL " "AND failed_at IS NULL AND failure_code IS NULL AND cleanup_after IS NULL) OR " "(status = 'issued' AND issued_at IS NOT NULL AND token_expires_at IS NOT NULL " "AND failed_at IS NULL AND failure_code IS NULL AND cleanup_after IS NOT NULL) OR " "(status = 'failed' AND issued_at IS NULL AND token_expires_at IS NULL " "AND failed_at IS NOT NULL AND failure_code IS NOT NULL AND cleanup_after IS NOT NULL)", name=sa.schema.conv("kfs_capability_issuance_reservation_status_fields_ck"), ), sa.CheckConstraint( "token_expires_at IS NULL OR cleanup_after >= token_expires_at", name=sa.schema.conv("kfs_capability_issuance_reservation_cleanup_window_ck"), ), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) grant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) trace_id: Mapped[str] = mapped_column(String(128), nullable=False) subject: Mapped[str] = mapped_column(String(255), nullable=False) caller_kind: Mapped[str] = mapped_column(String(32), nullable=False) request_summary: Mapped[KnowledgeFSCapabilityReservationSummary] = mapped_column(sa.JSON, nullable=False) status: Mapped[KnowledgeFSCapabilityIssuanceReservationStatus] = mapped_column( EnumText(KnowledgeFSCapabilityIssuanceReservationStatus, length=16), nullable=False, server_default=sa.text("'reserved'"), default=KnowledgeFSCapabilityIssuanceReservationStatus.RESERVED, ) issued_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) token_expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) failed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) failure_code: Mapped[str | None] = mapped_column(String(128), nullable=True, default=None) cleanup_after: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) row_version: Mapped[int] = mapped_column(sa.BigInteger, nullable=False, server_default=sa.text("0"), default=0) class KnowledgeFSLifecycleOutbox(DefaultFieldsDCMixin, TypeBase): """Durable command snapshot; it is never a product read-model source. Provision payload writers must snapshot name, icon, description, slug, model/profile intent, schema version, idempotency key, and expected revision before enabling the later P1B dispatcher. """ __tablename__ = "knowledge_fs_lifecycle_outbox" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="kfs_lifecycle_outbox_pkey"), UniqueConstraint("tenant_id", "operation_id", name="kfs_lifecycle_outbox_operation_uq"), UniqueConstraint("tenant_id", "idempotency_key", name="kfs_lifecycle_outbox_idempotency_uq"), sa.ForeignKeyConstraint( ["tenant_id", "control_space_id"], ["knowledge_fs_control_spaces.tenant_id", "knowledge_fs_control_spaces.id"], name="kfs_lifecycle_outbox_space_fk", ondelete="RESTRICT", ), Index("kfs_lifecycle_outbox_dispatch_idx", "status", "next_attempt_at", "id"), Index("kfs_lifecycle_outbox_space_created_idx", "tenant_id", "control_space_id", "created_at"), sa.CheckConstraint( "command_schema_version >= 1", name=sa.schema.conv("kfs_lifecycle_outbox_schema_version_ck"), ), sa.CheckConstraint( "expected_control_space_version >= 0", name=sa.schema.conv("kfs_lifecycle_outbox_expected_version_ck"), ), sa.CheckConstraint( "attempt_count >= 0", name=sa.schema.conv("kfs_lifecycle_outbox_attempt_count_ck"), ), sa.CheckConstraint( "status IN ('pending', 'processing', 'succeeded', 'retry', 'dead_letter')", name=sa.schema.conv("kfs_lifecycle_outbox_status_ck"), ), sa.CheckConstraint( "(status = 'processing' AND lease_owner IS NOT NULL AND lease_expires_at IS NOT NULL) " "OR (status != 'processing' AND lease_owner IS NULL AND lease_expires_at IS NULL)", name=sa.schema.conv("kfs_lifecycle_outbox_lease_state_ck"), ), sa.CheckConstraint( "(status IN ('succeeded', 'dead_letter') AND completed_at IS NOT NULL) " "OR (status NOT IN ('succeeded', 'dead_letter') AND completed_at IS NULL)", name=sa.schema.conv("kfs_lifecycle_outbox_terminal_state_ck"), ), ) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) control_space_id: Mapped[str] = mapped_column(StringUUID, nullable=False) operation_id: Mapped[str] = mapped_column(StringUUID, nullable=False) idempotency_key: Mapped[str] = mapped_column(String(255), nullable=False) operation: Mapped[KnowledgeFSLifecycleOperation] = mapped_column( EnumText(KnowledgeFSLifecycleOperation, length=32), nullable=False ) command_payload: Mapped[KnowledgeFSCommandPayload] = mapped_column(sa.JSON, nullable=False) expected_control_space_version: Mapped[int] = mapped_column(sa.BigInteger, nullable=False) expected_knowledge_space_revision: Mapped[int | None] = mapped_column(sa.BigInteger, nullable=True, default=None) command_schema_version: Mapped[int] = mapped_column( sa.Integer, nullable=False, server_default=sa.text("1"), default=1 ) status: Mapped[KnowledgeFSLifecycleOutboxStatus] = mapped_column( EnumText(KnowledgeFSLifecycleOutboxStatus, length=32), nullable=False, server_default=sa.text("'pending'"), default=KnowledgeFSLifecycleOutboxStatus.PENDING, ) attempt_count: Mapped[int] = mapped_column(sa.Integer, nullable=False, server_default=sa.text("0"), default=0) next_attempt_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) last_attempt_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) lease_owner: Mapped[str | None] = mapped_column(String(255), nullable=True, default=None) lease_expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) last_error_code: Mapped[str | None] = mapped_column(String(255), nullable=True, default=None) last_error_message: Mapped[str | None] = mapped_column(LongText, nullable=True, default=None) completed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) retain_until: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default=None) __all__ = [ "AppKnowledgeFSSpaceJoin", "KnowledgeFSAllowedActions", "KnowledgeFSApiCredential", "KnowledgeFSApiCredentialStatus", "KnowledgeFSAppSpaceJoinStatus", "KnowledgeFSAppSpaceJoinType", "KnowledgeFSAuthorizationRevision", "KnowledgeFSCapabilityAuthzRevisionSummary", "KnowledgeFSCapabilityClaimsSummary", "KnowledgeFSCapabilityIssuanceAudit", "KnowledgeFSCapabilityIssuanceReservation", "KnowledgeFSCapabilityIssuanceReservationStatus", "KnowledgeFSCapabilityReservationSummary", "KnowledgeFSCommandEnvelope", "KnowledgeFSCommandPayload", "KnowledgeFSControlSpace", "KnowledgeFSControlSpacePermission", "KnowledgeFSControlSpacePermissionRole", "KnowledgeFSControlSpacePermissionStatus", "KnowledgeFSControlSpaceState", "KnowledgeFSControlSpaceVisibility", "KnowledgeFSDeleteCommandPayload", "KnowledgeFSExternalAccessPolicy", "KnowledgeFSLifecycleOperation", "KnowledgeFSLifecycleOutbox", "KnowledgeFSLifecycleOutboxStatus", "KnowledgeFSMetadataUpdateCommandPayload", "KnowledgeFSModelSelectionIntentPayload", "KnowledgeFSProvisionCommandPayload", "KnowledgeFSRepairCommandPayload", "KnowledgeFSRerankIntentPayload", "KnowledgeFSRetrievalProfileIntentPayload", "KnowledgeFSRevokeCommandPayload", "KnowledgeFSScoreThresholdIntentPayload", ]