DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'dodo') THEN
        CREATE SCHEMA dodo;
    END IF;
END $EF$;
CREATE TABLE IF NOT EXISTS dodo."__EFMigrationsHistory" (
    migration_id character varying(150) NOT NULL,
    product_version character varying(32) NOT NULL,
    CONSTRAINT pk___ef_migrations_history PRIMARY KEY (migration_id)
);

START TRANSACTION;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
        IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'dodo') THEN
            CREATE SCHEMA dodo;
        END IF;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
        IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'dodo') THEN
            CREATE SCHEMA dodo;
        END IF;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE EXTENSION IF NOT EXISTS citext;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.key_log (
        sequence bigint GENERATED ALWAYS AS IDENTITY,
        user_id uuid NOT NULL,
        generation integer NOT NULL,
        encryption_public_key bytea NOT NULL,
        signing_public_key bytea NOT NULL,
        statement_signature bytea NOT NULL,
        previous_hash bytea NOT NULL,
        hash bytea NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        CONSTRAINT pk_key_log PRIMARY KEY (sequence)
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.sync_change (
        sequence bigint GENERATED ALWAYS AS IDENTITY,
        vault_id uuid NOT NULL,
        entity_type integer NOT NULL,
        entity_id uuid NOT NULL,
        operation integer NOT NULL,
        revision integer NOT NULL,
        actor_user_id uuid NOT NULL,
        occurred_at_utc timestamp with time zone NOT NULL,
        CONSTRAINT pk_sync_change PRIMARY KEY (sequence)
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.sync_operation_receipt (
        operation_id uuid NOT NULL,
        vault_id uuid NOT NULL,
        applied_change_sequence bigint,
        result_version integer,
        created_at_utc timestamp with time zone NOT NULL,
        CONSTRAINT pk_sync_operation_receipt PRIMARY KEY (operation_id)
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.team (
        id uuid NOT NULL,
        name character varying(256) NOT NULL,
        slug citext NOT NULL,
        description character varying(2048),
        created_by_user_id uuid NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        deleted_at_utc timestamp with time zone,
        CONSTRAINT pk_team PRIMARY KEY (id)
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.user_account (
        id uuid NOT NULL,
        issuer character varying(512) NOT NULL,
        subject character varying(256) NOT NULL,
        email citext,
        display_name character varying(256),
        status integer NOT NULL,
        enrolled_at_utc timestamp with time zone,
        created_at_utc timestamp with time zone NOT NULL,
        updated_at_utc timestamp with time zone NOT NULL,
        last_seen_at_utc timestamp with time zone,
        deleted_at_utc timestamp with time zone,
        CONSTRAINT pk_user_account PRIMARY KEY (id)
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.device (
        id uuid NOT NULL,
        user_id uuid NOT NULL,
        name character varying(256) NOT NULL,
        platform integer NOT NULL,
        public_key bytea NOT NULL,
        enrolled_at_utc timestamp with time zone NOT NULL,
        last_seen_at_utc timestamp with time zone,
        revoked_at_utc timestamp with time zone,
        CONSTRAINT pk_device PRIMARY KEY (id),
        CONSTRAINT fk_device_users_user_id FOREIGN KEY (user_id) REFERENCES dodo.user_account (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.team_membership (
        id uuid NOT NULL,
        team_id uuid NOT NULL,
        user_id uuid NOT NULL,
        role integer NOT NULL,
        status integer NOT NULL,
        invited_by_user_id uuid,
        joined_at_utc timestamp with time zone,
        created_at_utc timestamp with time zone NOT NULL,
        deleted_at_utc timestamp with time zone,
        CONSTRAINT pk_team_membership PRIMARY KEY (id),
        CONSTRAINT fk_team_membership_team_team_id FOREIGN KEY (team_id) REFERENCES dodo.team (id) ON DELETE CASCADE,
        CONSTRAINT fk_team_membership_users_user_id FOREIGN KEY (user_id) REFERENCES dodo.user_account (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.user_key (
        id uuid NOT NULL,
        user_id uuid NOT NULL,
        generation integer NOT NULL,
        encryption_public_key bytea NOT NULL,
        signing_public_key bytea NOT NULL,
        fingerprint_sha256 bytea NOT NULL,
        statement jsonb NOT NULL,
        statement_signature bytea NOT NULL,
        identity_provider_binding jsonb,
        is_current boolean NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        revoked_at_utc timestamp with time zone,
        CONSTRAINT pk_user_key PRIMARY KEY (id),
        CONSTRAINT fk_user_key_user_account_user_id FOREIGN KEY (user_id) REFERENCES dodo.user_account (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.vault (
        id uuid NOT NULL,
        name character varying(256) NOT NULL,
        owner_kind integer NOT NULL,
        owner_user_id uuid,
        team_id uuid,
        key_generation integer NOT NULL,
        rekey_required boolean NOT NULL,
        rekey_reason integer NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        updated_at_utc timestamp with time zone NOT NULL,
        deleted_at_utc timestamp with time zone,
        CONSTRAINT pk_vault PRIMARY KEY (id),
        CONSTRAINT ck_vault_key_generation CHECK (key_generation >= 1),
        CONSTRAINT ck_vault_owner CHECK ((owner_kind = 1 AND owner_user_id IS NOT NULL AND team_id IS NULL)
    OR (owner_kind = 2 AND team_id IS NOT NULL AND owner_user_id IS NULL)),
        CONSTRAINT fk_vault_team_team_id FOREIGN KEY (team_id) REFERENCES dodo.team (id) ON DELETE RESTRICT,
        CONSTRAINT fk_vault_user_account_owner_user_id FOREIGN KEY (owner_user_id) REFERENCES dodo.user_account (id) ON DELETE RESTRICT
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.user_key_wrap (
        id uuid NOT NULL,
        user_id uuid NOT NULL,
        kind integer NOT NULL,
        device_id uuid,
        wrap bytea NOT NULL,
        wrap_version integer NOT NULL,
        kdf_algorithm character varying(64),
        kdf_salt bytea,
        kdf_memory_kibibytes integer,
        kdf_passes integer,
        kdf_parallelism integer,
        created_at_utc timestamp with time zone NOT NULL,
        last_used_at_utc timestamp with time zone,
        CONSTRAINT pk_user_key_wrap PRIMARY KEY (id),
        CONSTRAINT ck_user_key_wrap_device CHECK ((kind = 2 AND device_id IS NOT NULL) OR (kind <> 2 AND device_id IS NULL)),
        CONSTRAINT ck_user_key_wrap_kdf CHECK ((kind IN (1, 3) AND kdf_algorithm IS NOT NULL AND kdf_salt IS NOT NULL
        AND kdf_memory_kibibytes IS NOT NULL AND kdf_passes IS NOT NULL
        AND kdf_parallelism IS NOT NULL)
    OR (kind IN (2, 4) AND kdf_algorithm IS NULL AND kdf_salt IS NULL)),
        CONSTRAINT fk_user_key_wrap_device_device_id FOREIGN KEY (device_id) REFERENCES dodo.device (id) ON DELETE CASCADE,
        CONSTRAINT fk_user_key_wrap_user_account_user_id FOREIGN KEY (user_id) REFERENCES dodo.user_account (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.host (
        id uuid NOT NULL,
        vault_id uuid NOT NULL,
        payload bytea NOT NULL,
        data_key_wrap bytea,
        content_key_id uuid,
        key_generation integer NOT NULL,
        payload_aad_version smallint NOT NULL,
        relay_enabled boolean NOT NULL,
        hostname character varying(255),
        port integer,
        group_id uuid,
        version integer NOT NULL,
        change_sequence bigint NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        updated_at_utc timestamp with time zone NOT NULL,
        deleted_at_utc timestamp with time zone,
        created_by_user_id uuid NOT NULL,
        updated_by_user_id uuid NOT NULL,
        CONSTRAINT pk_host PRIMARY KEY (id),
        CONSTRAINT ck_host_port_range CHECK (port IS NULL OR (port BETWEEN 1 AND 65535)),
        CONSTRAINT ck_host_relay_target CHECK ((relay_enabled AND hostname IS NOT NULL AND port IS NOT NULL)
    OR (NOT relay_enabled AND hostname IS NULL AND port IS NULL)),
        CONSTRAINT ck_host_version CHECK (version >= 1),
        CONSTRAINT fk_host_vaults_vault_id FOREIGN KEY (vault_id) REFERENCES dodo.vault (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE TABLE dodo.vault_key_grant (
        id uuid NOT NULL,
        vault_id uuid NOT NULL,
        key_generation integer NOT NULL,
        kind integer NOT NULL,
        recipient_user_id uuid,
        recipient_key_fingerprint bytea NOT NULL,
        wrapped_key bytea NOT NULL,
        granter_user_id uuid NOT NULL,
        granter_key_fingerprint bytea NOT NULL,
        key_log_head bytea,
        signature bytea NOT NULL,
        state integer NOT NULL,
        created_at_utc timestamp with time zone NOT NULL,
        revoked_at_utc timestamp with time zone,
        CONSTRAINT pk_vault_key_grant PRIMARY KEY (id),
        CONSTRAINT ck_vault_key_grant_recipient CHECK ((kind = 1 AND recipient_user_id IS NOT NULL) OR (kind <> 1 AND recipient_user_id IS NULL)),
        CONSTRAINT fk_vault_key_grant_user_account_recipient_user_id FOREIGN KEY (recipient_user_id) REFERENCES dodo.user_account (id) ON DELETE CASCADE,
        CONSTRAINT fk_vault_key_grant_vault_vault_id FOREIGN KEY (vault_id) REFERENCES dodo.vault (id) ON DELETE CASCADE
    );
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_device_user_id ON dodo.device (user_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_host_vault_id_change_sequence ON dodo.host (vault_id, change_sequence);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_host_vault_live ON dodo.host (vault_id) WHERE deleted_at_utc IS NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_key_log_hash ON dodo.key_log (hash);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_key_log_user_id ON dodo.key_log (user_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_sync_change_vault_id_entity_id_sequence ON dodo.sync_change (vault_id, entity_id, sequence DESC);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_sync_change_vault_id_sequence ON dodo.sync_change (vault_id, sequence);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_sync_operation_receipt_vault_id_created_at_utc ON dodo.sync_operation_receipt (vault_id, created_at_utc);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_team_slug ON dodo.team (slug) WHERE deleted_at_utc IS NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_team_membership_team_id_user_id ON dodo.team_membership (team_id, user_id) WHERE deleted_at_utc IS NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_team_membership_user_id ON dodo.team_membership (user_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_account_email ON dodo.user_account (email) WHERE email IS NOT NULL AND deleted_at_utc IS NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_account_issuer_subject ON dodo.user_account (issuer, subject);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_key_current ON dodo.user_key (user_id) WHERE is_current;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_key_fingerprint_sha256 ON dodo.user_key (fingerprint_sha256);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_key_user_id_generation ON dodo.user_key (user_id, generation);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_user_key_wrap_device_id ON dodo.user_key_wrap (device_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_key_wrap_user_device ON dodo.user_key_wrap (user_id, device_id) WHERE device_id IS NOT NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_user_key_wrap_user_kind ON dodo.user_key_wrap (user_id, kind) WHERE device_id IS NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_vault_owner_user_id ON dodo.vault (owner_user_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_vault_team_id ON dodo.vault (team_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE INDEX ix_vault_key_grant_recipient_user_id ON dodo.vault_key_grant (recipient_user_id);
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    CREATE UNIQUE INDEX ix_vault_key_grant_vault_id_key_generation_recipient_user_id ON dodo.vault_key_grant (vault_id, key_generation, recipient_user_id) WHERE revoked_at_utc IS NULL AND recipient_user_id IS NOT NULL;
    END IF;
END $EF$;

DO $EF$
BEGIN
    IF NOT EXISTS(SELECT 1 FROM dodo."__EFMigrationsHistory" WHERE "migration_id" = '20260728125751_InitialSchema') THEN
    INSERT INTO dodo."__EFMigrationsHistory" (migration_id, product_version)
    VALUES ('20260728125751_InitialSchema', '10.0.10');
    END IF;
END $EF$;
COMMIT;

