From 70e376615d8912a94cbc23af266a5ae87cb11527 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:16:22 +0100 Subject: [PATCH 01/14] NORY-41: add drizzle dependencies --- dashboard/bun.lockb | Bin 229372 -> 269452 bytes dashboard/package.json | 6 ++++++ 2 files changed, 6 insertions(+) diff --git a/dashboard/bun.lockb b/dashboard/bun.lockb index ec6a87b494fe9f97dc3d5c6a66a88bb89738459b..5fcc46ea3c3bd8011de21e746ae83543666ec38c 100755 GIT binary patch delta 68314 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

omknJGzZ|G{&AH;m*4EwRhPi{vL`B25M+Z3V z|FA~n+w$Pl+F@(HJ-oNqddIT#)zhnd2cK&p@((`2KDvKWl-1>;Z0z#B7oA7=GiUwI zFLm@yF5Q(oqJzYX_n5X!`twqCm(rkiZEM16?R*w?8o&7b+?Qol7nGhfADSvWdVT*# z7hi3Op+Qk{WzyEPgWEr9dsN*!rqyfK?46C$oEkOi?vS(SYHnpTFI4WUHatC+5|-&Ri->S(WU2b^J(|F|+-SG)PX~(QnaY!$%#> zUv`enc$C6EYPoXIz?;0`bQqqb=$gAhqNbyO?$fJ`0Z8-6x_OT zX@~82+492XEi5!VDI9tLj7TDN1b-vzi4>o9P1Sm)6?oawufQ*16y^MQu~6k zlD3!MKHMykRNB~u#SDDpv1FJ>qx+B7+BSZFria$FaMdmjSD*WDUGurm^Y`;wwyLcC z?Bh6BT&{1_W9NAn?&oU)6&Zy%MbWTwv2V3%j7$(^vG=V`wNr}bhQ_lJR6A8v_tZ4p zH|V%yzMiSg>($~mljrJPG}vXR-+N6f*$dOvdEGSzONti0R+UGBJE){8+SOZfe%bk7 z-CN8#a{pYl;V>W1RvSjI=p|c|JnsJ2&X#Uou8s%KYT6aAdw<;Qtl7JYCu>J`&uG5R z)>oYNvnqC;yFYgu<$n5;rf4`aOcbD#t6uzCP1G{t?9Tpr*+voz@9J3tCwvG@Z=?C9 z;e?CZT$}s;JM`1d}d3T%fo4T z9V^a!YpU5zcY%Vl*@|{!ntjq;xOd^2hTGOJ&b_f}lxicHRrjW!^;f)|)zR~0?S+ED z73p8pg37jkMZ>c`k3KP_&%1#~7u$U; zzwm8HylKCWf!Y`Mxf^HQj9GDaoc@|0dG;z7T`t5&e2?A!;)a&%OV3&n^WwCu@1EJa zB2FnD1ZOK67Hd1@9$G4i-=5xdw`@_1tD)OwOf?G~6x*vsKbxbuE&8{<+Cu!P&5`Hj z*}2(`FULADW#`PQr!m!eZo%_fwZMncXrtsJOn*AA?ou+?5xK><(;l&`I@ihfpAFIP`Jc5=RX`6vG}3kAFL|FDa{ zBmDH^f*Jjt4>TB}a>yvQ*Ufgww1>gt}J!1Jhj6Ig)DhLyQ1z9fvV^4sLlIcHXG=$Jd-w&l6~xi4q+85^{GGxuTqZU@*Zj`pWvg=W*NjvkSVGC9*x81zd zvU|^bkp649pKtWk8Zy{6m5R{$r;x;Hp7>nilEL4^duC~dG-=N%A zjB-pC4uCf7cAj!eUe0P|T_t6fO-xd!q{OI`$|PaE%@#9do|v7IoGSX=sT3*$P3ary z#--HB;e%shBNb~0=VdeHXHf(@w?bLM#4HU>%tQGeVrE|5RmxUMljoDsmb^h5l=F?K ze8~aH3Gw)I4vGPJuIrUelw9EsB}7`1IyoVBh+5H`z1gm0V9!*%fktub0`4Jmq!_3j67;3t^3I;^bt)T z=}SelP^BXDPF!31G#>qEkx7~6z%VI~7KoH*0UU=EYB{a#D33mawT>j?N6RwGBgHpJ zd9Kv3Ye3%M)X++XGHrl$fV>EyJnGBZbb=o(An24nC~G0*(cDj` zb^v|5i&{Avd8Axrz)x!NY>Cevd9|g+&Ea_(g#$9TLTl1KQ(|<)Ien^{ehhiks4Bo- z%D`{F#8(yP`vBr!fIR$DR0H-)dD#*lIp9Hnev2eNXPh5W^yh`?1E*BDI

A|L|KX z6(&zT2UG#%TPQVgeg+`H%O$>AI6nfA;1yEdTxr(w$znlnLKW80N!X#GFAur{9)Ks{ z1$YB70Db;yI6$ApqHlJ^00V%5Kr9dkxC0)5C*TFpmp#7#Ux9DHcYwTE2?&4@U<{Z5 z#pr94#c@&sC<&ATN&{tpvOqbYJYWh`04f4zfH`0RSOS#*E5I7C0c-&kU;VUW zhBFP{H^5tfhV6SHLZSE@Cp2FF0X_opP&g522s8p315JSdpc&8{XaNKQErHfRTc91# z9tZ+D03Cr&Krri6U8v;R52v9(7!VGiW0S~ZWiV&n28^@%|&t( zumzwFr_NjntO8~NvjB2wa$)jV@<#H$4gdv>+JFb(4fp^QG*-i@C{WPDvFX4hU@|Zg zpe<0kUE;4q1DoO`0B8mT0xf}7Kx?24KwI6k$=e>F_s1#%0$>Cb1BwGTShpHNGtCP$ z^(F8MpqENs18;!3Ks}&7;0MsB)_s zv#o$|fWB-R0?@Y@Mxy~OaC8Q`0^NXM;24GW%^=cSUt0nCKC3^_6qt(iuRtxFI|1~n z@}IyH;3@DNcnQ1$UITA{x4=8#1Mm+p2<4K26o4Z32!NvbFThyfj0Q~SfeXMz;1X~d zxCYz=ZUJin3ghbm3f+r=rND9^3PSn=1A#bzmN&zIY+w(fU7>C1vNv8Z8^en54g2CyA;dSNaA=goi_IG+x<;G8BM zSAf3d$$+^)7BCN(57dS{H^3aQ04f1iouW6<`Nc1|FgiefF|6PzEptOn_p* zcvLh2m$lE2Yv@m04IUdz**oNa2~h{TnBCdH-THgZQu^@2ap4N0jfZ$ zmas$`8We=%DkwG%IDz!7oJc?cbeg|qmMjhnSw|rj$uK+XfSOAuQtugxF4kwiXd%yvpuUPg( z;fv6c-k)d!&|2>qXzzi)i3fs)0%HJLw$TS?Gf^fTxQcSufa|~w;3jYjxDDI^{s8U* z_kjD<{||8T5O@SU2I%_i3Gftn20RB|0Iz@tP^2P`w2Y&@pVB}Xpe#Vkvks&blsO5| z$7gBPbqTzcQD!HO^}$yapwF$=2O7{s&=6<@GzOXg{yCn1 zv<2D$?SUYmF5m_ws4`l%?FSA3hk$dyZ@_WjEN}{NK7;>`07rpE(2NKKVhYWI+W5t8 zq@|U!hPHMl0uzAIKudsLXGj97fv*fu0qBl2bP$6Nbsx>VjQ|=sWC0hT7C<|yry#?F^w&(rrCJZ#vY{fZEM$|nNA}Lg^ z2I%^0GmbQrbAgQj!lxKLX=G4PBWvUVG^|emhk--DLEr#DmL!YPfT7SpAz~LmmZmTP zhj$bIxC>d5ESe)hHaVql0M~(Qz*XkyEmZAG9dH_;0dowHi<{tl67T|e4m<;%0Dl6H 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 UihR))?aev_;K`-B8lxls2Qxsu!vFvP delta 43210 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%0D=AGpqR&ApZ_9*XIBaGVMPA#=is# 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 Raj9a^2Boq%>gI6h{{VWi7>ED> diff --git a/dashboard/package.json b/dashboard/package.json index 4e18553..11080c0 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -30,10 +30,13 @@ "@tanstack/react-table": "^8.20.5", "class-variance-authority": "^0.7.1", "clsx": "^2.1.0", + "dotenv": "^16.4.7", + "drizzle-orm": "^0.38.3", "lucide-react": "^0.462.0", "next": "15.0.3", "next-themes": "^0.4.3", "oslo": "^1.1.3", + "pg": "^8.13.1", "react": "19.0.0-rc-66855b96-20241106", "react-dom": "19.0.0-rc-66855b96-20241106", "react-hook-form": "^7.51.0", @@ -48,14 +51,17 @@ }, "devDependencies": { "@types/node": "^22.9.3", + "@types/pg": "^8.11.10", "@types/react": "npm:types-react@19.0.0-rc.1", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1", "autoprefixer": "^10.0.1", + "drizzle-kit": "^0.30.1", "eslint": "^8", "eslint-config-next": "15.0.3", "postcss": "^8", "tailwindcss": "^3.3.0", "ts-node": "^10.9.2", + "tsx": "^4.19.2", "typescript": "^5.4.2" }, "overrides": { From a60800ad0183a235795cc5fc229f74d1e3fafac8 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:17:34 +0100 Subject: [PATCH 02/14] NORY-41: add basic drizzle configuration --- dashboard/drizzle.config.ts | 14 ++++++++++++++ dashboard/drizzle/relations.ts | 0 dashboard/drizzle/schema.ts | 0 dashboard/src/db/index.ts | 10 ++++++++++ dashboard/src/db/schema.ts | 0 5 files changed, 24 insertions(+) create mode 100644 dashboard/drizzle.config.ts create mode 100644 dashboard/drizzle/relations.ts create mode 100644 dashboard/drizzle/schema.ts create mode 100644 dashboard/src/db/index.ts create mode 100644 dashboard/src/db/schema.ts diff --git a/dashboard/drizzle.config.ts b/dashboard/drizzle.config.ts new file mode 100644 index 0000000..21ed5ad --- /dev/null +++ b/dashboard/drizzle.config.ts @@ -0,0 +1,14 @@ +'use server'; + +import 'dotenv/config'; +import { defineConfig } from 'drizzle-kit'; + + +export default defineConfig({ + out: './drizzle', + schema: './src/db/schema.ts', + dialect: 'postgresql', + dbCredentials: { + url: process.env.DATABASE_URL!, + }, +}); diff --git a/dashboard/drizzle/relations.ts b/dashboard/drizzle/relations.ts new file mode 100644 index 0000000..e69de29 diff --git a/dashboard/drizzle/schema.ts b/dashboard/drizzle/schema.ts new file mode 100644 index 0000000..e69de29 diff --git a/dashboard/src/db/index.ts b/dashboard/src/db/index.ts new file mode 100644 index 0000000..8b0e187 --- /dev/null +++ b/dashboard/src/db/index.ts @@ -0,0 +1,10 @@ +'use server'; + +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/node-postgres'; + +const db = drizzle(process.env.DATABASE_URL!); + +export async function getDB() { + return db; +} diff --git a/dashboard/src/db/schema.ts b/dashboard/src/db/schema.ts new file mode 100644 index 0000000..e69de29 From ebba31d6f621a0fedfe6ee195dd4804bf0a79848 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:19:20 +0100 Subject: [PATCH 03/14] NORY-41: pull drizzle schema from database --- dashboard/drizzle/0000_square_moondragon.sql | 484 ++ dashboard/drizzle/meta/0000_snapshot.json | 4700 ++++++++++++++++++ dashboard/drizzle/meta/_journal.json | 13 + dashboard/drizzle/relations.ts | 334 ++ dashboard/drizzle/schema.ts | 713 +++ dashboard/src/db/schema.ts | 713 +++ 6 files changed, 6957 insertions(+) create mode 100644 dashboard/drizzle/0000_square_moondragon.sql create mode 100644 dashboard/drizzle/meta/0000_snapshot.json create mode 100644 dashboard/drizzle/meta/_journal.json diff --git a/dashboard/drizzle/0000_square_moondragon.sql b/dashboard/drizzle/0000_square_moondragon.sql new file mode 100644 index 0000000..5400fe7 --- /dev/null +++ b/dashboard/drizzle/0000_square_moondragon.sql @@ -0,0 +1,484 @@ +-- Current sql file was generated after introspecting the database +-- If you want to run this migration please uncomment this code before executing migrations +/* +CREATE TABLE "schema_migration" ( + "version" varchar(48) NOT NULL, + "version_self" integer DEFAULT 0 NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_credentials" ( + "id" uuid PRIMARY KEY NOT NULL, + "config" jsonb NOT NULL, + "identity_credential_type_id" uuid NOT NULL, + "identity_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid, + "version" integer DEFAULT 0 NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_credential_types" ( + "id" uuid PRIMARY KEY NOT NULL, + "name" varchar(32) NOT NULL +); +--> statement-breakpoint +CREATE TABLE "selfservice_login_flows" ( + "id" uuid PRIMARY KEY NOT NULL, + "request_url" text NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "active_method" varchar(32) NOT NULL, + "csrf_token" varchar(255) NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "forced" boolean DEFAULT false NOT NULL, + "type" varchar(16) DEFAULT 'browser' NOT NULL, + "ui" jsonb, + "nid" uuid, + "requested_aal" varchar(4) DEFAULT 'aal1' NOT NULL, + "internal_context" jsonb NOT NULL, + "oauth2_login_challenge" uuid, + "oauth2_login_challenge_data" text, + "state" varchar(255), + "submit_count" integer DEFAULT 0 NOT NULL, + "organization_id" uuid +); +--> statement-breakpoint +CREATE TABLE "networks" ( + "id" uuid PRIMARY KEY NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE "selfservice_registration_flows" ( + "id" uuid PRIMARY KEY NOT NULL, + "request_url" text NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "active_method" varchar(32) NOT NULL, + "csrf_token" varchar(255) NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "type" varchar(16) DEFAULT 'browser' NOT NULL, + "ui" jsonb, + "nid" uuid, + "internal_context" jsonb NOT NULL, + "oauth2_login_challenge" uuid, + "oauth2_login_challenge_data" text, + "state" varchar(255), + "submit_count" integer DEFAULT 0 NOT NULL, + "organization_id" uuid +); +--> statement-breakpoint +CREATE TABLE "identities" ( + "id" uuid PRIMARY KEY NOT NULL, + "schema_id" varchar(2048) NOT NULL, + "traits" jsonb NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid, + "state" varchar(255) DEFAULT 'active' NOT NULL, + "state_changed_at" timestamp, + "metadata_public" jsonb, + "metadata_admin" jsonb, + "available_aal" varchar(4), + "organization_id" uuid +); +--> statement-breakpoint +CREATE TABLE "identity_credential_identifiers" ( + "id" uuid PRIMARY KEY NOT NULL, + "identifier" varchar(255) NOT NULL, + "identity_credential_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid, + "identity_credential_type_id" uuid NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_verifiable_addresses" ( + "id" uuid PRIMARY KEY NOT NULL, + "status" varchar(16) NOT NULL, + "via" varchar(16) NOT NULL, + "verified" boolean NOT NULL, + "value" varchar(400) NOT NULL, + "verified_at" timestamp, + "identity_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid +); +--> statement-breakpoint +CREATE TABLE "courier_messages" ( + "id" uuid PRIMARY KEY NOT NULL, + "type" integer NOT NULL, + "status" integer NOT NULL, + "body" text NOT NULL, + "subject" varchar(255) NOT NULL, + "recipient" varchar(255) NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "template_type" varchar(255) DEFAULT '' NOT NULL, + "template_data" "bytea", + "nid" uuid, + "send_count" integer DEFAULT 0 NOT NULL, + "channel" varchar(32) +); +--> statement-breakpoint +CREATE TABLE "selfservice_errors" ( + "id" uuid PRIMARY KEY NOT NULL, + "errors" jsonb NOT NULL, + "seen_at" timestamp, + "was_seen" boolean NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "csrf_token" varchar(255) DEFAULT '' NOT NULL, + "nid" uuid +); +--> statement-breakpoint +CREATE TABLE "selfservice_verification_flows" ( + "id" uuid PRIMARY KEY NOT NULL, + "request_url" text NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "csrf_token" varchar(255) NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "type" varchar(16) DEFAULT 'browser' NOT NULL, + "state" varchar(255) DEFAULT 'show_form' NOT NULL, + "active_method" varchar(32), + "ui" jsonb, + "nid" uuid, + "submit_count" integer DEFAULT 0 NOT NULL, + "oauth2_login_challenge" text, + "session_id" uuid, + "identity_id" uuid, + "authentication_methods" json +); +--> statement-breakpoint +CREATE TABLE "selfservice_settings_flows" ( + "id" uuid PRIMARY KEY NOT NULL, + "request_url" text NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "identity_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "active_method" varchar(32), + "state" varchar(255) DEFAULT 'show_form' NOT NULL, + "type" varchar(16) DEFAULT 'browser' NOT NULL, + "ui" jsonb, + "nid" uuid, + "internal_context" jsonb NOT NULL +); +--> statement-breakpoint +CREATE TABLE "continuity_containers" ( + "id" uuid PRIMARY KEY NOT NULL, + "identity_id" uuid, + "name" varchar(255) NOT NULL, + "payload" jsonb, + "expires_at" timestamp NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid +); +--> statement-breakpoint +CREATE TABLE "sessions" ( + "id" uuid PRIMARY KEY NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "authenticated_at" timestamp NOT NULL, + "identity_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "token" varchar(39), + "active" boolean DEFAULT false, + "nid" uuid, + "logout_token" varchar(39), + "aal" varchar(4) DEFAULT 'aal1' NOT NULL, + "authentication_methods" jsonb NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_recovery_addresses" ( + "id" uuid PRIMARY KEY NOT NULL, + "via" varchar(16) NOT NULL, + "value" varchar(400) NOT NULL, + "identity_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid +); +--> statement-breakpoint +CREATE TABLE "identity_verification_tokens" ( + "id" uuid PRIMARY KEY NOT NULL, + "token" varchar(64) NOT NULL, + "used" boolean DEFAULT false NOT NULL, + "used_at" timestamp, + "expires_at" timestamp NOT NULL, + "issued_at" timestamp NOT NULL, + "identity_verifiable_address_id" uuid NOT NULL, + "selfservice_verification_flow_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid +); +--> statement-breakpoint +CREATE TABLE "selfservice_recovery_flows" ( + "id" uuid PRIMARY KEY NOT NULL, + "request_url" text NOT NULL, + "issued_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "expires_at" timestamp NOT NULL, + "active_method" varchar(32), + "csrf_token" varchar(255) NOT NULL, + "state" varchar(32) NOT NULL, + "recovered_identity_id" uuid, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "type" varchar(16) DEFAULT 'browser' NOT NULL, + "ui" jsonb, + "nid" uuid, + "submit_count" integer DEFAULT 0 NOT NULL, + "skip_csrf_check" boolean DEFAULT false NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_recovery_tokens" ( + "id" uuid PRIMARY KEY NOT NULL, + "token" varchar(64) NOT NULL, + "used" boolean DEFAULT false NOT NULL, + "used_at" timestamp, + "identity_recovery_address_id" uuid, + "selfservice_recovery_flow_id" uuid, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "expires_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "issued_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "nid" uuid, + "identity_id" uuid NOT NULL, + "token_type" integer DEFAULT 0 NOT NULL, + CONSTRAINT "identity_recovery_tokens_token_type_ck" CHECK ((token_type = 1) OR (token_type = 2)) +); +--> statement-breakpoint +CREATE TABLE "identity_recovery_codes" ( + "id" uuid PRIMARY KEY NOT NULL, + "code" varchar(64) NOT NULL, + "used_at" timestamp, + "identity_recovery_address_id" uuid, + "code_type" integer NOT NULL, + "expires_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "issued_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "selfservice_recovery_flow_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid NOT NULL, + "identity_id" uuid NOT NULL +); +--> statement-breakpoint +CREATE TABLE "session_devices" ( + "id" uuid PRIMARY KEY NOT NULL, + "ip_address" varchar(50) DEFAULT '', + "user_agent" varchar(512) DEFAULT '', + "location" varchar(512) DEFAULT '', + "nid" uuid NOT NULL, + "session_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + CONSTRAINT "unique_session_device" UNIQUE("ip_address","user_agent","nid","session_id") +); +--> statement-breakpoint +CREATE TABLE "identity_verification_codes" ( + "id" uuid PRIMARY KEY NOT NULL, + "code_hmac" varchar(64) NOT NULL, + "used_at" timestamp, + "identity_verifiable_address_id" uuid, + "expires_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "issued_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "selfservice_verification_flow_id" uuid NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL, + "nid" uuid NOT NULL +); +--> statement-breakpoint +CREATE TABLE "courier_message_dispatches" ( + "id" uuid PRIMARY KEY NOT NULL, + "message_id" uuid NOT NULL, + "status" varchar(7) NOT NULL, + "error" json, + "nid" uuid NOT NULL, + "created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updated_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL +); +--> statement-breakpoint +CREATE TABLE "session_token_exchanges" ( + "id" uuid PRIMARY KEY NOT NULL, + "nid" uuid NOT NULL, + "flow_id" uuid NOT NULL, + "session_id" uuid, + "init_code" varchar(64) NOT NULL, + "return_to_code" varchar(64) NOT NULL, + "created_at" timestamp NOT NULL, + "updated_at" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_login_codes" ( + "id" uuid PRIMARY KEY NOT NULL, + "code" varchar(64) NOT NULL, + "address" varchar(255) NOT NULL, + "address_type" char(36) NOT NULL, + "used_at" timestamp, + "expires_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "issued_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "selfservice_login_flow_id" uuid NOT NULL, + "identity_id" uuid NOT NULL, + "created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updated_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "nid" uuid NOT NULL +); +--> statement-breakpoint +CREATE TABLE "identity_registration_codes" ( + "id" uuid PRIMARY KEY NOT NULL, + "code" varchar(64) NOT NULL, + "address" varchar(255) NOT NULL, + "address_type" char(36) NOT NULL, + "used_at" timestamp, + "expires_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "issued_at" timestamp DEFAULT '2000-01-01 00:00:00' NOT NULL, + "selfservice_registration_flow_id" uuid NOT NULL, + "created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updated_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, + "nid" uuid NOT NULL +); +--> statement-breakpoint +ALTER TABLE "identity_credentials" ADD CONSTRAINT "identity_credentials_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_credentials" ADD CONSTRAINT "identity_credentials_identity_credential_type_id_fkey" FOREIGN KEY ("identity_credential_type_id") REFERENCES "public"."identity_credential_types"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_credentials" ADD CONSTRAINT "identity_credentials_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_login_flows" ADD CONSTRAINT "selfservice_login_flows_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_registration_flows" ADD CONSTRAINT "selfservice_registration_flows_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identities" ADD CONSTRAINT "identities_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_credential_identifiers" ADD CONSTRAINT "identity_credential_identifiers_identity_credential_id_fkey" FOREIGN KEY ("identity_credential_id") REFERENCES "public"."identity_credentials"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_credential_identifiers" ADD CONSTRAINT "identity_credential_identifiers_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_credential_identifiers" ADD CONSTRAINT "identity_credential_identifiers_type_id_fk_idx" FOREIGN KEY ("identity_credential_type_id") REFERENCES "public"."identity_credential_types"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_verifiable_addresses" ADD CONSTRAINT "identity_verifiable_addresses_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verifiable_addresses" ADD CONSTRAINT "identity_verifiable_addresses_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "courier_messages" ADD CONSTRAINT "courier_messages_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_errors" ADD CONSTRAINT "selfservice_errors_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_verification_flows" ADD CONSTRAINT "selfservice_verification_flows_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_settings_flows" ADD CONSTRAINT "selfservice_profile_management_requests_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "selfservice_settings_flows" ADD CONSTRAINT "selfservice_settings_flows_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "continuity_containers" ADD CONSTRAINT "continuity_containers_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "continuity_containers" ADD CONSTRAINT "continuity_containers_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "sessions" ADD CONSTRAINT "sessions_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "sessions" ADD CONSTRAINT "sessions_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_recovery_addresses" ADD CONSTRAINT "identity_recovery_addresses_identity_id_fkey" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_recovery_addresses" ADD CONSTRAINT "identity_recovery_addresses_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_verification_tokens" ADD CONSTRAINT "identity_verification_tokens_identity_verifiable_address_i_fkey" FOREIGN KEY ("identity_verifiable_address_id") REFERENCES "public"."identity_verifiable_addresses"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verification_tokens" ADD CONSTRAINT "identity_verification_tokens_selfservice_verification_flow_fkey" FOREIGN KEY ("selfservice_verification_flow_id") REFERENCES "public"."selfservice_verification_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verification_tokens" ADD CONSTRAINT "identity_verification_tokens_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "selfservice_recovery_flows" ADD CONSTRAINT "selfservice_recovery_requests_recovered_identity_id_fkey" FOREIGN KEY ("recovered_identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "selfservice_recovery_flows" ADD CONSTRAINT "selfservice_recovery_flows_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_recovery_tokens" ADD CONSTRAINT "identity_recovery_tokens_selfservice_recovery_request_id_fkey" FOREIGN KEY ("selfservice_recovery_flow_id") REFERENCES "public"."selfservice_recovery_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_recovery_tokens" ADD CONSTRAINT "identity_recovery_tokens_nid_fk_idx" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_recovery_tokens" ADD CONSTRAINT "identity_recovery_tokens_identity_recovery_address_id_fkey" FOREIGN KEY ("identity_recovery_address_id") REFERENCES "public"."identity_recovery_addresses"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_recovery_tokens" ADD CONSTRAINT "identity_recovery_tokens_identity_id_fk_idx" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_recovery_codes" ADD CONSTRAINT "identity_recovery_codes_identity_recovery_addresses_id_fk" FOREIGN KEY ("identity_recovery_address_id") REFERENCES "public"."identity_recovery_addresses"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_recovery_codes" ADD CONSTRAINT "identity_recovery_codes_selfservice_recovery_flows_id_fk" FOREIGN KEY ("selfservice_recovery_flow_id") REFERENCES "public"."selfservice_recovery_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_recovery_codes" ADD CONSTRAINT "identity_recovery_codes_identity_id_fk" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_recovery_codes" ADD CONSTRAINT "identity_recovery_codes_networks_id_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "session_devices" ADD CONSTRAINT "session_metadata_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "session_devices" ADD CONSTRAINT "session_metadata_nid_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verification_codes" ADD CONSTRAINT "identity_verification_codes_identity_verifiable_addresses_id_fk" FOREIGN KEY ("identity_verifiable_address_id") REFERENCES "public"."identity_verifiable_addresses"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verification_codes" ADD CONSTRAINT "identity_verification_codes_selfservice_verification_flows_id_f" FOREIGN KEY ("selfservice_verification_flow_id") REFERENCES "public"."selfservice_verification_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_verification_codes" ADD CONSTRAINT "identity_verification_codes_networks_id_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "courier_message_dispatches" ADD CONSTRAINT "courier_message_dispatches_message_id_fk" FOREIGN KEY ("message_id") REFERENCES "public"."courier_messages"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "courier_message_dispatches" ADD CONSTRAINT "courier_message_dispatches_nid_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_login_codes" ADD CONSTRAINT "identity_login_codes_selfservice_login_flows_id_fk" FOREIGN KEY ("selfservice_login_flow_id") REFERENCES "public"."selfservice_login_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_login_codes" ADD CONSTRAINT "identity_login_codes_networks_id_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_login_codes" ADD CONSTRAINT "identity_login_codes_identity_id_fk" FOREIGN KEY ("identity_id") REFERENCES "public"."identities"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +ALTER TABLE "identity_registration_codes" ADD CONSTRAINT "identity_registration_codes_selfservice_registration_flows_id_f" FOREIGN KEY ("selfservice_registration_flow_id") REFERENCES "public"."selfservice_registration_flows"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "identity_registration_codes" ADD CONSTRAINT "identity_registration_codes_networks_id_fk" FOREIGN KEY ("nid") REFERENCES "public"."networks"("id") ON DELETE cascade ON UPDATE restrict;--> statement-breakpoint +CREATE UNIQUE INDEX "schema_migration_version_idx" ON "schema_migration" USING btree ("version" text_ops);--> statement-breakpoint +CREATE INDEX "schema_migration_version_self_idx" ON "schema_migration" USING btree ("version_self" int4_ops);--> statement-breakpoint +CREATE INDEX "identity_credentials_id_nid_idx" ON "identity_credentials" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_credentials_nid_id_idx" ON "identity_credentials" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_credentials_nid_identity_id_idx" ON "identity_credentials" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_credential_types_name_idx" ON "identity_credential_types" USING btree ("name" text_ops);--> statement-breakpoint +CREATE INDEX "selfservice_login_flows_id_nid_idx" ON "selfservice_login_flows" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_login_flows_nid_id_idx" ON "selfservice_login_flows" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_registration_flows_id_nid_idx" ON "selfservice_registration_flows" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_registration_flows_nid_id_idx" ON "selfservice_registration_flows" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identities_id_nid_idx" ON "identities" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identities_nid_id_idx" ON "identities" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_credential_identifiers_id_nid_idx" ON "identity_credential_identifiers" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_credential_identifiers_identifier_nid_type_uq_idx" ON "identity_credential_identifiers" USING btree ("nid" uuid_ops,"identity_credential_type_id" uuid_ops,"identifier" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_credential_identifiers_nid_i_ici_idx" ON "identity_credential_identifiers" USING btree ("nid" text_ops,"identifier" text_ops,"identity_credential_id" text_ops);--> statement-breakpoint +CREATE INDEX "identity_credential_identifiers_nid_id_idx" ON "identity_credential_identifiers" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_credential_identifiers_nid_identity_credential_id_idx" ON "identity_credential_identifiers" USING btree ("identity_credential_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verifiable_addresses_id_nid_idx" ON "identity_verifiable_addresses" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verifiable_addresses_nid_id_idx" ON "identity_verifiable_addresses" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verifiable_addresses_nid_identity_id_idx" ON "identity_verifiable_addresses" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verifiable_addresses_status_via_idx" ON "identity_verifiable_addresses" USING btree ("nid" text_ops,"via" text_ops,"value" text_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_verifiable_addresses_status_via_uq_idx" ON "identity_verifiable_addresses" USING btree ("nid" text_ops,"via" text_ops,"value" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_id_nid_idx" ON "courier_messages" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_nid_created_at_id_idx" ON "courier_messages" USING btree ("nid" timestamp_ops,"created_at" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_nid_id_idx" ON "courier_messages" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_nid_recipient_created_at_id_idx" ON "courier_messages" USING btree ("nid" timestamp_ops,"recipient" text_ops,"created_at" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_nid_status_created_at_id_idx" ON "courier_messages" USING btree ("nid" uuid_ops,"status" timestamp_ops,"created_at" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_messages_status_idx" ON "courier_messages" USING btree ("status" int4_ops);--> statement-breakpoint +CREATE INDEX "selfservice_errors_errors_nid_id_idx" ON "selfservice_errors" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_verification_flows_id_nid_idx" ON "selfservice_verification_flows" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_verification_flows_nid_id_idx" ON "selfservice_verification_flows" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_settings_flows_id_nid_idx" ON "selfservice_settings_flows" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_settings_flows_identity_id_nid_idx" ON "selfservice_settings_flows" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_settings_flows_nid_id_idx" ON "selfservice_settings_flows" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "continuity_containers_id_nid_idx" ON "continuity_containers" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "continuity_containers_identity_id_nid_idx" ON "continuity_containers" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "continuity_containers_nid_id_idx" ON "continuity_containers" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "sessions_id_nid_idx" ON "sessions" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "sessions_identity_id_nid_sorted_idx" ON "sessions" USING btree ("identity_id" timestamp_ops,"nid" timestamp_ops,"authenticated_at" uuid_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "sessions_logout_token_uq_idx" ON "sessions" USING btree ("logout_token" text_ops);--> statement-breakpoint +CREATE INDEX "sessions_nid_created_at_id_idx" ON "sessions" USING btree ("nid" uuid_ops,"created_at" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "sessions_nid_id_identity_id_idx" ON "sessions" USING btree ("nid" uuid_ops,"identity_id" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "sessions_token_nid_idx" ON "sessions" USING btree ("nid" uuid_ops,"token" text_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "sessions_token_uq_idx" ON "sessions" USING btree ("token" text_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_addresses_id_nid_idx" ON "identity_recovery_addresses" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_addresses_nid_id_idx" ON "identity_recovery_addresses" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_addresses_nid_identity_id_idx" ON "identity_recovery_addresses" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_addresses_status_via_idx" ON "identity_recovery_addresses" USING btree ("nid" text_ops,"via" text_ops,"value" text_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_recovery_addresses_status_via_uq_idx" ON "identity_recovery_addresses" USING btree ("nid" text_ops,"via" text_ops,"value" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_tokens_id_nid_idx" ON "identity_verification_tokens" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_tokens_nid_id_idx" ON "identity_verification_tokens" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_tokens_token_nid_used_flow_id_idx" ON "identity_verification_tokens" USING btree ("nid" uuid_ops,"token" bool_ops,"used" text_ops,"selfservice_verification_flow_id" uuid_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_verification_tokens_token_uq_idx" ON "identity_verification_tokens" USING btree ("token" text_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_tokens_verifiable_address_id_idx" ON "identity_verification_tokens" USING btree ("identity_verifiable_address_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_tokens_verification_flow_id_idx" ON "identity_verification_tokens" USING btree ("selfservice_verification_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_recovery_flows_id_nid_idx" ON "selfservice_recovery_flows" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_recovery_flows_nid_id_idx" ON "selfservice_recovery_flows" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "selfservice_recovery_flows_recovered_identity_id_nid_idx" ON "selfservice_recovery_flows" USING btree ("recovered_identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE UNIQUE INDEX "identity_recovery_addresses_code_uq_idx" ON "identity_recovery_tokens" USING btree ("token" text_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_id_nid_idx" ON "identity_recovery_tokens" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_identity_id_nid_idx" ON "identity_recovery_tokens" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_identity_recovery_address_id_idx" ON "identity_recovery_tokens" USING btree ("identity_recovery_address_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_nid_id_idx" ON "identity_recovery_tokens" USING btree ("nid" uuid_ops,"id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_selfservice_recovery_flow_id_idx" ON "identity_recovery_tokens" USING btree ("selfservice_recovery_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_tokens_token_nid_used_idx" ON "identity_recovery_tokens" USING btree ("nid" bool_ops,"token" text_ops,"used" bool_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_codes_flow_id_idx" ON "identity_recovery_codes" USING btree ("selfservice_recovery_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_codes_id_nid_idx" ON "identity_recovery_codes" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_codes_identity_id_nid_idx" ON "identity_recovery_codes" USING btree ("identity_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_codes_identity_recovery_address_id_nid_idx" ON "identity_recovery_codes" USING btree ("identity_recovery_address_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_recovery_codes_nid_flow_id_idx" ON "identity_recovery_codes" USING btree ("nid" uuid_ops,"selfservice_recovery_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "session_devices_id_nid_idx" ON "session_devices" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "session_devices_session_id_nid_idx" ON "session_devices" USING btree ("session_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_codes_flow_id_idx" ON "identity_verification_codes" USING btree ("selfservice_verification_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_codes_id_nid_idx" ON "identity_verification_codes" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_codes_nid_flow_id_idx" ON "identity_verification_codes" USING btree ("nid" uuid_ops,"selfservice_verification_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_verification_codes_verifiable_address_nid_idx" ON "identity_verification_codes" USING btree ("identity_verifiable_address_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "courier_message_dispatches_message_id_idx" ON "courier_message_dispatches" USING btree ("message_id" timestamp_ops,"created_at" timestamp_ops);--> statement-breakpoint +CREATE INDEX "courier_message_dispatches_nid_idx" ON "courier_message_dispatches" USING btree ("nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "session_token_exchanges_nid_code_idx" ON "session_token_exchanges" USING btree ("init_code" uuid_ops,"nid" text_ops);--> statement-breakpoint +CREATE INDEX "session_token_exchanges_nid_flow_id_idx" ON "session_token_exchanges" USING btree ("flow_id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_login_codes_flow_id_idx" ON "identity_login_codes" USING btree ("selfservice_login_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_login_codes_id_nid_idx" ON "identity_login_codes" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_login_codes_identity_id_idx" ON "identity_login_codes" USING btree ("identity_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_login_codes_nid_flow_id_idx" ON "identity_login_codes" USING btree ("nid" uuid_ops,"selfservice_login_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_registration_codes_flow_id_idx" ON "identity_registration_codes" USING btree ("selfservice_registration_flow_id" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_registration_codes_id_nid_idx" ON "identity_registration_codes" USING btree ("id" uuid_ops,"nid" uuid_ops);--> statement-breakpoint +CREATE INDEX "identity_registration_codes_nid_flow_id_idx" ON "identity_registration_codes" USING btree ("nid" uuid_ops,"selfservice_registration_flow_id" uuid_ops); +*/ \ No newline at end of file diff --git a/dashboard/drizzle/meta/0000_snapshot.json b/dashboard/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..4d455bc --- /dev/null +++ b/dashboard/drizzle/meta/0000_snapshot.json @@ -0,0 +1,4700 @@ +{ + "id": "00000000-0000-0000-0000-000000000000", + "prevId": "", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.schema_migration": { + "name": "schema_migration", + "schema": "", + "columns": { + "version": { + "name": "version", + "type": "varchar(48)", + "primaryKey": false, + "notNull": true + }, + "version_self": { + "name": "version_self", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "schema_migration_version_idx": { + "name": "schema_migration_version_idx", + "columns": [ + { + "expression": "version", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "schema_migration_version_self_idx": { + "name": "schema_migration_version_self_idx", + "columns": [ + { + "expression": "version_self", + "asc": true, + "nulls": "last", + "opclass": "int4_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_credentials": { + "name": "identity_credentials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "identity_credential_type_id": { + "name": "identity_credential_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "identity_credentials_id_nid_idx": { + "name": "identity_credentials_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credentials_nid_id_idx": { + "name": "identity_credentials_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credentials_nid_identity_id_idx": { + "name": "identity_credentials_nid_identity_id_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_credentials_identity_id_fkey": { + "name": "identity_credentials_identity_id_fkey", + "tableFrom": "identity_credentials", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_credentials_identity_credential_type_id_fkey": { + "name": "identity_credentials_identity_credential_type_id_fkey", + "tableFrom": "identity_credentials", + "tableTo": "identity_credential_types", + "schemaTo": "public", + "columnsFrom": [ + "identity_credential_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_credentials_nid_fk_idx": { + "name": "identity_credentials_nid_fk_idx", + "tableFrom": "identity_credentials", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_credential_types": { + "name": "identity_credential_types", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_credential_types_name_idx": { + "name": "identity_credential_types_name_idx", + "columns": [ + { + "expression": "name", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_login_flows": { + "name": "selfservice_login_flows", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "request_url": { + "name": "request_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "active_method": { + "name": "active_method", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "csrf_token": { + "name": "csrf_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "forced": { + "name": "forced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "type": { + "name": "type", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'browser'" + }, + "ui": { + "name": "ui", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "requested_aal": { + "name": "requested_aal", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true, + "default": "'aal1'" + }, + "internal_context": { + "name": "internal_context", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "oauth2_login_challenge": { + "name": "oauth2_login_challenge", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "oauth2_login_challenge_data": { + "name": "oauth2_login_challenge_data", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "submit_count": { + "name": "submit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "selfservice_login_flows_id_nid_idx": { + "name": "selfservice_login_flows_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_login_flows_nid_id_idx": { + "name": "selfservice_login_flows_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_login_flows_nid_fk_idx": { + "name": "selfservice_login_flows_nid_fk_idx", + "tableFrom": "selfservice_login_flows", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.networks": { + "name": "networks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_registration_flows": { + "name": "selfservice_registration_flows", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "request_url": { + "name": "request_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "active_method": { + "name": "active_method", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "csrf_token": { + "name": "csrf_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'browser'" + }, + "ui": { + "name": "ui", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "internal_context": { + "name": "internal_context", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "oauth2_login_challenge": { + "name": "oauth2_login_challenge", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "oauth2_login_challenge_data": { + "name": "oauth2_login_challenge_data", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "submit_count": { + "name": "submit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "selfservice_registration_flows_id_nid_idx": { + "name": "selfservice_registration_flows_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_registration_flows_nid_id_idx": { + "name": "selfservice_registration_flows_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_registration_flows_nid_fk_idx": { + "name": "selfservice_registration_flows_nid_fk_idx", + "tableFrom": "selfservice_registration_flows", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identities": { + "name": "identities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "schema_id": { + "name": "schema_id", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": true + }, + "traits": { + "name": "traits", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "state_changed_at": { + "name": "state_changed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "metadata_public": { + "name": "metadata_public", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metadata_admin": { + "name": "metadata_admin", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "available_aal": { + "name": "available_aal", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "identities_id_nid_idx": { + "name": "identities_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identities_nid_id_idx": { + "name": "identities_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identities_nid_fk_idx": { + "name": "identities_nid_fk_idx", + "tableFrom": "identities", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_credential_identifiers": { + "name": "identity_credential_identifiers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "identity_credential_id": { + "name": "identity_credential_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "identity_credential_type_id": { + "name": "identity_credential_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_credential_identifiers_id_nid_idx": { + "name": "identity_credential_identifiers_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credential_identifiers_identifier_nid_type_uq_idx": { + "name": "identity_credential_identifiers_identifier_nid_type_uq_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "identity_credential_type_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "identifier", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credential_identifiers_nid_i_ici_idx": { + "name": "identity_credential_identifiers_nid_i_ici_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "identifier", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "identity_credential_id", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credential_identifiers_nid_id_idx": { + "name": "identity_credential_identifiers_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_credential_identifiers_nid_identity_credential_id_idx": { + "name": "identity_credential_identifiers_nid_identity_credential_id_idx", + "columns": [ + { + "expression": "identity_credential_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_credential_identifiers_identity_credential_id_fkey": { + "name": "identity_credential_identifiers_identity_credential_id_fkey", + "tableFrom": "identity_credential_identifiers", + "tableTo": "identity_credentials", + "schemaTo": "public", + "columnsFrom": [ + "identity_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_credential_identifiers_nid_fk_idx": { + "name": "identity_credential_identifiers_nid_fk_idx", + "tableFrom": "identity_credential_identifiers", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + }, + "identity_credential_identifiers_type_id_fk_idx": { + "name": "identity_credential_identifiers_type_id_fk_idx", + "tableFrom": "identity_credential_identifiers", + "tableTo": "identity_credential_types", + "schemaTo": "public", + "columnsFrom": [ + "identity_credential_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_verifiable_addresses": { + "name": "identity_verifiable_addresses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "via": { + "name": "via", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "verified": { + "name": "verified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "varchar(400)", + "primaryKey": false, + "notNull": true + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "identity_verifiable_addresses_id_nid_idx": { + "name": "identity_verifiable_addresses_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verifiable_addresses_nid_id_idx": { + "name": "identity_verifiable_addresses_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verifiable_addresses_nid_identity_id_idx": { + "name": "identity_verifiable_addresses_nid_identity_id_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verifiable_addresses_status_via_idx": { + "name": "identity_verifiable_addresses_status_via_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "via", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "value", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verifiable_addresses_status_via_uq_idx": { + "name": "identity_verifiable_addresses_status_via_uq_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "via", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "value", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_verifiable_addresses_identity_id_fkey": { + "name": "identity_verifiable_addresses_identity_id_fkey", + "tableFrom": "identity_verifiable_addresses", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_verifiable_addresses_nid_fk_idx": { + "name": "identity_verifiable_addresses_nid_fk_idx", + "tableFrom": "identity_verifiable_addresses", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.courier_messages": { + "name": "courier_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "type": { + "name": "type", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "recipient": { + "name": "recipient", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "template_type": { + "name": "template_type", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "template_data": { + "name": "template_data", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "send_count": { + "name": "send_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "channel": { + "name": "channel", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "courier_messages_id_nid_idx": { + "name": "courier_messages_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_messages_nid_created_at_id_idx": { + "name": "courier_messages_nid_created_at_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "created_at", + "asc": false, + "nulls": "first", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_messages_nid_id_idx": { + "name": "courier_messages_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_messages_nid_recipient_created_at_id_idx": { + "name": "courier_messages_nid_recipient_created_at_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "recipient", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "created_at", + "asc": false, + "nulls": "first", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_messages_nid_status_created_at_id_idx": { + "name": "courier_messages_nid_status_created_at_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "status", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "created_at", + "asc": false, + "nulls": "first", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_messages_status_idx": { + "name": "courier_messages_status_idx", + "columns": [ + { + "expression": "status", + "asc": true, + "nulls": "last", + "opclass": "int4_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "courier_messages_nid_fk_idx": { + "name": "courier_messages_nid_fk_idx", + "tableFrom": "courier_messages", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_errors": { + "name": "selfservice_errors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "errors": { + "name": "errors", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "seen_at": { + "name": "seen_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "was_seen": { + "name": "was_seen", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "csrf_token": { + "name": "csrf_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "selfservice_errors_errors_nid_id_idx": { + "name": "selfservice_errors_errors_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_errors_nid_fk_idx": { + "name": "selfservice_errors_nid_fk_idx", + "tableFrom": "selfservice_errors", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_verification_flows": { + "name": "selfservice_verification_flows", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "request_url": { + "name": "request_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "csrf_token": { + "name": "csrf_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'browser'" + }, + "state": { + "name": "state", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'show_form'" + }, + "active_method": { + "name": "active_method", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "ui": { + "name": "ui", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "submit_count": { + "name": "submit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "oauth2_login_challenge": { + "name": "oauth2_login_challenge", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "authentication_methods": { + "name": "authentication_methods", + "type": "json", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "selfservice_verification_flows_id_nid_idx": { + "name": "selfservice_verification_flows_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_verification_flows_nid_id_idx": { + "name": "selfservice_verification_flows_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_verification_flows_nid_fk_idx": { + "name": "selfservice_verification_flows_nid_fk_idx", + "tableFrom": "selfservice_verification_flows", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_settings_flows": { + "name": "selfservice_settings_flows", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "request_url": { + "name": "request_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "active_method": { + "name": "active_method", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'show_form'" + }, + "type": { + "name": "type", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'browser'" + }, + "ui": { + "name": "ui", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "internal_context": { + "name": "internal_context", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "selfservice_settings_flows_id_nid_idx": { + "name": "selfservice_settings_flows_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_settings_flows_identity_id_nid_idx": { + "name": "selfservice_settings_flows_identity_id_nid_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_settings_flows_nid_id_idx": { + "name": "selfservice_settings_flows_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_profile_management_requests_identity_id_fkey": { + "name": "selfservice_profile_management_requests_identity_id_fkey", + "tableFrom": "selfservice_settings_flows", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "selfservice_settings_flows_nid_fk_idx": { + "name": "selfservice_settings_flows_nid_fk_idx", + "tableFrom": "selfservice_settings_flows", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.continuity_containers": { + "name": "continuity_containers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "continuity_containers_id_nid_idx": { + "name": "continuity_containers_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "continuity_containers_identity_id_nid_idx": { + "name": "continuity_containers_identity_id_nid_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "continuity_containers_nid_id_idx": { + "name": "continuity_containers_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "continuity_containers_identity_id_fkey": { + "name": "continuity_containers_identity_id_fkey", + "tableFrom": "continuity_containers", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "continuity_containers_nid_fk_idx": { + "name": "continuity_containers_nid_fk_idx", + "tableFrom": "continuity_containers", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "authenticated_at": { + "name": "authenticated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(39)", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "logout_token": { + "name": "logout_token", + "type": "varchar(39)", + "primaryKey": false, + "notNull": false + }, + "aal": { + "name": "aal", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true, + "default": "'aal1'" + }, + "authentication_methods": { + "name": "authentication_methods", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "sessions_id_nid_idx": { + "name": "sessions_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_identity_id_nid_sorted_idx": { + "name": "sessions_identity_id_nid_sorted_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "authenticated_at", + "asc": false, + "nulls": "first", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_logout_token_uq_idx": { + "name": "sessions_logout_token_uq_idx", + "columns": [ + { + "expression": "logout_token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_nid_created_at_id_idx": { + "name": "sessions_nid_created_at_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "created_at", + "asc": false, + "nulls": "first", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_nid_id_identity_id_idx": { + "name": "sessions_nid_id_identity_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_token_nid_idx": { + "name": "sessions_token_nid_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_token_uq_idx": { + "name": "sessions_token_uq_idx", + "columns": [ + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sessions_identity_id_fkey": { + "name": "sessions_identity_id_fkey", + "tableFrom": "sessions", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sessions_nid_fk_idx": { + "name": "sessions_nid_fk_idx", + "tableFrom": "sessions", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_recovery_addresses": { + "name": "identity_recovery_addresses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "via": { + "name": "via", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "varchar(400)", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "identity_recovery_addresses_id_nid_idx": { + "name": "identity_recovery_addresses_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_addresses_nid_id_idx": { + "name": "identity_recovery_addresses_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_addresses_nid_identity_id_idx": { + "name": "identity_recovery_addresses_nid_identity_id_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_addresses_status_via_idx": { + "name": "identity_recovery_addresses_status_via_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "via", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "value", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_addresses_status_via_uq_idx": { + "name": "identity_recovery_addresses_status_via_uq_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "via", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "value", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_recovery_addresses_identity_id_fkey": { + "name": "identity_recovery_addresses_identity_id_fkey", + "tableFrom": "identity_recovery_addresses", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_recovery_addresses_nid_fk_idx": { + "name": "identity_recovery_addresses_nid_fk_idx", + "tableFrom": "identity_recovery_addresses", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_verification_tokens": { + "name": "identity_verification_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "used": { + "name": "used", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "identity_verifiable_address_id": { + "name": "identity_verifiable_address_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "selfservice_verification_flow_id": { + "name": "selfservice_verification_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "identity_verification_tokens_id_nid_idx": { + "name": "identity_verification_tokens_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_tokens_nid_id_idx": { + "name": "identity_verification_tokens_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_tokens_token_nid_used_flow_id_idx": { + "name": "identity_verification_tokens_token_nid_used_flow_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "bool_ops", + "isExpression": false + }, + { + "expression": "used", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "selfservice_verification_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_tokens_token_uq_idx": { + "name": "identity_verification_tokens_token_uq_idx", + "columns": [ + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_tokens_verifiable_address_id_idx": { + "name": "identity_verification_tokens_verifiable_address_id_idx", + "columns": [ + { + "expression": "identity_verifiable_address_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_tokens_verification_flow_id_idx": { + "name": "identity_verification_tokens_verification_flow_id_idx", + "columns": [ + { + "expression": "selfservice_verification_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_verification_tokens_identity_verifiable_address_i_fkey": { + "name": "identity_verification_tokens_identity_verifiable_address_i_fkey", + "tableFrom": "identity_verification_tokens", + "tableTo": "identity_verifiable_addresses", + "schemaTo": "public", + "columnsFrom": [ + "identity_verifiable_address_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_verification_tokens_selfservice_verification_flow_fkey": { + "name": "identity_verification_tokens_selfservice_verification_flow_fkey", + "tableFrom": "identity_verification_tokens", + "tableTo": "selfservice_verification_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_verification_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_verification_tokens_nid_fk_idx": { + "name": "identity_verification_tokens_nid_fk_idx", + "tableFrom": "identity_verification_tokens", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.selfservice_recovery_flows": { + "name": "selfservice_recovery_flows", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "request_url": { + "name": "request_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "active_method": { + "name": "active_method", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + }, + "csrf_token": { + "name": "csrf_token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "recovered_identity_id": { + "name": "recovered_identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'browser'" + }, + "ui": { + "name": "ui", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "submit_count": { + "name": "submit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skip_csrf_check": { + "name": "skip_csrf_check", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "selfservice_recovery_flows_id_nid_idx": { + "name": "selfservice_recovery_flows_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_recovery_flows_nid_id_idx": { + "name": "selfservice_recovery_flows_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "selfservice_recovery_flows_recovered_identity_id_nid_idx": { + "name": "selfservice_recovery_flows_recovered_identity_id_nid_idx", + "columns": [ + { + "expression": "recovered_identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "selfservice_recovery_requests_recovered_identity_id_fkey": { + "name": "selfservice_recovery_requests_recovered_identity_id_fkey", + "tableFrom": "selfservice_recovery_flows", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "recovered_identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "selfservice_recovery_flows_nid_fk_idx": { + "name": "selfservice_recovery_flows_nid_fk_idx", + "tableFrom": "selfservice_recovery_flows", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_recovery_tokens": { + "name": "identity_recovery_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "used": { + "name": "used", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "identity_recovery_address_id": { + "name": "identity_recovery_address_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "selfservice_recovery_flow_id": { + "name": "selfservice_recovery_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_type": { + "name": "token_type", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "identity_recovery_addresses_code_uq_idx": { + "name": "identity_recovery_addresses_code_uq_idx", + "columns": [ + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_id_nid_idx": { + "name": "identity_recovery_tokens_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_identity_id_nid_idx": { + "name": "identity_recovery_tokens_identity_id_nid_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_identity_recovery_address_id_idx": { + "name": "identity_recovery_tokens_identity_recovery_address_id_idx", + "columns": [ + { + "expression": "identity_recovery_address_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_nid_id_idx": { + "name": "identity_recovery_tokens_nid_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_selfservice_recovery_flow_id_idx": { + "name": "identity_recovery_tokens_selfservice_recovery_flow_id_idx", + "columns": [ + { + "expression": "selfservice_recovery_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_tokens_token_nid_used_idx": { + "name": "identity_recovery_tokens_token_nid_used_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "bool_ops", + "isExpression": false + }, + { + "expression": "token", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + }, + { + "expression": "used", + "asc": true, + "nulls": "last", + "opclass": "bool_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_recovery_tokens_selfservice_recovery_request_id_fkey": { + "name": "identity_recovery_tokens_selfservice_recovery_request_id_fkey", + "tableFrom": "identity_recovery_tokens", + "tableTo": "selfservice_recovery_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_recovery_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_recovery_tokens_nid_fk_idx": { + "name": "identity_recovery_tokens_nid_fk_idx", + "tableFrom": "identity_recovery_tokens", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + }, + "identity_recovery_tokens_identity_recovery_address_id_fkey": { + "name": "identity_recovery_tokens_identity_recovery_address_id_fkey", + "tableFrom": "identity_recovery_tokens", + "tableTo": "identity_recovery_addresses", + "schemaTo": "public", + "columnsFrom": [ + "identity_recovery_address_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_recovery_tokens_identity_id_fk_idx": { + "name": "identity_recovery_tokens_identity_id_fk_idx", + "tableFrom": "identity_recovery_tokens", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "identity_recovery_tokens_token_type_ck": { + "name": "identity_recovery_tokens_token_type_ck", + "value": "(token_type = 1) OR (token_type = 2)" + } + }, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_recovery_codes": { + "name": "identity_recovery_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "identity_recovery_address_id": { + "name": "identity_recovery_address_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "code_type": { + "name": "code_type", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "selfservice_recovery_flow_id": { + "name": "selfservice_recovery_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_recovery_codes_flow_id_idx": { + "name": "identity_recovery_codes_flow_id_idx", + "columns": [ + { + "expression": "selfservice_recovery_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_codes_id_nid_idx": { + "name": "identity_recovery_codes_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_codes_identity_id_nid_idx": { + "name": "identity_recovery_codes_identity_id_nid_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_codes_identity_recovery_address_id_nid_idx": { + "name": "identity_recovery_codes_identity_recovery_address_id_nid_idx", + "columns": [ + { + "expression": "identity_recovery_address_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_recovery_codes_nid_flow_id_idx": { + "name": "identity_recovery_codes_nid_flow_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "selfservice_recovery_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_recovery_codes_identity_recovery_addresses_id_fk": { + "name": "identity_recovery_codes_identity_recovery_addresses_id_fk", + "tableFrom": "identity_recovery_codes", + "tableTo": "identity_recovery_addresses", + "schemaTo": "public", + "columnsFrom": [ + "identity_recovery_address_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_recovery_codes_selfservice_recovery_flows_id_fk": { + "name": "identity_recovery_codes_selfservice_recovery_flows_id_fk", + "tableFrom": "identity_recovery_codes", + "tableTo": "selfservice_recovery_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_recovery_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_recovery_codes_identity_id_fk": { + "name": "identity_recovery_codes_identity_id_fk", + "tableFrom": "identity_recovery_codes", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + }, + "identity_recovery_codes_networks_id_fk": { + "name": "identity_recovery_codes_networks_id_fk", + "tableFrom": "identity_recovery_codes", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.session_devices": { + "name": "session_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "user_agent": { + "name": "user_agent", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "location": { + "name": "location", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "session_devices_id_nid_idx": { + "name": "session_devices_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "session_devices_session_id_nid_idx": { + "name": "session_devices_session_id_nid_idx", + "columns": [ + { + "expression": "session_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_metadata_sessions_id_fk": { + "name": "session_metadata_sessions_id_fk", + "tableFrom": "session_devices", + "tableTo": "sessions", + "schemaTo": "public", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "session_metadata_nid_fk": { + "name": "session_metadata_nid_fk", + "tableFrom": "session_devices", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_session_device": { + "columns": [ + "ip_address", + "user_agent", + "nid", + "session_id" + ], + "nullsNotDistinct": false, + "name": "unique_session_device" + } + }, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_verification_codes": { + "name": "identity_verification_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "code_hmac": { + "name": "code_hmac", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "identity_verifiable_address_id": { + "name": "identity_verifiable_address_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "selfservice_verification_flow_id": { + "name": "selfservice_verification_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_verification_codes_flow_id_idx": { + "name": "identity_verification_codes_flow_id_idx", + "columns": [ + { + "expression": "selfservice_verification_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_codes_id_nid_idx": { + "name": "identity_verification_codes_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_codes_nid_flow_id_idx": { + "name": "identity_verification_codes_nid_flow_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "selfservice_verification_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_verification_codes_verifiable_address_nid_idx": { + "name": "identity_verification_codes_verifiable_address_nid_idx", + "columns": [ + { + "expression": "identity_verifiable_address_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_verification_codes_identity_verifiable_addresses_id_fk": { + "name": "identity_verification_codes_identity_verifiable_addresses_id_fk", + "tableFrom": "identity_verification_codes", + "tableTo": "identity_verifiable_addresses", + "schemaTo": "public", + "columnsFrom": [ + "identity_verifiable_address_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_verification_codes_selfservice_verification_flows_id_f": { + "name": "identity_verification_codes_selfservice_verification_flows_id_f", + "tableFrom": "identity_verification_codes", + "tableTo": "selfservice_verification_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_verification_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_verification_codes_networks_id_fk": { + "name": "identity_verification_codes_networks_id_fk", + "tableFrom": "identity_verification_codes", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.courier_message_dispatches": { + "name": "courier_message_dispatches", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "varchar(7)", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + } + }, + "indexes": { + "courier_message_dispatches_message_id_idx": { + "name": "courier_message_dispatches_message_id_idx", + "columns": [ + { + "expression": "message_id", + "asc": true, + "nulls": "last", + "opclass": "timestamp_ops", + "isExpression": false + }, + { + "expression": "created_at", + "asc": false, + "nulls": "first", + "opclass": "timestamp_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "courier_message_dispatches_nid_idx": { + "name": "courier_message_dispatches_nid_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "courier_message_dispatches_message_id_fk": { + "name": "courier_message_dispatches_message_id_fk", + "tableFrom": "courier_message_dispatches", + "tableTo": "courier_messages", + "schemaTo": "public", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "courier_message_dispatches_nid_fk": { + "name": "courier_message_dispatches_nid_fk", + "tableFrom": "courier_message_dispatches", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.session_token_exchanges": { + "name": "session_token_exchanges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "flow_id": { + "name": "flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "init_code": { + "name": "init_code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "return_to_code": { + "name": "return_to_code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "session_token_exchanges_nid_code_idx": { + "name": "session_token_exchanges_nid_code_idx", + "columns": [ + { + "expression": "init_code", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "text_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "session_token_exchanges_nid_flow_id_idx": { + "name": "session_token_exchanges_nid_flow_id_idx", + "columns": [ + { + "expression": "flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_login_codes": { + "name": "identity_login_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "address_type": { + "name": "address_type", + "type": "char(36)", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "selfservice_login_flow_id": { + "name": "selfservice_login_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "identity_id": { + "name": "identity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_login_codes_flow_id_idx": { + "name": "identity_login_codes_flow_id_idx", + "columns": [ + { + "expression": "selfservice_login_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_login_codes_id_nid_idx": { + "name": "identity_login_codes_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_login_codes_identity_id_idx": { + "name": "identity_login_codes_identity_id_idx", + "columns": [ + { + "expression": "identity_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_login_codes_nid_flow_id_idx": { + "name": "identity_login_codes_nid_flow_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "selfservice_login_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_login_codes_selfservice_login_flows_id_fk": { + "name": "identity_login_codes_selfservice_login_flows_id_fk", + "tableFrom": "identity_login_codes", + "tableTo": "selfservice_login_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_login_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_login_codes_networks_id_fk": { + "name": "identity_login_codes_networks_id_fk", + "tableFrom": "identity_login_codes", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + }, + "identity_login_codes_identity_id_fk": { + "name": "identity_login_codes_identity_id_fk", + "tableFrom": "identity_login_codes", + "tableTo": "identities", + "schemaTo": "public", + "columnsFrom": [ + "identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + }, + "public.identity_registration_codes": { + "name": "identity_registration_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "address_type": { + "name": "address_type", + "type": "char(36)", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "issued_at": { + "name": "issued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "'2000-01-01 00:00:00'" + }, + "selfservice_registration_flow_id": { + "name": "selfservice_registration_flow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "CURRENT_TIMESTAMP" + }, + "nid": { + "name": "nid", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "identity_registration_codes_flow_id_idx": { + "name": "identity_registration_codes_flow_id_idx", + "columns": [ + { + "expression": "selfservice_registration_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_registration_codes_id_nid_idx": { + "name": "identity_registration_codes_id_nid_idx", + "columns": [ + { + "expression": "id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "identity_registration_codes_nid_flow_id_idx": { + "name": "identity_registration_codes_nid_flow_id_idx", + "columns": [ + { + "expression": "nid", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + }, + { + "expression": "selfservice_registration_flow_id", + "asc": true, + "nulls": "last", + "opclass": "uuid_ops", + "isExpression": false + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "identity_registration_codes_selfservice_registration_flows_id_f": { + "name": "identity_registration_codes_selfservice_registration_flows_id_f", + "tableFrom": "identity_registration_codes", + "tableTo": "selfservice_registration_flows", + "schemaTo": "public", + "columnsFrom": [ + "selfservice_registration_flow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "identity_registration_codes_networks_id_fk": { + "name": "identity_registration_codes_networks_id_fk", + "tableFrom": "identity_registration_codes", + "tableTo": "networks", + "schemaTo": "public", + "columnsFrom": [ + "nid" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {}, + "policies": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": {} + } +} \ No newline at end of file diff --git a/dashboard/drizzle/meta/_journal.json b/dashboard/drizzle/meta/_journal.json new file mode 100644 index 0000000..b7874f0 --- /dev/null +++ b/dashboard/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1735943555589, + "tag": "0000_square_moondragon", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/dashboard/drizzle/relations.ts b/dashboard/drizzle/relations.ts index e69de29..615b353 100644 --- a/dashboard/drizzle/relations.ts +++ b/dashboard/drizzle/relations.ts @@ -0,0 +1,334 @@ +import { relations } from 'drizzle-orm/relations'; +import { + continuityContainers, + courierMessageDispatches, + courierMessages, + identities, + identityCredentialIdentifiers, + identityCredentials, + identityCredentialTypes, + identityLoginCodes, + identityRecoveryAddresses, + identityRecoveryCodes, + identityRecoveryTokens, + identityRegistrationCodes, + identityVerifiableAddresses, + identityVerificationCodes, + identityVerificationTokens, + networks, + selfserviceErrors, + selfserviceLoginFlows, + selfserviceRecoveryFlows, + selfserviceRegistrationFlows, + selfserviceSettingsFlows, + selfserviceVerificationFlows, + sessionDevices, + sessions, +} from './schema'; + +export const identityCredentialsRelations = relations(identityCredentials, ({ one, many }) => ({ + identity: one(identities, { + fields: [identityCredentials.identityId], + references: [identities.id], + }), + identityCredentialType: one(identityCredentialTypes, { + fields: [identityCredentials.identityCredentialTypeId], + references: [identityCredentialTypes.id], + }), + network: one(networks, { + fields: [identityCredentials.nid], + references: [networks.id], + }), + identityCredentialIdentifiers: many(identityCredentialIdentifiers), +})); + +export const identitiesRelations = relations(identities, ({ one, many }) => ({ + identityCredentials: many(identityCredentials), + network: one(networks, { + fields: [identities.nid], + references: [networks.id], + }), + identityVerifiableAddresses: many(identityVerifiableAddresses), + selfserviceSettingsFlows: many(selfserviceSettingsFlows), + continuityContainers: many(continuityContainers), + sessions: many(sessions), + identityRecoveryAddresses: many(identityRecoveryAddresses), + selfserviceRecoveryFlows: many(selfserviceRecoveryFlows), + identityRecoveryTokens: many(identityRecoveryTokens), + identityRecoveryCodes: many(identityRecoveryCodes), + identityLoginCodes: many(identityLoginCodes), +})); + +export const identityCredentialTypesRelations = relations(identityCredentialTypes, ({ many }) => ({ + identityCredentials: many(identityCredentials), + identityCredentialIdentifiers: many(identityCredentialIdentifiers), +})); + +export const networksRelations = relations(networks, ({ many }) => ({ + identityCredentials: many(identityCredentials), + selfserviceLoginFlows: many(selfserviceLoginFlows), + selfserviceRegistrationFlows: many(selfserviceRegistrationFlows), + identities: many(identities), + identityCredentialIdentifiers: many(identityCredentialIdentifiers), + identityVerifiableAddresses: many(identityVerifiableAddresses), + courierMessages: many(courierMessages), + selfserviceErrors: many(selfserviceErrors), + selfserviceVerificationFlows: many(selfserviceVerificationFlows), + selfserviceSettingsFlows: many(selfserviceSettingsFlows), + continuityContainers: many(continuityContainers), + sessions: many(sessions), + identityRecoveryAddresses: many(identityRecoveryAddresses), + identityVerificationTokens: many(identityVerificationTokens), + selfserviceRecoveryFlows: many(selfserviceRecoveryFlows), + identityRecoveryTokens: many(identityRecoveryTokens), + identityRecoveryCodes: many(identityRecoveryCodes), + sessionDevices: many(sessionDevices), + identityVerificationCodes: many(identityVerificationCodes), + courierMessageDispatches: many(courierMessageDispatches), + identityLoginCodes: many(identityLoginCodes), + identityRegistrationCodes: many(identityRegistrationCodes), +})); + +export const selfserviceLoginFlowsRelations = relations(selfserviceLoginFlows, ({ one, many }) => ({ + network: one(networks, { + fields: [selfserviceLoginFlows.nid], + references: [networks.id], + }), + identityLoginCodes: many(identityLoginCodes), +})); + +export const selfserviceRegistrationFlowsRelations = relations(selfserviceRegistrationFlows, ({ one, many }) => ({ + network: one(networks, { + fields: [selfserviceRegistrationFlows.nid], + references: [networks.id], + }), + identityRegistrationCodes: many(identityRegistrationCodes), +})); + +export const identityCredentialIdentifiersRelations = relations(identityCredentialIdentifiers, ({ one }) => ({ + identityCredential: one(identityCredentials, { + fields: [identityCredentialIdentifiers.identityCredentialId], + references: [identityCredentials.id], + }), + network: one(networks, { + fields: [identityCredentialIdentifiers.nid], + references: [networks.id], + }), + identityCredentialType: one(identityCredentialTypes, { + fields: [identityCredentialIdentifiers.identityCredentialTypeId], + references: [identityCredentialTypes.id], + }), +})); + +export const identityVerifiableAddressesRelations = relations(identityVerifiableAddresses, ({ one, many }) => ({ + identity: one(identities, { + fields: [identityVerifiableAddresses.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [identityVerifiableAddresses.nid], + references: [networks.id], + }), + identityVerificationTokens: many(identityVerificationTokens), + identityVerificationCodes: many(identityVerificationCodes), +})); + +export const courierMessagesRelations = relations(courierMessages, ({ one, many }) => ({ + network: one(networks, { + fields: [courierMessages.nid], + references: [networks.id], + }), + courierMessageDispatches: many(courierMessageDispatches), +})); + +export const selfserviceErrorsRelations = relations(selfserviceErrors, ({ one }) => ({ + network: one(networks, { + fields: [selfserviceErrors.nid], + references: [networks.id], + }), +})); + +export const selfserviceVerificationFlowsRelations = relations(selfserviceVerificationFlows, ({ one, many }) => ({ + network: one(networks, { + fields: [selfserviceVerificationFlows.nid], + references: [networks.id], + }), + identityVerificationTokens: many(identityVerificationTokens), + identityVerificationCodes: many(identityVerificationCodes), +})); + +export const selfserviceSettingsFlowsRelations = relations(selfserviceSettingsFlows, ({ one }) => ({ + identity: one(identities, { + fields: [selfserviceSettingsFlows.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [selfserviceSettingsFlows.nid], + references: [networks.id], + }), +})); + +export const continuityContainersRelations = relations(continuityContainers, ({ one }) => ({ + identity: one(identities, { + fields: [continuityContainers.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [continuityContainers.nid], + references: [networks.id], + }), +})); + +export const sessionsRelations = relations(sessions, ({ one, many }) => ({ + identity: one(identities, { + fields: [sessions.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [sessions.nid], + references: [networks.id], + }), + sessionDevices: many(sessionDevices), +})); + +export const identityRecoveryAddressesRelations = relations(identityRecoveryAddresses, ({ one, many }) => ({ + identity: one(identities, { + fields: [identityRecoveryAddresses.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [identityRecoveryAddresses.nid], + references: [networks.id], + }), + identityRecoveryTokens: many(identityRecoveryTokens), + identityRecoveryCodes: many(identityRecoveryCodes), +})); + +export const identityVerificationTokensRelations = relations(identityVerificationTokens, ({ one }) => ({ + identityVerifiableAddress: one(identityVerifiableAddresses, { + fields: [identityVerificationTokens.identityVerifiableAddressId], + references: [identityVerifiableAddresses.id], + }), + selfserviceVerificationFlow: one(selfserviceVerificationFlows, { + fields: [identityVerificationTokens.selfserviceVerificationFlowId], + references: [selfserviceVerificationFlows.id], + }), + network: one(networks, { + fields: [identityVerificationTokens.nid], + references: [networks.id], + }), +})); + +export const selfserviceRecoveryFlowsRelations = relations(selfserviceRecoveryFlows, ({ one, many }) => ({ + identity: one(identities, { + fields: [selfserviceRecoveryFlows.recoveredIdentityId], + references: [identities.id], + }), + network: one(networks, { + fields: [selfserviceRecoveryFlows.nid], + references: [networks.id], + }), + identityRecoveryTokens: many(identityRecoveryTokens), + identityRecoveryCodes: many(identityRecoveryCodes), +})); + +export const identityRecoveryTokensRelations = relations(identityRecoveryTokens, ({ one }) => ({ + selfserviceRecoveryFlow: one(selfserviceRecoveryFlows, { + fields: [identityRecoveryTokens.selfserviceRecoveryFlowId], + references: [selfserviceRecoveryFlows.id], + }), + network: one(networks, { + fields: [identityRecoveryTokens.nid], + references: [networks.id], + }), + identityRecoveryAddress: one(identityRecoveryAddresses, { + fields: [identityRecoveryTokens.identityRecoveryAddressId], + references: [identityRecoveryAddresses.id], + }), + identity: one(identities, { + fields: [identityRecoveryTokens.identityId], + references: [identities.id], + }), +})); + +export const identityRecoveryCodesRelations = relations(identityRecoveryCodes, ({ one }) => ({ + identityRecoveryAddress: one(identityRecoveryAddresses, { + fields: [identityRecoveryCodes.identityRecoveryAddressId], + references: [identityRecoveryAddresses.id], + }), + selfserviceRecoveryFlow: one(selfserviceRecoveryFlows, { + fields: [identityRecoveryCodes.selfserviceRecoveryFlowId], + references: [selfserviceRecoveryFlows.id], + }), + identity: one(identities, { + fields: [identityRecoveryCodes.identityId], + references: [identities.id], + }), + network: one(networks, { + fields: [identityRecoveryCodes.nid], + references: [networks.id], + }), +})); + +export const sessionDevicesRelations = relations(sessionDevices, ({ one }) => ({ + session: one(sessions, { + fields: [sessionDevices.sessionId], + references: [sessions.id], + }), + network: one(networks, { + fields: [sessionDevices.nid], + references: [networks.id], + }), +})); + +export const identityVerificationCodesRelations = relations(identityVerificationCodes, ({ one }) => ({ + identityVerifiableAddress: one(identityVerifiableAddresses, { + fields: [identityVerificationCodes.identityVerifiableAddressId], + references: [identityVerifiableAddresses.id], + }), + selfserviceVerificationFlow: one(selfserviceVerificationFlows, { + fields: [identityVerificationCodes.selfserviceVerificationFlowId], + references: [selfserviceVerificationFlows.id], + }), + network: one(networks, { + fields: [identityVerificationCodes.nid], + references: [networks.id], + }), +})); + +export const courierMessageDispatchesRelations = relations(courierMessageDispatches, ({ one }) => ({ + courierMessage: one(courierMessages, { + fields: [courierMessageDispatches.messageId], + references: [courierMessages.id], + }), + network: one(networks, { + fields: [courierMessageDispatches.nid], + references: [networks.id], + }), +})); + +export const identityLoginCodesRelations = relations(identityLoginCodes, ({ one }) => ({ + selfserviceLoginFlow: one(selfserviceLoginFlows, { + fields: [identityLoginCodes.selfserviceLoginFlowId], + references: [selfserviceLoginFlows.id], + }), + network: one(networks, { + fields: [identityLoginCodes.nid], + references: [networks.id], + }), + identity: one(identities, { + fields: [identityLoginCodes.identityId], + references: [identities.id], + }), +})); + +export const identityRegistrationCodesRelations = relations(identityRegistrationCodes, ({ one }) => ({ + selfserviceRegistrationFlow: one(selfserviceRegistrationFlows, { + fields: [identityRegistrationCodes.selfserviceRegistrationFlowId], + references: [selfserviceRegistrationFlows.id], + }), + network: one(networks, { + fields: [identityRegistrationCodes.nid], + references: [networks.id], + }), +})); \ No newline at end of file diff --git a/dashboard/drizzle/schema.ts b/dashboard/drizzle/schema.ts index e69de29..4aa73e5 100644 --- a/dashboard/drizzle/schema.ts +++ b/dashboard/drizzle/schema.ts @@ -0,0 +1,713 @@ +import { + boolean, + char, + check, + foreignKey, + index, + integer, + json, + jsonb, + pgTable, + text, + timestamp, + unique, + uniqueIndex, + uuid, + varchar, +} from 'drizzle-orm/pg-core'; +import { sql } from 'drizzle-orm'; + +export const schemaMigration = pgTable('schema_migration', { + version: varchar({ length: 48 }).notNull(), + versionSelf: integer('version_self').default(0).notNull(), +}, (table) => [ + uniqueIndex('schema_migration_version_idx').using('btree', table.version.asc().nullsLast().op('text_ops')), + index('schema_migration_version_self_idx').using('btree', table.versionSelf.asc().nullsLast().op('int4_ops')), +]); + +export const identityCredentials = pgTable('identity_credentials', { + id: uuid().primaryKey().notNull(), + config: jsonb().notNull(), + identityCredentialTypeId: uuid('identity_credential_type_id').notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + version: integer().default(0).notNull(), +}, (table) => [ + index('identity_credentials_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_credentials_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_credentials_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_credentials_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityCredentialTypeId], + foreignColumns: [identityCredentialTypes.id], + name: 'identity_credentials_identity_credential_type_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_credentials_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityCredentialTypes = pgTable('identity_credential_types', { + id: uuid().primaryKey().notNull(), + name: varchar({ length: 32 }).notNull(), +}, (table) => [ + uniqueIndex('identity_credential_types_name_idx').using('btree', table.name.asc().nullsLast().op('text_ops')), +]); + +export const selfserviceLoginFlows = pgTable('selfservice_login_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + forced: boolean().default(false).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + requestedAal: varchar('requested_aal', { length: 4 }).default('aal1').notNull(), + internalContext: jsonb('internal_context').notNull(), + oauth2LoginChallenge: uuid('oauth2_login_challenge'), + oauth2LoginChallengeData: text('oauth2_login_challenge_data'), + state: varchar({ length: 255 }), + submitCount: integer('submit_count').default(0).notNull(), + organizationId: uuid('organization_id'), +}, (table) => [ + index('selfservice_login_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_login_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_login_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const networks = pgTable('networks', { + id: uuid().primaryKey().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}); + +export const selfserviceRegistrationFlows = pgTable('selfservice_registration_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + internalContext: jsonb('internal_context').notNull(), + oauth2LoginChallenge: uuid('oauth2_login_challenge'), + oauth2LoginChallengeData: text('oauth2_login_challenge_data'), + state: varchar({ length: 255 }), + submitCount: integer('submit_count').default(0).notNull(), + organizationId: uuid('organization_id'), +}, (table) => [ + index('selfservice_registration_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_registration_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_registration_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identities = pgTable('identities', { + id: uuid().primaryKey().notNull(), + schemaId: varchar('schema_id', { length: 2048 }).notNull(), + traits: jsonb().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + state: varchar({ length: 255 }).default('active').notNull(), + stateChangedAt: timestamp('state_changed_at', { mode: 'string' }), + metadataPublic: jsonb('metadata_public'), + metadataAdmin: jsonb('metadata_admin'), + availableAal: varchar('available_aal', { length: 4 }), + organizationId: uuid('organization_id'), +}, (table) => [ + index('identities_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identities_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identities_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityCredentialIdentifiers = pgTable('identity_credential_identifiers', { + id: uuid().primaryKey().notNull(), + identifier: varchar({ length: 255 }).notNull(), + identityCredentialId: uuid('identity_credential_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + identityCredentialTypeId: uuid('identity_credential_type_id').notNull(), +}, (table) => [ + index('identity_credential_identifiers_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + uniqueIndex('identity_credential_identifiers_identifier_nid_type_uq_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.identityCredentialTypeId.asc().nullsLast().op('uuid_ops'), table.identifier.asc().nullsLast().op('uuid_ops')), + index('identity_credential_identifiers_nid_i_ici_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.identifier.asc().nullsLast().op('text_ops'), table.identityCredentialId.asc().nullsLast().op('text_ops')), + index('identity_credential_identifiers_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_credential_identifiers_nid_identity_credential_id_idx').using('btree', table.identityCredentialId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityCredentialId], + foreignColumns: [identityCredentials.id], + name: 'identity_credential_identifiers_identity_credential_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_credential_identifiers_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityCredentialTypeId], + foreignColumns: [identityCredentialTypes.id], + name: 'identity_credential_identifiers_type_id_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityVerifiableAddresses = pgTable('identity_verifiable_addresses', { + id: uuid().primaryKey().notNull(), + status: varchar({ length: 16 }).notNull(), + via: varchar({ length: 16 }).notNull(), + verified: boolean().notNull(), + value: varchar({ length: 400 }).notNull(), + verifiedAt: timestamp('verified_at', { mode: 'string' }), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_verifiable_addresses_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_status_via_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('text_ops')), + uniqueIndex('identity_verifiable_addresses_status_via_uq_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_verifiable_addresses_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verifiable_addresses_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const courierMessages = pgTable('courier_messages', { + id: uuid().primaryKey().notNull(), + type: integer().notNull(), + status: integer().notNull(), + body: text().notNull(), + subject: varchar({ length: 255 }).notNull(), + recipient: varchar({ length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + templateType: varchar('template_type', { length: 255 }).default('').notNull(), + // TODO: failed to parse database type 'bytea' + templateData: varchar('template_data'), + nid: uuid(), + sendCount: integer('send_count').default(0).notNull(), + channel: varchar({ length: 32 }), +}, (table) => [ + index('courier_messages_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('courier_messages_nid_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('courier_messages_nid_recipient_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('timestamp_ops'), table.recipient.asc().nullsLast().op('text_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_nid_status_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.status.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_status_idx').using('btree', table.status.asc().nullsLast().op('int4_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'courier_messages_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceErrors = pgTable('selfservice_errors', { + id: uuid().primaryKey().notNull(), + errors: jsonb().notNull(), + seenAt: timestamp('seen_at', { mode: 'string' }), + wasSeen: boolean('was_seen').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).default('').notNull(), + nid: uuid(), +}, (table) => [ + index('selfservice_errors_errors_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_errors_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceVerificationFlows = pgTable('selfservice_verification_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + state: varchar({ length: 255 }).default('show_form').notNull(), + activeMethod: varchar('active_method', { length: 32 }), + ui: jsonb(), + nid: uuid(), + submitCount: integer('submit_count').default(0).notNull(), + oauth2LoginChallenge: text('oauth2_login_challenge'), + sessionId: uuid('session_id'), + identityId: uuid('identity_id'), + authenticationMethods: json('authentication_methods'), +}, (table) => [ + index('selfservice_verification_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_verification_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_verification_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceSettingsFlows = pgTable('selfservice_settings_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }), + state: varchar({ length: 255 }).default('show_form').notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + internalContext: jsonb('internal_context').notNull(), +}, (table) => [ + index('selfservice_settings_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_settings_flows_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_settings_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'selfservice_profile_management_requests_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_settings_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const continuityContainers = pgTable('continuity_containers', { + id: uuid().primaryKey().notNull(), + identityId: uuid('identity_id'), + name: varchar({ length: 255 }).notNull(), + payload: jsonb(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('continuity_containers_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('continuity_containers_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('continuity_containers_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'continuity_containers_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'continuity_containers_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const sessions = pgTable('sessions', { + id: uuid().primaryKey().notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + authenticatedAt: timestamp('authenticated_at', { mode: 'string' }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + token: varchar({ length: 39 }), + active: boolean().default(false), + nid: uuid(), + logoutToken: varchar('logout_token', { length: 39 }), + aal: varchar({ length: 4 }).default('aal1').notNull(), + authenticationMethods: jsonb('authentication_methods').notNull(), +}, (table) => [ + index('sessions_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('sessions_identity_id_nid_sorted_idx').using('btree', table.identityId.asc().nullsLast().op('timestamp_ops'), table.nid.asc().nullsLast().op('timestamp_ops'), table.authenticatedAt.desc().nullsFirst().op('uuid_ops')), + uniqueIndex('sessions_logout_token_uq_idx').using('btree', table.logoutToken.asc().nullsLast().op('text_ops')), + index('sessions_nid_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('sessions_nid_id_identity_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.identityId.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('sessions_token_nid_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.token.asc().nullsLast().op('text_ops')), + uniqueIndex('sessions_token_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'sessions_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'sessions_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRecoveryAddresses = pgTable('identity_recovery_addresses', { + id: uuid().primaryKey().notNull(), + via: varchar({ length: 16 }).notNull(), + value: varchar({ length: 400 }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_recovery_addresses_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_status_via_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('text_ops')), + uniqueIndex('identity_recovery_addresses_status_via_uq_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_addresses_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_addresses_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityVerificationTokens = pgTable('identity_verification_tokens', { + id: uuid().primaryKey().notNull(), + token: varchar({ length: 64 }).notNull(), + used: boolean().default(false).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).notNull(), + identityVerifiableAddressId: uuid('identity_verifiable_address_id').notNull(), + selfserviceVerificationFlowId: uuid('selfservice_verification_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_verification_tokens_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_token_nid_used_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.token.asc().nullsLast().op('bool_ops'), table.used.asc().nullsLast().op('text_ops'), table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + uniqueIndex('identity_verification_tokens_token_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + index('identity_verification_tokens_verifiable_address_id_idx').using('btree', table.identityVerifiableAddressId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_verification_flow_id_idx').using('btree', table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityVerifiableAddressId], + foreignColumns: [identityVerifiableAddresses.id], + name: 'identity_verification_tokens_identity_verifiable_address_i_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceVerificationFlowId], + foreignColumns: [selfserviceVerificationFlows.id], + name: 'identity_verification_tokens_selfservice_verification_flow_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verification_tokens_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceRecoveryFlows = pgTable('selfservice_recovery_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + state: varchar({ length: 32 }).notNull(), + recoveredIdentityId: uuid('recovered_identity_id'), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + submitCount: integer('submit_count').default(0).notNull(), + skipCsrfCheck: boolean('skip_csrf_check').default(false).notNull(), +}, (table) => [ + index('selfservice_recovery_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_recovery_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('selfservice_recovery_flows_recovered_identity_id_nid_idx').using('btree', table.recoveredIdentityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.recoveredIdentityId], + foreignColumns: [identities.id], + name: 'selfservice_recovery_requests_recovered_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_recovery_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRecoveryTokens = pgTable('identity_recovery_tokens', { + id: uuid().primaryKey().notNull(), + token: varchar({ length: 64 }).notNull(), + used: boolean().default(false).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityRecoveryAddressId: uuid('identity_recovery_address_id'), + selfserviceRecoveryFlowId: uuid('selfservice_recovery_flow_id'), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + nid: uuid(), + identityId: uuid('identity_id').notNull(), + tokenType: integer('token_type').default(0).notNull(), +}, (table) => [ + uniqueIndex('identity_recovery_addresses_code_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + index('identity_recovery_tokens_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_identity_recovery_address_id_idx').using('btree', table.identityRecoveryAddressId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_selfservice_recovery_flow_id_idx').using('btree', table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_token_nid_used_idx').using('btree', table.nid.asc().nullsLast().op('bool_ops'), table.token.asc().nullsLast().op('text_ops'), table.used.asc().nullsLast().op('bool_ops')), + foreignKey({ + columns: [table.selfserviceRecoveryFlowId], + foreignColumns: [selfserviceRecoveryFlows.id], + name: 'identity_recovery_tokens_selfservice_recovery_request_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_tokens_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityRecoveryAddressId], + foreignColumns: [identityRecoveryAddresses.id], + name: 'identity_recovery_tokens_identity_recovery_address_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_tokens_identity_id_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + check('identity_recovery_tokens_token_type_ck', sql`(token_type = 1) + OR (token_type = 2)`), +]); + +export const identityRecoveryCodes = pgTable('identity_recovery_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityRecoveryAddressId: uuid('identity_recovery_address_id'), + codeType: integer('code_type').notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceRecoveryFlowId: uuid('selfservice_recovery_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid().notNull(), + identityId: uuid('identity_id').notNull(), +}, (table) => [ + index('identity_recovery_codes_flow_id_idx').using('btree', table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_identity_recovery_address_id_nid_idx').using('btree', table.identityRecoveryAddressId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityRecoveryAddressId], + foreignColumns: [identityRecoveryAddresses.id], + name: 'identity_recovery_codes_identity_recovery_addresses_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceRecoveryFlowId], + foreignColumns: [selfserviceRecoveryFlows.id], + name: 'identity_recovery_codes_selfservice_recovery_flows_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_codes_identity_id_fk', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const sessionDevices = pgTable('session_devices', { + id: uuid().primaryKey().notNull(), + ipAddress: varchar('ip_address', { length: 50 }).default(''), + userAgent: varchar('user_agent', { length: 512 }).default(''), + location: varchar({ length: 512 }).default(''), + nid: uuid().notNull(), + sessionId: uuid('session_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}, (table) => [ + index('session_devices_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('session_devices_session_id_nid_idx').using('btree', table.sessionId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.sessionId], + foreignColumns: [sessions.id], + name: 'session_metadata_sessions_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'session_metadata_nid_fk', + }).onDelete('cascade'), + unique('unique_session_device').on(table.ipAddress, table.userAgent, table.nid, table.sessionId), +]); + +export const identityVerificationCodes = pgTable('identity_verification_codes', { + id: uuid().primaryKey().notNull(), + codeHmac: varchar('code_hmac', { length: 64 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityVerifiableAddressId: uuid('identity_verifiable_address_id'), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceVerificationFlowId: uuid('selfservice_verification_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_verification_codes_flow_id_idx').using('btree', table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_verifiable_address_nid_idx').using('btree', table.identityVerifiableAddressId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityVerifiableAddressId], + foreignColumns: [identityVerifiableAddresses.id], + name: 'identity_verification_codes_identity_verifiable_addresses_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceVerificationFlowId], + foreignColumns: [selfserviceVerificationFlows.id], + name: 'identity_verification_codes_selfservice_verification_flows_id_f', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verification_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const courierMessageDispatches = pgTable('courier_message_dispatches', { + id: uuid().primaryKey().notNull(), + messageId: uuid('message_id').notNull(), + status: varchar({ length: 7 }).notNull(), + error: json(), + nid: uuid().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), +}, (table) => [ + index('courier_message_dispatches_message_id_idx').using('btree', table.messageId.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('timestamp_ops')), + index('courier_message_dispatches_nid_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.messageId], + foreignColumns: [courierMessages.id], + name: 'courier_message_dispatches_message_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'courier_message_dispatches_nid_fk', + }).onDelete('cascade'), +]); + +export const sessionTokenExchanges = pgTable('session_token_exchanges', { + id: uuid().primaryKey().notNull(), + nid: uuid().notNull(), + flowId: uuid('flow_id').notNull(), + sessionId: uuid('session_id'), + initCode: varchar('init_code', { length: 64 }).notNull(), + returnToCode: varchar('return_to_code', { length: 64 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}, (table) => [ + index('session_token_exchanges_nid_code_idx').using('btree', table.initCode.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('text_ops')), + index('session_token_exchanges_nid_flow_id_idx').using('btree', table.flowId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), +]); + +export const identityLoginCodes = pgTable('identity_login_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + address: varchar({ length: 255 }).notNull(), + addressType: char('address_type', { length: 36 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceLoginFlowId: uuid('selfservice_login_flow_id').notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_login_codes_flow_id_idx').using('btree', table.selfserviceLoginFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceLoginFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.selfserviceLoginFlowId], + foreignColumns: [selfserviceLoginFlows.id], + name: 'identity_login_codes_selfservice_login_flows_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_login_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_login_codes_identity_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRegistrationCodes = pgTable('identity_registration_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + address: varchar({ length: 255 }).notNull(), + addressType: char('address_type', { length: 36 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceRegistrationFlowId: uuid('selfservice_registration_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_registration_codes_flow_id_idx').using('btree', table.selfserviceRegistrationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_registration_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_registration_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceRegistrationFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.selfserviceRegistrationFlowId], + foreignColumns: [selfserviceRegistrationFlows.id], + name: 'identity_registration_codes_selfservice_registration_flows_id_f', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_registration_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); diff --git a/dashboard/src/db/schema.ts b/dashboard/src/db/schema.ts index e69de29..5514575 100644 --- a/dashboard/src/db/schema.ts +++ b/dashboard/src/db/schema.ts @@ -0,0 +1,713 @@ +import { + boolean, + char, + check, + foreignKey, + index, + integer, + json, + jsonb, + pgTable, + text, + timestamp, + unique, + uniqueIndex, + uuid, + varchar, +} from 'drizzle-orm/pg-core'; +import { sql } from 'drizzle-orm'; + +export const schemaMigration = pgTable('schema_migration', { + version: varchar({ length: 48 }).notNull(), + versionSelf: integer('version_self').default(0).notNull(), +}, (table) => [ + uniqueIndex('schema_migration_version_idx').using('btree', table.version.asc().nullsLast().op('text_ops')), + index('schema_migration_version_self_idx').using('btree', table.versionSelf.asc().nullsLast().op('int4_ops')), +]); + +export const identityCredentials = pgTable('identity_credentials', { + id: uuid().primaryKey().notNull(), + config: jsonb().notNull(), + identityCredentialTypeId: uuid('identity_credential_type_id').notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + version: integer().default(0).notNull(), +}, (table) => [ + index('identity_credentials_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_credentials_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_credentials_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_credentials_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityCredentialTypeId], + foreignColumns: [identityCredentialTypes.id], + name: 'identity_credentials_identity_credential_type_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_credentials_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityCredentialTypes = pgTable('identity_credential_types', { + id: uuid().primaryKey().notNull(), + name: varchar({ length: 32 }).notNull(), +}, (table) => [ + uniqueIndex('identity_credential_types_name_idx').using('btree', table.name.asc().nullsLast().op('text_ops')), +]); + +export const selfserviceLoginFlows = pgTable('selfservice_login_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + forced: boolean().default(false).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + requestedAal: varchar('requested_aal', { length: 4 }).default('aal1').notNull(), + internalContext: jsonb('internal_context').notNull(), + oauth2LoginChallenge: uuid('oauth2_login_challenge'), + oauth2LoginChallengeData: text('oauth2_login_challenge_data'), + state: varchar({ length: 255 }), + submitCount: integer('submit_count').default(0).notNull(), + organizationId: uuid('organization_id'), +}, (table) => [ + index('selfservice_login_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_login_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_login_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const networks = pgTable('networks', { + id: uuid().primaryKey().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}); + +export const selfserviceRegistrationFlows = pgTable('selfservice_registration_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + internalContext: jsonb('internal_context').notNull(), + oauth2LoginChallenge: uuid('oauth2_login_challenge'), + oauth2LoginChallengeData: text('oauth2_login_challenge_data'), + state: varchar({ length: 255 }), + submitCount: integer('submit_count').default(0).notNull(), + organizationId: uuid('organization_id'), +}, (table) => [ + index('selfservice_registration_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_registration_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_registration_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identities = pgTable('identities', { + id: uuid().primaryKey().notNull(), + schemaId: varchar('schema_id', { length: 2048 }).notNull(), + traits: jsonb().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + state: varchar({ length: 255 }).default('active').notNull(), + stateChangedAt: timestamp('state_changed_at', { mode: 'string' }), + metadataPublic: jsonb('metadata_public'), + metadataAdmin: jsonb('metadata_admin'), + availableAal: varchar('available_aal', { length: 4 }), + organizationId: uuid('organization_id'), +}, (table) => [ + index('identities_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identities_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identities_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityCredentialIdentifiers = pgTable('identity_credential_identifiers', { + id: uuid().primaryKey().notNull(), + identifier: varchar({ length: 255 }).notNull(), + identityCredentialId: uuid('identity_credential_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), + identityCredentialTypeId: uuid('identity_credential_type_id').notNull(), +}, (table) => [ + index('identity_credential_identifiers_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + uniqueIndex('identity_credential_identifiers_identifier_nid_type_uq_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.identityCredentialTypeId.asc().nullsLast().op('uuid_ops'), table.identifier.asc().nullsLast().op('uuid_ops')), + index('identity_credential_identifiers_nid_i_ici_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.identifier.asc().nullsLast().op('text_ops'), table.identityCredentialId.asc().nullsLast().op('text_ops')), + index('identity_credential_identifiers_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_credential_identifiers_nid_identity_credential_id_idx').using('btree', table.identityCredentialId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityCredentialId], + foreignColumns: [identityCredentials.id], + name: 'identity_credential_identifiers_identity_credential_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_credential_identifiers_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityCredentialTypeId], + foreignColumns: [identityCredentialTypes.id], + name: 'identity_credential_identifiers_type_id_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityVerifiableAddresses = pgTable('identity_verifiable_addresses', { + id: uuid().primaryKey().notNull(), + status: varchar({ length: 16 }).notNull(), + via: varchar({ length: 16 }).notNull(), + verified: boolean().notNull(), + value: varchar({ length: 400 }).notNull(), + verifiedAt: timestamp('verified_at', { mode: 'string' }), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_verifiable_addresses_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verifiable_addresses_status_via_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('text_ops')), + uniqueIndex('identity_verifiable_addresses_status_via_uq_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_verifiable_addresses_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verifiable_addresses_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const courierMessages = pgTable('courier_messages', { + id: uuid().primaryKey().notNull(), + type: integer().notNull(), + status: integer().notNull(), + body: text().notNull(), + subject: varchar({ length: 255 }).notNull(), + recipient: varchar({ length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + templateType: varchar('template_type', { length: 255 }).default('').notNull(), + // TODO: failed to parse database type 'bytea' + templateData: varchar('template_data'), + nid: uuid(), + sendCount: integer('send_count').default(0).notNull(), + channel: varchar({ length: 32 }), +}, (table) => [ + index('courier_messages_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('courier_messages_nid_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('courier_messages_nid_recipient_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('timestamp_ops'), table.recipient.asc().nullsLast().op('text_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_nid_status_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.status.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops')), + index('courier_messages_status_idx').using('btree', table.status.asc().nullsLast().op('int4_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'courier_messages_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceErrors = pgTable('selfservice_errors', { + id: uuid().primaryKey().notNull(), + errors: jsonb().notNull(), + seenAt: timestamp('seen_at', { mode: 'string' }), + wasSeen: boolean('was_seen').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).default('').notNull(), + nid: uuid(), +}, (table) => [ + index('selfservice_errors_errors_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_errors_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceVerificationFlows = pgTable('selfservice_verification_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + state: varchar({ length: 255 }).default('show_form').notNull(), + activeMethod: varchar('active_method', { length: 32 }), + ui: jsonb(), + nid: uuid(), + submitCount: integer('submit_count').default(0).notNull(), + oauth2LoginChallenge: text('oauth2_login_challenge'), + sessionId: uuid('session_id'), + identityId: uuid('identity_id'), + authenticationMethods: json('authentication_methods'), +}, (table) => [ + index('selfservice_verification_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_verification_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_verification_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceSettingsFlows = pgTable('selfservice_settings_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }), + state: varchar({ length: 255 }).default('show_form').notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + internalContext: jsonb('internal_context').notNull(), +}, (table) => [ + index('selfservice_settings_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_settings_flows_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_settings_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'selfservice_profile_management_requests_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_settings_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const continuityContainers = pgTable('continuity_containers', { + id: uuid().primaryKey().notNull(), + identityId: uuid('identity_id'), + name: varchar({ length: 255 }).notNull(), + payload: jsonb(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('continuity_containers_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('continuity_containers_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('continuity_containers_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'continuity_containers_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'continuity_containers_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const sessions = pgTable('sessions', { + id: uuid().primaryKey().notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + authenticatedAt: timestamp('authenticated_at', { mode: 'string' }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + token: varchar({ length: 39 }), + active: boolean().default(false), + nid: uuid(), + logoutToken: varchar('logout_token', { length: 39 }), + aal: varchar({ length: 4 }).default('aal1').notNull(), + authenticationMethods: jsonb('authentication_methods').notNull(), +}, (table) => [ + index('sessions_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('sessions_identity_id_nid_sorted_idx').using('btree', table.identityId.asc().nullsLast().op('timestamp_ops'), table.nid.asc().nullsLast().op('timestamp_ops'), table.authenticatedAt.desc().nullsFirst().op('uuid_ops')), + uniqueIndex('sessions_logout_token_uq_idx').using('btree', table.logoutToken.asc().nullsLast().op('text_ops')), + index('sessions_nid_created_at_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.createdAt.desc().nullsFirst().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('sessions_nid_id_identity_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.identityId.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('sessions_token_nid_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.token.asc().nullsLast().op('text_ops')), + uniqueIndex('sessions_token_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'sessions_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'sessions_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRecoveryAddresses = pgTable('identity_recovery_addresses', { + id: uuid().primaryKey().notNull(), + via: varchar({ length: 16 }).notNull(), + value: varchar({ length: 400 }).notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_recovery_addresses_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_nid_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_addresses_status_via_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('text_ops')), + uniqueIndex('identity_recovery_addresses_status_via_uq_idx').using('btree', table.nid.asc().nullsLast().op('text_ops'), table.via.asc().nullsLast().op('text_ops'), table.value.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_addresses_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_addresses_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityVerificationTokens = pgTable('identity_verification_tokens', { + id: uuid().primaryKey().notNull(), + token: varchar({ length: 64 }).notNull(), + used: boolean().default(false).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).notNull(), + identityVerifiableAddressId: uuid('identity_verifiable_address_id').notNull(), + selfserviceVerificationFlowId: uuid('selfservice_verification_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid(), +}, (table) => [ + index('identity_verification_tokens_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_token_nid_used_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.token.asc().nullsLast().op('bool_ops'), table.used.asc().nullsLast().op('text_ops'), table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + uniqueIndex('identity_verification_tokens_token_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + index('identity_verification_tokens_verifiable_address_id_idx').using('btree', table.identityVerifiableAddressId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_tokens_verification_flow_id_idx').using('btree', table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityVerifiableAddressId], + foreignColumns: [identityVerifiableAddresses.id], + name: 'identity_verification_tokens_identity_verifiable_address_i_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceVerificationFlowId], + foreignColumns: [selfserviceVerificationFlows.id], + name: 'identity_verification_tokens_selfservice_verification_flow_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verification_tokens_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const selfserviceRecoveryFlows = pgTable('selfservice_recovery_flows', { + id: uuid().primaryKey().notNull(), + requestUrl: text('request_url').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).notNull(), + activeMethod: varchar('active_method', { length: 32 }), + csrfToken: varchar('csrf_token', { length: 255 }).notNull(), + state: varchar({ length: 32 }).notNull(), + recoveredIdentityId: uuid('recovered_identity_id'), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + type: varchar({ length: 16 }).default('browser').notNull(), + ui: jsonb(), + nid: uuid(), + submitCount: integer('submit_count').default(0).notNull(), + skipCsrfCheck: boolean('skip_csrf_check').default(false).notNull(), +}, (table) => [ + index('selfservice_recovery_flows_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('selfservice_recovery_flows_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('selfservice_recovery_flows_recovered_identity_id_nid_idx').using('btree', table.recoveredIdentityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.recoveredIdentityId], + foreignColumns: [identities.id], + name: 'selfservice_recovery_requests_recovered_identity_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'selfservice_recovery_flows_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRecoveryTokens = pgTable('identity_recovery_tokens', { + id: uuid().primaryKey().notNull(), + token: varchar({ length: 64 }).notNull(), + used: boolean().default(false).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityRecoveryAddressId: uuid('identity_recovery_address_id'), + selfserviceRecoveryFlowId: uuid('selfservice_recovery_flow_id'), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + nid: uuid(), + identityId: uuid('identity_id').notNull(), + tokenType: integer('token_type').default(0).notNull(), +}, (table) => [ + uniqueIndex('identity_recovery_addresses_code_uq_idx').using('btree', table.token.asc().nullsLast().op('text_ops')), + index('identity_recovery_tokens_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_identity_recovery_address_id_idx').using('btree', table.identityRecoveryAddressId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_nid_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.id.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_selfservice_recovery_flow_id_idx').using('btree', table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_tokens_token_nid_used_idx').using('btree', table.nid.asc().nullsLast().op('bool_ops'), table.token.asc().nullsLast().op('text_ops'), table.used.asc().nullsLast().op('bool_ops')), + foreignKey({ + columns: [table.selfserviceRecoveryFlowId], + foreignColumns: [selfserviceRecoveryFlows.id], + name: 'identity_recovery_tokens_selfservice_recovery_request_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_tokens_nid_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityRecoveryAddressId], + foreignColumns: [identityRecoveryAddresses.id], + name: 'identity_recovery_tokens_identity_recovery_address_id_fkey', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_tokens_identity_id_fk_idx', + }).onUpdate('restrict').onDelete('cascade'), + check('identity_recovery_tokens_token_type_ck', sql`(token_type = 1) + OR (token_type = 2)`), +]); + +export const identityRecoveryCodes = pgTable('identity_recovery_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityRecoveryAddressId: uuid('identity_recovery_address_id'), + codeType: integer('code_type').notNull(), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceRecoveryFlowId: uuid('selfservice_recovery_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid().notNull(), + identityId: uuid('identity_id').notNull(), +}, (table) => [ + index('identity_recovery_codes_flow_id_idx').using('btree', table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_identity_id_nid_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_identity_recovery_address_id_nid_idx').using('btree', table.identityRecoveryAddressId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_recovery_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceRecoveryFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityRecoveryAddressId], + foreignColumns: [identityRecoveryAddresses.id], + name: 'identity_recovery_codes_identity_recovery_addresses_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceRecoveryFlowId], + foreignColumns: [selfserviceRecoveryFlows.id], + name: 'identity_recovery_codes_selfservice_recovery_flows_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_recovery_codes_identity_id_fk', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_recovery_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const sessionDevices = pgTable('session_devices', { + id: uuid().primaryKey().notNull(), + ipAddress: varchar('ip_address', { length: 50 }).default(''), + userAgent: varchar('user_agent', { length: 512 }).default(''), + location: varchar({ length: 512 }).default(''), + nid: uuid().notNull(), + sessionId: uuid('session_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}, (table) => [ + index('session_devices_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('session_devices_session_id_nid_idx').using('btree', table.sessionId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.sessionId], + foreignColumns: [sessions.id], + name: 'session_metadata_sessions_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'session_metadata_nid_fk', + }).onDelete('cascade'), + unique('unique_session_device').on(table.ipAddress, table.userAgent, table.nid, table.sessionId), +]); + +export const identityVerificationCodes = pgTable('identity_verification_codes', { + id: uuid().primaryKey().notNull(), + codeHmac: varchar('code_hmac', { length: 64 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + identityVerifiableAddressId: uuid('identity_verifiable_address_id'), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceVerificationFlowId: uuid('selfservice_verification_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_verification_codes_flow_id_idx').using('btree', table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceVerificationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_verification_codes_verifiable_address_nid_idx').using('btree', table.identityVerifiableAddressId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.identityVerifiableAddressId], + foreignColumns: [identityVerifiableAddresses.id], + name: 'identity_verification_codes_identity_verifiable_addresses_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.selfserviceVerificationFlowId], + foreignColumns: [selfserviceVerificationFlows.id], + name: 'identity_verification_codes_selfservice_verification_flows_id_f', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_verification_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const courierMessageDispatches = pgTable('courier_message_dispatches', { + id: uuid().primaryKey().notNull(), + messageId: uuid('message_id').notNull(), + status: varchar({ length: 7 }).notNull(), + error: json(), + nid: uuid().notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), +}, (table) => [ + index('courier_message_dispatches_message_id_idx').using('btree', table.messageId.asc().nullsLast().op('timestamp_ops'), table.createdAt.desc().nullsFirst().op('timestamp_ops')), + index('courier_message_dispatches_nid_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.messageId], + foreignColumns: [courierMessages.id], + name: 'courier_message_dispatches_message_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'courier_message_dispatches_nid_fk', + }).onDelete('cascade'), +]); + +export const sessionTokenExchanges = pgTable('session_token_exchanges', { + id: uuid().primaryKey().notNull(), + nid: uuid().notNull(), + flowId: uuid('flow_id').notNull(), + sessionId: uuid('session_id'), + initCode: varchar('init_code', { length: 64 }).notNull(), + returnToCode: varchar('return_to_code', { length: 64 }).notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).notNull(), +}, (table) => [ + index('session_token_exchanges_nid_code_idx').using('btree', table.initCode.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('text_ops')), + index('session_token_exchanges_nid_flow_id_idx').using('btree', table.flowId.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), +]); + +export const identityLoginCodes = pgTable('identity_login_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + address: varchar({ length: 255 }).notNull(), + addressType: char('address_type', { length: 36 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceLoginFlowId: uuid('selfservice_login_flow_id').notNull(), + identityId: uuid('identity_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_login_codes_flow_id_idx').using('btree', table.selfserviceLoginFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_identity_id_idx').using('btree', table.identityId.asc().nullsLast().op('uuid_ops')), + index('identity_login_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceLoginFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.selfserviceLoginFlowId], + foreignColumns: [selfserviceLoginFlows.id], + name: 'identity_login_codes_selfservice_login_flows_id_fk', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_login_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), + foreignKey({ + columns: [table.identityId], + foreignColumns: [identities.id], + name: 'identity_login_codes_identity_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); + +export const identityRegistrationCodes = pgTable('identity_registration_codes', { + id: uuid().primaryKey().notNull(), + code: varchar({ length: 64 }).notNull(), + address: varchar({ length: 255 }).notNull(), + addressType: char('address_type', { length: 36 }).notNull(), + usedAt: timestamp('used_at', { mode: 'string' }), + expiresAt: timestamp('expires_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + issuedAt: timestamp('issued_at', { mode: 'string' }).default('2000-01-01 00:00:00').notNull(), + selfserviceRegistrationFlowId: uuid('selfservice_registration_flow_id').notNull(), + createdAt: timestamp('created_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + updatedAt: timestamp('updated_at', { mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(), + nid: uuid().notNull(), +}, (table) => [ + index('identity_registration_codes_flow_id_idx').using('btree', table.selfserviceRegistrationFlowId.asc().nullsLast().op('uuid_ops')), + index('identity_registration_codes_id_nid_idx').using('btree', table.id.asc().nullsLast().op('uuid_ops'), table.nid.asc().nullsLast().op('uuid_ops')), + index('identity_registration_codes_nid_flow_id_idx').using('btree', table.nid.asc().nullsLast().op('uuid_ops'), table.selfserviceRegistrationFlowId.asc().nullsLast().op('uuid_ops')), + foreignKey({ + columns: [table.selfserviceRegistrationFlowId], + foreignColumns: [selfserviceRegistrationFlows.id], + name: 'identity_registration_codes_selfservice_registration_flows_id_f', + }).onDelete('cascade'), + foreignKey({ + columns: [table.nid], + foreignColumns: [networks.id], + name: 'identity_registration_codes_networks_id_fk', + }).onUpdate('restrict').onDelete('cascade'), +]); From 8aa942be2d4c7f1b8bfa9cd7a0753cceaa1b8fd2 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:20:02 +0100 Subject: [PATCH 04/14] NORY-41: add database url to dashboard's .env.example --- dashboard/.env.example | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dashboard/.env.example b/dashboard/.env.example index 0890e33..fbb1831 100644 --- a/dashboard/.env.example +++ b/dashboard/.env.example @@ -1,4 +1,6 @@ +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/kratos + ORY_KRATOS_ADMIN_URL=http://localhost:4434 ORY_HYDRA_ADMIN_URL=http://localhost:4445 From 21dbd4cb05808015dde9ac3dcbf59102b0cd727b Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:52:05 +0100 Subject: [PATCH 05/14] NORY-41: implement drizzle query function --- dashboard/src/lib/action/identity.ts | 39 +++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/dashboard/src/lib/action/identity.ts b/dashboard/src/lib/action/identity.ts index 7497f3c..9e1054c 100644 --- a/dashboard/src/lib/action/identity.ts +++ b/dashboard/src/lib/action/identity.ts @@ -2,7 +2,44 @@ import { getIdentityApi } from '@/ory/sdk/server'; import { revalidatePath } from 'next/cache'; -import { DeleteIdentityCredentialsTypeEnum, UpdateIdentityBody } from '@ory/client'; +import { + DeleteIdentityCredentialsTypeEnum, + Identity, + RecoveryIdentityAddress, + UpdateIdentityBody, + VerifiableIdentityAddress, +} from '@ory/client'; +import { getDB } from '@/db'; +import { identities, identityRecoveryAddresses, identityVerifiableAddresses } from '@/db/schema'; +import { eq, ilike, or, sql } from 'drizzle-orm'; + +interface QueryIdentitiesProps { + page: number, + pageSize?: number, + query?: string, +} + +export async function queryIdentities({ page, pageSize, query }: QueryIdentitiesProps) { + + const db = await getDB(); + const results = await db.select() + .from(identities) + .leftJoin(identityVerifiableAddresses, eq(identities.id, identityVerifiableAddresses.identityId)) + .leftJoin(identityRecoveryAddresses, eq(identities.id, identityRecoveryAddresses.identityId)) + .where(or( + sql`${identities.traits}::text ILIKE + ${`%${query}%`}`, + ilike(identityVerifiableAddresses.value, `%${query}%`), + )); + + return results.map((it) => { + const typed = it.identities as unknown as Identity; + typed.verifiable_addresses = [it.identity_verifiable_addresses] as unknown as VerifiableIdentityAddress[]; + typed.recovery_addresses = [it.identity_verifiable_addresses] as unknown as RecoveryIdentityAddress[]; + return typed; + }); +} + interface UpdatedIdentityProps { id: string; From 7df37e400188a3e66e096ac5d3764196b1b8f774 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:53:08 +0100 Subject: [PATCH 06/14] NORY-41: apply new query and temporarily remove pagination --- .../src/app/(inside)/user/data-table.tsx | 97 +++++-------------- dashboard/src/app/(inside)/user/page.tsx | 57 ++--------- 2 files changed, 29 insertions(+), 125 deletions(-) diff --git a/dashboard/src/app/(inside)/user/data-table.tsx b/dashboard/src/app/(inside)/user/data-table.tsx index 8f4e3ac..510ee6c 100644 --- a/dashboard/src/app/(inside)/user/data-table.tsx +++ b/dashboard/src/app/(inside)/user/data-table.tsx @@ -4,9 +4,7 @@ import { ColumnDef } from '@tanstack/react-table'; import { Identity } from '@ory/client'; import { DataTable } from '@/components/ui/data-table'; import { CircleCheck, CircleX, Copy, MoreHorizontal, Trash, UserCheck, UserMinus, UserPen, UserX } from 'lucide-react'; -import React, { useEffect, useRef, useState } from 'react'; -import { FetchIdentityPageProps } from '@/app/(inside)/user/page'; -import { Spinner } from '@/components/ui/spinner'; +import React, { useEffect, useState } from 'react'; import { DropdownMenu, DropdownMenuContent, @@ -33,13 +31,11 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip interface IdentityDataTableProps { data: Identity[]; - pageSize: number; - pageToken: string | undefined; + page: number; query: string; - fetchIdentityPage: (props: FetchIdentityPageProps) => Promise<{ data: Identity[], tokens: Map }>; } -export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdentityPage }: IdentityDataTableProps) { +export function IdentityDataTable({ data, page, query }: IdentityDataTableProps) { const columns: ColumnDef[] = [ { @@ -81,27 +77,24 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent return (

{email.value} - { - email.verified ? - - - - - - This email was confirmed at - {new Date(email.verified_at!!).toLocaleString()} - - - : - - - - - - This email is not confirmed yet - - - } + + + { + email.verified ? : + } + + + { + email.verified ? + <> + This email was confirmed at + {new Date(email.verified_at!!).toLocaleString()} + + : +

This email is not confirmed yet

+ } +
+
); } @@ -189,49 +182,10 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent ]; const [items, setItems] = useState(data); - const [nextToken, setNextToken] = useState(pageToken); - // react on changes from ssr (query params) useEffect(() => { setItems(data); - setNextToken(pageToken); - }, [data, pageSize, pageToken, query]); - - // infinite scroll handling - const infiniteScrollSensor = useRef(null); - useEffect(() => { - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting) { - fetchMore(); - } - }, - { threshold: 0.5 }, // Adjust threshold as needed - ); - - if (infiniteScrollSensor.current) { - observer.observe(infiniteScrollSensor.current); - } - - return () => { - if (infiniteScrollSensor.current) { - observer.unobserve(infiniteScrollSensor.current); - } - }; - }, [items]); - - const fetchMore = async () => { - if (!nextToken) return; - - const response = await fetchIdentityPage({ - pageSize: pageSize, - pageToken: nextToken, - query: query, - }); - - setItems([...items, ...response.data]); - setNextToken(response.tokens.get('next') ?? undefined); - }; + }, [data]); // quick actions const [currentIdentity, setCurrentIdentity] = useState(undefined); @@ -341,13 +295,6 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent ) } - { - nextToken && ( -
- -
- ) - } ); } diff --git a/dashboard/src/app/(inside)/user/page.tsx b/dashboard/src/app/(inside)/user/page.tsx index f02c636..c1acd7e 100644 --- a/dashboard/src/app/(inside)/user/page.tsx +++ b/dashboard/src/app/(inside)/user/page.tsx @@ -1,49 +1,7 @@ import React from 'react'; import { IdentityDataTable } from '@/app/(inside)/user/data-table'; -import { getIdentityApi } from '@/ory/sdk/server'; import { SearchInput } from '@/components/search-input'; - -export interface FetchIdentityPageProps { - pageSize: number; - pageToken: string; - query: string; -} - -async function fetchIdentityPage({ pageSize, pageToken, query }: FetchIdentityPageProps) { - 'use server'; - - const identityApi = await getIdentityApi(); - const response = await identityApi.listIdentities({ - pageSize: pageSize, - pageToken: pageToken, - previewCredentialsIdentifierSimilar: query, - }); - - return { - data: response.data, - tokens: parseTokens(response.headers.link), - }; -} - -function parseTokens(link: string) { - - const parsed = link.split(',').map((it) => { - const startRel = it.lastIndexOf('rel="'); - const endRel = it.lastIndexOf('"'); - const rel = it.slice(startRel, endRel); - - const startToken = it.lastIndexOf('page_token='); - const endToken = it.lastIndexOf('&'); - const token = it.slice(startToken, endToken); - - return [rel, token]; - }); - - return new Map(parsed.map(obj => [ - obj[0].replace('rel="', ''), - obj[1].replace('page_token=', ''), - ])); -} +import { queryIdentities } from '@/lib/action/identity'; export default async function UserPage( { @@ -54,12 +12,13 @@ export default async function UserPage( ) { const params = await searchParams; + + const page = params.page ? Number(params.page) : 1; const query = params.query ? params.query as string : ''; let pageSize = 250; - let pageToken: string = '00000000-0000-0000-0000-000000000000'; - const initialFetch = await fetchIdentityPage({ pageSize, pageToken, query: query }); + const initialData = await queryIdentities({ page, pageSize, query }); return (
@@ -72,11 +31,9 @@ export default async function UserPage(
+ data={initialData} + page={page} + query={query}/>
); From 19e68b89297a50ed2faf98f2427271a33bdaa4aa Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 11:02:25 +0100 Subject: [PATCH 07/14] NORY-41: add shadcn-ui pagination component --- dashboard/bun.lockb | Bin 269452 -> 270420 bytes dashboard/package.json | 2 +- dashboard/src/components/ui/pagination.tsx | 117 +++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 dashboard/src/components/ui/pagination.tsx diff --git a/dashboard/bun.lockb b/dashboard/bun.lockb index 5fcc46ea3c3bd8011de21e746ae83543666ec38c..457965a40f7a0aaced242625b14554add2363733 100755 GIT binary patch delta 28554 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

4X*IjQ en{j0G2c8r18!VDx@IUp$gxzXwan{@A&Ho4d+D<(H delta 28078 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 K6@&fVzW+aiLeJ3v diff --git a/dashboard/package.json b/dashboard/package.json index 11080c0..9641b8b 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -20,7 +20,7 @@ "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-separator": "^1.1.0", - "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.4", "@serwist/next": "^9.0.0-preview.21", diff --git a/dashboard/src/components/ui/pagination.tsx b/dashboard/src/components/ui/pagination.tsx new file mode 100644 index 0000000..db9b2d6 --- /dev/null +++ b/dashboard/src/components/ui/pagination.tsx @@ -0,0 +1,117 @@ +import * as React from 'react'; +import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'; + +import { cn } from '@/lib/utils'; +import { ButtonProps, buttonVariants } from '@/components/ui/button'; + +const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( +