CREATE TABLE IF NOT EXISTS auth_webauthn_credentials ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, credential_id BYTEA NOT NULL, passkey JSONB NOT NULL, sign_count BIGINT NOT NULL DEFAULT 0, name VARCHAR(100), last_used_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT auth_webauthn_credentials_credential_id_unique UNIQUE (credential_id), CONSTRAINT auth_webauthn_credentials_passkey_object CHECK (jsonb_typeof(passkey) = 'object'), CONSTRAINT auth_webauthn_credentials_name_not_empty CHECK (name IS NULL OR length(trim(name)) > 0) ); CREATE INDEX IF NOT EXISTS idx_auth_webauthn_credentials_user_id ON auth_webauthn_credentials(user_id); CREATE INDEX IF NOT EXISTS idx_auth_webauthn_credentials_last_used_at ON auth_webauthn_credentials(last_used_at) WHERE last_used_at IS NOT NULL; CREATE TRIGGER update_auth_webauthn_credentials_updated_at BEFORE UPDATE ON auth_webauthn_credentials FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();