Add governed tabular and LDAP address sources

This commit is contained in:
2026-08-02 15:39:34 +02:00
parent e60339a5bf
commit 2c421022d4
19 changed files with 3846 additions and 78 deletions
+63 -1
View File
@@ -4,7 +4,7 @@ import uuid
from datetime import datetime
from typing import Any
from sqlalchemy import Boolean, DateTime, ForeignKey, Index, Integer, JSON, String, Text, text
from sqlalchemy import Boolean, DateTime, ForeignKey, Index, Integer, JSON, String, Text, UniqueConstraint, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from govoplan_core.db.base import Base, TimestampMixin
@@ -549,8 +549,70 @@ class AddressSyncDiagnostic(Base, TimestampMixin):
sync_source: Mapped[AddressSyncSource] = relationship(back_populates="diagnostics")
class AddressImportProfile(Base, TimestampMixin):
__tablename__ = "addresses_import_profiles"
__table_args__ = (
UniqueConstraint("profile_key", "version", name="uq_addresses_import_profile_version"),
Index("ix_addresses_import_profiles_scope", "tenant_id", "scope_type", "scope_id", "is_current"),
Index("ix_addresses_import_profiles_format", "tenant_id", "source_format"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
profile_key: Mapped[str] = mapped_column(String(36), nullable=False, default=new_uuid, index=True)
version: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
scope_type: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
scope_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
source_format: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
configuration: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
is_current: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, index=True)
created_by_account_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
superseded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
class AddressImportRun(Base, TimestampMixin):
__tablename__ = "addresses_import_runs"
__table_args__ = (
Index("ix_addresses_import_runs_book_status", "address_book_id", "status", "created_at"),
Index("ix_addresses_import_runs_tenant_hash", "tenant_id", "input_hash"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
address_book_id: Mapped[str] = mapped_column(
ForeignKey("addresses_address_books.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
profile_id: Mapped[str] = mapped_column(
ForeignKey("addresses_import_profiles.id", ondelete="RESTRICT"),
nullable=False,
index=True,
)
source_filename: Mapped[str] = mapped_column(String(500), nullable=False)
source_format: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
input_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
plan_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="previewed", index=True)
row_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
statistics: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
diagnostics: Mapped[list[dict[str, Any]]] = mapped_column(JSON, nullable=False, default=list)
plan_data: Mapped[list[dict[str, Any]]] = mapped_column(JSON, nullable=False, default=list)
result_evidence: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
created_by_account_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
applied_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
rolled_back_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
address_book: Mapped[AddressBook] = relationship()
profile: Mapped[AddressImportProfile] = relationship()
__all__ = [
"AddressBook",
"AddressImportProfile",
"AddressImportRun",
"AddressList",
"AddressListEntry",
"AddressSyncConflict",