Release v0.1.8

This commit is contained in:
2026-07-11 16:49:02 +02:00
parent b9b371a704
commit b47f71916d
8 changed files with 79 additions and 9 deletions
@@ -1,139 +0,0 @@
"""idm organization function assignments
Revision ID: 8f9a0b1c2d3e
Revises:
Create Date: 2026-07-10 00:00:00.000000
"""
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = "8f9a0b1c2d3e"
down_revision = None
branch_labels = None
depends_on = None
def _tables() -> set[str]:
return set(sa.inspect(op.get_bind()).get_table_names())
def _indexes(table_name: str) -> set[str]:
if table_name not in _tables():
return set()
return {item["name"] for item in sa.inspect(op.get_bind()).get_indexes(table_name)}
def _create_index_if_missing(name: str, table_name: str, columns: list[str], *, unique: bool = False) -> None:
if table_name in _tables() and name not in _indexes(table_name):
op.create_index(name, table_name, columns, unique=unique)
def _drop_index_if_exists(name: str, table_name: str) -> None:
if table_name in _tables() and name in _indexes(table_name):
op.drop_index(name, table_name=table_name)
def upgrade() -> None:
if "idm_tenant_settings" not in _tables():
op.create_table(
"idm_tenant_settings",
sa.Column("tenant_id", sa.String(length=36), nullable=False),
sa.Column("require_assignment_change_requests", sa.Boolean(), nullable=False),
sa.Column("audit_detail_level", sa.String(length=20), nullable=False),
sa.Column("change_retention_days", sa.Integer(), nullable=True),
sa.Column("settings", sa.JSON(), nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint("tenant_id", name=op.f("pk_idm_tenant_settings")),
)
if "idm_organization_function_assignments" not in _tables():
op.create_table(
"idm_organization_function_assignments",
sa.Column("id", sa.String(length=36), nullable=False),
sa.Column("tenant_id", sa.String(length=36), nullable=False),
sa.Column("identity_id", sa.String(length=36), nullable=False),
sa.Column("account_id", sa.String(length=36), nullable=True),
sa.Column("function_id", sa.String(length=36), nullable=False),
sa.Column("organization_unit_id", sa.String(length=36), nullable=False),
sa.Column("applies_to_subunits", sa.Boolean(), nullable=False),
sa.Column("source", sa.String(length=50), nullable=False),
sa.Column("delegated_from_assignment_id", sa.String(length=36), nullable=True),
sa.Column("acting_for_account_id", sa.String(length=36), nullable=True),
sa.Column("valid_from", sa.DateTime(timezone=True), nullable=True),
sa.Column("valid_until", sa.DateTime(timezone=True), nullable=True),
sa.Column("is_active", sa.Boolean(), nullable=False),
sa.Column("settings", sa.JSON(), nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(
["delegated_from_assignment_id"],
["idm_organization_function_assignments.id"],
name=op.f("fk_idm_organization_function_assignments_delegated_from_assignment_id_idm_organization_function_assignments"),
ondelete="SET NULL",
),
sa.ForeignKeyConstraint(
["function_id"],
["organizations_functions.id"],
name=op.f("fk_idm_organization_function_assignments_function_id_organizations_functions"),
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["identity_id"],
["identity_identities.id"],
name=op.f("fk_idm_organization_function_assignments_identity_id_identity_identities"),
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["organization_unit_id"],
["organizations_units.id"],
name=op.f("fk_idm_organization_function_assignments_organization_unit_id_organizations_units"),
ondelete="CASCADE",
),
sa.PrimaryKeyConstraint("id", name=op.f("pk_idm_organization_function_assignments")),
sa.UniqueConstraint(
"tenant_id",
"identity_id",
"function_id",
"organization_unit_id",
name="uq_idm_org_function_assignments_identity_scope",
),
)
for column in (
"account_id",
"acting_for_account_id",
"delegated_from_assignment_id",
"function_id",
"identity_id",
"organization_unit_id",
"tenant_id",
):
_create_index_if_missing(
op.f(f"ix_idm_organization_function_assignments_{column}"),
"idm_organization_function_assignments",
[column],
)
def downgrade() -> None:
for column in (
"tenant_id",
"organization_unit_id",
"identity_id",
"function_id",
"delegated_from_assignment_id",
"acting_for_account_id",
"account_id",
):
_drop_index_if_exists(
op.f(f"ix_idm_organization_function_assignments_{column}"),
"idm_organization_function_assignments",
)
if "idm_organization_function_assignments" in _tables():
op.drop_table("idm_organization_function_assignments")
if "idm_tenant_settings" in _tables():
op.drop_table("idm_tenant_settings")
@@ -0,0 +1,65 @@
"""v0.1.7 idm baseline
Revision ID: 8f9a0b1c2d3e
Revises: None
Create Date: 2026-07-11 00:00:00.000000
"""
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = '8f9a0b1c2d3e'
down_revision = None
branch_labels = None
depends_on = ('5c6d7e8f9a10', '6d7e8f9a0b1c')
def upgrade() -> None:
op.create_table('idm_tenant_settings',
sa.Column('tenant_id', sa.String(length=36), nullable=False),
sa.Column('require_assignment_change_requests', sa.Boolean(), nullable=False),
sa.Column('audit_detail_level', sa.String(length=20), nullable=False),
sa.Column('change_retention_days', sa.Integer(), nullable=True),
sa.Column('settings', sa.JSON(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('tenant_id', name=op.f('pk_idm_tenant_settings'))
)
op.create_table('idm_organization_function_assignments',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('tenant_id', sa.String(length=36), nullable=False),
sa.Column('identity_id', sa.String(length=36), nullable=False),
sa.Column('account_id', sa.String(length=36), nullable=True),
sa.Column('function_id', sa.String(length=36), nullable=False),
sa.Column('organization_unit_id', sa.String(length=36), nullable=False),
sa.Column('applies_to_subunits', sa.Boolean(), nullable=False),
sa.Column('source', sa.String(length=50), nullable=False),
sa.Column('delegated_from_assignment_id', sa.String(length=36), nullable=True),
sa.Column('acting_for_account_id', sa.String(length=36), nullable=True),
sa.Column('valid_from', sa.DateTime(timezone=True), nullable=True),
sa.Column('valid_until', sa.DateTime(timezone=True), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('settings', sa.JSON(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['delegated_from_assignment_id'], ['idm_organization_function_assignments.id'], name=op.f('fk_idm_organization_function_assignments_delegated_from_assignment_id_idm_organization_function_assignments'), ondelete='SET NULL'),
sa.ForeignKeyConstraint(['function_id'], ['organizations_functions.id'], name=op.f('fk_idm_organization_function_assignments_function_id_organizations_functions'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['identity_id'], ['identity_identities.id'], name=op.f('fk_idm_organization_function_assignments_identity_id_identity_identities'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['organization_unit_id'], ['organizations_units.id'], name=op.f('fk_idm_organization_function_assignments_organization_unit_id_organizations_units'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_idm_organization_function_assignments')),
sa.UniqueConstraint('tenant_id', 'identity_id', 'function_id', 'organization_unit_id', name='uq_idm_org_function_assignments_identity_scope')
)
op.create_index(op.f('ix_idm_organization_function_assignments_account_id'), 'idm_organization_function_assignments', ['account_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_acting_for_account_id'), 'idm_organization_function_assignments', ['acting_for_account_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_delegated_from_assignment_id'), 'idm_organization_function_assignments', ['delegated_from_assignment_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_function_id'), 'idm_organization_function_assignments', ['function_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_identity_id'), 'idm_organization_function_assignments', ['identity_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_organization_unit_id'), 'idm_organization_function_assignments', ['organization_unit_id'], unique=False)
op.create_index(op.f('ix_idm_organization_function_assignments_tenant_id'), 'idm_organization_function_assignments', ['tenant_id'], unique=False)
def downgrade() -> None:
op.drop_table('idm_organization_function_assignments')
op.drop_table('idm_tenant_settings')