"""Release 1 initial schema. Revision ID: r1_0001 Revises: Create Date: 2026-09-15 """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op revision: str = "r1_0001" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str] | None] = None depends_on: Union[str, Sequence[str] | None] = None def upgrade() -> None: op.create_table( "users", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("username", sa.String(100), nullable=False, unique=True, index=True), sa.Column("password_hash", sa.String(255), nullable=False), sa.Column("display_name", sa.String(200), nullable=True), sa.Column( "role", sa.Enum( "SUPER_ADMIN", "BROKER_ADMIN", "PKI_ADMIN", "OPERATOR", "AUDITOR", name="management_role", ), nullable=False, ), sa.Column("enabled", sa.Boolean(), nullable=False, server_default=sa.true()), sa.Column( "must_change_password", sa.Boolean(), nullable=False, server_default=sa.true() ), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("modified_at", sa.DateTime(timezone=True), nullable=False), ) op.create_table( "sessions", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column( "user_id", sa.Uuid(), sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True, ), sa.Column("expires_at", sa.DateTime(timezone=True), nullable=False, index=True), sa.Column("revoked", sa.Boolean(), nullable=False, server_default=sa.false()), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), ) op.create_table( "certificates", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("common_name", sa.String(200), nullable=False), sa.Column("certificate_pem", sa.Text(), nullable=False), sa.Column("private_key_pem", sa.Text(), nullable=True), sa.Column("expiry_date", sa.DateTime(timezone=True), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), ) op.create_table( "broker_listeners", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("name", sa.String(100), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False, server_default=sa.true()), sa.Column("port", sa.Integer(), nullable=False), sa.Column("bind_address", sa.String(100), nullable=True), sa.Column("protocol", sa.String(20), nullable=False), sa.Column("allow_anonymous", sa.Boolean(), nullable=False, server_default=sa.false()), sa.Column("max_connections", sa.Integer(), nullable=False), sa.Column("tls_enabled", sa.Boolean(), nullable=False, server_default=sa.false()), sa.Column("tls_min_version", sa.String(20), nullable=True), sa.Column( "require_certificate", sa.Boolean(), nullable=False, server_default=sa.false() ), sa.Column( "use_identity_as_username", sa.Boolean(), nullable=False, server_default=sa.false(), ), sa.Column("cert_id", sa.Uuid(), sa.ForeignKey("certificates.id"), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("modified_at", sa.DateTime(timezone=True), nullable=False), ) op.create_table( "broker_settings", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("key", sa.String(100), nullable=False, unique=True, index=True), sa.Column("value", sa.Text(), nullable=False), sa.Column("value_type", sa.String(20), nullable=False), ) op.create_table( "broker_config_revisions", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("revision_number", sa.Integer(), nullable=False, unique=True, index=True), sa.Column("created_by", sa.String(100), nullable=True), sa.Column("comment", sa.Text(), nullable=True), sa.Column("config_text", sa.Text(), nullable=False), sa.Column("validation_result", sa.JSON(), nullable=False), sa.Column("deployed", sa.Boolean(), nullable=False, server_default=sa.false()), sa.Column("deployed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), ) op.create_table( "mqtt_client_metadata", sa.Column("username", sa.String(100), primary_key=True), sa.Column("display_name", sa.String(200), nullable=True), sa.Column("description", sa.Text(), nullable=True), sa.Column("owner", sa.String(200), nullable=True), sa.Column("purpose", sa.String(200), nullable=True), sa.Column("tags", sa.JSON(), nullable=False), sa.Column("last_known_connection", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("modified_at", sa.DateTime(timezone=True), nullable=False), sa.Column( "certificate_id", sa.Uuid(), sa.ForeignKey("certificates.id", ondelete="SET NULL"), nullable=True, ), ) op.create_table( "audit_events", sa.Column("id", sa.Uuid(), primary_key=True), sa.Column("timestamp", sa.DateTime(timezone=True), nullable=False, index=True), sa.Column("user", sa.String(100), nullable=True), sa.Column("source_ip", sa.String(64), nullable=True), sa.Column("action", sa.String(100), nullable=False, index=True), sa.Column("object_type", sa.String(100), nullable=True), sa.Column("object_id", sa.String(200), nullable=True), sa.Column("old_value", sa.JSON(), nullable=True), sa.Column("new_value", sa.JSON(), nullable=True), sa.Column("result", sa.String(20), nullable=False), sa.Column("correlation_id", sa.String(64), nullable=True), ) def downgrade() -> None: op.drop_table("audit_events") op.drop_table("mqtt_client_metadata") op.drop_table("broker_config_revisions") op.drop_table("broker_settings") op.drop_table("broker_listeners") op.drop_table("certificates") op.drop_table("sessions") op.drop_table("users") op.execute("DROP TYPE IF EXISTS management_role")