From ec190413107a217e782990980ad3749b457c03fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 14:36:04 +0200 Subject: [PATCH 01/34] docs(billing): specify Apple credit purchases --- .specs/kiloclaw-billing.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.specs/kiloclaw-billing.md b/.specs/kiloclaw-billing.md index 400338a073..dd19abffca 100644 --- a/.specs/kiloclaw-billing.md +++ b/.specs/kiloclaw-billing.md @@ -424,6 +424,35 @@ rules resolve conflicts. date six calendar months from enrollment, consistent with Commit Plan Lifecycle rule 2. +### Apple In-App Credit Purchases + +1. The system MAY allow iOS users to purchase personal credits through + Apple in-app purchases. Apple in-app purchases are a credit + acquisition mechanism only; they MUST NOT create Apple-funded + KiloClaw subscription rows. +2. Apple in-app credit purchases MUST be personal-only. They MUST NOT + credit an organization balance. +3. Apple in-app credit products MUST be server-allowlisted by product + ID. The backend MUST determine the credited amount from server + configuration, not from client-provided price or product data. +4. The backend MUST verify Apple-signed transaction data before + granting credits. A transaction with the wrong bundle ID, + environment, product ID, owning account, or revocation state MUST + NOT grant credits. +5. Each Apple transaction MUST grant credits at most once. Replays of + an already-granted transaction MUST return an idempotent success + for the owning user and MUST NOT create duplicate credit + transactions. +6. Apple refund or revocation events MUST append a negative paid credit + transaction for the full credited amount and decrement acquired + credits by the same amount. The user's computed balance MAY become + negative. +7. Apple-purchased credits MUST NOT receive first-top-up or + promotional bonus grants in the initial Apple IAP implementation. +8. User-facing purchase UI MUST describe the credits granted and MUST + NOT describe store commission, provider deductions, or internal + pricing math. + ### Kilo Pass Upsell Checkout Kilo Pass is the RECOMMENDED checkout path for KiloClaw hosting. The From 348bf025baae6dfa96029ebe6a1a910dadafe7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:01:54 +0200 Subject: [PATCH 02/34] feat(db): add Apple IAP purchase tables --- .../src/migrations/0115_amazing_scrambler.sql | 50 + .../db/src/migrations/meta/0115_snapshot.json | 19144 ++++++++++++++++ packages/db/src/migrations/meta/_journal.json | 7 + packages/db/src/schema.test.ts | 5 + packages/db/src/schema.ts | 89 + 5 files changed, 19295 insertions(+) create mode 100644 packages/db/src/migrations/0115_amazing_scrambler.sql create mode 100644 packages/db/src/migrations/meta/0115_snapshot.json diff --git a/packages/db/src/migrations/0115_amazing_scrambler.sql b/packages/db/src/migrations/0115_amazing_scrambler.sql new file mode 100644 index 0000000000..5d33103df6 --- /dev/null +++ b/packages/db/src/migrations/0115_amazing_scrambler.sql @@ -0,0 +1,50 @@ +CREATE TABLE "apple_iap_notifications" ( + "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, + "notification_uuid" text NOT NULL, + "notification_type" text NOT NULL, + "subtype" text, + "environment" text NOT NULL, + "apple_transaction_id" text, + "apple_original_transaction_id" text, + "signed_payload_jws" text NOT NULL, + "processed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "apple_iap_notifications_environment_check" CHECK ("apple_iap_notifications"."environment" IN ('Sandbox', 'Production')) +); +--> statement-breakpoint +CREATE TABLE "apple_iap_purchases" ( + "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, + "kilo_user_id" text NOT NULL, + "apple_transaction_id" text NOT NULL, + "apple_original_transaction_id" text NOT NULL, + "apple_web_order_line_item_id" text, + "product_id" text NOT NULL, + "environment" text NOT NULL, + "bundle_id" text NOT NULL, + "purchase_date" timestamp with time zone NOT NULL, + "gross_price_cents" integer NOT NULL, + "credited_cents" integer NOT NULL, + "credited_microdollars" bigint NOT NULL, + "signed_transaction_jws" text NOT NULL, + "status" text NOT NULL, + "credit_transaction_id" uuid NOT NULL, + "refunded_at" timestamp with time zone, + "refund_credit_transaction_id" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "apple_iap_purchases_status_check" CHECK ("apple_iap_purchases"."status" IN ('granted', 'refunded', 'revoked')), + CONSTRAINT "apple_iap_purchases_environment_check" CHECK ("apple_iap_purchases"."environment" IN ('Sandbox', 'Production')), + CONSTRAINT "apple_iap_purchases_credited_positive_check" CHECK ("apple_iap_purchases"."credited_cents" > 0) +); +--> statement-breakpoint +ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk" FOREIGN KEY ("kilo_user_id") REFERENCES "public"."kilocode_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk" FOREIGN KEY ("credit_transaction_id") REFERENCES "public"."credit_transactions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk" FOREIGN KEY ("refund_credit_transaction_id") REFERENCES "public"."credit_transactions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_apple_iap_notifications_uuid" ON "apple_iap_notifications" USING btree ("notification_uuid");--> statement-breakpoint +CREATE INDEX "IDX_apple_iap_notifications_transaction_id" ON "apple_iap_notifications" USING btree ("apple_transaction_id");--> statement-breakpoint +CREATE INDEX "IDX_apple_iap_notifications_original_transaction_id" ON "apple_iap_notifications" USING btree ("apple_original_transaction_id");--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_apple_iap_purchases_transaction_id" ON "apple_iap_purchases" USING btree ("apple_transaction_id");--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_apple_iap_purchases_credit_transaction_id" ON "apple_iap_purchases" USING btree ("credit_transaction_id");--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_apple_iap_purchases_refund_credit_transaction_id" ON "apple_iap_purchases" USING btree ("refund_credit_transaction_id") WHERE "apple_iap_purchases"."refund_credit_transaction_id" is not null;--> statement-breakpoint +CREATE INDEX "IDX_apple_iap_purchases_user_id" ON "apple_iap_purchases" USING btree ("kilo_user_id");--> statement-breakpoint +CREATE INDEX "IDX_apple_iap_purchases_original_transaction_id" ON "apple_iap_purchases" USING btree ("apple_original_transaction_id"); \ No newline at end of file diff --git a/packages/db/src/migrations/meta/0115_snapshot.json b/packages/db/src/migrations/meta/0115_snapshot.json new file mode 100644 index 0000000000..5407eb7de1 --- /dev/null +++ b/packages/db/src/migrations/meta/0115_snapshot.json @@ -0,0 +1,19144 @@ +{ + "id": "41340d66-6132-4f01-b848-ea197b8dc15b", + "prevId": "cd0d7b9b-c7a1-41d2-a29e-b62696cba715", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.agent_configs": { + "name": "agent_configs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agent_type": { + "name": "agent_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "runtime_state": { + "name": "runtime_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_configs_org_id": { + "name": "IDX_agent_configs_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_owned_by_user_id": { + "name": "IDX_agent_configs_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_agent_type": { + "name": "IDX_agent_configs_agent_type", + "columns": [ + { + "expression": "agent_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_platform": { + "name": "IDX_agent_configs_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_configs_owned_by_organization_id_organizations_id_fk": { + "name": "agent_configs_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_configs", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_configs_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_configs_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_configs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_configs_org_agent_platform": { + "name": "UQ_agent_configs_org_agent_platform", + "nullsNotDistinct": false, + "columns": [ + "owned_by_organization_id", + "agent_type", + "platform" + ] + }, + "UQ_agent_configs_user_agent_platform": { + "name": "UQ_agent_configs_user_agent_platform", + "nullsNotDistinct": false, + "columns": [ + "owned_by_user_id", + "agent_type", + "platform" + ] + } + }, + "policies": {}, + "checkConstraints": { + "agent_configs_owner_check": { + "name": "agent_configs_owner_check", + "value": "(\n (\"agent_configs\".\"owned_by_user_id\" IS NOT NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_configs\".\"owned_by_user_id\" IS NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "agent_configs_agent_type_check": { + "name": "agent_configs_agent_type_check", + "value": "\"agent_configs\".\"agent_type\" IN ('code_review', 'auto_triage', 'auto_fix', 'security_scan')" + } + }, + "isRLSEnabled": false + }, + "public.agent_environment_profile_commands": { + "name": "agent_environment_profile_commands", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_env_profile_commands_profile_id": { + "name": "IDX_agent_env_profile_commands_profile_id", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_commands", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_env_profile_commands_profile_sequence": { + "name": "UQ_agent_env_profile_commands_profile_sequence", + "nullsNotDistinct": false, + "columns": [ + "profile_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_environment_profile_repo_bindings": { + "name": "agent_environment_profile_repo_bindings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_agent_env_profile_repo_bindings_user": { + "name": "UQ_agent_env_profile_repo_bindings_user", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profile_repo_bindings_org": { + "name": "UQ_agent_env_profile_repo_bindings_org", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk": { + "name": "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "agent_env_profile_repo_bindings_owner_check": { + "name": "agent_env_profile_repo_bindings_owner_check", + "value": "(\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.agent_environment_profile_vars": { + "name": "agent_environment_profile_vars", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_secret": { + "name": "is_secret", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_env_profile_vars_profile_id": { + "name": "IDX_agent_env_profile_vars_profile_id", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_vars", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_env_profile_vars_profile_key": { + "name": "UQ_agent_env_profile_vars_profile_key", + "nullsNotDistinct": false, + "columns": [ + "profile_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_environment_profiles": { + "name": "agent_environment_profiles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_agent_env_profiles_org_name": { + "name": "UQ_agent_env_profiles_org_name", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_user_name": { + "name": "UQ_agent_env_profiles_user_name", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_org_default": { + "name": "UQ_agent_env_profiles_org_default", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_user_default": { + "name": "UQ_agent_env_profiles_user_default", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_env_profiles_org_id": { + "name": "IDX_agent_env_profiles_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_env_profiles_user_id": { + "name": "IDX_agent_env_profiles_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profiles_owned_by_organization_id_organizations_id_fk": { + "name": "agent_environment_profiles_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_environment_profiles", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_environment_profiles", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "agent_env_profiles_owner_check": { + "name": "agent_env_profiles_owner_check", + "value": "(\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.api_kind": { + "name": "api_kind", + "schema": "", + "columns": { + "api_kind_id": { + "name": "api_kind_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "api_kind": { + "name": "api_kind", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_api_kind": { + "name": "UQ_api_kind", + "columns": [ + { + "expression": "api_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.api_request_log": { + "name": "api_request_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "request": { + "name": "request", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "response": { + "name": "response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_api_request_log_created_at": { + "name": "idx_api_request_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_feedback": { + "name": "app_builder_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preview_status": { + "name": "preview_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_streaming": { + "name": "is_streaming", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recent_messages": { + "name": "recent_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_app_builder_feedback_created_at": { + "name": "IDX_app_builder_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_feedback_kilo_user_id": { + "name": "IDX_app_builder_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_feedback_project_id": { + "name": "IDX_app_builder_feedback_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "app_builder_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "app_builder_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "app_builder_feedback_project_id_app_builder_projects_id_fk": { + "name": "app_builder_feedback_project_id_app_builder_projects_id_fk", + "tableFrom": "app_builder_feedback", + "tableTo": "app_builder_projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_project_sessions": { + "name": "app_builder_project_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "worker_version": { + "name": "worker_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'v2'" + } + }, + "indexes": { + "IDX_app_builder_project_sessions_project_id": { + "name": "IDX_app_builder_project_sessions_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_project_sessions_project_id_app_builder_projects_id_fk": { + "name": "app_builder_project_sessions_project_id_app_builder_projects_id_fk", + "tableFrom": "app_builder_project_sessions", + "tableTo": "app_builder_projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_app_builder_project_sessions_cloud_agent_session_id": { + "name": "UQ_app_builder_project_sessions_cloud_agent_session_id", + "nullsNotDistinct": false, + "columns": [ + "cloud_agent_session_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_projects": { + "name": "app_builder_projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template": { + "name": "template", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "git_repo_full_name": { + "name": "git_repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_platform_integration_id": { + "name": "git_platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "migrated_at": { + "name": "migrated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_app_builder_projects_created_by_user_id": { + "name": "IDX_app_builder_projects_created_by_user_id", + "columns": [ + { + "expression": "created_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_owned_by_user_id": { + "name": "IDX_app_builder_projects_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_owned_by_organization_id": { + "name": "IDX_app_builder_projects_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_created_at": { + "name": "IDX_app_builder_projects_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_last_message_at": { + "name": "IDX_app_builder_projects_last_message_at", + "columns": [ + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_projects_owned_by_user_id_kilocode_users_id_fk": { + "name": "app_builder_projects_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "app_builder_projects_owned_by_organization_id_organizations_id_fk": { + "name": "app_builder_projects_owned_by_organization_id_organizations_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "app_builder_projects_deployment_id_deployments_id_fk": { + "name": "app_builder_projects_deployment_id_deployments_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk": { + "name": "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "platform_integrations", + "columnsFrom": [ + "git_platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "app_builder_projects_owner_check": { + "name": "app_builder_projects_owner_check", + "value": "(\n (\"app_builder_projects\".\"owned_by_user_id\" IS NOT NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NULL) OR\n (\"app_builder_projects\".\"owned_by_user_id\" IS NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.app_min_versions": { + "name": "app_min_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "ios_min_version": { + "name": "ios_min_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'1.0.0'" + }, + "android_min_version": { + "name": "android_min_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'1.0.0'" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_reported_messages": { + "name": "app_reported_messages", + "schema": "", + "columns": { + "report_id": { + "name": "report_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "report_type": { + "name": "report_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signature": { + "name": "signature", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "app_reported_messages_cli_session_id_cli_sessions_session_id_fk": { + "name": "app_reported_messages_cli_session_id_cli_sessions_session_id_fk", + "tableFrom": "app_reported_messages", + "tableTo": "cli_sessions", + "columnsFrom": [ + "cli_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apple_iap_notifications": { + "name": "apple_iap_notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "notification_uuid": { + "name": "notification_uuid", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notification_type": { + "name": "notification_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subtype": { + "name": "subtype", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "environment": { + "name": "environment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apple_transaction_id": { + "name": "apple_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "apple_original_transaction_id": { + "name": "apple_original_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signed_payload_jws": { + "name": "signed_payload_jws", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_apple_iap_notifications_uuid": { + "name": "UQ_apple_iap_notifications_uuid", + "columns": [ + { + "expression": "notification_uuid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_apple_iap_notifications_transaction_id": { + "name": "IDX_apple_iap_notifications_transaction_id", + "columns": [ + { + "expression": "apple_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_apple_iap_notifications_original_transaction_id": { + "name": "IDX_apple_iap_notifications_original_transaction_id", + "columns": [ + { + "expression": "apple_original_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "apple_iap_notifications_environment_check": { + "name": "apple_iap_notifications_environment_check", + "value": "\"apple_iap_notifications\".\"environment\" IN ('Sandbox', 'Production')" + } + }, + "isRLSEnabled": false + }, + "public.apple_iap_purchases": { + "name": "apple_iap_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apple_transaction_id": { + "name": "apple_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apple_original_transaction_id": { + "name": "apple_original_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apple_web_order_line_item_id": { + "name": "apple_web_order_line_item_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_id": { + "name": "product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment": { + "name": "environment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bundle_id": { + "name": "bundle_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "purchase_date": { + "name": "purchase_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "gross_price_cents": { + "name": "gross_price_cents", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credited_cents": { + "name": "credited_cents", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credited_microdollars": { + "name": "credited_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "signed_transaction_jws": { + "name": "signed_transaction_jws", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credit_transaction_id": { + "name": "credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "refunded_at": { + "name": "refunded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refund_credit_transaction_id": { + "name": "refund_credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_apple_iap_purchases_transaction_id": { + "name": "UQ_apple_iap_purchases_transaction_id", + "columns": [ + { + "expression": "apple_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_apple_iap_purchases_credit_transaction_id": { + "name": "UQ_apple_iap_purchases_credit_transaction_id", + "columns": [ + { + "expression": "credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_apple_iap_purchases_refund_credit_transaction_id": { + "name": "UQ_apple_iap_purchases_refund_credit_transaction_id", + "columns": [ + { + "expression": "refund_credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"apple_iap_purchases\".\"refund_credit_transaction_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_apple_iap_purchases_user_id": { + "name": "IDX_apple_iap_purchases_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_apple_iap_purchases_original_transaction_id": { + "name": "IDX_apple_iap_purchases_original_transaction_id", + "columns": [ + { + "expression": "apple_original_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk": { + "name": "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "apple_iap_purchases", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk": { + "name": "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "apple_iap_purchases", + "tableTo": "credit_transactions", + "columnsFrom": [ + "credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk": { + "name": "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "apple_iap_purchases", + "tableTo": "credit_transactions", + "columnsFrom": [ + "refund_credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "apple_iap_purchases_status_check": { + "name": "apple_iap_purchases_status_check", + "value": "\"apple_iap_purchases\".\"status\" IN ('granted', 'refunded', 'revoked')" + }, + "apple_iap_purchases_environment_check": { + "name": "apple_iap_purchases_environment_check", + "value": "\"apple_iap_purchases\".\"environment\" IN ('Sandbox', 'Production')" + }, + "apple_iap_purchases_credited_positive_check": { + "name": "apple_iap_purchases_credited_positive_check", + "value": "\"apple_iap_purchases\".\"credited_cents\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.auto_fix_tickets": { + "name": "auto_fix_tickets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "triage_ticket_id": { + "name": "triage_ticket_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_number": { + "name": "issue_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "issue_url": { + "name": "issue_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_title": { + "name": "issue_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_body": { + "name": "issue_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issue_author": { + "name": "issue_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_labels": { + "name": "issue_labels", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "trigger_source": { + "name": "trigger_source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'label'" + }, + "review_comment_id": { + "name": "review_comment_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "review_comment_body": { + "name": "review_comment_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "line_number": { + "name": "line_number", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "diff_hunk": { + "name": "diff_hunk", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pr_head_ref": { + "name": "pr_head_ref", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "classification": { + "name": "classification", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confidence": { + "name": "confidence", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "intent_summary": { + "name": "intent_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_files": { + "name": "related_files", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "pr_number": { + "name": "pr_number", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "pr_url": { + "name": "pr_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pr_branch": { + "name": "pr_branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_fix_tickets_repo_issue": { + "name": "UQ_auto_fix_tickets_repo_issue", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "issue_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_fix_tickets\".\"trigger_source\" = 'label'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_auto_fix_tickets_repo_review_comment": { + "name": "UQ_auto_fix_tickets_repo_review_comment", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "review_comment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_fix_tickets\".\"review_comment_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_owned_by_org": { + "name": "IDX_auto_fix_tickets_owned_by_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_owned_by_user": { + "name": "IDX_auto_fix_tickets_owned_by_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_status": { + "name": "IDX_auto_fix_tickets_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_created_at": { + "name": "IDX_auto_fix_tickets_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_triage_ticket_id": { + "name": "IDX_auto_fix_tickets_triage_ticket_id", + "columns": [ + { + "expression": "triage_ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_session_id": { + "name": "IDX_auto_fix_tickets_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_fix_tickets_owned_by_organization_id_organizations_id_fk": { + "name": "auto_fix_tickets_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk": { + "name": "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk": { + "name": "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "auto_triage_tickets", + "columnsFrom": [ + "triage_ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk": { + "name": "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "cli_sessions", + "columnsFrom": [ + "cli_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_fix_tickets_owner_check": { + "name": "auto_fix_tickets_owner_check", + "value": "(\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "auto_fix_tickets_status_check": { + "name": "auto_fix_tickets_status_check", + "value": "\"auto_fix_tickets\".\"status\" IN ('pending', 'running', 'completed', 'failed', 'cancelled')" + }, + "auto_fix_tickets_classification_check": { + "name": "auto_fix_tickets_classification_check", + "value": "\"auto_fix_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'unclear')" + }, + "auto_fix_tickets_confidence_check": { + "name": "auto_fix_tickets_confidence_check", + "value": "\"auto_fix_tickets\".\"confidence\" >= 0 AND \"auto_fix_tickets\".\"confidence\" <= 1" + }, + "auto_fix_tickets_trigger_source_check": { + "name": "auto_fix_tickets_trigger_source_check", + "value": "\"auto_fix_tickets\".\"trigger_source\" IN ('label', 'review_comment')" + } + }, + "isRLSEnabled": false + }, + "public.auto_model": { + "name": "auto_model", + "schema": "", + "columns": { + "auto_model_id": { + "name": "auto_model_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "auto_model": { + "name": "auto_model", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_auto_model": { + "name": "UQ_auto_model", + "columns": [ + { + "expression": "auto_model", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auto_top_up_configs": { + "name": "auto_top_up_configs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_payment_method_id": { + "name": "stripe_payment_method_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_cents": { + "name": "amount_cents", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5000 + }, + "last_auto_top_up_at": { + "name": "last_auto_top_up_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempt_started_at": { + "name": "attempt_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_top_up_configs_owned_by_user_id": { + "name": "UQ_auto_top_up_configs_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_auto_top_up_configs_owned_by_organization_id": { + "name": "UQ_auto_top_up_configs_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_top_up_configs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "auto_top_up_configs_owned_by_organization_id_organizations_id_fk": { + "name": "auto_top_up_configs_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_top_up_configs", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_top_up_configs_exactly_one_owner": { + "name": "auto_top_up_configs_exactly_one_owner", + "value": "(\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NULL) OR (\"auto_top_up_configs\".\"owned_by_user_id\" IS NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.auto_triage_tickets": { + "name": "auto_triage_tickets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_number": { + "name": "issue_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "issue_url": { + "name": "issue_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_title": { + "name": "issue_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_body": { + "name": "issue_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issue_author": { + "name": "issue_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_type": { + "name": "issue_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_labels": { + "name": "issue_labels", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "classification": { + "name": "classification", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confidence": { + "name": "confidence", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "intent_summary": { + "name": "intent_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_files": { + "name": "related_files", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_duplicate": { + "name": "is_duplicate", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "duplicate_of_ticket_id": { + "name": "duplicate_of_ticket_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "similarity_score": { + "name": "similarity_score", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "qdrant_point_id": { + "name": "qdrant_point_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "should_auto_fix": { + "name": "should_auto_fix", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "action_taken": { + "name": "action_taken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action_metadata": { + "name": "action_metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_triage_tickets_repo_issue": { + "name": "UQ_auto_triage_tickets_repo_issue", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "issue_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owned_by_org": { + "name": "IDX_auto_triage_tickets_owned_by_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owned_by_user": { + "name": "IDX_auto_triage_tickets_owned_by_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_status": { + "name": "IDX_auto_triage_tickets_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_created_at": { + "name": "IDX_auto_triage_tickets_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_qdrant_point_id": { + "name": "IDX_auto_triage_tickets_qdrant_point_id", + "columns": [ + { + "expression": "qdrant_point_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owner_status_created": { + "name": "IDX_auto_triage_tickets_owner_status_created", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_user_status_created": { + "name": "IDX_auto_triage_tickets_user_status_created", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_repo_classification": { + "name": "IDX_auto_triage_tickets_repo_classification", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "classification", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_triage_tickets_owned_by_organization_id_organizations_id_fk": { + "name": "auto_triage_tickets_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk": { + "name": "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk": { + "name": "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "auto_triage_tickets", + "columnsFrom": [ + "duplicate_of_ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_triage_tickets_owner_check": { + "name": "auto_triage_tickets_owner_check", + "value": "(\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "auto_triage_tickets_issue_type_check": { + "name": "auto_triage_tickets_issue_type_check", + "value": "\"auto_triage_tickets\".\"issue_type\" IN ('issue', 'pull_request')" + }, + "auto_triage_tickets_classification_check": { + "name": "auto_triage_tickets_classification_check", + "value": "\"auto_triage_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'duplicate', 'unclear')" + }, + "auto_triage_tickets_confidence_check": { + "name": "auto_triage_tickets_confidence_check", + "value": "\"auto_triage_tickets\".\"confidence\" >= 0 AND \"auto_triage_tickets\".\"confidence\" <= 1" + }, + "auto_triage_tickets_similarity_score_check": { + "name": "auto_triage_tickets_similarity_score_check", + "value": "\"auto_triage_tickets\".\"similarity_score\" >= 0 AND \"auto_triage_tickets\".\"similarity_score\" <= 1" + }, + "auto_triage_tickets_status_check": { + "name": "auto_triage_tickets_status_check", + "value": "\"auto_triage_tickets\".\"status\" IN ('pending', 'analyzing', 'actioned', 'failed', 'skipped')" + }, + "auto_triage_tickets_action_taken_check": { + "name": "auto_triage_tickets_action_taken_check", + "value": "\"auto_triage_tickets\".\"action_taken\" IN ('pr_created', 'comment_posted', 'closed_duplicate', 'needs_clarification')" + } + }, + "isRLSEnabled": false + }, + "public.bot_request_cloud_agent_sessions": { + "name": "bot_request_cloud_agent_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "bot_request_id": { + "name": "bot_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "spawn_group_id": { + "name": "spawn_group_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_session_id": { + "name": "kilo_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "execution_id": { + "name": "execution_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'running'" + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_repo": { + "name": "github_repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlab_project": { + "name": "gitlab_project", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "callback_step": { + "name": "callback_step", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "final_message": { + "name": "final_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "final_message_fetched_at": { + "name": "final_message_fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "final_message_error": { + "name": "final_message_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_at": { + "name": "terminal_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "continuation_started_at": { + "name": "continuation_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_bot_request_cas_cloud_agent_session_id": { + "name": "UQ_bot_request_cas_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id": { + "name": "IDX_bot_request_cas_bot_request_id", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id_spawn_group_id": { + "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "spawn_group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id_spawn_group_id_status": { + "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id_status", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "spawn_group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk": { + "name": "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk", + "tableFrom": "bot_request_cloud_agent_sessions", + "tableTo": "bot_requests", + "columnsFrom": [ + "bot_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bot_requests": { + "name": "bot_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_thread_id": { + "name": "platform_thread_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_message_id": { + "name": "platform_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_message": { + "name": "user_message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_used": { + "name": "model_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "steps": { + "name": "steps", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_time_ms": { + "name": "response_time_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_bot_requests_created_at": { + "name": "IDX_bot_requests_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_created_by": { + "name": "IDX_bot_requests_created_by", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_organization_id": { + "name": "IDX_bot_requests_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_platform_integration_id": { + "name": "IDX_bot_requests_platform_integration_id", + "columns": [ + { + "expression": "platform_integration_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_status": { + "name": "IDX_bot_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "bot_requests_created_by_kilocode_users_id_fk": { + "name": "bot_requests_created_by_kilocode_users_id_fk", + "tableFrom": "bot_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bot_requests_organization_id_organizations_id_fk": { + "name": "bot_requests_organization_id_organizations_id_fk", + "tableFrom": "bot_requests", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bot_requests_platform_integration_id_platform_integrations_id_fk": { + "name": "bot_requests_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "bot_requests", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.byok_api_keys": { + "name": "byok_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_api_key": { + "name": "encrypted_api_key", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "IDX_byok_api_keys_organization_id": { + "name": "IDX_byok_api_keys_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_byok_api_keys_kilo_user_id": { + "name": "IDX_byok_api_keys_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_byok_api_keys_provider_id": { + "name": "IDX_byok_api_keys_provider_id", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "byok_api_keys_organization_id_organizations_id_fk": { + "name": "byok_api_keys_organization_id_organizations_id_fk", + "tableFrom": "byok_api_keys", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "byok_api_keys_kilo_user_id_kilocode_users_id_fk": { + "name": "byok_api_keys_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "byok_api_keys", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_byok_api_keys_org_provider": { + "name": "UQ_byok_api_keys_org_provider", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "provider_id" + ] + }, + "UQ_byok_api_keys_user_provider": { + "name": "UQ_byok_api_keys_user_provider", + "nullsNotDistinct": false, + "columns": [ + "kilo_user_id", + "provider_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "byok_api_keys_owner_check": { + "name": "byok_api_keys_owner_check", + "value": "(\n (\"byok_api_keys\".\"kilo_user_id\" IS NOT NULL AND \"byok_api_keys\".\"organization_id\" IS NULL) OR\n (\"byok_api_keys\".\"kilo_user_id\" IS NULL AND \"byok_api_keys\".\"organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.cli_sessions": { + "name": "cli_sessions", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_on_platform": { + "name": "created_on_platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "api_conversation_history_blob_url": { + "name": "api_conversation_history_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "task_metadata_blob_url": { + "name": "task_metadata_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ui_messages_blob_url": { + "name": "ui_messages_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_state_blob_url": { + "name": "git_state_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_url": { + "name": "git_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "forked_from": { + "name": "forked_from", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "parent_session_id": { + "name": "parent_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "last_mode": { + "name": "last_mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_model": { + "name": "last_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cli_sessions_kilo_user_id": { + "name": "IDX_cli_sessions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_created_at": { + "name": "IDX_cli_sessions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_updated_at": { + "name": "IDX_cli_sessions_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_organization_id": { + "name": "IDX_cli_sessions_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_user_updated": { + "name": "IDX_cli_sessions_user_updated", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cli_sessions_kilo_user_id_kilocode_users_id_fk": { + "name": "cli_sessions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "cli_sessions_forked_from_cli_sessions_session_id_fk": { + "name": "cli_sessions_forked_from_cli_sessions_session_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "forked_from" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_parent_session_id_cli_sessions_session_id_fk": { + "name": "cli_sessions_parent_session_id_cli_sessions_session_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "parent_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_organization_id_organizations_id_fk": { + "name": "cli_sessions_organization_id_organizations_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "cli_sessions_cloud_agent_session_id_unique": { + "name": "cli_sessions_cloud_agent_session_id_unique", + "nullsNotDistinct": false, + "columns": [ + "cloud_agent_session_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cli_sessions_v2": { + "name": "cli_sessions_v2", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_id": { + "name": "public_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "parent_session_id": { + "name": "parent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_on_platform": { + "name": "created_on_platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "git_url": { + "name": "git_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_updated_at": { + "name": "status_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cli_sessions_v2_parent_session_id_kilo_user_id": { + "name": "IDX_cli_sessions_v2_parent_session_id_kilo_user_id", + "columns": [ + { + "expression": "parent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cli_sessions_v2_public_id": { + "name": "UQ_cli_sessions_v2_public_id", + "columns": [ + { + "expression": "public_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cli_sessions_v2\".\"public_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cli_sessions_v2_cloud_agent_session_id": { + "name": "UQ_cli_sessions_v2_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cli_sessions_v2\".\"cloud_agent_session_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_organization_id": { + "name": "IDX_cli_sessions_v2_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_kilo_user_id": { + "name": "IDX_cli_sessions_v2_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_created_at": { + "name": "IDX_cli_sessions_v2_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_user_updated": { + "name": "IDX_cli_sessions_v2_user_updated", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk": { + "name": "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "cli_sessions_v2_organization_id_organizations_id_fk": { + "name": "cli_sessions_v2_organization_id_organizations_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_v2_parent_session_id_kilo_user_id_fk": { + "name": "cli_sessions_v2_parent_session_id_kilo_user_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "cli_sessions_v2", + "columnsFrom": [ + "parent_session_id", + "kilo_user_id" + ], + "columnsTo": [ + "session_id", + "kilo_user_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "cli_sessions_v2_session_id_kilo_user_id_pk": { + "name": "cli_sessions_v2_session_id_kilo_user_id_pk", + "columns": [ + "session_id", + "kilo_user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cloud_agent_code_reviews": { + "name": "cloud_agent_code_reviews", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_number": { + "name": "pr_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pr_url": { + "name": "pr_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_title": { + "name": "pr_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_author": { + "name": "pr_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_author_github_id": { + "name": "pr_author_github_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "base_ref": { + "name": "base_ref", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "head_ref": { + "name": "head_ref", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "head_sha": { + "name": "head_sha", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "platform_project_id": { + "name": "platform_project_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_reason": { + "name": "terminal_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agent_version": { + "name": "agent_version", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'v1'" + }, + "check_run_id": { + "name": "check_run_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "total_tokens_in": { + "name": "total_tokens_in", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_tokens_out": { + "name": "total_tokens_out", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_cost_musd": { + "name": "total_cost_musd", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_cloud_agent_code_reviews_repo_pr_sha": { + "name": "UQ_cloud_agent_code_reviews_repo_pr_sha", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pr_number", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "head_sha", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_owned_by_org_id": { + "name": "idx_cloud_agent_code_reviews_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_owned_by_user_id": { + "name": "idx_cloud_agent_code_reviews_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_session_id": { + "name": "idx_cloud_agent_code_reviews_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_cli_session_id": { + "name": "idx_cloud_agent_code_reviews_cli_session_id", + "columns": [ + { + "expression": "cli_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_status": { + "name": "idx_cloud_agent_code_reviews_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_repo": { + "name": "idx_cloud_agent_code_reviews_repo", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_pr_number": { + "name": "idx_cloud_agent_code_reviews_pr_number", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pr_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_created_at": { + "name": "idx_cloud_agent_code_reviews_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_pr_author_github_id": { + "name": "idx_cloud_agent_code_reviews_pr_author_github_id", + "columns": [ + { + "expression": "pr_author_github_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk": { + "name": "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk": { + "name": "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "cloud_agent_code_reviews_owner_check": { + "name": "cloud_agent_code_reviews_owner_check", + "value": "(\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NOT NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NULL) OR\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.cloud_agent_feedback": { + "name": "cloud_agent_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_streaming": { + "name": "is_streaming", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recent_messages": { + "name": "recent_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cloud_agent_feedback_created_at": { + "name": "IDX_cloud_agent_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_feedback_kilo_user_id": { + "name": "IDX_cloud_agent_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_feedback_cloud_agent_session_id": { + "name": "IDX_cloud_agent_feedback_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "cloud_agent_feedback_organization_id_organizations_id_fk": { + "name": "cloud_agent_feedback_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_feedback", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cloud_agent_webhook_triggers": { + "name": "cloud_agent_webhook_triggers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "trigger_id": { + "name": "trigger_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'cloud_agent'" + }, + "kiloclaw_instance_id": { + "name": "kiloclaw_instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "activation_mode": { + "name": "activation_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'webhook'" + }, + "cron_expression": { + "name": "cron_expression", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cron_timezone": { + "name": "cron_timezone", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'UTC'" + }, + "github_repo": { + "name": "github_repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_cloud_agent_webhook_triggers_user_trigger": { + "name": "UQ_cloud_agent_webhook_triggers_user_trigger", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trigger_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cloud_agent_webhook_triggers\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cloud_agent_webhook_triggers_org_trigger": { + "name": "UQ_cloud_agent_webhook_triggers_org_trigger", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trigger_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cloud_agent_webhook_triggers\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_user": { + "name": "IDX_cloud_agent_webhook_triggers_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_org": { + "name": "IDX_cloud_agent_webhook_triggers_org", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_active": { + "name": "IDX_cloud_agent_webhook_triggers_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_profile": { + "name": "IDX_cloud_agent_webhook_triggers_profile", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_organization_id_organizations_id_fk": { + "name": "cloud_agent_webhook_triggers_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk": { + "name": "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "kiloclaw_instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk": { + "name": "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "CHK_cloud_agent_webhook_triggers_owner": { + "name": "CHK_cloud_agent_webhook_triggers_owner", + "value": "(\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NULL) OR\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NOT NULL)\n )" + }, + "CHK_cloud_agent_webhook_triggers_cloud_agent_fields": { + "name": "CHK_cloud_agent_webhook_triggers_cloud_agent_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'cloud_agent' OR\n (\"cloud_agent_webhook_triggers\".\"github_repo\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"profile_id\" IS NOT NULL)\n )" + }, + "CHK_cloud_agent_webhook_triggers_kiloclaw_fields": { + "name": "CHK_cloud_agent_webhook_triggers_kiloclaw_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'kiloclaw_chat' OR\n \"cloud_agent_webhook_triggers\".\"kiloclaw_instance_id\" IS NOT NULL\n )" + }, + "CHK_cloud_agent_webhook_triggers_scheduled_fields": { + "name": "CHK_cloud_agent_webhook_triggers_scheduled_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"activation_mode\" != 'scheduled' OR\n \"cloud_agent_webhook_triggers\".\"cron_expression\" IS NOT NULL\n )" + } + }, + "isRLSEnabled": false + }, + "public.code_indexing_manifest": { + "name": "code_indexing_manifest", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_hash": { + "name": "file_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chunk_count": { + "name": "chunk_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "total_lines": { + "name": "total_lines", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_ai_lines": { + "name": "total_ai_lines", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_code_indexing_manifest_organization_id": { + "name": "IDX_code_indexing_manifest_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_kilo_user_id": { + "name": "IDX_code_indexing_manifest_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_project_id": { + "name": "IDX_code_indexing_manifest_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_file_hash": { + "name": "IDX_code_indexing_manifest_file_hash", + "columns": [ + { + "expression": "file_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_git_branch": { + "name": "IDX_code_indexing_manifest_git_branch", + "columns": [ + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_created_at": { + "name": "IDX_code_indexing_manifest_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk": { + "name": "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "code_indexing_manifest", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_code_indexing_manifest_org_user_project_hash_branch": { + "name": "UQ_code_indexing_manifest_org_user_project_hash_branch", + "nullsNotDistinct": true, + "columns": [ + "organization_id", + "kilo_user_id", + "project_id", + "file_path", + "git_branch" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.code_indexing_search": { + "name": "code_indexing_search", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_code_indexing_search_organization_id": { + "name": "IDX_code_indexing_search_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_kilo_user_id": { + "name": "IDX_code_indexing_search_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_project_id": { + "name": "IDX_code_indexing_search_project_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_created_at": { + "name": "IDX_code_indexing_search_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "code_indexing_search_kilo_user_id_kilocode_users_id_fk": { + "name": "code_indexing_search_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "code_indexing_search", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_contributors": { + "name": "contributor_champion_contributors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "github_login": { + "name": "github_login", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_user_id": { + "name": "github_user_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "first_contribution_at": { + "name": "first_contribution_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_contribution_at": { + "name": "last_contribution_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "all_time_contributions": { + "name": "all_time_contributions", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "manual_email": { + "name": "manual_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_contributors_last_contribution_at": { + "name": "IDX_contributor_champion_contributors_last_contribution_at", + "columns": [ + { + "expression": "last_contribution_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_contributors_manual_email": { + "name": "IDX_contributor_champion_contributors_manual_email", + "columns": [ + { + "expression": "manual_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_contributors_github_login": { + "name": "UQ_contributor_champion_contributors_github_login", + "nullsNotDistinct": false, + "columns": [ + "github_login" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_events": { + "name": "contributor_champion_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "contributor_id": { + "name": "contributor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_pr_number": { + "name": "github_pr_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "github_pr_url": { + "name": "github_pr_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_pr_title": { + "name": "github_pr_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_author_login": { + "name": "github_author_login", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_author_email": { + "name": "github_author_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_events_contributor_id": { + "name": "IDX_contributor_champion_events_contributor_id", + "columns": [ + { + "expression": "contributor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_events_merged_at": { + "name": "IDX_contributor_champion_events_merged_at", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_events_author_email": { + "name": "IDX_contributor_champion_events_author_email", + "columns": [ + { + "expression": "github_author_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk": { + "name": "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk", + "tableFrom": "contributor_champion_events", + "tableTo": "contributor_champion_contributors", + "columnsFrom": [ + "contributor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_events_repo_pr": { + "name": "UQ_contributor_champion_events_repo_pr", + "nullsNotDistinct": false, + "columns": [ + "repo_full_name", + "github_pr_number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_memberships": { + "name": "contributor_champion_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "contributor_id": { + "name": "contributor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "selected_tier": { + "name": "selected_tier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enrolled_tier": { + "name": "enrolled_tier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enrolled_at": { + "name": "enrolled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "credit_amount_microdollars": { + "name": "credit_amount_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "credits_last_granted_at": { + "name": "credits_last_granted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "linked_kilo_user_id": { + "name": "linked_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_memberships_credits_due": { + "name": "IDX_contributor_champion_memberships_credits_due", + "columns": [ + { + "expression": "credits_last_granted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NOT NULL AND \"contributor_champion_memberships\".\"credit_amount_microdollars\" > 0", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_memberships_linked_kilo_user_id": { + "name": "IDX_contributor_champion_memberships_linked_kilo_user_id", + "columns": [ + { + "expression": "linked_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk": { + "name": "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk", + "tableFrom": "contributor_champion_memberships", + "tableTo": "contributor_champion_contributors", + "columnsFrom": [ + "contributor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk": { + "name": "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "contributor_champion_memberships", + "tableTo": "kilocode_users", + "columnsFrom": [ + "linked_kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_memberships_contributor_id": { + "name": "UQ_contributor_champion_memberships_contributor_id", + "nullsNotDistinct": false, + "columns": [ + "contributor_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "contributor_champion_memberships_selected_tier_check": { + "name": "contributor_champion_memberships_selected_tier_check", + "value": "\"contributor_champion_memberships\".\"selected_tier\" IS NULL OR \"contributor_champion_memberships\".\"selected_tier\" IN ('contributor', 'ambassador', 'champion')" + }, + "contributor_champion_memberships_enrolled_tier_check": { + "name": "contributor_champion_memberships_enrolled_tier_check", + "value": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NULL OR \"contributor_champion_memberships\".\"enrolled_tier\" IN ('contributor', 'ambassador', 'champion')" + } + }, + "isRLSEnabled": false + }, + "public.contributor_champion_sync_state": { + "name": "contributor_champion_sync_state", + "schema": "", + "columns": { + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_merged_at": { + "name": "last_merged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.credit_campaigns": { + "name": "credit_campaigns", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credit_category": { + "name": "credit_category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_microdollars": { + "name": "amount_microdollars", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credit_expiry_hours": { + "name": "credit_expiry_hours", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_ends_at": { + "name": "campaign_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_redemptions_allowed": { + "name": "total_redemptions_allowed", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by_kilo_user_id": { + "name": "created_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_credit_campaigns_slug": { + "name": "UQ_credit_campaigns_slug", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_credit_campaigns_credit_category": { + "name": "UQ_credit_campaigns_credit_category", + "columns": [ + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "credit_campaigns_slug_format_check": { + "name": "credit_campaigns_slug_format_check", + "value": "\"credit_campaigns\".\"slug\" ~ '^[a-z0-9-]{5,40}$'" + }, + "credit_campaigns_amount_positive_check": { + "name": "credit_campaigns_amount_positive_check", + "value": "\"credit_campaigns\".\"amount_microdollars\" > 0" + }, + "credit_campaigns_credit_expiry_hours_positive_check": { + "name": "credit_campaigns_credit_expiry_hours_positive_check", + "value": "\"credit_campaigns\".\"credit_expiry_hours\" IS NULL OR \"credit_campaigns\".\"credit_expiry_hours\" > 0" + }, + "credit_campaigns_total_redemptions_allowed_positive_check": { + "name": "credit_campaigns_total_redemptions_allowed_positive_check", + "value": "\"credit_campaigns\".\"total_redemptions_allowed\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.credit_transactions": { + "name": "credit_transactions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_microdollars": { + "name": "amount_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "expiration_baseline_microdollars_used": { + "name": "expiration_baseline_microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "original_baseline_microdollars_used": { + "name": "original_baseline_microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "original_transaction_id": { + "name": "original_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "stripe_payment_id": { + "name": "stripe_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "coinbase_credit_block_id": { + "name": "coinbase_credit_block_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credit_category": { + "name": "credit_category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expiry_date": { + "name": "expiry_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "check_category_uniqueness": { + "name": "check_category_uniqueness", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "IDX_credit_transactions_created_at": { + "name": "IDX_credit_transactions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_is_free": { + "name": "IDX_credit_transactions_is_free", + "columns": [ + { + "expression": "is_free", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_kilo_user_id": { + "name": "IDX_credit_transactions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_credit_category": { + "name": "IDX_credit_transactions_credit_category", + "columns": [ + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_stripe_payment_id": { + "name": "IDX_credit_transactions_stripe_payment_id", + "columns": [ + { + "expression": "stripe_payment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_original_transaction_id": { + "name": "IDX_credit_transactions_original_transaction_id", + "columns": [ + { + "expression": "original_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_coinbase_credit_block_id": { + "name": "IDX_credit_transactions_coinbase_credit_block_id", + "columns": [ + { + "expression": "coinbase_credit_block_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_organization_id": { + "name": "IDX_credit_transactions_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_unique_category": { + "name": "IDX_credit_transactions_unique_category", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"credit_transactions\".\"check_category_uniqueness\" = TRUE", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_llm2": { + "name": "custom_llm2", + "schema": "", + "columns": { + "public_id": { + "name": "public_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "definition": { + "name": "definition", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_builds": { + "name": "deployment_builds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_builds_deployment_id": { + "name": "idx_deployment_builds_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_builds_status": { + "name": "idx_deployment_builds_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_builds_deployment_id_deployments_id_fk": { + "name": "deployment_builds_deployment_id_deployments_id_fk", + "tableFrom": "deployment_builds", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_env_vars": { + "name": "deployment_env_vars", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_secret": { + "name": "is_secret", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_env_vars_deployment_id": { + "name": "idx_deployment_env_vars_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_env_vars_deployment_id_deployments_id_fk": { + "name": "deployment_env_vars_deployment_id_deployments_id_fk", + "tableFrom": "deployment_env_vars", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_deployment_env_vars_deployment_key": { + "name": "UQ_deployment_env_vars_deployment_key", + "nullsNotDistinct": false, + "columns": [ + "deployment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_events": { + "name": "deployment_events", + "schema": "", + "columns": { + "build_id": { + "name": "build_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'log'" + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_deployment_events_build_id": { + "name": "idx_deployment_events_build_id", + "columns": [ + { + "expression": "build_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_events_timestamp": { + "name": "idx_deployment_events_timestamp", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_events_type": { + "name": "idx_deployment_events_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_events_build_id_deployment_builds_id_fk": { + "name": "deployment_events_build_id_deployment_builds_id_fk", + "tableFrom": "deployment_events", + "tableTo": "deployment_builds", + "columnsFrom": [ + "build_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "deployment_events_build_id_event_id_pk": { + "name": "deployment_events_build_id_event_id_pk", + "columns": [ + "build_id", + "event_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_threat_detections": { + "name": "deployment_threat_detections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "build_id": { + "name": "build_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "threat_type": { + "name": "threat_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_threat_detections_deployment_id": { + "name": "idx_deployment_threat_detections_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_threat_detections_created_at": { + "name": "idx_deployment_threat_detections_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_threat_detections_deployment_id_deployments_id_fk": { + "name": "deployment_threat_detections_deployment_id_deployments_id_fk", + "tableFrom": "deployment_threat_detections", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_threat_detections_build_id_deployment_builds_id_fk": { + "name": "deployment_threat_detections_build_id_deployment_builds_id_fk", + "tableFrom": "deployment_threat_detections", + "tableTo": "deployment_builds", + "columnsFrom": [ + "build_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployments": { + "name": "deployments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "deployment_slug": { + "name": "deployment_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_worker_name": { + "name": "internal_worker_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repository_source": { + "name": "repository_source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deployment_url": { + "name": "deployment_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "git_auth_token": { + "name": "git_auth_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_deployed_at": { + "name": "last_deployed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_build_id": { + "name": "last_build_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "threat_status": { + "name": "threat_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_from": { + "name": "created_from", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_deployments_owned_by_user_id": { + "name": "idx_deployments_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_owned_by_organization_id": { + "name": "idx_deployments_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_platform_integration_id": { + "name": "idx_deployments_platform_integration_id", + "columns": [ + { + "expression": "platform_integration_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_repository_source_branch": { + "name": "idx_deployments_repository_source_branch", + "columns": [ + { + "expression": "repository_source", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_threat_status_pending": { + "name": "idx_deployments_threat_status_pending", + "columns": [ + { + "expression": "threat_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"deployments\".\"threat_status\" = 'pending_scan'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployments_owned_by_user_id_kilocode_users_id_fk": { + "name": "deployments_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "deployments", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployments_owned_by_organization_id_organizations_id_fk": { + "name": "deployments_owned_by_organization_id_organizations_id_fk", + "tableFrom": "deployments", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_deployments_deployment_slug": { + "name": "UQ_deployments_deployment_slug", + "nullsNotDistinct": false, + "columns": [ + "deployment_slug" + ] + } + }, + "policies": {}, + "checkConstraints": { + "deployments_owner_check": { + "name": "deployments_owner_check", + "value": "(\n (\"deployments\".\"owned_by_user_id\" IS NOT NULL AND \"deployments\".\"owned_by_organization_id\" IS NULL) OR\n (\"deployments\".\"owned_by_user_id\" IS NULL AND \"deployments\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "deployments_source_type_check": { + "name": "deployments_source_type_check", + "value": "\"deployments\".\"source_type\" IN ('github', 'git', 'app-builder')" + } + }, + "isRLSEnabled": false + }, + "public.device_auth_requests": { + "name": "device_auth_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_device_auth_requests_code": { + "name": "UQ_device_auth_requests_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_status": { + "name": "IDX_device_auth_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_expires_at": { + "name": "IDX_device_auth_requests_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_kilo_user_id": { + "name": "IDX_device_auth_requests_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "device_auth_requests_kilo_user_id_kilocode_users_id_fk": { + "name": "device_auth_requests_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "device_auth_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.discord_gateway_listener": { + "name": "discord_gateway_listener", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "default": 1 + }, + "listener_id": { + "name": "listener_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.editor_name": { + "name": "editor_name", + "schema": "", + "columns": { + "editor_name_id": { + "name": "editor_name_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "editor_name": { + "name": "editor_name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_editor_name": { + "name": "UQ_editor_name", + "columns": [ + { + "expression": "editor_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.enrichment_data": { + "name": "enrichment_data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_enrichment_data": { + "name": "github_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "linkedin_enrichment_data": { + "name": "linkedin_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "clay_enrichment_data": { + "name": "clay_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_enrichment_data_user_id": { + "name": "IDX_enrichment_data_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "enrichment_data_user_id_kilocode_users_id_fk": { + "name": "enrichment_data_user_id_kilocode_users_id_fk", + "tableFrom": "enrichment_data", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_enrichment_data_user_id": { + "name": "UQ_enrichment_data_user_id", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exa_monthly_usage": { + "name": "exa_monthly_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "month": { + "name": "month", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "total_cost_microdollars": { + "name": "total_cost_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "total_charged_microdollars": { + "name": "total_charged_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "free_allowance_microdollars": { + "name": "free_allowance_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 10000000 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_exa_monthly_usage_personal": { + "name": "idx_exa_monthly_usage_personal", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"exa_monthly_usage\".\"organization_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_exa_monthly_usage_org": { + "name": "idx_exa_monthly_usage_org", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"exa_monthly_usage\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exa_usage_log": { + "name": "exa_usage_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost_microdollars": { + "name": "cost_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "charged_to_balance": { + "name": "charged_to_balance", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_exa_usage_log_user_created": { + "name": "idx_exa_usage_log_user_created", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "exa_usage_log_id_created_at_pk": { + "name": "exa_usage_log_id_created_at_pk", + "columns": [ + "id", + "created_at" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.feature": { + "name": "feature", + "schema": "", + "columns": { + "feature_id": { + "name": "feature_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "feature": { + "name": "feature", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_feature": { + "name": "UQ_feature", + "columns": [ + { + "expression": "feature", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.finish_reason": { + "name": "finish_reason", + "schema": "", + "columns": { + "finish_reason_id": { + "name": "finish_reason_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "finish_reason": { + "name": "finish_reason", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_finish_reason": { + "name": "UQ_finish_reason", + "columns": [ + { + "expression": "finish_reason", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.free_model_usage": { + "name": "free_model_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_free_model_usage_ip_created_at": { + "name": "idx_free_model_usage_ip_created_at", + "columns": [ + { + "expression": "ip_address", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_free_model_usage_created_at": { + "name": "idx_free_model_usage_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_free_model_usage_user_created_at": { + "name": "idx_free_model_usage_user_created_at", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"free_model_usage\".\"kilo_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.http_ip": { + "name": "http_ip", + "schema": "", + "columns": { + "http_ip_id": { + "name": "http_ip_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "http_ip": { + "name": "http_ip", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_http_ip": { + "name": "UQ_http_ip", + "columns": [ + { + "expression": "http_ip", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.http_user_agent": { + "name": "http_user_agent", + "schema": "", + "columns": { + "http_user_agent_id": { + "name": "http_user_agent_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_http_user_agent": { + "name": "UQ_http_user_agent", + "columns": [ + { + "expression": "http_user_agent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ja4_digest": { + "name": "ja4_digest", + "schema": "", + "columns": { + "ja4_digest_id": { + "name": "ja4_digest_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "ja4_digest": { + "name": "ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_ja4_digest": { + "name": "UQ_ja4_digest", + "columns": [ + { + "expression": "ja4_digest", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kilo_pass_audit_log": { + "name": "kilo_pass_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_event_id": { + "name": "stripe_event_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_credit_transaction_id": { + "name": "related_credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "related_monthly_issuance_id": { + "name": "related_monthly_issuance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "payload_json": { + "name": "payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "IDX_kilo_pass_audit_log_created_at": { + "name": "IDX_kilo_pass_audit_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_kilo_user_id": { + "name": "IDX_kilo_pass_audit_log_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_kilo_pass_subscription_id": { + "name": "IDX_kilo_pass_audit_log_kilo_pass_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_action": { + "name": "IDX_kilo_pass_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_result": { + "name": "IDX_kilo_pass_audit_log_result", + "columns": [ + { + "expression": "result", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_idempotency_key": { + "name": "IDX_kilo_pass_audit_log_idempotency_key", + "columns": [ + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_event_id": { + "name": "IDX_kilo_pass_audit_log_stripe_event_id", + "columns": [ + { + "expression": "stripe_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_invoice_id": { + "name": "IDX_kilo_pass_audit_log_stripe_invoice_id", + "columns": [ + { + "expression": "stripe_invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_subscription_id": { + "name": "IDX_kilo_pass_audit_log_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_related_credit_transaction_id": { + "name": "IDX_kilo_pass_audit_log_related_credit_transaction_id", + "columns": [ + { + "expression": "related_credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_related_monthly_issuance_id": { + "name": "IDX_kilo_pass_audit_log_related_monthly_issuance_id", + "columns": [ + { + "expression": "related_monthly_issuance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk": { + "name": "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "credit_transactions", + "columnsFrom": [ + "related_credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk": { + "name": "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilo_pass_issuances", + "columnsFrom": [ + "related_monthly_issuance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_audit_log_action_check": { + "name": "kilo_pass_audit_log_action_check", + "value": "\"kilo_pass_audit_log\".\"action\" IN ('stripe_webhook_received', 'kilo_pass_invoice_paid_handled', 'base_credits_issued', 'bonus_credits_issued', 'bonus_credits_skipped_idempotent', 'first_month_50pct_promo_issued', 'yearly_monthly_base_cron_started', 'yearly_monthly_base_cron_completed', 'issue_yearly_remaining_credits', 'yearly_monthly_bonus_cron_started', 'yearly_monthly_bonus_cron_completed')" + }, + "kilo_pass_audit_log_result_check": { + "name": "kilo_pass_audit_log_result_check", + "value": "\"kilo_pass_audit_log\".\"result\" IN ('success', 'skipped_idempotent', 'failed')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_issuance_items": { + "name": "kilo_pass_issuance_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_issuance_id": { + "name": "kilo_pass_issuance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credit_transaction_id": { + "name": "credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true + }, + "bonus_percent_applied": { + "name": "bonus_percent_applied", + "type": "numeric(6, 4)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_issuance_items_issuance_id": { + "name": "IDX_kilo_pass_issuance_items_issuance_id", + "columns": [ + { + "expression": "kilo_pass_issuance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuance_items_credit_transaction_id": { + "name": "IDX_kilo_pass_issuance_items_credit_transaction_id", + "columns": [ + { + "expression": "credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk": { + "name": "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk", + "tableFrom": "kilo_pass_issuance_items", + "tableTo": "kilo_pass_issuances", + "columnsFrom": [ + "kilo_pass_issuance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk": { + "name": "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "kilo_pass_issuance_items", + "tableTo": "credit_transactions", + "columnsFrom": [ + "credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kilo_pass_issuance_items_credit_transaction_id_unique": { + "name": "kilo_pass_issuance_items_credit_transaction_id_unique", + "nullsNotDistinct": false, + "columns": [ + "credit_transaction_id" + ] + }, + "UQ_kilo_pass_issuance_items_issuance_kind": { + "name": "UQ_kilo_pass_issuance_items_issuance_kind", + "nullsNotDistinct": false, + "columns": [ + "kilo_pass_issuance_id", + "kind" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_issuance_items_bonus_percent_applied_range_check": { + "name": "kilo_pass_issuance_items_bonus_percent_applied_range_check", + "value": "\"kilo_pass_issuance_items\".\"bonus_percent_applied\" IS NULL OR (\"kilo_pass_issuance_items\".\"bonus_percent_applied\" >= 0 AND \"kilo_pass_issuance_items\".\"bonus_percent_applied\" <= 1)" + }, + "kilo_pass_issuance_items_amount_usd_non_negative_check": { + "name": "kilo_pass_issuance_items_amount_usd_non_negative_check", + "value": "\"kilo_pass_issuance_items\".\"amount_usd\" >= 0" + }, + "kilo_pass_issuance_items_kind_check": { + "name": "kilo_pass_issuance_items_kind_check", + "value": "\"kilo_pass_issuance_items\".\"kind\" IN ('base', 'bonus', 'promo_first_month_50pct')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_issuances": { + "name": "kilo_pass_issuances", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "issue_month": { + "name": "issue_month", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kilo_pass_issuances_stripe_invoice_id": { + "name": "UQ_kilo_pass_issuances_stripe_invoice_id", + "columns": [ + { + "expression": "stripe_invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_issuances\".\"stripe_invoice_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuances_subscription_id": { + "name": "IDX_kilo_pass_issuances_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuances_issue_month": { + "name": "IDX_kilo_pass_issuances_issue_month", + "columns": [ + { + "expression": "issue_month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_issuances", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_kilo_pass_issuances_subscription_issue_month": { + "name": "UQ_kilo_pass_issuances_subscription_issue_month", + "nullsNotDistinct": false, + "columns": [ + "kilo_pass_subscription_id", + "issue_month" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_issuances_issue_month_day_one_check": { + "name": "kilo_pass_issuances_issue_month_day_one_check", + "value": "EXTRACT(DAY FROM \"kilo_pass_issuances\".\"issue_month\") = 1" + }, + "kilo_pass_issuances_source_check": { + "name": "kilo_pass_issuances_source_check", + "value": "\"kilo_pass_issuances\".\"source\" IN ('stripe_invoice', 'cron')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_pause_events": { + "name": "kilo_pass_pause_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "paused_at": { + "name": "paused_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "resumes_at": { + "name": "resumes_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "resumed_at": { + "name": "resumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_pause_events_subscription_id": { + "name": "IDX_kilo_pass_pause_events_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilo_pass_pause_events_one_open_per_sub": { + "name": "UQ_kilo_pass_pause_events_one_open_per_sub", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_pause_events", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_pause_events_resumed_at_after_paused_at_check": { + "name": "kilo_pass_pause_events_resumed_at_after_paused_at_check", + "value": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL OR \"kilo_pass_pause_events\".\"resumed_at\" >= \"kilo_pass_pause_events\".\"paused_at\"" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_scheduled_changes": { + "name": "kilo_pass_scheduled_changes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_tier": { + "name": "from_tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_cadence": { + "name": "from_cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_tier": { + "name": "to_tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_cadence": { + "name": "to_cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_schedule_id": { + "name": "stripe_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "effective_at": { + "name": "effective_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_scheduled_changes_kilo_user_id": { + "name": "IDX_kilo_pass_scheduled_changes_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_status": { + "name": "IDX_kilo_pass_scheduled_changes_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_stripe_subscription_id": { + "name": "IDX_kilo_pass_scheduled_changes_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id": { + "name": "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_scheduled_changes\".\"deleted_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_effective_at": { + "name": "IDX_kilo_pass_scheduled_changes_effective_at", + "columns": [ + { + "expression": "effective_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_deleted_at": { + "name": "IDX_kilo_pass_scheduled_changes_deleted_at", + "columns": [ + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_scheduled_changes", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk": { + "name": "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk", + "tableFrom": "kilo_pass_scheduled_changes", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "stripe_subscription_id" + ], + "columnsTo": [ + "stripe_subscription_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_scheduled_changes_from_tier_check": { + "name": "kilo_pass_scheduled_changes_from_tier_check", + "value": "\"kilo_pass_scheduled_changes\".\"from_tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_scheduled_changes_from_cadence_check": { + "name": "kilo_pass_scheduled_changes_from_cadence_check", + "value": "\"kilo_pass_scheduled_changes\".\"from_cadence\" IN ('monthly', 'yearly')" + }, + "kilo_pass_scheduled_changes_to_tier_check": { + "name": "kilo_pass_scheduled_changes_to_tier_check", + "value": "\"kilo_pass_scheduled_changes\".\"to_tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_scheduled_changes_to_cadence_check": { + "name": "kilo_pass_scheduled_changes_to_cadence_check", + "value": "\"kilo_pass_scheduled_changes\".\"to_cadence\" IN ('monthly', 'yearly')" + }, + "kilo_pass_scheduled_changes_status_check": { + "name": "kilo_pass_scheduled_changes_status_check", + "value": "\"kilo_pass_scheduled_changes\".\"status\" IN ('not_started', 'active', 'completed', 'released', 'canceled')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_subscriptions": { + "name": "kilo_pass_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cadence": { + "name": "cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_streak_months": { + "name": "current_streak_months", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_yearly_issue_at": { + "name": "next_yearly_issue_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_subscriptions_kilo_user_id": { + "name": "IDX_kilo_pass_subscriptions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_subscriptions_status": { + "name": "IDX_kilo_pass_subscriptions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_subscriptions_cadence": { + "name": "IDX_kilo_pass_subscriptions_cadence", + "columns": [ + { + "expression": "cadence", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_subscriptions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kilo_pass_subscriptions_stripe_subscription_id_unique": { + "name": "kilo_pass_subscriptions_stripe_subscription_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_subscription_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_subscriptions_current_streak_months_non_negative_check": { + "name": "kilo_pass_subscriptions_current_streak_months_non_negative_check", + "value": "\"kilo_pass_subscriptions\".\"current_streak_months\" >= 0" + }, + "kilo_pass_subscriptions_tier_check": { + "name": "kilo_pass_subscriptions_tier_check", + "value": "\"kilo_pass_subscriptions\".\"tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_subscriptions_cadence_check": { + "name": "kilo_pass_subscriptions_cadence_check", + "value": "\"kilo_pass_subscriptions\".\"cadence\" IN ('monthly', 'yearly')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_access_codes": { + "name": "kiloclaw_access_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "redeemed_at": { + "name": "redeemed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_access_codes_code": { + "name": "UQ_kiloclaw_access_codes_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_access_codes_user_status": { + "name": "IDX_kiloclaw_access_codes_user_status", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_access_codes_one_active_per_user": { + "name": "UQ_kiloclaw_access_codes_one_active_per_user", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "status = 'active'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_access_codes", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_admin_audit_logs": { + "name": "kiloclaw_admin_audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kiloclaw_admin_audit_logs_target_user_id": { + "name": "IDX_kiloclaw_admin_audit_logs_target_user_id", + "columns": [ + { + "expression": "target_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_admin_audit_logs_action": { + "name": "IDX_kiloclaw_admin_audit_logs_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_admin_audit_logs_created_at": { + "name": "IDX_kiloclaw_admin_audit_logs_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_cli_runs": { + "name": "kiloclaw_cli_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "initiated_by_admin_id": { + "name": "initiated_by_admin_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'running'" + }, + "exit_code": { + "name": "exit_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_cli_runs_user_id": { + "name": "IDX_kiloclaw_cli_runs_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_cli_runs_started_at": { + "name": "IDX_kiloclaw_cli_runs_started_at", + "columns": [ + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_cli_runs_instance_id": { + "name": "IDX_kiloclaw_cli_runs_instance_id", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_cli_runs_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_cli_runs_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk": { + "name": "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "initiated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_earlybird_purchases": { + "name": "kiloclaw_earlybird_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manual_payment_id": { + "name": "manual_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_earlybird_purchases", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_earlybird_purchases_user_id_unique": { + "name": "kiloclaw_earlybird_purchases_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + }, + "kiloclaw_earlybird_purchases_stripe_charge_id_unique": { + "name": "kiloclaw_earlybird_purchases_stripe_charge_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_charge_id" + ] + }, + "kiloclaw_earlybird_purchases_manual_payment_id_unique": { + "name": "kiloclaw_earlybird_purchases_manual_payment_id_unique", + "nullsNotDistinct": false, + "columns": [ + "manual_payment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_email_log": { + "name": "kiloclaw_email_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "email_type": { + "name": "email_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "'epoch'" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_email_log_user_type_global": { + "name": "UQ_kiloclaw_email_log_user_type_global", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_email_log\".\"instance_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_email_log_user_instance_type_period": { + "name": "UQ_kiloclaw_email_log_user_instance_type_period", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_email_log_type_sent_instance": { + "name": "IDX_kiloclaw_email_log_type_sent_instance", + "columns": [ + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sent_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_email_log_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_email_log_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_email_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_email_log", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_google_oauth_connections": { + "name": "kiloclaw_google_oauth_connections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'google'" + }, + "account_email": { + "name": "account_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_subject": { + "name": "account_subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oauth_client_id": { + "name": "oauth_client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oauth_client_secret_encrypted": { + "name": "oauth_client_secret_encrypted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_profile": { + "name": "credential_profile", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'kilo_owned'" + }, + "refresh_token_encrypted": { + "name": "refresh_token_encrypted", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "grants_by_source": { + "name": "grants_by_source", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "capabilities": { + "name": "capabilities", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_at": { + "name": "last_error_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "connected_at": { + "name": "connected_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_google_oauth_connections_instance": { + "name": "UQ_kiloclaw_google_oauth_connections_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_google_oauth_connections_status": { + "name": "IDX_kiloclaw_google_oauth_connections_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_google_oauth_connections_provider": { + "name": "IDX_kiloclaw_google_oauth_connections_provider", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_google_oauth_connections", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kiloclaw_google_oauth_connections_status_check": { + "name": "kiloclaw_google_oauth_connections_status_check", + "value": "\"kiloclaw_google_oauth_connections\".\"status\" IN ('active', 'action_required', 'disconnected')" + }, + "kiloclaw_google_oauth_connections_credential_profile_check": { + "name": "kiloclaw_google_oauth_connections_credential_profile_check", + "value": "\"kiloclaw_google_oauth_connections\".\"credential_profile\" IN ('legacy', 'kilo_owned')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_image_catalog": { + "name": "kiloclaw_image_catalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "openclaw_version": { + "name": "openclaw_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "variant": { + "name": "variant", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + }, + "image_tag": { + "name": "image_tag", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image_digest": { + "name": "image_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'available'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_by": { + "name": "updated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "synced_at": { + "name": "synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "rollout_percent": { + "name": "rollout_percent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_latest": { + "name": "is_latest", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "IDX_kiloclaw_image_catalog_status": { + "name": "IDX_kiloclaw_image_catalog_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_image_catalog_variant": { + "name": "IDX_kiloclaw_image_catalog_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_image_catalog_one_latest_per_variant": { + "name": "UQ_kiloclaw_image_catalog_one_latest_per_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_image_catalog\".\"is_latest\" = true", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_image_catalog_one_candidate_per_variant": { + "name": "UQ_kiloclaw_image_catalog_one_candidate_per_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_image_catalog\".\"is_latest\" = false AND \"kiloclaw_image_catalog\".\"rollout_percent\" > 0 AND \"kiloclaw_image_catalog\".\"status\" = 'available'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_image_catalog_image_tag_unique": { + "name": "kiloclaw_image_catalog_image_tag_unique", + "nullsNotDistinct": false, + "columns": [ + "image_tag" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_inbound_email_aliases": { + "name": "kiloclaw_inbound_email_aliases", + "schema": "", + "columns": { + "alias": { + "name": "alias", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "retired_at": { + "name": "retired_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_inbound_email_aliases_instance_id": { + "name": "IDX_kiloclaw_inbound_email_aliases_instance_id", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_inbound_email_aliases_active_instance": { + "name": "UQ_kiloclaw_inbound_email_aliases_active_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_inbound_email_aliases\".\"retired_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_inbound_email_aliases", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_inbound_email_reserved_aliases": { + "name": "kiloclaw_inbound_email_reserved_aliases", + "schema": "", + "columns": { + "alias": { + "name": "alias", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_instances": { + "name": "kiloclaw_instances", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sandbox_id": { + "name": "sandbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'fly'" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "inbound_email_enabled": { + "name": "inbound_email_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "inactive_trial_stopped_at": { + "name": "inactive_trial_stopped_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "destroyed_at": { + "name": "destroyed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tracked_image_tag": { + "name": "tracked_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_instances_active": { + "name": "UQ_kiloclaw_instances_active", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sandbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_active_personal_by_user": { + "name": "IDX_kiloclaw_instances_active_personal_by_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"organization_id\" IS NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_active_org_by_user_org": { + "name": "IDX_kiloclaw_instances_active_org_by_user_org", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"organization_id\" IS NOT NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_tracked_image_tag": { + "name": "IDX_kiloclaw_instances_tracked_image_tag", + "columns": [ + { + "expression": "tracked_image_tag", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_instances_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_instances_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_instances", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_instances_organization_id_organizations_id_fk": { + "name": "kiloclaw_instances_organization_id_organizations_id_fk", + "tableFrom": "kiloclaw_instances", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_notifications": { + "name": "kiloclaw_scheduled_action_notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'notice'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel": { + "name": "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel", + "columns": [ + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_notifications_pending": { + "name": "IDX_kiloclaw_scheduled_action_notifications_pending", + "columns": [ + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_notifications\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk": { + "name": "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk", + "tableFrom": "kiloclaw_scheduled_action_notifications", + "tableTo": "kiloclaw_scheduled_action_targets", + "columnsFrom": [ + "target_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_stages": { + "name": "kiloclaw_scheduled_action_stages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scheduled_action_id": { + "name": "scheduled_action_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "stage_index": { + "name": "stage_index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "notice_sent_at": { + "name": "notice_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "applied_count": { + "name": "applied_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skipped_count": { + "name": "skipped_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed_count": { + "name": "failed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_stages_parent_index": { + "name": "UQ_kiloclaw_scheduled_action_stages_parent_index", + "columns": [ + { + "expression": "scheduled_action_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stage_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_stages_notice_due": { + "name": "IDX_kiloclaw_scheduled_action_stages_notice_due", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_stages\".\"notice_sent_at\" IS NULL AND \"kiloclaw_scheduled_action_stages\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { + "name": "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", + "tableFrom": "kiloclaw_scheduled_action_stages", + "tableTo": "kiloclaw_scheduled_actions", + "columnsFrom": [ + "scheduled_action_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_targets": { + "name": "kiloclaw_scheduled_action_targets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scheduled_action_id": { + "name": "scheduled_action_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "stage_id": { + "name": "stage_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source_image_tag": { + "name": "source_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_image_tag": { + "name": "target_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applied_at": { + "name": "applied_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "skip_reason": { + "name": "skip_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_targets_parent_instance": { + "name": "UQ_kiloclaw_scheduled_action_targets_parent_instance", + "columns": [ + { + "expression": "scheduled_action_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_targets_stage": { + "name": "IDX_kiloclaw_scheduled_action_targets_stage", + "columns": [ + { + "expression": "stage_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_targets_pending_by_instance": { + "name": "IDX_kiloclaw_scheduled_action_targets_pending_by_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_targets\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { + "name": "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_scheduled_actions", + "columnsFrom": [ + "scheduled_action_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk": { + "name": "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_scheduled_action_stages", + "columnsFrom": [ + "stage_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_actions": { + "name": "kiloclaw_scheduled_actions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action_type": { + "name": "action_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_image_tag": { + "name": "target_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "override_pins": { + "name": "override_pins", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notice_lead_hours": { + "name": "notice_lead_hours", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "notice_subject": { + "name": "notice_subject", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "notice_body": { + "name": "notice_body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'scheduled'" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancelled_at": { + "name": "cancelled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_count": { + "name": "total_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "applied_count": { + "name": "applied_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skipped_count": { + "name": "skipped_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed_count": { + "name": "failed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "IDX_kiloclaw_scheduled_actions_status": { + "name": "IDX_kiloclaw_scheduled_actions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_actions_action_type": { + "name": "IDX_kiloclaw_scheduled_actions_action_type", + "columns": [ + { + "expression": "action_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_actions_created_by": { + "name": "IDX_kiloclaw_scheduled_actions_created_by", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk": { + "name": "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk", + "tableFrom": "kiloclaw_scheduled_actions", + "tableTo": "kiloclaw_image_catalog", + "columnsFrom": [ + "target_image_tag" + ], + "columnsTo": [ + "image_tag" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk": { + "name": "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk", + "tableFrom": "kiloclaw_scheduled_actions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_subscription_change_log": { + "name": "kiloclaw_subscription_change_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "subscription_id": { + "name": "subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "actor_type": { + "name": "actor_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before_state": { + "name": "before_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after_state": { + "name": "after_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_subscription_change_log_subscription_created_at": { + "name": "IDX_kiloclaw_subscription_change_log_subscription_created_at", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscription_change_log_created_at": { + "name": "IDX_kiloclaw_subscription_change_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk": { + "name": "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk", + "tableFrom": "kiloclaw_subscription_change_log", + "tableTo": "kiloclaw_subscriptions", + "columnsFrom": [ + "subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kiloclaw_subscription_change_log_actor_type_check": { + "name": "kiloclaw_subscription_change_log_actor_type_check", + "value": "\"kiloclaw_subscription_change_log\".\"actor_type\" IN ('user', 'system')" + }, + "kiloclaw_subscription_change_log_action_check": { + "name": "kiloclaw_subscription_change_log_action_check", + "value": "\"kiloclaw_subscription_change_log\".\"action\" IN ('created', 'status_changed', 'plan_switched', 'period_advanced', 'canceled', 'reactivated', 'suspended', 'destruction_scheduled', 'reassigned', 'backfilled', 'payment_source_changed', 'schedule_changed', 'admin_override')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_subscriptions": { + "name": "kiloclaw_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_schedule_id": { + "name": "stripe_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "transferred_to_subscription_id": { + "name": "transferred_to_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "access_origin": { + "name": "access_origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_source": { + "name": "payment_source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scheduled_plan": { + "name": "scheduled_plan", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_by": { + "name": "scheduled_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "pending_conversion": { + "name": "pending_conversion", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "trial_started_at": { + "name": "trial_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "trial_ends_at": { + "name": "trial_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_period_start": { + "name": "current_period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "credit_renewal_at": { + "name": "credit_renewal_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "commit_ends_at": { + "name": "commit_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "past_due_since": { + "name": "past_due_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "suspended_at": { + "name": "suspended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "destruction_deadline": { + "name": "destruction_deadline", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_requested_at": { + "name": "auto_resume_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_retry_after": { + "name": "auto_resume_retry_after", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_attempt_count": { + "name": "auto_resume_attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "auto_top_up_triggered_for_period": { + "name": "auto_top_up_triggered_for_period", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kiloclaw_subscriptions_status": { + "name": "IDX_kiloclaw_subscriptions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_user_id": { + "name": "IDX_kiloclaw_subscriptions_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_user_status": { + "name": "IDX_kiloclaw_subscriptions_user_status", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_transferred_to": { + "name": "IDX_kiloclaw_subscriptions_transferred_to", + "columns": [ + { + "expression": "transferred_to_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_stripe_schedule_id": { + "name": "IDX_kiloclaw_subscriptions_stripe_schedule_id", + "columns": [ + { + "expression": "stripe_schedule_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_auto_resume_retry_after": { + "name": "IDX_kiloclaw_subscriptions_auto_resume_retry_after", + "columns": [ + { + "expression": "auto_resume_retry_after", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_subscriptions_instance": { + "name": "UQ_kiloclaw_subscriptions_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_subscriptions\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_subscriptions_transferred_to": { + "name": "UQ_kiloclaw_subscriptions_transferred_to", + "columns": [ + { + "expression": "transferred_to_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_subscriptions\".\"transferred_to_subscription_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_earlybird_origin": { + "name": "IDX_kiloclaw_subscriptions_earlybird_origin", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "access_origin", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_subscriptions\".\"access_origin\" = 'earlybird'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_subscriptions_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_subscriptions_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk": { + "name": "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kiloclaw_subscriptions", + "columnsFrom": [ + "transferred_to_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_subscriptions_stripe_subscription_id_unique": { + "name": "kiloclaw_subscriptions_stripe_subscription_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_subscription_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kiloclaw_subscriptions_plan_check": { + "name": "kiloclaw_subscriptions_plan_check", + "value": "\"kiloclaw_subscriptions\".\"plan\" IN ('trial', 'commit', 'standard')" + }, + "kiloclaw_subscriptions_scheduled_plan_check": { + "name": "kiloclaw_subscriptions_scheduled_plan_check", + "value": "\"kiloclaw_subscriptions\".\"scheduled_plan\" IN ('commit', 'standard')" + }, + "kiloclaw_subscriptions_scheduled_by_check": { + "name": "kiloclaw_subscriptions_scheduled_by_check", + "value": "\"kiloclaw_subscriptions\".\"scheduled_by\" IN ('auto', 'user')" + }, + "kiloclaw_subscriptions_status_check": { + "name": "kiloclaw_subscriptions_status_check", + "value": "\"kiloclaw_subscriptions\".\"status\" IN ('trialing', 'active', 'past_due', 'canceled', 'unpaid')" + }, + "kiloclaw_subscriptions_access_origin_check": { + "name": "kiloclaw_subscriptions_access_origin_check", + "value": "\"kiloclaw_subscriptions\".\"access_origin\" IN ('earlybird')" + }, + "kiloclaw_subscriptions_payment_source_check": { + "name": "kiloclaw_subscriptions_payment_source_check", + "value": "\"kiloclaw_subscriptions\".\"payment_source\" IN ('stripe', 'credits')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_version_pins": { + "name": "kiloclaw_version_pins", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "image_tag": { + "name": "image_tag", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pinned_by": { + "name": "pinned_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk": { + "name": "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kiloclaw_image_catalog", + "columnsFrom": [ + "image_tag" + ], + "columnsTo": [ + "image_tag" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk": { + "name": "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kilocode_users", + "columnsFrom": [ + "pinned_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_version_pins_instance_id_unique": { + "name": "kiloclaw_version_pins_instance_id_unique", + "nullsNotDistinct": false, + "columns": [ + "instance_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kilocode_users": { + "name": "kilocode_users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "google_user_email": { + "name": "google_user_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "google_user_name": { + "name": "google_user_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "google_user_image_url": { + "name": "google_user_image_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "hosted_domain": { + "name": "hosted_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "microdollars_used": { + "name": "microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "kilo_pass_threshold": { + "name": "kilo_pass_threshold", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_admin": { + "name": "is_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "total_microdollars_acquired": { + "name": "total_microdollars_acquired", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "next_credit_expiration_at": { + "name": "next_credit_expiration_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "has_validation_stytch": { + "name": "has_validation_stytch", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "has_validation_novel_card_with_hold": { + "name": "has_validation_novel_card_with_hold", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_by_kilo_user_id": { + "name": "blocked_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_token_pepper": { + "name": "api_token_pepper", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "web_session_pepper": { + "name": "web_session_pepper", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_top_up_enabled": { + "name": "auto_top_up_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_bot": { + "name": "is_bot", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "kiloclaw_early_access": { + "name": "kiloclaw_early_access", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "default_model": { + "name": "default_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cohorts": { + "name": "cohorts", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "completed_welcome_form": { + "name": "completed_welcome_form", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "linkedin_url": { + "name": "linkedin_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_url": { + "name": "github_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discord_server_membership_verified_at": { + "name": "discord_server_membership_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "openrouter_upstream_safety_identifier": { + "name": "openrouter_upstream_safety_identifier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vercel_downstream_safety_identifier": { + "name": "vercel_downstream_safety_identifier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customer_source": { + "name": "customer_source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signup_ip": { + "name": "signup_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "account_deletion_requested_at": { + "name": "account_deletion_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "normalized_email": { + "name": "normalized_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_domain": { + "name": "email_domain", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kilocode_users_signup_ip_created_at": { + "name": "IDX_kilocode_users_signup_ip_created_at", + "columns": [ + { + "expression": "signup_ip", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_blocked_at": { + "name": "IDX_kilocode_users_blocked_at", + "columns": [ + { + "expression": "blocked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_blocked_by_kilo_user_id": { + "name": "IDX_kilocode_users_blocked_by_kilo_user_id", + "columns": [ + { + "expression": "blocked_by_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilocode_users_openrouter_upstream_safety_identifier": { + "name": "UQ_kilocode_users_openrouter_upstream_safety_identifier", + "columns": [ + { + "expression": "openrouter_upstream_safety_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilocode_users\".\"openrouter_upstream_safety_identifier\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilocode_users_vercel_downstream_safety_identifier": { + "name": "UQ_kilocode_users_vercel_downstream_safety_identifier", + "columns": [ + { + "expression": "vercel_downstream_safety_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilocode_users\".\"vercel_downstream_safety_identifier\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_normalized_email": { + "name": "IDX_kilocode_users_normalized_email", + "columns": [ + { + "expression": "normalized_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_email_domain": { + "name": "IDX_kilocode_users_email_domain", + "columns": [ + { + "expression": "email_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_b1afacbcf43f2c7c4cb9f7e7faa": { + "name": "UQ_b1afacbcf43f2c7c4cb9f7e7faa", + "nullsNotDistinct": false, + "columns": [ + "google_user_email" + ] + } + }, + "policies": {}, + "checkConstraints": { + "blocked_reason_not_empty": { + "name": "blocked_reason_not_empty", + "value": "length(blocked_reason) > 0" + } + }, + "isRLSEnabled": false + }, + "public.magic_link_tokens": { + "name": "magic_link_tokens", + "schema": "", + "columns": { + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_magic_link_tokens_email": { + "name": "idx_magic_link_tokens_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_magic_link_tokens_expires_at": { + "name": "idx_magic_link_tokens_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "check_expires_at_future": { + "name": "check_expires_at_future", + "value": "\"magic_link_tokens\".\"expires_at\" > \"magic_link_tokens\".\"created_at\"" + } + }, + "isRLSEnabled": false + }, + "public.microdollar_usage": { + "name": "microdollar_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost": { + "name": "cost", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "output_tokens": { + "name": "output_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_write_tokens": { + "name": "cache_write_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_hit_tokens": { + "name": "cache_hit_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_model": { + "name": "requested_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cache_discount": { + "name": "cache_discount", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_error": { + "name": "has_error", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "abuse_classification": { + "name": "abuse_classification", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "inference_provider": { + "name": "inference_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_created_at": { + "name": "idx_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_abuse_classification": { + "name": "idx_abuse_classification", + "columns": [ + { + "expression": "abuse_classification", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_kilo_user_id_created_at2": { + "name": "idx_kilo_user_id_created_at2", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_microdollar_usage_organization_id": { + "name": "idx_microdollar_usage_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"microdollar_usage\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.microdollar_usage_metadata": { + "name": "microdollar_usage_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "http_user_agent_id": { + "name": "http_user_agent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "http_ip_id": { + "name": "http_ip_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_city_id": { + "name": "vercel_ip_city_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_country_id": { + "name": "vercel_ip_country_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_latitude": { + "name": "vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_longitude": { + "name": "vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "ja4_digest_id": { + "name": "ja4_digest_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "user_prompt_prefix": { + "name": "user_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_prefix_id": { + "name": "system_prompt_prefix_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "system_prompt_length": { + "name": "system_prompt_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_tokens": { + "name": "max_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_middle_out_transform": { + "name": "has_middle_out_transform", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "upstream_id": { + "name": "upstream_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finish_reason_id": { + "name": "finish_reason_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "latency": { + "name": "latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "moderation_latency": { + "name": "moderation_latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "generation_time": { + "name": "generation_time", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "is_byok": { + "name": "is_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_user_byok": { + "name": "is_user_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "streamed": { + "name": "streamed", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "cancelled": { + "name": "cancelled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "editor_name_id": { + "name": "editor_name_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "api_kind_id": { + "name": "api_kind_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "has_tools": { + "name": "has_tools", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "machine_id": { + "name": "machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mode_id": { + "name": "mode_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "auto_model_id": { + "name": "auto_model_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "market_cost": { + "name": "market_cost", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_microdollar_usage_metadata_created_at": { + "name": "idx_microdollar_usage_metadata_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk": { + "name": "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "http_user_agent", + "columnsFrom": [ + "http_user_agent_id" + ], + "columnsTo": [ + "http_user_agent_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk": { + "name": "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "http_ip", + "columnsFrom": [ + "http_ip_id" + ], + "columnsTo": [ + "http_ip_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk": { + "name": "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "vercel_ip_city", + "columnsFrom": [ + "vercel_ip_city_id" + ], + "columnsTo": [ + "vercel_ip_city_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk": { + "name": "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "vercel_ip_country", + "columnsFrom": [ + "vercel_ip_country_id" + ], + "columnsTo": [ + "vercel_ip_country_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk": { + "name": "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "ja4_digest", + "columnsFrom": [ + "ja4_digest_id" + ], + "columnsTo": [ + "ja4_digest_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk": { + "name": "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "system_prompt_prefix", + "columnsFrom": [ + "system_prompt_prefix_id" + ], + "columnsTo": [ + "system_prompt_prefix_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mode": { + "name": "mode", + "schema": "", + "columns": { + "mode_id": { + "name": "mode_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_mode": { + "name": "UQ_mode", + "columns": [ + { + "expression": "mode", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.model_stats": { + "name": "model_stats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "is_featured": { + "name": "is_featured", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_stealth": { + "name": "is_stealth", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_recommended": { + "name": "is_recommended", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "openrouter_id": { + "name": "openrouter_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "aa_slug": { + "name": "aa_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_creator": { + "name": "model_creator", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "creator_slug": { + "name": "creator_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "release_date": { + "name": "release_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "price_input": { + "name": "price_input", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "price_output": { + "name": "price_output", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "coding_index": { + "name": "coding_index", + "type": "numeric(5, 2)", + "primaryKey": false, + "notNull": false + }, + "speed_tokens_per_sec": { + "name": "speed_tokens_per_sec", + "type": "numeric(8, 2)", + "primaryKey": false, + "notNull": false + }, + "context_length": { + "name": "context_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_output_tokens": { + "name": "max_output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "input_modalities": { + "name": "input_modalities", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "openrouter_data": { + "name": "openrouter_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "benchmarks": { + "name": "benchmarks", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "chart_data": { + "name": "chart_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_model_stats_openrouter_id": { + "name": "IDX_model_stats_openrouter_id", + "columns": [ + { + "expression": "openrouter_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_slug": { + "name": "IDX_model_stats_slug", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_is_active": { + "name": "IDX_model_stats_is_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_creator_slug": { + "name": "IDX_model_stats_creator_slug", + "columns": [ + { + "expression": "creator_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_price_input": { + "name": "IDX_model_stats_price_input", + "columns": [ + { + "expression": "price_input", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_coding_index": { + "name": "IDX_model_stats_coding_index", + "columns": [ + { + "expression": "coding_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_context_length": { + "name": "IDX_model_stats_context_length", + "columns": [ + { + "expression": "context_length", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "model_stats_openrouter_id_unique": { + "name": "model_stats_openrouter_id_unique", + "nullsNotDistinct": false, + "columns": [ + "openrouter_id" + ] + }, + "model_stats_slug_unique": { + "name": "model_stats_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.models_by_provider": { + "name": "models_by_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "openrouter": { + "name": "openrouter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "vercel": { + "name": "vercel", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_audit_logs": { + "name": "organization_audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_audit_logs_organization_id": { + "name": "IDX_organization_audit_logs_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_action": { + "name": "IDX_organization_audit_logs_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_actor_id": { + "name": "IDX_organization_audit_logs_actor_id", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_created_at": { + "name": "IDX_organization_audit_logs_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_invitations": { + "name": "organization_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invited_by": { + "name": "invited_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_organization_invitations_token": { + "name": "UQ_organization_invitations_token", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_org_id": { + "name": "IDX_organization_invitations_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_email": { + "name": "IDX_organization_invitations_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_expires_at": { + "name": "IDX_organization_invitations_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_membership_removals": { + "name": "organization_membership_removals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "removed_at": { + "name": "removed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "removed_by": { + "name": "removed_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_role": { + "name": "previous_role", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "IDX_org_membership_removals_org_id": { + "name": "IDX_org_membership_removals_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_org_membership_removals_user_id": { + "name": "IDX_org_membership_removals_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_org_membership_removals_org_user": { + "name": "UQ_org_membership_removals_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_memberships": { + "name": "organization_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "invited_by": { + "name": "invited_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_memberships_org_id": { + "name": "IDX_organization_memberships_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_memberships_user_id": { + "name": "IDX_organization_memberships_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_memberships_org_user": { + "name": "UQ_organization_memberships_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_seats_purchases": { + "name": "organization_seats_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "subscription_stripe_id": { + "name": "subscription_stripe_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "seat_count": { + "name": "seat_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "subscription_status": { + "name": "subscription_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "starts_at": { + "name": "starts_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "billing_cycle": { + "name": "billing_cycle", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'monthly'" + } + }, + "indexes": { + "IDX_organization_seats_org_id": { + "name": "IDX_organization_seats_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_expires_at": { + "name": "IDX_organization_seats_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_created_at": { + "name": "IDX_organization_seats_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_updated_at": { + "name": "IDX_organization_seats_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_starts_at": { + "name": "IDX_organization_seats_starts_at", + "columns": [ + { + "expression": "starts_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_seats_idempotency_key": { + "name": "UQ_organization_seats_idempotency_key", + "nullsNotDistinct": false, + "columns": [ + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_user_limits": { + "name": "organization_user_limits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit_type": { + "name": "limit_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "microdollar_limit": { + "name": "microdollar_limit", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_user_limits_org_id": { + "name": "IDX_organization_user_limits_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_user_limits_user_id": { + "name": "IDX_organization_user_limits_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_user_limits_org_user": { + "name": "UQ_organization_user_limits_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id", + "limit_type" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_user_usage": { + "name": "organization_user_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "usage_date": { + "name": "usage_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "limit_type": { + "name": "limit_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "microdollar_usage": { + "name": "microdollar_usage", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_user_daily_usage_org_id": { + "name": "IDX_organization_user_daily_usage_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_user_daily_usage_user_id": { + "name": "IDX_organization_user_daily_usage_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_user_daily_usage_org_user_date": { + "name": "UQ_organization_user_daily_usage_org_user_date", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id", + "limit_type", + "usage_date" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organizations": { + "name": "organizations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "microdollars_used": { + "name": "microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "microdollars_balance": { + "name": "microdollars_balance", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "total_microdollars_acquired": { + "name": "total_microdollars_acquired", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "next_credit_expiration_at": { + "name": "next_credit_expiration_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_top_up_enabled": { + "name": "auto_top_up_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "seat_count": { + "name": "seat_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "require_seats": { + "name": "require_seats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by_kilo_user_id": { + "name": "created_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sso_domain": { + "name": "sso_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'teams'" + }, + "free_trial_end_at": { + "name": "free_trial_end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "company_domain": { + "name": "company_domain", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_organizations_sso_domain": { + "name": "IDX_organizations_sso_domain", + "columns": [ + { + "expression": "sso_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "organizations_name_not_empty_check": { + "name": "organizations_name_not_empty_check", + "value": "length(trim(\"organizations\".\"name\")) > 0" + } + }, + "isRLSEnabled": false + }, + "public.organization_modes": { + "name": "organization_modes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "IDX_organization_modes_organization_id": { + "name": "IDX_organization_modes_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_modes_org_id_slug": { + "name": "UQ_organization_modes_org_id_slug", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payment_methods": { + "name": "payment_methods", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "stripe_fingerprint": { + "name": "stripe_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last4": { + "name": "last4", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand": { + "name": "brand", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line1": { + "name": "address_line1", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line2": { + "name": "address_line2", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_city": { + "name": "address_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_state": { + "name": "address_state", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_zip": { + "name": "address_zip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "three_d_secure_supported": { + "name": "three_d_secure_supported", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "funding": { + "name": "funding", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "regulated_status": { + "name": "regulated_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line1_check_status": { + "name": "address_line1_check_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code_check_status": { + "name": "postal_code_check_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "eligible_for_free_credits": { + "name": "eligible_for_free_credits", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "stripe_data": { + "name": "stripe_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_d7d7fb15569674aaadcfbc0428": { + "name": "IDX_d7d7fb15569674aaadcfbc0428", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_e1feb919d0ab8a36381d5d5138": { + "name": "IDX_e1feb919d0ab8a36381d5d5138", + "columns": [ + { + "expression": "stripe_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_payment_methods_organization_id": { + "name": "IDX_payment_methods_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_29df1b0403df5792c96bbbfdbe6": { + "name": "UQ_29df1b0403df5792c96bbbfdbe6", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "stripe_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pending_impact_sale_reversals": { + "name": "pending_impact_sale_reversals", + "schema": "", + "columns": { + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "dispute_id": { + "name": "dispute_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_date": { + "name": "event_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_attempt_at": { + "name": "last_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "pending_impact_sale_reversals_attempt_count_non_negative_check": { + "name": "pending_impact_sale_reversals_attempt_count_non_negative_check", + "value": "\"pending_impact_sale_reversals\".\"attempt_count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.platform_integrations": { + "name": "platform_integrations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "integration_type": { + "name": "integration_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_installation_id": { + "name": "platform_installation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_account_id": { + "name": "platform_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_account_login": { + "name": "platform_account_login", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permissions": { + "name": "permissions", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "repository_access": { + "name": "repository_access", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "repositories": { + "name": "repositories", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "repositories_synced_at": { + "name": "repositories_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "kilo_requester_user_id": { + "name": "kilo_requester_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_requester_account_id": { + "name": "platform_requester_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "integration_status": { + "name": "integration_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "suspended_at": { + "name": "suspended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "suspended_by": { + "name": "suspended_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_app_type": { + "name": "github_app_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'standard'" + }, + "installed_at": { + "name": "installed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_platform_integrations_owned_by_org_platform_inst": { + "name": "UQ_platform_integrations_owned_by_org_platform_inst", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_platform_integrations_owned_by_user_platform_inst": { + "name": "UQ_platform_integrations_owned_by_user_platform_inst", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_platform_integrations_slack_platform_inst": { + "name": "UQ_platform_integrations_slack_platform_inst", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"platform\" = 'slack' AND \"platform_integrations\".\"platform_installation_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_org_id": { + "name": "IDX_platform_integrations_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_user_id": { + "name": "IDX_platform_integrations_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform_inst_id": { + "name": "IDX_platform_integrations_platform_inst_id", + "columns": [ + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform": { + "name": "IDX_platform_integrations_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_org_platform": { + "name": "IDX_platform_integrations_owned_by_org_platform", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_user_platform": { + "name": "IDX_platform_integrations_owned_by_user_platform", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_integration_status": { + "name": "IDX_platform_integrations_integration_status", + "columns": [ + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_kilo_requester": { + "name": "IDX_platform_integrations_kilo_requester", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kilo_requester_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform_requester": { + "name": "IDX_platform_integrations_platform_requester", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_requester_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "platform_integrations_owned_by_organization_id_organizations_id_fk": { + "name": "platform_integrations_owned_by_organization_id_organizations_id_fk", + "tableFrom": "platform_integrations", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "platform_integrations_owned_by_user_id_kilocode_users_id_fk": { + "name": "platform_integrations_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "platform_integrations", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "platform_integrations_owner_check": { + "name": "platform_integrations_owner_check", + "value": "(\n (\"platform_integrations\".\"owned_by_user_id\" IS NOT NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NULL) OR\n (\"platform_integrations\".\"owned_by_user_id\" IS NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.referral_code_usages": { + "name": "referral_code_usages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "referring_kilo_user_id": { + "name": "referring_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "redeeming_kilo_user_id": { + "name": "redeeming_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "paid_at": { + "name": "paid_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_referral_code_usages_redeeming_kilo_user_id": { + "name": "IDX_referral_code_usages_redeeming_kilo_user_id", + "columns": [ + { + "expression": "redeeming_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_referral_code_usages_redeeming_user_id_code": { + "name": "UQ_referral_code_usages_redeeming_user_id_code", + "nullsNotDistinct": false, + "columns": [ + "redeeming_kilo_user_id", + "referring_kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.referral_codes": { + "name": "referral_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "max_redemptions": { + "name": "max_redemptions", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_referral_codes_kilo_user_id": { + "name": "UQ_referral_codes_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_referral_codes_code": { + "name": "IDX_referral_codes_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_check_catalog": { + "name": "security_advisor_check_catalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "check_id": { + "name": "check_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "explanation": { + "name": "explanation", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "risk": { + "name": "risk", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_check_catalog_check_id_unique": { + "name": "security_advisor_check_catalog_check_id_unique", + "nullsNotDistinct": false, + "columns": [ + "check_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "security_advisor_check_catalog_severity_check": { + "name": "security_advisor_check_catalog_severity_check", + "value": "\"security_advisor_check_catalog\".\"severity\" in ('critical', 'warn', 'info')" + } + }, + "isRLSEnabled": false + }, + "public.security_advisor_content": { + "name": "security_advisor_content", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_content_key_unique": { + "name": "security_advisor_content_key_unique", + "nullsNotDistinct": false, + "columns": [ + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_kiloclaw_coverage": { + "name": "security_advisor_kiloclaw_coverage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "area": { + "name": "area", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "match_check_ids": { + "name": "match_check_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_kiloclaw_coverage_area_unique": { + "name": "security_advisor_kiloclaw_coverage_area_unique", + "nullsNotDistinct": false, + "columns": [ + "area" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_scans": { + "name": "security_advisor_scans", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_platform": { + "name": "source_platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_method": { + "name": "source_method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "plugin_version": { + "name": "plugin_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "openclaw_version": { + "name": "openclaw_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_ip": { + "name": "public_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "findings_critical": { + "name": "findings_critical", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "findings_warn": { + "name": "findings_warn", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "findings_info": { + "name": "findings_info", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_security_advisor_scans_user_created_at": { + "name": "idx_security_advisor_scans_user_created_at", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_advisor_scans_created_at": { + "name": "idx_security_advisor_scans_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_advisor_scans_platform": { + "name": "idx_security_advisor_scans_platform", + "columns": [ + { + "expression": "source_platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_analysis_owner_state": { + "name": "security_analysis_owner_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_analysis_enabled_at": { + "name": "auto_analysis_enabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_until": { + "name": "blocked_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "block_reason": { + "name": "block_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "consecutive_actor_resolution_failures": { + "name": "consecutive_actor_resolution_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_actor_resolution_failure_at": { + "name": "last_actor_resolution_failure_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_security_analysis_owner_state_org_owner": { + "name": "UQ_security_analysis_owner_state_org_owner", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"security_analysis_owner_state\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_security_analysis_owner_state_user_owner": { + "name": "UQ_security_analysis_owner_state_user_owner", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"security_analysis_owner_state\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk": { + "name": "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_analysis_owner_state", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_analysis_owner_state", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_analysis_owner_state_owner_check": { + "name": "security_analysis_owner_state_owner_check", + "value": "(\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "security_analysis_owner_state_block_reason_check": { + "name": "security_analysis_owner_state_block_reason_check", + "value": "\"security_analysis_owner_state\".\"block_reason\" IS NULL OR \"security_analysis_owner_state\".\"block_reason\" IN ('INSUFFICIENT_CREDITS', 'ACTOR_RESOLUTION_FAILED', 'OPERATOR_PAUSE')" + } + }, + "isRLSEnabled": false + }, + "public.security_analysis_queue": { + "name": "security_analysis_queue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "finding_id": { + "name": "finding_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "queue_status": { + "name": "queue_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity_rank": { + "name": "severity_rank", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "queued_at": { + "name": "queued_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_by_job_id": { + "name": "claimed_by_job_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "claim_token": { + "name": "claim_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reopen_requeue_count": { + "name": "reopen_requeue_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failure_code": { + "name": "failure_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_redacted": { + "name": "last_error_redacted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_security_analysis_queue_finding_id": { + "name": "UQ_security_analysis_queue_finding_id", + "columns": [ + { + "expression": "finding_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_claim_path_org": { + "name": "idx_security_analysis_queue_claim_path_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "severity_rank", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_claim_path_user": { + "name": "idx_security_analysis_queue_claim_path_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "severity_rank", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_in_flight_org": { + "name": "idx_security_analysis_queue_in_flight_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queue_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_in_flight_user": { + "name": "idx_security_analysis_queue_in_flight_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queue_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_lag_dashboards": { + "name": "idx_security_analysis_queue_lag_dashboards", + "columns": [ + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_pending_reconciliation": { + "name": "idx_security_analysis_queue_pending_reconciliation", + "columns": [ + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_running_reconciliation": { + "name": "idx_security_analysis_queue_running_reconciliation", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'running'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_failure_trend": { + "name": "idx_security_analysis_queue_failure_trend", + "columns": [ + { + "expression": "failure_code", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"failure_code\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_analysis_queue_finding_id_security_findings_id_fk": { + "name": "security_analysis_queue_finding_id_security_findings_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "security_findings", + "columnsFrom": [ + "finding_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_queue_owned_by_organization_id_organizations_id_fk": { + "name": "security_analysis_queue_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_analysis_queue_owner_check": { + "name": "security_analysis_queue_owner_check", + "value": "(\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "security_analysis_queue_status_check": { + "name": "security_analysis_queue_status_check", + "value": "\"security_analysis_queue\".\"queue_status\" IN ('queued', 'pending', 'running', 'failed', 'completed')" + }, + "security_analysis_queue_claim_token_required_check": { + "name": "security_analysis_queue_claim_token_required_check", + "value": "\"security_analysis_queue\".\"queue_status\" NOT IN ('pending', 'running') OR \"security_analysis_queue\".\"claim_token\" IS NOT NULL" + }, + "security_analysis_queue_attempt_count_non_negative_check": { + "name": "security_analysis_queue_attempt_count_non_negative_check", + "value": "\"security_analysis_queue\".\"attempt_count\" >= 0" + }, + "security_analysis_queue_reopen_requeue_count_non_negative_check": { + "name": "security_analysis_queue_reopen_requeue_count_non_negative_check", + "value": "\"security_analysis_queue\".\"reopen_requeue_count\" >= 0" + }, + "security_analysis_queue_severity_rank_check": { + "name": "security_analysis_queue_severity_rank_check", + "value": "\"security_analysis_queue\".\"severity_rank\" IN (0, 1, 2, 3)" + }, + "security_analysis_queue_failure_code_check": { + "name": "security_analysis_queue_failure_code_check", + "value": "\"security_analysis_queue\".\"failure_code\" IS NULL OR \"security_analysis_queue\".\"failure_code\" IN (\n 'NETWORK_TIMEOUT',\n 'UPSTREAM_5XX',\n 'TEMP_TOKEN_FAILURE',\n 'START_CALL_AMBIGUOUS',\n 'REQUEUE_TEMPORARY_PRECONDITION',\n 'ACTOR_RESOLUTION_FAILED',\n 'GITHUB_TOKEN_UNAVAILABLE',\n 'INVALID_CONFIG',\n 'MISSING_OWNERSHIP',\n 'PERMISSION_DENIED_PERMANENT',\n 'UNSUPPORTED_SEVERITY',\n 'INSUFFICIENT_CREDITS',\n 'STATE_GUARD_REJECTED',\n 'SKIPPED_ALREADY_IN_PROGRESS',\n 'SKIPPED_NO_LONGER_ELIGIBLE',\n 'REOPEN_LOOP_GUARD',\n 'RUN_LOST'\n )" + } + }, + "isRLSEnabled": false + }, + "public.security_audit_log": { + "name": "security_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "before_state": { + "name": "before_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after_state": { + "name": "after_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_security_audit_log_org_created": { + "name": "IDX_security_audit_log_org_created", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_user_created": { + "name": "IDX_security_audit_log_user_created", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_resource": { + "name": "IDX_security_audit_log_resource", + "columns": [ + { + "expression": "resource_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_actor": { + "name": "IDX_security_audit_log_actor", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_action": { + "name": "IDX_security_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_audit_log_owned_by_organization_id_organizations_id_fk": { + "name": "security_audit_log_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_audit_log", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_audit_log_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_audit_log_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_audit_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_audit_log_owner_check": { + "name": "security_audit_log_owner_check", + "value": "(\"security_audit_log\".\"owned_by_user_id\" IS NOT NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NULL) OR (\"security_audit_log\".\"owned_by_user_id\" IS NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NOT NULL)" + }, + "security_audit_log_action_check": { + "name": "security_audit_log_action_check", + "value": "\"security_audit_log\".\"action\" IN ('security.finding.created', 'security.finding.status_change', 'security.finding.dismissed', 'security.finding.auto_dismissed', 'security.finding.analysis_started', 'security.finding.analysis_completed', 'security.finding.deleted', 'security.config.enabled', 'security.config.disabled', 'security.config.updated', 'security.sync.triggered', 'security.sync.completed', 'security.audit_log.exported')" + } + }, + "isRLSEnabled": false + }, + "public.security_findings": { + "name": "security_findings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ghsa_id": { + "name": "ghsa_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cve_id": { + "name": "cve_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "package_name": { + "name": "package_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "package_ecosystem": { + "name": "package_ecosystem", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "vulnerable_version_range": { + "name": "vulnerable_version_range", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "patched_version": { + "name": "patched_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manifest_path": { + "name": "manifest_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "ignored_reason": { + "name": "ignored_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ignored_by": { + "name": "ignored_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fixed_at": { + "name": "fixed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sla_due_at": { + "name": "sla_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dependabot_html_url": { + "name": "dependabot_html_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cwe_ids": { + "name": "cwe_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "cvss_score": { + "name": "cvss_score", + "type": "numeric(3, 1)", + "primaryKey": false, + "notNull": false + }, + "dependency_scope": { + "name": "dependency_scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis_status": { + "name": "analysis_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis_started_at": { + "name": "analysis_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "analysis_completed_at": { + "name": "analysis_completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "analysis_error": { + "name": "analysis_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis": { + "name": "analysis", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "raw_data": { + "name": "raw_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "first_detected_at": { + "name": "first_detected_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_security_findings_org_id": { + "name": "idx_security_findings_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_user_id": { + "name": "idx_security_findings_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_repo": { + "name": "idx_security_findings_repo", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_severity": { + "name": "idx_security_findings_severity", + "columns": [ + { + "expression": "severity", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_status": { + "name": "idx_security_findings_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_package": { + "name": "idx_security_findings_package", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_sla_due_at": { + "name": "idx_security_findings_sla_due_at", + "columns": [ + { + "expression": "sla_due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_session_id": { + "name": "idx_security_findings_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_cli_session_id": { + "name": "idx_security_findings_cli_session_id", + "columns": [ + { + "expression": "cli_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_analysis_status": { + "name": "idx_security_findings_analysis_status", + "columns": [ + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_org_analysis_in_flight": { + "name": "idx_security_findings_org_analysis_in_flight", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_user_analysis_in_flight": { + "name": "idx_security_findings_user_analysis_in_flight", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_findings_owned_by_organization_id_organizations_id_fk": { + "name": "security_findings_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_findings", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_findings_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_findings_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_findings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_findings_platform_integration_id_platform_integrations_id_fk": { + "name": "security_findings_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "security_findings", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_security_findings_source": { + "name": "uq_security_findings_source", + "nullsNotDistinct": false, + "columns": [ + "repo_full_name", + "source", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "security_findings_owner_check": { + "name": "security_findings_owner_check", + "value": "(\n (\"security_findings\".\"owned_by_user_id\" IS NOT NULL AND \"security_findings\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_findings\".\"owned_by_user_id\" IS NULL AND \"security_findings\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.shared_cli_sessions": { + "name": "shared_cli_sessions", + "schema": "", + "columns": { + "share_id": { + "name": "share_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shared_state": { + "name": "shared_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'public'" + }, + "api_conversation_history_blob_url": { + "name": "api_conversation_history_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "task_metadata_blob_url": { + "name": "task_metadata_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ui_messages_blob_url": { + "name": "ui_messages_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_state_blob_url": { + "name": "git_state_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_shared_cli_sessions_session_id": { + "name": "IDX_shared_cli_sessions_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_shared_cli_sessions_created_at": { + "name": "IDX_shared_cli_sessions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_cli_sessions_session_id_cli_sessions_session_id_fk": { + "name": "shared_cli_sessions_session_id_cli_sessions_session_id_fk", + "tableFrom": "shared_cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk": { + "name": "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "shared_cli_sessions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "shared_cli_sessions_shared_state_check": { + "name": "shared_cli_sessions_shared_state_check", + "value": "\"shared_cli_sessions\".\"shared_state\" IN ('public', 'organization')" + } + }, + "isRLSEnabled": false + }, + "public.slack_bot_requests": { + "name": "slack_bot_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "slack_team_id": { + "name": "slack_team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_team_name": { + "name": "slack_team_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slack_channel_id": { + "name": "slack_channel_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_user_id": { + "name": "slack_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_thread_ts": { + "name": "slack_thread_ts", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_message": { + "name": "user_message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_message_truncated": { + "name": "user_message_truncated", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_time_ms": { + "name": "response_time_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "model_used": { + "name": "model_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tool_calls_made": { + "name": "tool_calls_made", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_slack_bot_requests_created_at": { + "name": "idx_slack_bot_requests_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_slack_team_id": { + "name": "idx_slack_bot_requests_slack_team_id", + "columns": [ + { + "expression": "slack_team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_owned_by_org_id": { + "name": "idx_slack_bot_requests_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_owned_by_user_id": { + "name": "idx_slack_bot_requests_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_status": { + "name": "idx_slack_bot_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_event_type": { + "name": "idx_slack_bot_requests_event_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_team_created": { + "name": "idx_slack_bot_requests_team_created", + "columns": [ + { + "expression": "slack_team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "slack_bot_requests_owned_by_organization_id_organizations_id_fk": { + "name": "slack_bot_requests_owned_by_organization_id_organizations_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk": { + "name": "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "slack_bot_requests_platform_integration_id_platform_integrations_id_fk": { + "name": "slack_bot_requests_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "slack_bot_requests_owner_check": { + "name": "slack_bot_requests_owner_check", + "value": "(\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NOT NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NOT NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.source_embeddings": { + "name": "source_embeddings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": true + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_hash": { + "name": "file_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_line": { + "name": "start_line", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "end_line": { + "name": "end_line", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'main'" + }, + "is_base_branch": { + "name": "is_base_branch", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_source_embeddings_organization_id": { + "name": "IDX_source_embeddings_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_kilo_user_id": { + "name": "IDX_source_embeddings_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_project_id": { + "name": "IDX_source_embeddings_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_created_at": { + "name": "IDX_source_embeddings_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_updated_at": { + "name": "IDX_source_embeddings_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_file_path_lower": { + "name": "IDX_source_embeddings_file_path_lower", + "columns": [ + { + "expression": "LOWER(\"file_path\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_git_branch": { + "name": "IDX_source_embeddings_git_branch", + "columns": [ + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_org_project_branch": { + "name": "IDX_source_embeddings_org_project_branch", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "source_embeddings_organization_id_organizations_id_fk": { + "name": "source_embeddings_organization_id_organizations_id_fk", + "tableFrom": "source_embeddings", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "source_embeddings_kilo_user_id_kilocode_users_id_fk": { + "name": "source_embeddings_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "source_embeddings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_source_embeddings_org_project_branch_file_lines": { + "name": "UQ_source_embeddings_org_project_branch_file_lines", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "project_id", + "git_branch", + "file_path", + "start_line", + "end_line" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.stytch_fingerprints": { + "name": "stytch_fingerprints", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visitor_fingerprint": { + "name": "visitor_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "browser_fingerprint": { + "name": "browser_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "browser_id": { + "name": "browser_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hardware_fingerprint": { + "name": "hardware_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "network_fingerprint": { + "name": "network_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visitor_id": { + "name": "visitor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verdict_action": { + "name": "verdict_action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "detected_device_type": { + "name": "detected_device_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_authentic_device": { + "name": "is_authentic_device", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{\"\"}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fingerprint_data": { + "name": "fingerprint_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "kilo_free_tier_allowed": { + "name": "kilo_free_tier_allowed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_fingerprint_data": { + "name": "idx_fingerprint_data", + "columns": [ + { + "expression": "fingerprint_data", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_hardware_fingerprint": { + "name": "idx_hardware_fingerprint", + "columns": [ + { + "expression": "hardware_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_kilo_user_id": { + "name": "idx_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reasons": { + "name": "idx_reasons", + "columns": [ + { + "expression": "reasons", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_verdict_action": { + "name": "idx_verdict_action", + "columns": [ + { + "expression": "verdict_action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_visitor_fingerprint": { + "name": "idx_visitor_fingerprint", + "columns": [ + { + "expression": "visitor_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.system_prompt_prefix": { + "name": "system_prompt_prefix", + "schema": "", + "columns": { + "system_prompt_prefix_id": { + "name": "system_prompt_prefix_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "system_prompt_prefix": { + "name": "system_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_system_prompt_prefix": { + "name": "UQ_system_prompt_prefix", + "columns": [ + { + "expression": "system_prompt_prefix", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.transactional_email_log": { + "name": "transactional_email_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_type": { + "name": "email_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_transactional_email_log_type_idempotency_key": { + "name": "UQ_transactional_email_log_type_idempotency_key", + "columns": [ + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_transactional_email_log_user_id": { + "name": "IDX_transactional_email_log_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "transactional_email_log_user_id_kilocode_users_id_fk": { + "name": "transactional_email_log_user_id_kilocode_users_id_fk", + "tableFrom": "transactional_email_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_admin_notes": { + "name": "user_admin_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "note_content": { + "name": "note_content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "admin_kilo_user_id": { + "name": "admin_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_34517df0b385234babc38fe81b": { + "name": "IDX_34517df0b385234babc38fe81b", + "columns": [ + { + "expression": "admin_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_ccbde98c4c14046daa5682ec4f": { + "name": "IDX_ccbde98c4c14046daa5682ec4f", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_d0270eb24ef6442d65a0b7853c": { + "name": "IDX_d0270eb24ef6442d65a0b7853c", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_affiliate_attributions": { + "name": "user_affiliate_attributions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tracking_id": { + "name": "tracking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_affiliate_attributions_user_id": { + "name": "IDX_user_affiliate_attributions_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_affiliate_attributions_user_id_kilocode_users_id_fk": { + "name": "user_affiliate_attributions_user_id_kilocode_users_id_fk", + "tableFrom": "user_affiliate_attributions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_user_affiliate_attributions_user_provider": { + "name": "UQ_user_affiliate_attributions_user_provider", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "provider" + ] + } + }, + "policies": {}, + "checkConstraints": { + "user_affiliate_attributions_provider_check": { + "name": "user_affiliate_attributions_provider_check", + "value": "\"user_affiliate_attributions\".\"provider\" IN ('impact')" + } + }, + "isRLSEnabled": false + }, + "public.user_affiliate_events": { + "name": "user_affiliate_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parent_event_id": { + "name": "parent_event_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "delivery_state": { + "name": "delivery_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "payload_json": { + "name": "payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impact_action_id": { + "name": "impact_action_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impact_submission_uri": { + "name": "impact_submission_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_affiliate_events_claim_path": { + "name": "IDX_user_affiliate_events_claim_path", + "columns": [ + { + "expression": "delivery_state", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_affiliate_events_parent_event_id": { + "name": "IDX_user_affiliate_events_parent_event_id", + "columns": [ + { + "expression": "parent_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_affiliate_events_provider_event_type_charge": { + "name": "IDX_user_affiliate_events_provider_event_type_charge", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stripe_charge_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_affiliate_events_user_id_kilocode_users_id_fk": { + "name": "user_affiliate_events_user_id_kilocode_users_id_fk", + "tableFrom": "user_affiliate_events", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "user_affiliate_events_parent_event_id_fk": { + "name": "user_affiliate_events_parent_event_id_fk", + "tableFrom": "user_affiliate_events", + "tableTo": "user_affiliate_events", + "columnsFrom": [ + "parent_event_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_user_affiliate_events_dedupe_key": { + "name": "UQ_user_affiliate_events_dedupe_key", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "user_affiliate_events_provider_check": { + "name": "user_affiliate_events_provider_check", + "value": "\"user_affiliate_events\".\"provider\" IN ('impact')" + }, + "user_affiliate_events_event_type_check": { + "name": "user_affiliate_events_event_type_check", + "value": "\"user_affiliate_events\".\"event_type\" IN ('signup', 'trial_start', 'trial_end', 'sale', 'sale_reversal')" + }, + "user_affiliate_events_delivery_state_check": { + "name": "user_affiliate_events_delivery_state_check", + "value": "\"user_affiliate_events\".\"delivery_state\" IN ('queued', 'blocked', 'sending', 'delivered', 'failed')" + }, + "user_affiliate_events_attempt_count_non_negative_check": { + "name": "user_affiliate_events_attempt_count_non_negative_check", + "value": "\"user_affiliate_events\".\"attempt_count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.user_auth_provider": { + "name": "user_auth_provider", + "schema": "", + "columns": { + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hosted_domain": { + "name": "hosted_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_auth_provider_kilo_user_id": { + "name": "IDX_user_auth_provider_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_auth_provider_hosted_domain": { + "name": "IDX_user_auth_provider_hosted_domain", + "columns": [ + { + "expression": "hosted_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "user_auth_provider_provider_provider_account_id_pk": { + "name": "user_auth_provider_provider_provider_account_id_pk", + "columns": [ + "provider", + "provider_account_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_feedback": { + "name": "user_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "feedback_for": { + "name": "feedback_for", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "feedback_batch": { + "name": "feedback_batch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "context_json": { + "name": "context_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_feedback_created_at": { + "name": "IDX_user_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_kilo_user_id": { + "name": "IDX_user_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_feedback_for": { + "name": "IDX_user_feedback_feedback_for", + "columns": [ + { + "expression": "feedback_for", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_feedback_batch": { + "name": "IDX_user_feedback_feedback_batch", + "columns": [ + { + "expression": "feedback_batch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_source": { + "name": "IDX_user_feedback_source", + "columns": [ + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "user_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "user_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_period_cache": { + "name": "user_period_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cache_type": { + "name": "cache_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_type": { + "name": "period_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_key": { + "name": "period_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "computed_at": { + "name": "computed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "shared_url_token": { + "name": "shared_url_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shared_at": { + "name": "shared_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_user_period_cache_kilo_user_id": { + "name": "IDX_user_period_cache_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_user_period_cache": { + "name": "UQ_user_period_cache", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "cache_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_period_cache_lookup": { + "name": "IDX_user_period_cache_lookup", + "columns": [ + { + "expression": "cache_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_user_period_cache_share_token": { + "name": "UQ_user_period_cache_share_token", + "columns": [ + { + "expression": "shared_url_token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"user_period_cache\".\"shared_url_token\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_period_cache_kilo_user_id_kilocode_users_id_fk": { + "name": "user_period_cache_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "user_period_cache", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "user_period_cache_period_type_check": { + "name": "user_period_cache_period_type_check", + "value": "\"user_period_cache\".\"period_type\" IN ('year', 'quarter', 'month', 'week', 'custom')" + } + }, + "isRLSEnabled": false + }, + "public.user_push_tokens": { + "name": "user_push_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_user_push_tokens_token": { + "name": "UQ_user_push_tokens_token", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_push_tokens_user_id": { + "name": "IDX_user_push_tokens_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_push_tokens_user_id_kilocode_users_id_fk": { + "name": "user_push_tokens_user_id_kilocode_users_id_fk", + "tableFrom": "user_push_tokens", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vercel_ip_city": { + "name": "vercel_ip_city", + "schema": "", + "columns": { + "vercel_ip_city_id": { + "name": "vercel_ip_city_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "vercel_ip_city": { + "name": "vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_vercel_ip_city": { + "name": "UQ_vercel_ip_city", + "columns": [ + { + "expression": "vercel_ip_city", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vercel_ip_country": { + "name": "vercel_ip_country", + "schema": "", + "columns": { + "vercel_ip_country_id": { + "name": "vercel_ip_country_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "vercel_ip_country": { + "name": "vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_vercel_ip_country": { + "name": "UQ_vercel_ip_country", + "columns": [ + { + "expression": "vercel_ip_country", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_events": { + "name": "webhook_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_action": { + "name": "event_action", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "processed": { + "name": "processed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "handlers_triggered": { + "name": "handlers_triggered", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "errors": { + "name": "errors", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "event_signature": { + "name": "event_signature", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_webhook_events_owned_by_org_id": { + "name": "IDX_webhook_events_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_owned_by_user_id": { + "name": "IDX_webhook_events_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_platform": { + "name": "IDX_webhook_events_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_event_type": { + "name": "IDX_webhook_events_event_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_created_at": { + "name": "IDX_webhook_events_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_events_owned_by_organization_id_organizations_id_fk": { + "name": "webhook_events_owned_by_organization_id_organizations_id_fk", + "tableFrom": "webhook_events", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_events_owned_by_user_id_kilocode_users_id_fk": { + "name": "webhook_events_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "webhook_events", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_webhook_events_signature": { + "name": "UQ_webhook_events_signature", + "nullsNotDistinct": false, + "columns": [ + "event_signature" + ] + } + }, + "policies": {}, + "checkConstraints": { + "webhook_events_owner_check": { + "name": "webhook_events_owner_check", + "value": "(\n (\"webhook_events\".\"owned_by_user_id\" IS NOT NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NULL) OR\n (\"webhook_events\".\"owned_by_user_id\" IS NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "public.microdollar_usage_view": { + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "output_tokens": { + "name": "output_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_write_tokens": { + "name": "cache_write_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_hit_tokens": { + "name": "cache_hit_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_model": { + "name": "requested_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_prompt_prefix": { + "name": "user_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_prefix": { + "name": "system_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_length": { + "name": "system_prompt_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cache_discount": { + "name": "cache_discount", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "max_tokens": { + "name": "max_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_middle_out_transform": { + "name": "has_middle_out_transform", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "has_error": { + "name": "has_error", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "abuse_classification": { + "name": "abuse_classification", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "inference_provider": { + "name": "inference_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "upstream_id": { + "name": "upstream_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finish_reason": { + "name": "finish_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "latency": { + "name": "latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "moderation_latency": { + "name": "moderation_latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "generation_time": { + "name": "generation_time", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "is_byok": { + "name": "is_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_user_byok": { + "name": "is_user_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "streamed": { + "name": "streamed", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "cancelled": { + "name": "cancelled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "editor_name": { + "name": "editor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_kind": { + "name": "api_kind", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "has_tools": { + "name": "has_tools", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "machine_id": { + "name": "machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature": { + "name": "feature", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_model": { + "name": "auto_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "market_cost": { + "name": "market_cost", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "definition": "\n SELECT\n mu.id,\n mu.kilo_user_id,\n meta.message_id,\n mu.cost,\n mu.input_tokens,\n mu.output_tokens,\n mu.cache_write_tokens,\n mu.cache_hit_tokens,\n mu.created_at,\n ip.http_ip AS http_x_forwarded_for,\n city.vercel_ip_city AS http_x_vercel_ip_city,\n country.vercel_ip_country AS http_x_vercel_ip_country,\n meta.vercel_ip_latitude AS http_x_vercel_ip_latitude,\n meta.vercel_ip_longitude AS http_x_vercel_ip_longitude,\n ja4.ja4_digest AS http_x_vercel_ja4_digest,\n mu.provider,\n mu.model,\n mu.requested_model,\n meta.user_prompt_prefix,\n spp.system_prompt_prefix,\n meta.system_prompt_length,\n ua.http_user_agent,\n mu.cache_discount,\n meta.max_tokens,\n meta.has_middle_out_transform,\n mu.has_error,\n mu.abuse_classification,\n mu.organization_id,\n mu.inference_provider,\n mu.project_id,\n meta.status_code,\n meta.upstream_id,\n frfr.finish_reason,\n meta.latency,\n meta.moderation_latency,\n meta.generation_time,\n meta.is_byok,\n meta.is_user_byok,\n meta.streamed,\n meta.cancelled,\n edit.editor_name,\n ak.api_kind,\n meta.has_tools,\n meta.machine_id,\n feat.feature,\n meta.session_id,\n md.mode,\n am.auto_model,\n meta.market_cost,\n meta.is_free\n FROM \"microdollar_usage\" mu\n LEFT JOIN \"microdollar_usage_metadata\" meta ON mu.id = meta.id\n LEFT JOIN \"http_ip\" ip ON meta.http_ip_id = ip.http_ip_id\n LEFT JOIN \"vercel_ip_city\" city ON meta.vercel_ip_city_id = city.vercel_ip_city_id\n LEFT JOIN \"vercel_ip_country\" country ON meta.vercel_ip_country_id = country.vercel_ip_country_id\n LEFT JOIN \"ja4_digest\" ja4 ON meta.ja4_digest_id = ja4.ja4_digest_id\n LEFT JOIN \"system_prompt_prefix\" spp ON meta.system_prompt_prefix_id = spp.system_prompt_prefix_id\n LEFT JOIN \"http_user_agent\" ua ON meta.http_user_agent_id = ua.http_user_agent_id\n LEFT JOIN \"finish_reason\" frfr ON meta.finish_reason_id = frfr.finish_reason_id\n LEFT JOIN \"editor_name\" edit ON meta.editor_name_id = edit.editor_name_id\n LEFT JOIN \"api_kind\" ak ON meta.api_kind_id = ak.api_kind_id\n LEFT JOIN \"feature\" feat ON meta.feature_id = feat.feature_id\n LEFT JOIN \"mode\" md ON meta.mode_id = md.mode_id\n LEFT JOIN \"auto_model\" am ON meta.auto_model_id = am.auto_model_id\n", + "name": "microdollar_usage_view", + "schema": "public", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json index 36cd2f4db1..748eb41d1b 100644 --- a/packages/db/src/migrations/meta/_journal.json +++ b/packages/db/src/migrations/meta/_journal.json @@ -806,6 +806,13 @@ "when": 1778050833487, "tag": "0114_steep_hercules", "breakpoints": true + }, + { + "idx": 115, + "version": "7", + "when": 1778071256277, + "tag": "0115_amazing_scrambler", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema.test.ts b/packages/db/src/schema.test.ts index 860645307e..761bbdd4bf 100644 --- a/packages/db/src/schema.test.ts +++ b/packages/db/src/schema.test.ts @@ -6,6 +6,11 @@ import * as schema from './schema'; import { SCHEMA_CHECK_ENUMS } from './schema'; describe('database schema', () => { + it('includes Apple IAP purchase and notification tables', () => { + expect(Object.hasOwn(schema, 'apple_iap_purchases')).toBe(true); + expect(Object.hasOwn(schema, 'apple_iap_notifications')).toBe(true); + }); + it("should be up to date with migrations (run 'pnpm drizzle generate' if this fails)", async () => { const migrationsDir = './packages/db/src/migrations'; diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index d6bdfb58fb..51d301a1d7 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -194,6 +194,95 @@ export const credit_transactions = pgTable( export type CreditTransaction = typeof credit_transactions.$inferSelect; +export const apple_iap_purchases = pgTable( + 'apple_iap_purchases', + { + id: uuid() + .default(sql`pg_catalog.gen_random_uuid()`) + .primaryKey() + .notNull(), + kilo_user_id: text() + .notNull() + .references(() => kilocode_users.id), + apple_transaction_id: text().notNull(), + apple_original_transaction_id: text().notNull(), + apple_web_order_line_item_id: text(), + product_id: text().notNull(), + environment: text().notNull(), + bundle_id: text().notNull(), + purchase_date: timestamp({ withTimezone: true, mode: 'string' }).notNull(), + gross_price_cents: integer().notNull(), + credited_cents: integer().notNull(), + credited_microdollars: bigint({ mode: 'number' }).notNull(), + signed_transaction_jws: text().notNull(), + status: text().notNull(), + credit_transaction_id: uuid() + .notNull() + .references(() => credit_transactions.id), + refunded_at: timestamp({ withTimezone: true, mode: 'string' }), + refund_credit_transaction_id: uuid().references(() => credit_transactions.id), + created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), + updated_at: timestamp({ withTimezone: true, mode: 'string' }) + .defaultNow() + .notNull() + .$onUpdateFn(() => sql`now()`), + }, + table => [ + uniqueIndex('UQ_apple_iap_purchases_transaction_id').on(table.apple_transaction_id), + uniqueIndex('UQ_apple_iap_purchases_credit_transaction_id').on(table.credit_transaction_id), + uniqueIndex('UQ_apple_iap_purchases_refund_credit_transaction_id') + .on(table.refund_credit_transaction_id) + .where(isNotNull(table.refund_credit_transaction_id)), + index('IDX_apple_iap_purchases_user_id').on(table.kilo_user_id), + index('IDX_apple_iap_purchases_original_transaction_id').on( + table.apple_original_transaction_id + ), + check( + 'apple_iap_purchases_status_check', + sql`${table.status} IN ('granted', 'refunded', 'revoked')` + ), + check( + 'apple_iap_purchases_environment_check', + sql`${table.environment} IN ('Sandbox', 'Production')` + ), + check('apple_iap_purchases_credited_positive_check', sql`${table.credited_cents} > 0`), + ] +); + +export type AppleIapPurchase = typeof apple_iap_purchases.$inferSelect; + +export const apple_iap_notifications = pgTable( + 'apple_iap_notifications', + { + id: uuid() + .default(sql`pg_catalog.gen_random_uuid()`) + .primaryKey() + .notNull(), + notification_uuid: text().notNull(), + notification_type: text().notNull(), + subtype: text(), + environment: text().notNull(), + apple_transaction_id: text(), + apple_original_transaction_id: text(), + signed_payload_jws: text().notNull(), + processed_at: timestamp({ withTimezone: true, mode: 'string' }), + created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), + }, + table => [ + uniqueIndex('UQ_apple_iap_notifications_uuid').on(table.notification_uuid), + index('IDX_apple_iap_notifications_transaction_id').on(table.apple_transaction_id), + index('IDX_apple_iap_notifications_original_transaction_id').on( + table.apple_original_transaction_id + ), + check( + 'apple_iap_notifications_environment_check', + sql`${table.environment} IN ('Sandbox', 'Production')` + ), + ] +); + +export type AppleIapNotification = typeof apple_iap_notifications.$inferSelect; + export const credit_campaigns = pgTable( 'credit_campaigns', { From 724094f2c966b3eeec2a3580da8737d4b4cf627c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:02:39 +0200 Subject: [PATCH 03/34] feat(web): define Apple credit products --- apps/web/src/lib/apple-iap/products.test.ts | 43 ++++++++++++++++++ apps/web/src/lib/apple-iap/products.ts | 50 +++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 apps/web/src/lib/apple-iap/products.test.ts create mode 100644 apps/web/src/lib/apple-iap/products.ts diff --git a/apps/web/src/lib/apple-iap/products.test.ts b/apps/web/src/lib/apple-iap/products.test.ts new file mode 100644 index 0000000000..2a4c332f40 --- /dev/null +++ b/apps/web/src/lib/apple-iap/products.test.ts @@ -0,0 +1,43 @@ +import { APPLE_IAP_CREDIT_PRODUCTS, getEnabledAppleCreditProducts } from './products'; + +describe('Apple IAP products', () => { + it('defines the three v1 products with credited amounts', () => { + expect(APPLE_IAP_CREDIT_PRODUCTS).toEqual([ + { + id: 'com.kilocode.kiloapp.credits.small.999', + tier: 'small', + grossPriceCents: 999, + creditedCents: 699, + creditedMicrodollars: 6_990_000, + enabled: true, + }, + { + id: 'com.kilocode.kiloapp.credits.medium.1999', + tier: 'medium', + grossPriceCents: 1999, + creditedCents: 1399, + creditedMicrodollars: 13_990_000, + enabled: true, + }, + { + id: 'com.kilocode.kiloapp.credits.large.4999', + tier: 'large', + grossPriceCents: 4999, + creditedCents: 3499, + creditedMicrodollars: 34_990_000, + enabled: true, + }, + ]); + }); + + it('returns only enabled products for clients', () => { + expect(getEnabledAppleCreditProducts()).toEqual( + APPLE_IAP_CREDIT_PRODUCTS.map(product => ({ + id: product.id, + tier: product.tier, + creditedCents: product.creditedCents, + creditedMicrodollars: product.creditedMicrodollars, + })) + ); + }); +}); diff --git a/apps/web/src/lib/apple-iap/products.ts b/apps/web/src/lib/apple-iap/products.ts new file mode 100644 index 0000000000..4d2e2166b8 --- /dev/null +++ b/apps/web/src/lib/apple-iap/products.ts @@ -0,0 +1,50 @@ +export type AppleCreditProductTier = 'small' | 'medium' | 'large'; + +export type AppleCreditProduct = { + id: string; + tier: AppleCreditProductTier; + grossPriceCents: number; + creditedCents: number; + creditedMicrodollars: number; + enabled: boolean; +}; + +export const APPLE_IAP_CREDIT_PRODUCTS = [ + { + id: 'com.kilocode.kiloapp.credits.small.999', + tier: 'small', + grossPriceCents: 999, + creditedCents: 699, + creditedMicrodollars: 6_990_000, + enabled: true, + }, + { + id: 'com.kilocode.kiloapp.credits.medium.1999', + tier: 'medium', + grossPriceCents: 1999, + creditedCents: 1399, + creditedMicrodollars: 13_990_000, + enabled: true, + }, + { + id: 'com.kilocode.kiloapp.credits.large.4999', + tier: 'large', + grossPriceCents: 4999, + creditedCents: 3499, + creditedMicrodollars: 34_990_000, + enabled: true, + }, +] as const satisfies readonly AppleCreditProduct[]; + +export function getAppleCreditProduct(productId: string): AppleCreditProduct | null { + return APPLE_IAP_CREDIT_PRODUCTS.find(product => product.id === productId) ?? null; +} + +export function getEnabledAppleCreditProducts() { + return APPLE_IAP_CREDIT_PRODUCTS.filter(product => product.enabled).map(product => ({ + id: product.id, + tier: product.tier, + creditedCents: product.creditedCents, + creditedMicrodollars: product.creditedMicrodollars, + })); +} From cd0581090911bc8cf509fa78a384088e419816a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:04:37 +0200 Subject: [PATCH 04/34] feat(web): add Apple signed data verifier --- apps/web/package.json | 1 + apps/web/src/lib/apple-iap/types.ts | 24 ++++++ apps/web/src/lib/apple-iap/verifier.ts | 107 +++++++++++++++++++++++++ pnpm-lock.yaml | 43 ++++++++++ 4 files changed, 175 insertions(+) create mode 100644 apps/web/src/lib/apple-iap/types.ts create mode 100644 apps/web/src/lib/apple-iap/verifier.ts diff --git a/apps/web/package.json b/apps/web/package.json index 761e4508da..6144e50118 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -33,6 +33,7 @@ "@ai-sdk/openai": "^3.0.41", "@ai-sdk/openai-compatible": "^2.0.35", "@anthropic-ai/sdk": "^0.90.0", + "@apple/app-store-server-library": "^3.0.0", "@aws-sdk/client-s3": "^3.1009.0", "@aws-sdk/s3-request-presigner": "^3.1009.0", "@chat-adapter/github": "4.27.0", diff --git a/apps/web/src/lib/apple-iap/types.ts b/apps/web/src/lib/apple-iap/types.ts new file mode 100644 index 0000000000..69540f1ae8 --- /dev/null +++ b/apps/web/src/lib/apple-iap/types.ts @@ -0,0 +1,24 @@ +export type AppleIapEnvironment = 'Sandbox' | 'Production'; + +export type AppleDecodedTransaction = { + transactionId: string; + originalTransactionId: string; + webOrderLineItemId?: string; + bundleId: string; + productId: string; + purchaseDate: number; + revocationDate?: number; + appAccountToken?: string; + environment: AppleIapEnvironment; + type?: string; +}; + +export type AppleDecodedNotification = { + notificationUUID: string; + notificationType: string; + subtype?: string; + data?: { + environment?: AppleIapEnvironment; + signedTransactionInfo?: string; + }; +}; diff --git a/apps/web/src/lib/apple-iap/verifier.ts b/apps/web/src/lib/apple-iap/verifier.ts new file mode 100644 index 0000000000..a7d06e8a76 --- /dev/null +++ b/apps/web/src/lib/apple-iap/verifier.ts @@ -0,0 +1,107 @@ +import { + Environment, + SignedDataVerifier, + type JWSTransactionDecodedPayload, + type ResponseBodyV2DecodedPayload, +} from '@apple/app-store-server-library'; +import { getEnvVariable } from '@/lib/dotenvx'; +import type { + AppleDecodedNotification, + AppleDecodedTransaction, + AppleIapEnvironment, +} from './types'; + +const BUNDLE_ID = 'com.kilocode.kiloapp'; + +function requiredEnv(name: string): string { + const value = getEnvVariable(name); + if (!value) throw new Error(`${name} is not set`); + return value; +} + +function getAppleEnvironment(): Environment { + return requiredEnv('APPLE_IAP_ENVIRONMENT') === 'Production' + ? Environment.PRODUCTION + : Environment.SANDBOX; +} + +function getAppleAppAppleId(): number | undefined { + const value = getEnvVariable('APPLE_APP_APPLE_ID'); + return value ? Number(value) : undefined; +} + +function getAppleRootCertificates(): Buffer[] { + const pemBundle = requiredEnv('APPLE_ROOT_CERTIFICATES_PEM'); + return pemBundle + .split('-----END CERTIFICATE-----') + .map(part => part.trim()) + .filter(Boolean) + .map(part => Buffer.from(`${part}\n-----END CERTIFICATE-----\n`)); +} + +function createVerifier(): SignedDataVerifier { + return new SignedDataVerifier( + getAppleRootCertificates(), + true, + getAppleEnvironment(), + BUNDLE_ID, + getAppleAppAppleId() + ); +} + +function normalizeEnvironment(environment: string | undefined): AppleIapEnvironment { + if (environment === 'Production') return 'Production'; + return 'Sandbox'; +} + +export async function verifyAppleTransactionJws( + transactionJws: string +): Promise { + const decoded = (await createVerifier().verifyAndDecodeTransaction( + transactionJws + )) as JWSTransactionDecodedPayload; + + if (!decoded.transactionId || !decoded.originalTransactionId || !decoded.bundleId) { + throw new Error('Apple transaction payload missing required identifiers'); + } + if (!decoded.productId || !decoded.purchaseDate) { + throw new Error('Apple transaction payload missing purchase fields'); + } + + return { + transactionId: decoded.transactionId, + originalTransactionId: decoded.originalTransactionId, + webOrderLineItemId: decoded.webOrderLineItemId, + bundleId: decoded.bundleId, + productId: decoded.productId, + purchaseDate: decoded.purchaseDate, + revocationDate: decoded.revocationDate, + appAccountToken: decoded.appAccountToken, + environment: normalizeEnvironment(decoded.environment), + type: decoded.type, + }; +} + +export async function verifyAppleNotificationJws( + signedPayload: string +): Promise { + const decoded = (await createVerifier().verifyAndDecodeNotification( + signedPayload + )) as ResponseBodyV2DecodedPayload; + + if (!decoded.notificationUUID || !decoded.notificationType) { + throw new Error('Apple notification payload missing required identifiers'); + } + + return { + notificationUUID: decoded.notificationUUID, + notificationType: decoded.notificationType, + subtype: decoded.subtype, + data: decoded.data + ? { + environment: normalizeEnvironment(decoded.data.environment), + signedTransactionInfo: decoded.data.signedTransactionInfo, + } + : undefined, + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4127c8720e..fc094db0a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -473,6 +473,9 @@ importers: '@anthropic-ai/sdk': specifier: ^0.90.0 version: 0.90.0(zod@4.3.6) + '@apple/app-store-server-library': + specifier: ^3.0.0 + version: 3.0.0 '@aws-sdk/client-s3': specifier: ^3.1009.0 version: 3.1009.0 @@ -2382,6 +2385,9 @@ packages: zod: optional: true + '@apple/app-store-server-library@3.0.0': + resolution: {integrity: sha512-H7WYYxA5PXXDjTA0WPa2e+8yQzY3loXF+71PslshJgggJnR0Dpt5bZFCTEYC542Rx03wmnj5e4PHk0AWaU9hFA==} + '@ashishkumar472/cf-git@1.0.5': resolution: {integrity: sha512-89+6PVvewx4ap9ZctVEkGA5SEspYOpJMXfa1btDFV3xuERsRfCZJR+sB4JRRkbEdA8ppFKpvsVAzZ3h77miClw==} engines: {node: '>=14.17'} @@ -7996,6 +8002,9 @@ packages: '@types/jsonwebtoken@9.0.10': resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} + '@types/jsrsasign@10.5.15': + resolution: {integrity: sha512-3stUTaSRtN09PPzVWR6aySD9gNnuymz+WviNHoTb85dKu+BjaV4uBbWWGykBBJkfwPtcNZVfTn2lbX00U+yhpQ==} + '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} @@ -8011,6 +8020,9 @@ packages: '@types/mysql@2.15.27': resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + '@types/node-fetch@2.6.13': + resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + '@types/node@20.19.37': resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} @@ -8905,6 +8917,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + base64url@3.0.1: + resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} + engines: {node: '>=6.0.0'} + baseline-browser-mapping@2.10.8: resolution: {integrity: sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==} engines: {node: '>=6.0.0'} @@ -11847,6 +11863,9 @@ packages: resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} engines: {node: '>=12', npm: '>=6'} + jsrsasign@11.1.3: + resolution: {integrity: sha512-nPnK5D/4lv0Dwr7TlzrKtAd8JlLZwFTqTUUB3NQCbtdobcRcohGFxjbPySDVh74iWUudcCsapYT6OxoyhJLhhA==} + jsx-ast-utils-x@0.1.0: resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -15482,6 +15501,19 @@ snapshots: optionalDependencies: zod: 4.3.6 + '@apple/app-store-server-library@3.0.0': + dependencies: + '@types/jsonwebtoken': 9.0.10 + '@types/jsrsasign': 10.5.15 + '@types/node': 25.5.0 + '@types/node-fetch': 2.6.13 + base64url: 3.0.1 + jsonwebtoken: 9.0.3 + jsrsasign: 11.1.3 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + '@ashishkumar472/cf-git@1.0.5': dependencies: clean-git-ref: 2.0.1 @@ -22792,6 +22824,8 @@ snapshots: '@types/ms': 2.1.0 '@types/node': 25.5.0 + '@types/jsrsasign@10.5.15': {} + '@types/linkify-it@5.0.0': {} '@types/mdast@4.0.4': @@ -22806,6 +22840,11 @@ snapshots: dependencies: '@types/node': 25.5.0 + '@types/node-fetch@2.6.13': + dependencies: + '@types/node': 25.5.0 + form-data: 4.0.5 + '@types/node@20.19.37': dependencies: undici-types: 6.21.0 @@ -23788,6 +23827,8 @@ snapshots: base64-js@1.5.1: {} + base64url@3.0.1: {} + baseline-browser-mapping@2.10.8: {} before-after-hook@4.0.0: {} @@ -27419,6 +27460,8 @@ snapshots: ms: 2.1.3 semver: 7.7.4 + jsrsasign@11.1.3: {} + jsx-ast-utils-x@0.1.0: {} jwa@2.0.1: From f0681cbc4f668d11f34dd49599900b78257dfe5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:06:02 +0200 Subject: [PATCH 05/34] feat(web): process Apple credit purchases --- apps/web/src/lib/apple-iap/purchases.test.ts | 160 +++++++++++++++++++ apps/web/src/lib/apple-iap/purchases.ts | 147 +++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 apps/web/src/lib/apple-iap/purchases.test.ts create mode 100644 apps/web/src/lib/apple-iap/purchases.ts diff --git a/apps/web/src/lib/apple-iap/purchases.test.ts b/apps/web/src/lib/apple-iap/purchases.test.ts new file mode 100644 index 0000000000..0b0c1e3d35 --- /dev/null +++ b/apps/web/src/lib/apple-iap/purchases.test.ts @@ -0,0 +1,160 @@ +import { db } from '@/lib/drizzle'; +import { processAppleCreditPurchase, reverseAppleCreditPurchase } from './purchases'; +import { apple_iap_purchases, credit_transactions, kilocode_users } from '@kilocode/db/schema'; +import { insertTestUser } from '@/tests/helpers/user.helper'; +import { eq } from 'drizzle-orm'; + +function makeTransaction(transactionId: string) { + return { + ...baseTransaction, + transactionId, + originalTransactionId: `${transactionId}-original`, + }; +} + +const baseTransaction = { + transactionId: 'apple-txn-base', + originalTransactionId: 'apple-original-1', + bundleId: 'com.kilocode.kiloapp', + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseDate: Date.UTC(2026, 0, 1), + environment: 'Sandbox' as const, + appAccountToken: undefined, +}; + +describe('processAppleCreditPurchase', () => { + it('grants configured credits for a valid purchase', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0 }); + + const result = await processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-grant'), + }); + + expect(result).toEqual({ + creditedCents: 699, + creditedMicrodollars: 6_990_000, + alreadyProcessed: false, + }); + + const updatedUser = await db.query.kilocode_users.findFirst({ + where: eq(kilocode_users.id, user.id), + }); + expect(updatedUser?.total_microdollars_acquired).toBe(6_990_000); + + const purchase = await db.query.apple_iap_purchases.findFirst({ + where: eq(apple_iap_purchases.apple_transaction_id, 'apple-txn-grant'), + }); + expect(purchase?.credit_transaction_id).toBeTruthy(); + }); + + it('does not double grant duplicate submissions by the owning user', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0 }); + + await processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-duplicate-owner'), + }); + const replay = await processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-duplicate-owner'), + }); + + expect(replay.alreadyProcessed).toBe(true); + + const updatedUser = await db.query.kilocode_users.findFirst({ + where: eq(kilocode_users.id, user.id), + }); + expect(updatedUser?.total_microdollars_acquired).toBe(6_990_000); + }); + + it('rejects duplicate transaction submitted by a different user', async () => { + const owner = await insertTestUser(); + const attacker = await insertTestUser(); + + await processAppleCreditPurchase({ + user: owner, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-duplicate-other-user'), + }); + + await expect( + processAppleCreditPurchase({ + user: attacker, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-duplicate-other-user'), + }) + ).rejects.toThrow('Apple transaction already belongs to another user'); + }); + + it('rejects unknown product IDs', async () => { + const user = await insertTestUser(); + + await expect( + processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => ({ ...baseTransaction, productId: 'unknown' }), + }) + ).rejects.toThrow('Apple product is not enabled'); + }); + + it('rejects wrong bundle IDs', async () => { + const user = await insertTestUser(); + + await expect( + processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => ({ ...baseTransaction, bundleId: 'com.example.other' }), + }) + ).rejects.toThrow('Apple transaction bundle mismatch'); + }); + + it('rejects revoked transactions at completion time', async () => { + const user = await insertTestUser(); + + await expect( + processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => ({ ...baseTransaction, revocationDate: Date.now() }), + }) + ).rejects.toThrow('Apple transaction has been revoked'); + }); + + it('reverses refunds and allows negative balance', async () => { + const user = await insertTestUser({ + total_microdollars_acquired: 0, + microdollars_used: 1_000_000, + }); + + await processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => makeTransaction('apple-txn-refund'), + }); + await reverseAppleCreditPurchase({ + appleTransactionId: 'apple-txn-refund', + reversalReason: 'refunded', + }); + + const updatedUser = await db.query.kilocode_users.findFirst({ + where: eq(kilocode_users.id, user.id), + }); + expect(updatedUser?.total_microdollars_acquired).toBe(0); + expect( + (updatedUser?.total_microdollars_acquired ?? 0) - (updatedUser?.microdollars_used ?? 0) + ).toBe(-1_000_000); + + const transactions = await db.query.credit_transactions.findMany({ + where: eq(credit_transactions.kilo_user_id, user.id), + }); + expect(transactions.map(t => t.amount_microdollars).sort((a, b) => a - b)).toEqual([ + -6_990_000, 6_990_000, + ]); + }); +}); diff --git a/apps/web/src/lib/apple-iap/purchases.ts b/apps/web/src/lib/apple-iap/purchases.ts new file mode 100644 index 0000000000..2a2f5c5265 --- /dev/null +++ b/apps/web/src/lib/apple-iap/purchases.ts @@ -0,0 +1,147 @@ +import type { User } from '@kilocode/db/schema'; +import { apple_iap_purchases, credit_transactions, kilocode_users } from '@kilocode/db/schema'; +import { db, type DrizzleTransaction } from '@/lib/drizzle'; +import { eq, sql } from 'drizzle-orm'; +import { getAppleCreditProduct } from './products'; +import type { AppleDecodedTransaction } from './types'; +import { verifyAppleTransactionJws } from './verifier'; + +const EXPECTED_BUNDLE_ID = 'com.kilocode.kiloapp'; + +type ProcessAppleCreditPurchaseParams = { + user: User; + transactionJws: string; + verifyTransaction?: (transactionJws: string) => Promise; +}; + +export type ProcessAppleCreditPurchaseResult = { + creditedCents: number; + creditedMicrodollars: number; + alreadyProcessed: boolean; +}; + +function assertValidTransaction(transaction: AppleDecodedTransaction) { + if (transaction.bundleId !== EXPECTED_BUNDLE_ID) { + throw new Error('Apple transaction bundle mismatch'); + } + if (transaction.revocationDate) { + throw new Error('Apple transaction has been revoked'); + } + const product = getAppleCreditProduct(transaction.productId); + if (!product || !product.enabled) { + throw new Error('Apple product is not enabled'); + } + return product; +} + +export async function processAppleCreditPurchase({ + user, + transactionJws, + verifyTransaction = verifyAppleTransactionJws, +}: ProcessAppleCreditPurchaseParams): Promise { + const transaction = await verifyTransaction(transactionJws); + const product = assertValidTransaction(transaction); + + return db.transaction(async tx => { + const existing = await tx.query.apple_iap_purchases.findFirst({ + where: eq(apple_iap_purchases.apple_transaction_id, transaction.transactionId), + }); + + if (existing) { + if (existing.kilo_user_id !== user.id) { + throw new Error('Apple transaction already belongs to another user'); + } + return { + creditedCents: existing.credited_cents, + creditedMicrodollars: existing.credited_microdollars, + alreadyProcessed: true, + }; + } + + const creditTransactionId = crypto.randomUUID(); + await tx.insert(credit_transactions).values({ + id: creditTransactionId, + kilo_user_id: user.id, + is_free: false, + amount_microdollars: product.creditedMicrodollars, + description: 'Top-up via Apple', + original_baseline_microdollars_used: user.microdollars_used, + }); + + await tx.insert(apple_iap_purchases).values({ + kilo_user_id: user.id, + apple_transaction_id: transaction.transactionId, + apple_original_transaction_id: transaction.originalTransactionId, + apple_web_order_line_item_id: transaction.webOrderLineItemId ?? null, + product_id: transaction.productId, + environment: transaction.environment, + bundle_id: transaction.bundleId, + purchase_date: new Date(transaction.purchaseDate).toISOString(), + gross_price_cents: product.grossPriceCents, + credited_cents: product.creditedCents, + credited_microdollars: product.creditedMicrodollars, + signed_transaction_jws: transactionJws, + status: 'granted', + credit_transaction_id: creditTransactionId, + }); + + await incrementUserAcquiredCredits(tx, user.id, product.creditedMicrodollars); + + return { + creditedCents: product.creditedCents, + creditedMicrodollars: product.creditedMicrodollars, + alreadyProcessed: false, + }; + }); +} + +async function incrementUserAcquiredCredits( + tx: DrizzleTransaction, + userId: string, + amountMicrodollars: number +) { + const result = await tx + .update(kilocode_users) + .set({ + total_microdollars_acquired: sql`${kilocode_users.total_microdollars_acquired} + ${amountMicrodollars}`, + }) + .where(eq(kilocode_users.id, userId)); + if ((result.rowCount ?? 0) === 0) { + throw new Error(`Failed to update Apple IAP credit balance for user ${userId}`); + } +} + +export async function reverseAppleCreditPurchase(params: { + appleTransactionId: string; + reversalReason: 'refunded' | 'revoked'; +}): Promise<{ reversed: boolean }> { + return db.transaction(async tx => { + const purchase = await tx.query.apple_iap_purchases.findFirst({ + where: eq(apple_iap_purchases.apple_transaction_id, params.appleTransactionId), + }); + if (!purchase) return { reversed: false }; + if (purchase.refund_credit_transaction_id) return { reversed: false }; + + const refundCreditTransactionId = crypto.randomUUID(); + await tx.insert(credit_transactions).values({ + id: refundCreditTransactionId, + kilo_user_id: purchase.kilo_user_id, + is_free: false, + amount_microdollars: -purchase.credited_microdollars, + description: `Apple top-up ${params.reversalReason}`, + original_transaction_id: purchase.credit_transaction_id, + }); + + await tx + .update(apple_iap_purchases) + .set({ + status: params.reversalReason === 'refunded' ? 'refunded' : 'revoked', + refunded_at: new Date().toISOString(), + refund_credit_transaction_id: refundCreditTransactionId, + }) + .where(eq(apple_iap_purchases.id, purchase.id)); + + await incrementUserAcquiredCredits(tx, purchase.kilo_user_id, -purchase.credited_microdollars); + return { reversed: true }; + }); +} From f877f8f85f87f0fcf00aa85c4a767361b32ebb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:06:32 +0200 Subject: [PATCH 06/34] feat(web): expose Apple credit purchase APIs --- apps/web/src/routers/user-router.test.ts | 30 ++++++++++++++++++++++++ apps/web/src/routers/user-router.ts | 15 ++++++++++++ 2 files changed, 45 insertions(+) diff --git a/apps/web/src/routers/user-router.test.ts b/apps/web/src/routers/user-router.test.ts index 5585567d49..94734b8487 100644 --- a/apps/web/src/routers/user-router.test.ts +++ b/apps/web/src/routers/user-router.test.ts @@ -274,6 +274,36 @@ describe('user router - submitCustomerSource', () => { }); }); +describe('user router - Apple IAP credits', () => { + it('returns enabled Apple credit products', async () => { + const user = await insertTestUser(); + const caller = await createCallerForUser(user.id); + + await expect(caller.user.getAppleCreditProducts()).resolves.toEqual({ + products: [ + { + id: 'com.kilocode.kiloapp.credits.small.999', + tier: 'small', + creditedCents: 699, + creditedMicrodollars: 6_990_000, + }, + { + id: 'com.kilocode.kiloapp.credits.medium.1999', + tier: 'medium', + creditedCents: 1399, + creditedMicrodollars: 13_990_000, + }, + { + id: 'com.kilocode.kiloapp.credits.large.4999', + tier: 'large', + creditedCents: 3499, + creditedMicrodollars: 34_990_000, + }, + ], + }); + }); +}); + describe('user router - skipCustomerSource', () => { beforeAll(async () => { skipTestUser = await insertTestUser({ diff --git a/apps/web/src/routers/user-router.ts b/apps/web/src/routers/user-router.ts index f6eb3ba0d6..300157ee5c 100644 --- a/apps/web/src/routers/user-router.ts +++ b/apps/web/src/routers/user-router.ts @@ -38,6 +38,8 @@ import { getCreditBlocks } from '@/lib/getCreditBlocks'; import { getBalanceForUser } from '@/lib/user.balance'; import { getBalanceAndOrgSettings } from '@/lib/organizations/organization-usage'; import { revokeWebSessions } from '@/lib/web-session-revocation'; +import { getEnabledAppleCreditProducts } from '@/lib/apple-iap/products'; +import { processAppleCreditPurchase } from '@/lib/apple-iap/purchases'; const ACCOUNT_DELETION_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour @@ -354,6 +356,19 @@ export const userRouter = createTRPCRouter({ return { balance, isDepleted: balance <= 0 }; }), + getAppleCreditProducts: baseProcedure.query(() => { + return { products: getEnabledAppleCreditProducts() }; + }), + + completeAppleCreditPurchase: baseProcedure + .input(z.object({ transactionJws: z.string().min(1) })) + .mutation(async ({ ctx, input }) => { + return processAppleCreditPurchase({ + user: ctx.user, + transactionJws: input.transactionJws, + }); + }), + getAutocompleteMetrics: baseProcedure .input(AutocompleteMetricsInputSchema) .output(AutocompleteMetricsOutputSchema) From ca2c87b9403b67c02be3c637cc9ba8b1e87db83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:07:24 +0200 Subject: [PATCH 07/34] feat(web): handle Apple IAP notifications --- .../api/apple/iap/notifications/route.test.ts | 15 ++++ .../app/api/apple/iap/notifications/route.ts | 32 ++++++++ .../src/lib/apple-iap/notifications.test.ts | 78 +++++++++++++++++++ apps/web/src/lib/apple-iap/notifications.ts | 53 +++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 apps/web/src/app/api/apple/iap/notifications/route.test.ts create mode 100644 apps/web/src/app/api/apple/iap/notifications/route.ts create mode 100644 apps/web/src/lib/apple-iap/notifications.test.ts create mode 100644 apps/web/src/lib/apple-iap/notifications.ts diff --git a/apps/web/src/app/api/apple/iap/notifications/route.test.ts b/apps/web/src/app/api/apple/iap/notifications/route.test.ts new file mode 100644 index 0000000000..6932880421 --- /dev/null +++ b/apps/web/src/app/api/apple/iap/notifications/route.test.ts @@ -0,0 +1,15 @@ +import { POST } from './route'; + +describe('Apple IAP notification route', () => { + it('rejects missing signedPayload', async () => { + const response = await POST( + new Request('https://kilo.test/api/apple/iap/notifications', { + method: 'POST', + body: JSON.stringify({}), + }) + ); + + await expect(response.text()).resolves.toBe('Missing signedPayload'); + expect(response.status).toBe(400); + }); +}); diff --git a/apps/web/src/app/api/apple/iap/notifications/route.ts b/apps/web/src/app/api/apple/iap/notifications/route.ts new file mode 100644 index 0000000000..b5d11ba8ac --- /dev/null +++ b/apps/web/src/app/api/apple/iap/notifications/route.ts @@ -0,0 +1,32 @@ +import { NextResponse } from 'next/server'; +import { captureException } from '@sentry/nextjs'; +import { processAppleIapNotification } from '@/lib/apple-iap/notifications'; + +export async function POST(req: Request): Promise> { + let body: unknown; + try { + body = await req.json(); + } catch { + return new NextResponse('Invalid JSON', { status: 400 }); + } + + const signedPayload = + typeof body === 'object' && + body !== null && + 'signedPayload' in body && + typeof body.signedPayload === 'string' + ? body.signedPayload + : null; + + if (!signedPayload) { + return new NextResponse('Missing signedPayload', { status: 400 }); + } + + try { + await processAppleIapNotification({ signedPayload }); + return new NextResponse('OK', { status: 200 }); + } catch (error) { + captureException(error, { tags: { source: 'apple_iap_notification' } }); + return new NextResponse('Apple notification processing failed', { status: 400 }); + } +} diff --git a/apps/web/src/lib/apple-iap/notifications.test.ts b/apps/web/src/lib/apple-iap/notifications.test.ts new file mode 100644 index 0000000000..14ff871fa4 --- /dev/null +++ b/apps/web/src/lib/apple-iap/notifications.test.ts @@ -0,0 +1,78 @@ +import { db } from '@/lib/drizzle'; +import { processAppleCreditPurchase } from './purchases'; +import { processAppleIapNotification } from './notifications'; +import { insertTestUser } from '@/tests/helpers/user.helper'; +import { apple_iap_notifications, credit_transactions, kilocode_users } from '@kilocode/db/schema'; +import { eq } from 'drizzle-orm'; + +const transaction = { + transactionId: 'apple-notification-txn-1', + originalTransactionId: 'apple-notification-original-1', + bundleId: 'com.kilocode.kiloapp', + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseDate: Date.UTC(2026, 0, 1), + environment: 'Sandbox' as const, +}; + +describe('processAppleIapNotification', () => { + it('records duplicate notification UUIDs idempotently', async () => { + const notification = { + notificationUUID: 'notification-duplicate-1', + notificationType: 'DID_RENEW', + data: { environment: 'Sandbox' as const }, + }; + + const first = await processAppleIapNotification({ + signedPayload: 'signed-notification', + verifyNotification: async () => notification, + }); + const second = await processAppleIapNotification({ + signedPayload: 'signed-notification', + verifyNotification: async () => notification, + }); + + expect(first).toEqual({ duplicate: false, reversed: false }); + expect(second).toEqual({ duplicate: true, reversed: false }); + }); + + it('reverses a refund notification once', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0 }); + await processAppleCreditPurchase({ + user, + transactionJws: 'signed-transaction', + verifyTransaction: async () => transaction, + }); + + const result = await processAppleIapNotification({ + signedPayload: 'signed-refund-notification', + verifyNotification: async () => ({ + notificationUUID: 'notification-refund-1', + notificationType: 'REFUND', + data: { + environment: 'Sandbox', + signedTransactionInfo: 'signed-transaction', + }, + }), + verifyTransaction: async () => transaction, + }); + + expect(result).toEqual({ duplicate: false, reversed: true }); + + const updatedUser = await db.query.kilocode_users.findFirst({ + where: eq(kilocode_users.id, user.id), + }); + expect(updatedUser?.total_microdollars_acquired).toBe(0); + + const transactions = await db.query.credit_transactions.findMany({ + where: eq(credit_transactions.kilo_user_id, user.id), + }); + expect(transactions.map(t => t.amount_microdollars).sort((a, b) => a - b)).toEqual([ + -6_990_000, 6_990_000, + ]); + + const storedNotification = await db.query.apple_iap_notifications.findFirst({ + where: eq(apple_iap_notifications.notification_uuid, 'notification-refund-1'), + }); + expect(storedNotification?.processed_at).toBeTruthy(); + }); +}); diff --git a/apps/web/src/lib/apple-iap/notifications.ts b/apps/web/src/lib/apple-iap/notifications.ts new file mode 100644 index 0000000000..b1943dea1c --- /dev/null +++ b/apps/web/src/lib/apple-iap/notifications.ts @@ -0,0 +1,53 @@ +import { apple_iap_notifications } from '@kilocode/db/schema'; +import { db } from '@/lib/drizzle'; +import { eq } from 'drizzle-orm'; +import { verifyAppleNotificationJws, verifyAppleTransactionJws } from './verifier'; +import { reverseAppleCreditPurchase } from './purchases'; +import type { AppleDecodedNotification, AppleDecodedTransaction } from './types'; + +const REVERSAL_NOTIFICATION_TYPES = new Set(['REFUND', 'REVOKE', 'CONSUMPTION_REQUEST']); + +export async function processAppleIapNotification(params: { + signedPayload: string; + verifyNotification?: (signedPayload: string) => Promise; + verifyTransaction?: (transactionJws: string) => Promise; +}): Promise<{ duplicate: boolean; reversed: boolean }> { + const verifyNotification = params.verifyNotification ?? verifyAppleNotificationJws; + const verifyTransaction = params.verifyTransaction ?? verifyAppleTransactionJws; + const notification = await verifyNotification(params.signedPayload); + const signedTransactionInfo = notification.data?.signedTransactionInfo; + const transaction = signedTransactionInfo ? await verifyTransaction(signedTransactionInfo) : null; + + const insert = await db + .insert(apple_iap_notifications) + .values({ + notification_uuid: notification.notificationUUID, + notification_type: notification.notificationType, + subtype: notification.subtype ?? null, + environment: notification.data?.environment ?? transaction?.environment ?? 'Sandbox', + apple_transaction_id: transaction?.transactionId ?? null, + apple_original_transaction_id: transaction?.originalTransactionId ?? null, + signed_payload_jws: params.signedPayload, + }) + .onConflictDoNothing(); + + if ((insert.rowCount ?? 0) === 0) { + return { duplicate: true, reversed: false }; + } + + let reversed = false; + if (transaction && REVERSAL_NOTIFICATION_TYPES.has(notification.notificationType)) { + const result = await reverseAppleCreditPurchase({ + appleTransactionId: transaction.transactionId, + reversalReason: notification.notificationType === 'REFUND' ? 'refunded' : 'revoked', + }); + reversed = result.reversed; + } + + await db + .update(apple_iap_notifications) + .set({ processed_at: new Date().toISOString() }) + .where(eq(apple_iap_notifications.notification_uuid, notification.notificationUUID)); + + return { duplicate: false, reversed }; +} From 00f815e419dd8cb59253fb4d72c441744155be47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:11:27 +0200 Subject: [PATCH 08/34] feat(mobile): add Apple credit purchase hooks --- apps/mobile/package.json | 1 + apps/mobile/src/lib/apple-iap/storekit.ts | 50 ++++++ apps/mobile/src/lib/apple-iap/types.ts | 13 ++ .../apple-iap/use-apple-credit-products.ts | 55 ++++++ .../use-apple-credit-purchase.test.tsx | 162 ++++++++++++++++++ .../apple-iap/use-apple-credit-purchase.ts | 29 ++++ pnpm-lock.yaml | 50 +++++- 7 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 apps/mobile/src/lib/apple-iap/storekit.ts create mode 100644 apps/mobile/src/lib/apple-iap/types.ts create mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts create mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx create mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 28bee34109..7ced05aa52 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -53,6 +53,7 @@ "expo-document-picker": "~55.0.12", "expo-font": "~55.0.6", "expo-haptics": "~55.0.13", + "expo-iap": "^4.2.4", "expo-image": "~55.0.8", "expo-image-picker": "~55.0.17", "expo-insights": "55.0.15", diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts new file mode 100644 index 0000000000..5586ae5205 --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -0,0 +1,50 @@ +import type { Purchase } from 'expo-iap'; + +export type StoreKitProduct = { + id: string; + title: string; + localizedPrice: string; +}; + +export type StoreKitPurchaseResult = { + productId: string; + transactionJws: string; + nativeTransaction: Purchase; +}; + +export async function fetchStoreKitProducts(productIds: string[]): Promise { + const iap = await import('expo-iap'); + await iap.initConnection(); + const products = await iap.fetchProducts({ skus: productIds, type: 'in-app' }); + return (products ?? []).map(product => ({ + id: product.id, + title: product.title, + localizedPrice: product.displayPrice, + })); +} + +export async function purchaseStoreKitProduct( + productId: string +): Promise { + const iap = await import('expo-iap'); + await iap.initConnection(); + const purchaseResult = await iap.requestPurchase({ + request: { apple: { sku: productId } }, + type: 'in-app', + }); + const purchase = Array.isArray(purchaseResult) ? purchaseResult[0] : purchaseResult; + if (!purchase) { + throw new Error('StoreKit purchase did not return a transaction'); + } + const transactionJws = purchase.purchaseToken; + if (!transactionJws) { + throw new Error('StoreKit purchase did not include a signed transaction JWS'); + } + + return { productId, transactionJws, nativeTransaction: purchase }; +} + +export async function finishStoreKitTransaction(nativeTransaction: Purchase): Promise { + const iap = await import('expo-iap'); + await iap.finishTransaction({ purchase: nativeTransaction, isConsumable: true }); +} diff --git a/apps/mobile/src/lib/apple-iap/types.ts b/apps/mobile/src/lib/apple-iap/types.ts new file mode 100644 index 0000000000..a74506a38c --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/types.ts @@ -0,0 +1,13 @@ +export type AppleCreditProductTier = 'small' | 'medium' | 'large'; + +export type BackendAppleCreditProduct = { + id: string; + tier: AppleCreditProductTier; + creditedCents: number; + creditedMicrodollars: number; +}; + +export type AppleCreditDisplayProduct = BackendAppleCreditProduct & { + localizedPrice: string; + title: string; +}; diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts new file mode 100644 index 0000000000..9f264b23aa --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts @@ -0,0 +1,55 @@ +import { useQuery } from '@tanstack/react-query'; +import { Platform } from 'react-native'; + +import { useTRPC } from '@/lib/trpc'; +import { fetchStoreKitProducts } from './storekit'; +import type { AppleCreditDisplayProduct, BackendAppleCreditProduct } from './types'; + +export function joinAppleCreditProducts( + backendProducts: BackendAppleCreditProduct[] | undefined, + storeKitProducts: { id: string; title: string; localizedPrice: string }[] | undefined +): AppleCreditDisplayProduct[] { + const storeKitById = new Map((storeKitProducts ?? []).map(product => [product.id, product])); + return (backendProducts ?? []).flatMap(product => { + const storeKitProduct = storeKitById.get(product.id); + if (!storeKitProduct) return []; + return [ + { + ...product, + title: storeKitProduct.title, + localizedPrice: storeKitProduct.localizedPrice, + }, + ]; + }); +} + +export function useAppleCreditProducts() { + const trpc = useTRPC(); + const isIos = Platform.OS === 'ios'; + + const backendProducts = useQuery( + trpc.user.getAppleCreditProducts.queryOptions(undefined, { + enabled: isIos, + staleTime: 5 * 60_000, + }) + ); + const productIds = backendProducts.data?.products.map(product => product.id) ?? []; + + const storeKitProducts = useQuery({ + queryKey: ['apple-credit-storekit-products', productIds], + queryFn: () => fetchStoreKitProducts(productIds), + enabled: isIos && productIds.length > 0, + staleTime: 5 * 60_000, + }); + + return { + products: isIos ? joinAppleCreditProducts(backendProducts.data?.products, storeKitProducts.data) : [], + isLoading: isIos && (backendProducts.isLoading || storeKitProducts.isLoading), + isFetching: isIos && (backendProducts.isFetching || storeKitProducts.isFetching), + isError: isIos && (backendProducts.isError || storeKitProducts.isError), + refetch: async () => { + await backendProducts.refetch(); + await storeKitProducts.refetch(); + }, + }; +} diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx new file mode 100644 index 0000000000..8f7a9dd330 --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx @@ -0,0 +1,162 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { useAppleCreditProducts } from './use-apple-credit-products'; +import { useAppleCreditPurchase } from './use-apple-credit-purchase'; +import { finishStoreKitTransaction, purchaseStoreKitProduct } from './storekit'; + +const testState = vi.hoisted(() => ({ + backendProducts: [ + { + id: 'com.kilocode.kiloapp.credits.small.999', + tier: 'small' as const, + creditedCents: 699, + creditedMicrodollars: 6_990_000, + }, + ], + invalidations: [] as unknown[], + mutationResult: { + creditedCents: 699, + creditedMicrodollars: 6_990_000, + alreadyProcessed: false, + }, + mutationShouldReject: false, + platform: 'ios', + storeKitProducts: [ + { + id: 'com.kilocode.kiloapp.credits.small.999', + title: 'Small Credit Pack', + localizedPrice: '$9.99', + }, + ], +})); + +const mocks = vi.hoisted(() => ({ + finishStoreKitTransaction: vi.fn(), + fetchStoreKitProducts: vi.fn(), + purchaseStoreKitProduct: vi.fn(), +})); + +vi.mock('react-native', () => ({ + Platform: { + get OS() { + return testState.platform; + }, + }, +})); + +vi.mock('./storekit', () => mocks); + +vi.mock('@tanstack/react-query', () => ({ + useMutation: () => ({ + error: null, + isPending: false, + mutateAsync: async () => { + if (testState.mutationShouldReject) { + throw new Error('Backend rejected purchase'); + } + return testState.mutationResult; + }, + }), + useQuery: (options: { queryKey?: unknown[] }) => { + const isStoreKitQuery = options.queryKey?.[0] === 'apple-credit-storekit-products'; + return { + data: isStoreKitQuery ? testState.storeKitProducts : { products: testState.backendProducts }, + isError: false, + isFetching: false, + isLoading: false, + refetch: vi.fn(), + }; + }, + useQueryClient: () => ({ + invalidateQueries: async (filter: unknown) => { + testState.invalidations.push(filter); + }, + }), +})); + +vi.mock('@/lib/trpc', () => ({ + useTRPC: () => ({ + user: { + completeAppleCreditPurchase: { + mutationOptions: () => ({}), + }, + getAppleCreditProducts: { + queryOptions: () => ({ queryKey: ['user', 'getAppleCreditProducts'] }), + }, + getContextBalance: { + pathFilter: () => ({ queryKey: ['user', 'getContextBalance'] }), + }, + getCreditBlocks: { + pathFilter: () => ({ queryKey: ['user', 'getCreditBlocks'] }), + }, + }, + }), +})); + +beforeEach(() => { + testState.invalidations = []; + testState.mutationShouldReject = false; + testState.mutationResult = { + creditedCents: 699, + creditedMicrodollars: 6_990_000, + alreadyProcessed: false, + }; + testState.platform = 'ios'; + vi.clearAllMocks(); + mocks.fetchStoreKitProducts.mockResolvedValue(testState.storeKitProducts); + mocks.purchaseStoreKitProduct.mockResolvedValue({ + productId: 'com.kilocode.kiloapp.credits.small.999', + transactionJws: 'signed-transaction', + nativeTransaction: { id: 'native-transaction' }, + }); + mocks.finishStoreKitTransaction.mockResolvedValue(undefined); +}); + +describe('useAppleCreditProducts', () => { + it('returns no products outside iOS', () => { + testState.platform = 'android'; + + expect(useAppleCreditProducts().products).toEqual([]); + }); +}); + +describe('useAppleCreditPurchase', () => { + it('finishes the StoreKit transaction after backend success', async () => { + const result = await useAppleCreditPurchase().purchaseProduct( + 'com.kilocode.kiloapp.credits.small.999' + ); + + expect(result.alreadyProcessed).toBe(false); + expect(purchaseStoreKitProduct).toHaveBeenCalledWith('com.kilocode.kiloapp.credits.small.999'); + expect(testState.invalidations).toEqual([ + { queryKey: ['user', 'getContextBalance'] }, + { queryKey: ['user', 'getCreditBlocks'] }, + ]); + expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'native-transaction' }); + }); + + it('finishes the StoreKit transaction after already-processed backend success', async () => { + testState.mutationResult = { + creditedCents: 699, + creditedMicrodollars: 6_990_000, + alreadyProcessed: true, + }; + + const result = await useAppleCreditPurchase().purchaseProduct( + 'com.kilocode.kiloapp.credits.small.999' + ); + + expect(result.alreadyProcessed).toBe(true); + expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'native-transaction' }); + }); + + it('does not finish the StoreKit transaction when backend completion fails', async () => { + testState.mutationShouldReject = true; + + await expect( + useAppleCreditPurchase().purchaseProduct('com.kilocode.kiloapp.credits.small.999') + ).rejects.toThrow('Backend rejected purchase'); + + expect(finishStoreKitTransaction).not.toHaveBeenCalled(); + }); +}); diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts new file mode 100644 index 0000000000..72d54dc3db --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts @@ -0,0 +1,29 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { useTRPC } from '@/lib/trpc'; +import { finishStoreKitTransaction, purchaseStoreKitProduct } from './storekit'; + +export function useAppleCreditPurchase() { + const trpc = useTRPC(); + const queryClient = useQueryClient(); + const completeAppleCreditPurchase = useMutation( + trpc.user.completeAppleCreditPurchase.mutationOptions() + ); + + const purchaseProduct = async (productId: string) => { + const purchase = await purchaseStoreKitProduct(productId); + const result = await completeAppleCreditPurchase.mutateAsync({ + transactionJws: purchase.transactionJws, + }); + await queryClient.invalidateQueries(trpc.user.getContextBalance.pathFilter()); + await queryClient.invalidateQueries(trpc.user.getCreditBlocks.pathFilter()); + await finishStoreKitTransaction(purchase.nativeTransaction); + return result; + }; + + return { + purchaseProduct, + isPending: completeAppleCreditPurchase.isPending, + error: completeAppleCreditPurchase.error, + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc094db0a5..1c7643dad5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -228,6 +228,9 @@ importers: expo-haptics: specifier: ~55.0.13 version: 55.0.13(expo@55.0.12) + expo-iap: + specifier: ^4.2.4 + version: 4.2.4(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-image: specifier: ~55.0.8 version: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) @@ -1608,7 +1611,7 @@ importers: version: 7.0.0-dev.20260319.1 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@24.12.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + version: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) typescript: specifier: 'catalog:' version: 5.9.3 @@ -10424,6 +10427,13 @@ packages: peerDependencies: expo: '*' + expo-iap@4.2.4: + resolution: {integrity: sha512-gOiplvAnjxc/EG/9ojzuJk9IC+yl52D86KpHdvbwzM9rkqZt1DkOA1hDojClQS5TnuuuCTuWK39usgCYxdDG4w==} + peerDependencies: + expo: '*' + react: '*' + react-native: '*' + expo-image-loader@55.0.0: resolution: {integrity: sha512-NOjp56wDrfuA5aiNAybBIjqIn1IxKeGJ8CECWZncQ/GzjZfyTYAHTCyeApYkdKkMBLHINzI4BbTGSlbCa0fXXQ==} peerDependencies: @@ -25382,6 +25392,12 @@ snapshots: dependencies: expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-iap@4.2.4(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + dependencies: + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react: 19.2.0 + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo-image-loader@55.0.0(expo@55.0.12): dependencies: expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) @@ -26702,6 +26718,25 @@ snapshots: - supports-color - ts-node + jest-cli@30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)): + dependencies: + '@jest/core': 30.3.0(esbuild-register@3.6.0(esbuild@0.27.4)) + '@jest/test-result': 30.3.0 + '@jest/types': 30.3.0 + chalk: 4.1.2 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + jest-util: 30.3.0 + jest-validate: 30.3.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jest-config@29.7.0(@types/node@24.12.0): dependencies: '@babel/core': 7.29.0 @@ -27353,6 +27388,19 @@ snapshots: - supports-color - ts-node + jest@30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)): + dependencies: + '@jest/core': 30.3.0(esbuild-register@3.6.0(esbuild@0.27.4)) + '@jest/types': 30.3.0 + import-local: 3.2.0 + jest-cli: 30.3.0(@types/node@25.5.0)(esbuild-register@3.6.0(esbuild@0.27.4)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jimp-compact@0.16.1: {} jiti@2.6.1: {} From e3b14c35a2d9718d82b3fb5765d424725b3f23c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:16:17 +0200 Subject: [PATCH 09/34] feat(mobile): add Apple credit purchase UI --- .../apple-credit-purchase-sheet.test.ts | 44 +++++ .../apple-credit-purchase-sheet.tsx | 134 +++++++++++++ .../components/apple-credit-purchase-utils.ts | 16 ++ .../src/components/profile-credits-card.tsx | 185 ++++++++++++++++++ apps/mobile/src/components/profile-screen.tsx | 148 +------------- 5 files changed, 383 insertions(+), 144 deletions(-) create mode 100644 apps/mobile/src/components/apple-credit-purchase-sheet.test.ts create mode 100644 apps/mobile/src/components/apple-credit-purchase-sheet.tsx create mode 100644 apps/mobile/src/components/apple-credit-purchase-utils.ts create mode 100644 apps/mobile/src/components/profile-credits-card.tsx diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts b/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts new file mode 100644 index 0000000000..76f1bc782f --- /dev/null +++ b/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from 'vitest'; + +import { + formatAppleCreditAmount, + getAppleCreditProductButtonText, + shouldShowAppleCreditPurchaseEntry, +} from './apple-credit-purchase-utils'; + +describe('Apple credit purchase sheet helpers', () => { + it('hides the buy entry point for organization balances', () => { + expect( + shouldShowAppleCreditPurchaseEntry({ + platform: 'ios', + selectedOrgId: 'org-1', + }) + ).toBe(false); + }); + + it('hides the buy entry point outside iOS', () => { + expect( + shouldShowAppleCreditPurchaseEntry({ + platform: 'android', + selectedOrgId: undefined, + }) + ).toBe(false); + }); + + it('shows the credited amount and localized Apple price', () => { + expect( + getAppleCreditProductButtonText({ + id: 'com.kilocode.kiloapp.credits.small.999', + tier: 'small', + creditedCents: 699, + creditedMicrodollars: 6_990_000, + title: 'Small Credit Pack', + localizedPrice: '$9.99', + }) + ).toBe('$6.99 credits - Pay $9.99'); + }); + + it('formats credited amounts for retryable purchase rows', () => { + expect(formatAppleCreditAmount(3499)).toBe('$34.99 credits'); + }); +}); diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx new file mode 100644 index 0000000000..a85b792a7f --- /dev/null +++ b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx @@ -0,0 +1,134 @@ +import { ShoppingBag, X } from 'lucide-react-native'; +import { useState } from 'react'; +import { ActivityIndicator, Modal, Pressable, View } from 'react-native'; +import { toast } from 'sonner-native'; + +import { Button } from '@/components/ui/button'; +import { Text } from '@/components/ui/text'; +import { useAppleCreditProducts } from '@/lib/apple-iap/use-apple-credit-products'; +import { useAppleCreditPurchase } from '@/lib/apple-iap/use-apple-credit-purchase'; +import { useThemeColors } from '@/lib/hooks/use-theme-colors'; +import { type AppleCreditDisplayProduct } from '@/lib/apple-iap/types'; +import { + formatAppleCreditAmount, + getAppleCreditProductButtonText, +} from '@/components/apple-credit-purchase-utils'; + +type AppleCreditPurchaseSheetProps = { + visible: boolean; + onClose: () => void; + onPurchaseSuccess: () => void; +}; + +export function AppleCreditPurchaseSheet({ + visible, + onClose, + onPurchaseSuccess, +}: Readonly) { + const colors = useThemeColors(); + const { products, isLoading, isError, refetch } = useAppleCreditProducts(); + const { purchaseProduct, isPending } = useAppleCreditPurchase(); + const [activeProductId, setActiveProductId] = useState(null); + const [purchaseError, setPurchaseError] = useState(null); + + const handlePurchase = async (product: AppleCreditDisplayProduct) => { + setActiveProductId(product.id); + setPurchaseError(null); + try { + await purchaseProduct(product.id); + toast.success(`${formatAppleCreditAmount(product.creditedCents)} added`); + onPurchaseSuccess(); + onClose(); + } catch (error) { + setPurchaseError(error instanceof Error ? error.message : 'Purchase failed. Try again.'); + } finally { + setActiveProductId(null); + } + }; + + return ( + + + + { + event.stopPropagation(); + }} + > + + + + Buy Credits + + + + + {isLoading && ( + + + + )} + + {isError && ( + { + void refetch(); + }} + > + + Failed to load products. Tap to retry. + + + )} + + {!isLoading && !isError && ( + + {products.map(product => { + const isActive = activeProductId === product.id; + return ( + + ); + })} + {products.length === 0 && ( + + Credit packs are unavailable. + + )} + + )} + + {purchaseError && ( + + {purchaseError} + + )} + + + + ); +} diff --git a/apps/mobile/src/components/apple-credit-purchase-utils.ts b/apps/mobile/src/components/apple-credit-purchase-utils.ts new file mode 100644 index 0000000000..bfafe2d0c8 --- /dev/null +++ b/apps/mobile/src/components/apple-credit-purchase-utils.ts @@ -0,0 +1,16 @@ +import { type AppleCreditDisplayProduct } from '@/lib/apple-iap/types'; + +export function formatAppleCreditAmount(creditedCents: number): string { + return `$${(creditedCents / 100).toFixed(2)} credits`; +} + +export function getAppleCreditProductButtonText(product: AppleCreditDisplayProduct): string { + return `${formatAppleCreditAmount(product.creditedCents)} - Pay ${product.localizedPrice}`; +} + +export function shouldShowAppleCreditPurchaseEntry(params: { + platform: string; + selectedOrgId: string | undefined; +}): boolean { + return params.platform === 'ios' && params.selectedOrgId === undefined; +} diff --git a/apps/mobile/src/components/profile-credits-card.tsx b/apps/mobile/src/components/profile-credits-card.tsx new file mode 100644 index 0000000000..ce87947352 --- /dev/null +++ b/apps/mobile/src/components/profile-credits-card.tsx @@ -0,0 +1,185 @@ +import { useActionSheet } from '@expo/react-native-action-sheet'; +import { keepPreviousData, useQuery } from '@tanstack/react-query'; +import { ChevronDown, ShoppingBag } from 'lucide-react-native'; +import { useState } from 'react'; +import { ActivityIndicator, Platform, Pressable, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'; + +import { AppleCreditPurchaseSheet } from '@/components/apple-credit-purchase-sheet'; +import { shouldShowAppleCreditPurchaseEntry } from '@/components/apple-credit-purchase-utils'; +import { Button } from '@/components/ui/button'; +import { Skeleton } from '@/components/ui/skeleton'; +import { Text } from '@/components/ui/text'; +import { useThemeColors } from '@/lib/hooks/use-theme-colors'; +import { useOrganization } from '@/lib/organization-context'; +import { useTRPC } from '@/lib/trpc'; +import { parseTimestamp } from '@/lib/utils'; + +type CreditsCardProps = { + orgs: { organizationId: string; organizationName: string }[] | undefined; +}; + +export function CreditsCard({ orgs }: Readonly) { + const trpc = useTRPC(); + const colors = useThemeColors(); + const { showActionSheetWithOptions } = useActionSheet(); + const { bottom } = useSafeAreaInsets(); + const { organizationId, setOrganizationId } = useOrganization(); + const selectedOrgId = organizationId ?? undefined; + const [purchaseSheetVisible, setPurchaseSheetVisible] = useState(false); + + const { + data: balance, + isLoading: balanceLoading, + isFetching: balanceFetching, + isError: balanceError, + refetch: refetchBalance, + } = useQuery({ + ...trpc.user.getContextBalance.queryOptions({ organizationId: selectedOrgId }), + placeholderData: keepPreviousData, + }); + + const { data: personalCreditData, isLoading: personalCreditsLoading } = useQuery({ + ...trpc.user.getCreditBlocks.queryOptions({}), + enabled: !selectedOrgId, + }); + + const { data: orgCreditData, isLoading: orgCreditsLoading } = useQuery({ + ...trpc.organizations.getCreditBlocks.queryOptions({ organizationId: selectedOrgId ?? '' }), + enabled: Boolean(selectedOrgId), + placeholderData: keepPreviousData, + }); + + const creditData = selectedOrgId ? orgCreditData : personalCreditData; + const creditsLoading = selectedOrgId ? orgCreditsLoading : personalCreditsLoading; + + const balanceDollars = balance?.balance ?? 0; + const expiringBlocks = creditData?.creditBlocks.filter(b => b.expiry_date !== null) ?? []; + const expiringTotal = expiringBlocks.reduce((sum, b) => sum + b.balance_mUsd, 0) / 1_000_000; + const earliestExpiry = expiringBlocks + .map(b => b.expiry_date) + .filter((d): d is string => d !== null) + // eslint-disable-next-line unicorn/no-array-sort -- toSorted() is not available in Hermes + .sort((a, b) => a.localeCompare(b))[0]; + + const selectedLabel = selectedOrgId + ? (orgs?.find(o => o.organizationId === selectedOrgId)?.organizationName ?? 'Organization') + : 'Personal'; + + const hasOrgs = orgs && orgs.length > 0; + const showAppleCreditPurchase = shouldShowAppleCreditPurchaseEntry({ + platform: Platform.OS, + selectedOrgId, + }); + + const openPicker = () => { + if (!orgs || orgs.length === 0) { + return; + } + const options = ['Personal', ...orgs.map(o => o.organizationName), 'Cancel']; + const cancelButtonIndex = options.length - 1; + showActionSheetWithOptions( + { + options, + cancelButtonIndex, + title: 'Select account', + containerStyle: { paddingBottom: bottom }, + }, + index => { + if (index === undefined || index === cancelButtonIndex) { + return; + } + if (index === 0) { + setOrganizationId(null); + } else { + const org = orgs[index - 1]; + if (org) { + setOrganizationId(org.organizationId); + } + } + } + ); + }; + + return ( + + + + Credits + + {hasOrgs && ( + + {selectedLabel} + + + )} + + + {balanceLoading && } + {balanceError && ( + void refetchBalance()} + > + Failed to load balance. Tap to retry. + + )} + {!balanceLoading && !balanceError && ( + + + ${balanceDollars.toFixed(2)} + {creditsLoading ? ( + + + + ) : ( + expiringTotal > 0 && + earliestExpiry != null && ( + + + ${expiringTotal.toFixed(2)} in bonus credits expiring{' '} + {parseTimestamp(earliestExpiry).toLocaleDateString(undefined, { + month: 'short', + day: 'numeric', + })} + + + ) + )} + + {balanceFetching && } + + )} + + {showAppleCreditPurchase && ( + + )} + + { + setPurchaseSheetVisible(false); + }} + onPurchaseSuccess={() => { + void refetchBalance(); + }} + /> + + ); +} diff --git a/apps/mobile/src/components/profile-screen.tsx b/apps/mobile/src/components/profile-screen.tsx index 6e41ab0fb3..edf969fa70 100644 --- a/apps/mobile/src/components/profile-screen.tsx +++ b/apps/mobile/src/components/profile-screen.tsx @@ -1,165 +1,25 @@ -import { useActionSheet } from '@expo/react-native-action-sheet'; -import { keepPreviousData, useMutation, useQuery } from '@tanstack/react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import * as Application from 'expo-application'; -import { ChevronDown, KeyRound, LogOut, Trash2 } from 'lucide-react-native'; -import { ActivityIndicator, Alert, Platform, Pressable, View } from 'react-native'; +import { KeyRound, LogOut, Trash2 } from 'lucide-react-native'; +import { Alert, Platform, Pressable, View } from 'react-native'; import { toast } from 'sonner-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'; import { NotificationsCard } from '@/components/notifications-card'; +import { CreditsCard } from '@/components/profile-credits-card'; import { ScreenHeader } from '@/components/screen-header'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { Text } from '@/components/ui/text'; import { useAuth } from '@/lib/auth/auth-context'; import { useThemeColors } from '@/lib/hooks/use-theme-colors'; -import { useOrganization } from '@/lib/organization-context'; import { useTRPC } from '@/lib/trpc'; -import { parseTimestamp } from '@/lib/utils'; function providerIcon(_provider: string) { return KeyRound; } -type CreditsCardProps = { - orgs: { organizationId: string; organizationName: string }[] | undefined; -}; - -function CreditsCard({ orgs }: Readonly) { - const trpc = useTRPC(); - const colors = useThemeColors(); - const { showActionSheetWithOptions } = useActionSheet(); - const { bottom } = useSafeAreaInsets(); - const { organizationId, setOrganizationId } = useOrganization(); - const selectedOrgId = organizationId ?? undefined; - - const { - data: balance, - isLoading: balanceLoading, - isFetching: balanceFetching, - isError: balanceError, - refetch: refetchBalance, - } = useQuery({ - ...trpc.user.getContextBalance.queryOptions({ organizationId: selectedOrgId }), - placeholderData: keepPreviousData, - }); - - const { data: personalCreditData, isLoading: personalCreditsLoading } = useQuery({ - ...trpc.user.getCreditBlocks.queryOptions({}), - enabled: !selectedOrgId, - }); - - const { data: orgCreditData, isLoading: orgCreditsLoading } = useQuery({ - ...trpc.organizations.getCreditBlocks.queryOptions({ organizationId: selectedOrgId ?? '' }), - enabled: Boolean(selectedOrgId), - placeholderData: keepPreviousData, - }); - - const creditData = selectedOrgId ? orgCreditData : personalCreditData; - const creditsLoading = selectedOrgId ? orgCreditsLoading : personalCreditsLoading; - - const balanceDollars = balance?.balance ?? 0; - const expiringBlocks = creditData?.creditBlocks.filter(b => b.expiry_date !== null) ?? []; - const expiringTotal = expiringBlocks.reduce((sum, b) => sum + b.balance_mUsd, 0) / 1_000_000; - const earliestExpiry = expiringBlocks - .map(b => b.expiry_date) - .filter((d): d is string => d !== null) - // eslint-disable-next-line unicorn/no-array-sort -- toSorted() is not available in Hermes - .sort((a, b) => a.localeCompare(b))[0]; - - const selectedLabel = selectedOrgId - ? (orgs?.find(o => o.organizationId === selectedOrgId)?.organizationName ?? 'Organization') - : 'Personal'; - - const hasOrgs = orgs && orgs.length > 0; - - const openPicker = () => { - if (!orgs || orgs.length === 0) { - return; - } - const options = ['Personal', ...orgs.map(o => o.organizationName), 'Cancel']; - const cancelButtonIndex = options.length - 1; - showActionSheetWithOptions( - { - options, - cancelButtonIndex, - title: 'Select account', - containerStyle: { paddingBottom: bottom }, - }, - index => { - if (index === undefined || index === cancelButtonIndex) { - return; - } - if (index === 0) { - setOrganizationId(null); - } else { - const org = orgs[index - 1]; - if (org) { - setOrganizationId(org.organizationId); - } - } - } - ); - }; - - return ( - - - - Credits - - {hasOrgs && ( - - {selectedLabel} - - - )} - - - {balanceLoading && } - {balanceError && ( - void refetchBalance()} - > - Failed to load balance. Tap to retry. - - )} - {!balanceLoading && !balanceError && ( - - - ${balanceDollars.toFixed(2)} - {creditsLoading ? ( - - - - ) : ( - expiringTotal > 0 && - earliestExpiry != null && ( - - - ${expiringTotal.toFixed(2)} in bonus credits expiring{' '} - {parseTimestamp(earliestExpiry).toLocaleDateString(undefined, { - month: 'short', - day: 'numeric', - })} - - - ) - )} - - {balanceFetching && } - - )} - - ); -} - export function ProfileScreen() { const { signOut } = useAuth(); const trpc = useTRPC(); From 34ca77a687f9bde4cd774b22844d4db5a4bab412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:16:31 +0200 Subject: [PATCH 10/34] fix(mobile): stabilize Apple credit purchase hooks --- apps/mobile/src/lib/apple-iap/storekit.ts | 2 +- .../src/lib/apple-iap/use-apple-credit-products.ts | 11 ++++++++--- .../lib/apple-iap/use-apple-credit-purchase.test.tsx | 5 ++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts index 5586ae5205..b885b1e032 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -1,4 +1,4 @@ -import type { Purchase } from 'expo-iap'; +import { type Purchase } from 'expo-iap'; export type StoreKitProduct = { id: string; diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts index 9f264b23aa..6d024535a9 100644 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts @@ -3,7 +3,7 @@ import { Platform } from 'react-native'; import { useTRPC } from '@/lib/trpc'; import { fetchStoreKitProducts } from './storekit'; -import type { AppleCreditDisplayProduct, BackendAppleCreditProduct } from './types'; +import { type AppleCreditDisplayProduct, type BackendAppleCreditProduct } from './types'; export function joinAppleCreditProducts( backendProducts: BackendAppleCreditProduct[] | undefined, @@ -12,7 +12,9 @@ export function joinAppleCreditProducts( const storeKitById = new Map((storeKitProducts ?? []).map(product => [product.id, product])); return (backendProducts ?? []).flatMap(product => { const storeKitProduct = storeKitById.get(product.id); - if (!storeKitProduct) return []; + if (!storeKitProduct) { + return []; + } return [ { ...product, @@ -37,7 +39,10 @@ export function useAppleCreditProducts() { const storeKitProducts = useQuery({ queryKey: ['apple-credit-storekit-products', productIds], - queryFn: () => fetchStoreKitProducts(productIds), + queryFn: async () => { + const products = await fetchStoreKitProducts(productIds); + return products; + }, enabled: isIos && productIds.length > 0, staleTime: 5 * 60_000, }); diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx index 8f7a9dd330..0d0aa9e716 100644 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx @@ -52,9 +52,11 @@ vi.mock('@tanstack/react-query', () => ({ isPending: false, mutateAsync: async () => { if (testState.mutationShouldReject) { + await Promise.resolve(); throw new Error('Backend rejected purchase'); } - return testState.mutationResult; + const result = await Promise.resolve(testState.mutationResult); + return result; }, }), useQuery: (options: { queryKey?: unknown[] }) => { @@ -70,6 +72,7 @@ vi.mock('@tanstack/react-query', () => ({ useQueryClient: () => ({ invalidateQueries: async (filter: unknown) => { testState.invalidations.push(filter); + await Promise.resolve(); }, }), })); From 72128b2589d797e3081439961816231cee7989a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:16:57 +0200 Subject: [PATCH 11/34] docs(mobile): document Apple credit purchase setup --- apps/mobile/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/mobile/README.md b/apps/mobile/README.md index 9823333400..bf9f38b10b 100644 --- a/apps/mobile/README.md +++ b/apps/mobile/README.md @@ -25,3 +25,25 @@ Generally speaking, you only need a new dev build if making dependency/native ch 3. create a new dev build using `pnpm build:ios` 4. `pnpm start` 5. open installed app on your phone + +## Apple In-App Credit Purchases + +iOS credit purchases require an EAS development build or TestFlight build with +the in-app purchase capability enabled. Expo Go is not supported for this +feature. + +Configured consumable product IDs: + +- `com.kilocode.kiloapp.credits.small.999` +- `com.kilocode.kiloapp.credits.medium.1999` +- `com.kilocode.kiloapp.credits.large.4999` + +Use App Store Connect sandbox tester accounts for local and TestFlight sandbox +verification. Configure App Store Server Notifications V2 to post to +`/api/apple/iap/notifications`. + +Backend environment variables: + +- `APPLE_IAP_ENVIRONMENT` +- `APPLE_APP_APPLE_ID` +- `APPLE_ROOT_CERTIFICATES_PEM` From 471bbc0664003bf9bf7f61d0465bf9d059d892cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 15:19:45 +0200 Subject: [PATCH 12/34] fix: stabilize Apple credit purchase verification --- apps/mobile/src/components/apple-credit-purchase-sheet.tsx | 4 +++- apps/mobile/src/lib/apple-iap/storekit.ts | 4 +--- apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx index a85b792a7f..344e1d811d 100644 --- a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx +++ b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx @@ -109,7 +109,9 @@ export function AppleCreditPurchaseSheet({ Pay {product.localizedPrice} - {isActive && } + {isActive && ( + + )} ); diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts index b885b1e032..a330eba455 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -23,9 +23,7 @@ export async function fetchStoreKitProducts(productIds: string[]): Promise { +export async function purchaseStoreKitProduct(productId: string): Promise { const iap = await import('expo-iap'); await iap.initConnection(); const purchaseResult = await iap.requestPurchase({ diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts index 6d024535a9..76a085ad72 100644 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts @@ -48,7 +48,9 @@ export function useAppleCreditProducts() { }); return { - products: isIos ? joinAppleCreditProducts(backendProducts.data?.products, storeKitProducts.data) : [], + products: isIos + ? joinAppleCreditProducts(backendProducts.data?.products, storeKitProducts.data) + : [], isLoading: isIos && (backendProducts.isLoading || storeKitProducts.isLoading), isFetching: isIos && (backendProducts.isFetching || storeKitProducts.isFetching), isError: isIos && (backendProducts.isError || storeKitProducts.isError), From d658a9051d9743ad8f3a3527575df8dd41687528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 16:09:21 +0200 Subject: [PATCH 13/34] fix: address Apple IAP review feedback --- apps/mobile/src/lib/apple-iap/storekit.ts | 21 +++++++++++-------- .../app/api/apple/iap/notifications/route.ts | 18 +++++++--------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts index a330eba455..7354389229 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -1,4 +1,10 @@ -import { type Purchase } from 'expo-iap'; +import { + fetchProducts, + finishTransaction, + initConnection, + type Purchase, + requestPurchase, +} from 'expo-iap'; export type StoreKitProduct = { id: string; @@ -13,9 +19,8 @@ export type StoreKitPurchaseResult = { }; export async function fetchStoreKitProducts(productIds: string[]): Promise { - const iap = await import('expo-iap'); - await iap.initConnection(); - const products = await iap.fetchProducts({ skus: productIds, type: 'in-app' }); + await initConnection(); + const products = await fetchProducts({ skus: productIds, type: 'in-app' }); return (products ?? []).map(product => ({ id: product.id, title: product.title, @@ -24,9 +29,8 @@ export async function fetchStoreKitProducts(productIds: string[]): Promise { - const iap = await import('expo-iap'); - await iap.initConnection(); - const purchaseResult = await iap.requestPurchase({ + await initConnection(); + const purchaseResult = await requestPurchase({ request: { apple: { sku: productId } }, type: 'in-app', }); @@ -43,6 +47,5 @@ export async function purchaseStoreKitProduct(productId: string): Promise { - const iap = await import('expo-iap'); - await iap.finishTransaction({ purchase: nativeTransaction, isConsumable: true }); + await finishTransaction({ purchase: nativeTransaction, isConsumable: true }); } diff --git a/apps/web/src/app/api/apple/iap/notifications/route.ts b/apps/web/src/app/api/apple/iap/notifications/route.ts index b5d11ba8ac..ae33de5f43 100644 --- a/apps/web/src/app/api/apple/iap/notifications/route.ts +++ b/apps/web/src/app/api/apple/iap/notifications/route.ts @@ -1,7 +1,12 @@ import { NextResponse } from 'next/server'; import { captureException } from '@sentry/nextjs'; +import { z } from 'zod'; import { processAppleIapNotification } from '@/lib/apple-iap/notifications'; +const AppleIapNotificationRequestSchema = z.object({ + signedPayload: z.string().min(1), +}); + export async function POST(req: Request): Promise> { let body: unknown; try { @@ -10,20 +15,13 @@ export async function POST(req: Request): Promise> { return new NextResponse('Invalid JSON', { status: 400 }); } - const signedPayload = - typeof body === 'object' && - body !== null && - 'signedPayload' in body && - typeof body.signedPayload === 'string' - ? body.signedPayload - : null; - - if (!signedPayload) { + const parsedBody = AppleIapNotificationRequestSchema.safeParse(body); + if (!parsedBody.success) { return new NextResponse('Missing signedPayload', { status: 400 }); } try { - await processAppleIapNotification({ signedPayload }); + await processAppleIapNotification({ signedPayload: parsedBody.data.signedPayload }); return new NextResponse('OK', { status: 200 }); } catch (error) { captureException(error, { tags: { source: 'apple_iap_notification' } }); From 1a57af88223abb768a2cde765fe412bcb371fa83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 17:32:43 +0200 Subject: [PATCH 14/34] fix(mobile): remove home welcome headline --- .../src/components/home/home-screen.test.ts | 88 +++++++++++++++++++ .../src/components/home/home-screen.tsx | 7 +- 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 apps/mobile/src/components/home/home-screen.test.ts diff --git a/apps/mobile/src/components/home/home-screen.test.ts b/apps/mobile/src/components/home/home-screen.test.ts new file mode 100644 index 0000000000..75161114d2 --- /dev/null +++ b/apps/mobile/src/components/home/home-screen.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { HomeScreen } from '@/components/home/home-screen'; + +vi.mock('@tanstack/react-query', () => ({ + useQueryClient: () => ({ invalidateQueries: vi.fn() }), +})); +vi.mock('expo-router', () => ({ + useFocusEffect: vi.fn(), + useIsFocused: () => true, +})); +vi.mock('react-native', () => ({ + AppState: { addEventListener: vi.fn(() => ({ remove: vi.fn() })) }, + RefreshControl: 'RefreshControl', + ScrollView: 'ScrollView', + View: 'View', +})); +vi.mock('react-native-reanimated', () => ({ + default: { View: 'Animated.View' }, + FadeIn: { duration: vi.fn() }, + FadeOut: { duration: vi.fn() }, +})); +vi.mock('@kilocode/notifications', () => ({ + badgeBucketForInstance: (sandboxId: string) => sandboxId, +})); +vi.mock('@/components/home/agent-sessions-section', () => ({ + AgentSessionsSection: () => null, +})); +vi.mock('@/components/home/agents-promo-card', () => ({ + AgentsPromoCard: () => null, +})); +vi.mock('@/components/home/greeting', () => ({ + buildTimedGreeting: () => 'Good morning', +})); +vi.mock('@/components/home/kiloclaw-promo-card', () => ({ + KiloClawPromoCard: () => null, +})); +vi.mock('@/components/home/new-task-button', () => ({ + NewTaskButton: () => null, +})); +vi.mock('@/components/home/section-header', () => ({ + SectionHeader: () => null, +})); +vi.mock('@/components/kiloclaw/instance-card', () => ({ + KiloClawCard: () => null, +})); +vi.mock('@/components/kiloclaw/status-badge', () => ({ + isTransitionalStatus: () => false, +})); +vi.mock('@/components/profile-avatar-button', () => ({ + ProfileAvatarButton: () => null, +})); +vi.mock('@/components/screen-header', () => ({ + ScreenHeader: () => null, +})); +vi.mock('@/components/ui/skeleton', () => ({ + Skeleton: () => null, +})); +vi.mock('@/lib/hooks/use-agent-sessions', () => ({ + useAgentSessions: () => ({ activeSessions: [], isLoading: false, storedSessions: [] }), +})); +vi.mock('@/lib/hooks/use-instance-context', () => ({ + useAllKiloClawInstances: () => ({ + data: [], + isError: false, + isPending: false, + }), +})); +vi.mock('@/lib/hooks/use-unread-counts', () => ({ + useUnreadCounts: () => ({ byBadgeBucket: new Map() }), +})); +vi.mock('@/lib/organization-context', () => ({ + useOrganization: () => ({ organizationId: null }), +})); +vi.mock('@/lib/trpc', () => ({ + useTRPC: () => ({ + kiloclaw: { + getStatus: { queryKey: () => ['kiloclaw', 'getStatus'] }, + listAllInstances: { queryKey: () => ['kiloclaw', 'listAllInstances'] }, + }, + }), +})); + +describe('HomeScreen copy', () => { + it('does not show the first-time welcome headline on the main page', () => { + expect(HomeScreen.toString()).not.toContain('Welcome to Kilo'); + }); +}); diff --git a/apps/mobile/src/components/home/home-screen.tsx b/apps/mobile/src/components/home/home-screen.tsx index 72e45f70d3..c04ce14fde 100644 --- a/apps/mobile/src/components/home/home-screen.tsx +++ b/apps/mobile/src/components/home/home-screen.tsx @@ -8,7 +8,7 @@ import { badgeBucketForInstance } from '@kilocode/notifications'; import { AgentSessionsSection } from '@/components/home/agent-sessions-section'; import { AgentsPromoCard } from '@/components/home/agents-promo-card'; -import { buildTimedGreeting, Greeting } from '@/components/home/greeting'; +import { buildTimedGreeting } from '@/components/home/greeting'; import { KiloClawPromoCard } from '@/components/home/kiloclaw-promo-card'; import { NewTaskButton } from '@/components/home/new-task-button'; import { SectionHeader } from '@/components/home/section-header'; @@ -93,9 +93,6 @@ export function HomeScreen() { const isLoading = instancesPending || sessionsLoading; const hasAnySession = storedSessions.length > 0 || activeSessions.length > 0; - const hasInstance = (instances?.length ?? 0) > 0; - const isFirstTime = !hasInstance && !hasAnySession && !instancesError; - const headerTitle = buildTimedGreeting(null); const handleRefresh = useCallback(() => { @@ -124,8 +121,6 @@ export function HomeScreen() { showsVerticalScrollIndicator={false} refreshControl={} > - {isFirstTime ? : null} - {isLoading ? ( From 1ef7981130d70f284a1c5a8353c24713585c2370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 17:32:49 +0200 Subject: [PATCH 15/34] fix(mobile): remove kilo chat debug logs --- .../kilo-chat/conversation-screen.tsx | 35 ------------------- apps/mobile/src/components/kilo-chat/debug.ts | 16 --------- .../hooks/use-instance-event-subscription.ts | 10 +----- 3 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 apps/mobile/src/components/kilo-chat/debug.ts diff --git a/apps/mobile/src/components/kilo-chat/conversation-screen.tsx b/apps/mobile/src/components/kilo-chat/conversation-screen.tsx index 8753e8b283..31add7f713 100644 --- a/apps/mobile/src/components/kilo-chat/conversation-screen.tsx +++ b/apps/mobile/src/components/kilo-chat/conversation-screen.tsx @@ -43,7 +43,6 @@ import { MessageInput } from './message-input'; import { type MessageInputSubmitControls } from './message-input-state'; import { MessageList } from './message-list'; import { MessageReactionPickerSheet } from './message-reaction-picker-sheet'; -import { debugKiloChat } from './debug'; import { buildSendMessageVariables, canCopyMessage, @@ -176,40 +175,6 @@ export function ConversationScreen({ editing: editingMessage !== null, }); - useEffect( - () => - client.onBotStatus((context, event) => { - debugKiloChat( - event.sandboxId === sandboxId ? 'bot.status event received' : 'bot.status event ignored', - { - context, - routeSandboxId: sandboxId, - eventSandboxId: event.sandboxId, - online: event.online, - ageMs: Date.now() - event.at, - } - ); - }), - [client, sandboxId] - ); - - useEffect(() => { - debugKiloChat('bot input state', { - sandboxId, - instanceStatus, - hasBotStatus: botStatus !== null, - botOnline: botStatus?.online ?? null, - botAgeMs: botStatus ? Date.now() - botStatus.at : null, - displayState: inputAvailability.botDisplay.state, - disabledReason: inputAvailability.disabledReason, - }); - }, [ - botStatus, - inputAvailability.botDisplay.state, - inputAvailability.disabledReason, - instanceStatus, - sandboxId, - ]); const canSwitchInstance = (instances?.length ?? 0) > 1; const instanceLabel = kiloclawConversationEyebrow(currentInstance); diff --git a/apps/mobile/src/components/kilo-chat/debug.ts b/apps/mobile/src/components/kilo-chat/debug.ts deleted file mode 100644 index 5d202949f7..0000000000 --- a/apps/mobile/src/components/kilo-chat/debug.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable no-console */ - -function isReactNativeDev(): boolean { - return (globalThis as { __DEV__?: boolean }).__DEV__ === true; -} - -export function debugKiloChat(message: string, data?: Record): void { - if (!isReactNativeDev()) { - return; - } - if (data) { - console.log(`[kilo-chat] ${message}`, data); - return; - } - console.log(`[kilo-chat] ${message}`); -} diff --git a/apps/mobile/src/components/kilo-chat/hooks/use-instance-event-subscription.ts b/apps/mobile/src/components/kilo-chat/hooks/use-instance-event-subscription.ts index 49af8eb1a7..84c28b7124 100644 --- a/apps/mobile/src/components/kilo-chat/hooks/use-instance-event-subscription.ts +++ b/apps/mobile/src/components/kilo-chat/hooks/use-instance-event-subscription.ts @@ -7,7 +7,6 @@ import { conversationsKey, registerConversationListCacheHandlers } from '@kiloco import { useCurrentUserId } from './use-current-user-id'; import { useEventServiceClient, useKiloChatClient } from './use-kilo-chat-client'; -import { debugKiloChat } from '../debug'; export function useInstanceEventSubscription( sandboxId: string | undefined, @@ -25,18 +24,11 @@ export function useInstanceEventSubscription( if (!ctx) { return undefined; } - debugKiloChat('instance event subscribe', { - context: ctx, - connected: - typeof eventService.isConnected === 'function' ? eventService.isConnected() : null, - hasActiveConversation: activeConversationId !== null && activeConversationId !== undefined, - }); eventService.subscribe([ctx]); return () => { - debugKiloChat('instance event unsubscribe', { context: ctx }); eventService.unsubscribe([ctx]); }; - }, [activeConversationId, ctx, eventService]) + }, [ctx, eventService]) ); useFocusEffect( From 1124806d5a34af39a5d2769a5db3ab5d1a5824bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 17:44:58 +0200 Subject: [PATCH 16/34] fix(mobile): enable expo iap config plugin --- apps/mobile/app.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts index 6273d8d324..b5065a982f 100644 --- a/apps/mobile/app.config.ts +++ b/apps/mobile/app.config.ts @@ -122,6 +122,7 @@ const config: ExpoConfig = { ], 'expo-apple-authentication', 'expo-audio', + 'expo-iap', 'expo-sharing', 'expo-video', 'expo-asset', From 147dc4cd3ea13790109b13c798b6afd1ce348f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 18:06:25 +0200 Subject: [PATCH 17/34] fix(mobile): handle apple purchases from storekit events --- .../mobile/src/lib/apple-iap/storekit.test.ts | 180 ++++++++++++++++++ apps/mobile/src/lib/apple-iap/storekit.ts | 94 ++++++++- apps/mobile/vitest.config.ts | 2 + 3 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 apps/mobile/src/lib/apple-iap/storekit.test.ts diff --git a/apps/mobile/src/lib/apple-iap/storekit.test.ts b/apps/mobile/src/lib/apple-iap/storekit.test.ts new file mode 100644 index 0000000000..305867b7cc --- /dev/null +++ b/apps/mobile/src/lib/apple-iap/storekit.test.ts @@ -0,0 +1,180 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { + finishTransaction, + initConnection, + type Purchase, + type PurchaseError, + purchaseErrorListener, + purchaseUpdatedListener, + requestPurchase, +} from 'expo-iap'; + +import { + finishStoreKitTransaction, + purchaseStoreKitProduct, + STOREKIT_PURCHASE_TIMEOUT_MS, +} from './storekit'; + +const listenerState = vi.hoisted(() => ({ + onPurchase: null as ((purchase: Purchase) => void) | null, + onPurchaseError: null as ((error: PurchaseError) => void) | null, + purchaseErrorRemove: vi.fn(), + purchaseRemove: vi.fn(), +})); + +function makePurchase(overrides: Partial = {}): Purchase { + return { + id: 'transaction-id', + isAutoRenewing: false, + platform: 'ios', + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseState: 'purchased', + purchaseToken: 'signed-transaction-jws', + quantity: 1, + store: 'apple', + transactionDate: Date.now(), + ...overrides, + }; +} + +vi.mock('expo-iap', () => ({ + finishTransaction: vi.fn(), + initConnection: vi.fn(), + purchaseErrorListener: vi.fn((listener: (error: PurchaseError) => void) => { + listenerState.onPurchaseError = listener; + return { remove: listenerState.purchaseErrorRemove }; + }), + purchaseUpdatedListener: vi.fn((listener: (purchase: Purchase) => void) => { + listenerState.onPurchase = listener; + return { remove: listenerState.purchaseRemove }; + }), + requestPurchase: vi.fn(), +})); + +beforeEach(() => { + vi.useRealTimers(); + listenerState.onPurchase = null; + listenerState.onPurchaseError = null; + listenerState.purchaseErrorRemove.mockClear(); + listenerState.purchaseRemove.mockClear(); + vi.clearAllMocks(); + vi.mocked(initConnection).mockResolvedValue(true); + vi.mocked(requestPurchase).mockResolvedValue( + makePurchase({ + productId: 'ignored-return-value', + purchaseToken: 'ignored-token', + }) + ); + vi.mocked(finishTransaction).mockResolvedValue(undefined); +}); + +describe('purchaseStoreKitProduct', () => { + it('resolves from purchaseUpdatedListener instead of requestPurchase return value', async () => { + const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); + await Promise.resolve(); + + expect(vi.mocked(purchaseUpdatedListener).mock.invocationCallOrder[0]).toBeLessThan( + vi.mocked(requestPurchase).mock.invocationCallOrder[0] ?? 0 + ); + expect(vi.mocked(purchaseErrorListener).mock.invocationCallOrder[0]).toBeLessThan( + vi.mocked(requestPurchase).mock.invocationCallOrder[0] ?? 0 + ); + expect(requestPurchase).toHaveBeenCalledWith({ + request: { apple: { sku: 'com.kilocode.kiloapp.credits.small.999' } }, + type: 'in-app', + }); + + listenerState.onPurchase?.( + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseToken: 'listener-signed-transaction', + }) + ); + + await expect(purchasePromise).resolves.toMatchObject({ + productId: 'com.kilocode.kiloapp.credits.small.999', + transactionJws: 'listener-signed-transaction', + }); + expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); + expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); + }); + + it('ignores purchaseUpdatedListener events for other products', async () => { + const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); + await Promise.resolve(); + + listenerState.onPurchase?.( + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.large.4999', + purchaseToken: 'wrong-product-token', + }) + ); + listenerState.onPurchase?.( + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseToken: 'right-product-token', + }) + ); + + await expect(purchasePromise).resolves.toMatchObject({ + transactionJws: 'right-product-token', + }); + }); + + it('rejects when the matching purchase is missing a signed transaction JWS', async () => { + const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); + await Promise.resolve(); + + listenerState.onPurchase?.( + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseToken: null, + }) + ); + + await expect(purchasePromise).rejects.toThrow( + 'StoreKit purchase did not include a signed transaction JWS' + ); + }); + + it('rejects when purchaseErrorListener receives an error', async () => { + const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); + await Promise.resolve(); + + listenerState.onPurchaseError?.({ + code: 'user-cancelled' as PurchaseError['code'], + message: 'User cancelled purchase', + productId: 'com.kilocode.kiloapp.credits.small.999', + }); + + await expect(purchasePromise).rejects.toThrow('User cancelled purchase'); + expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); + expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); + }); + + it('rejects if StoreKit never emits a purchase event', async () => { + vi.useFakeTimers(); + const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); + await Promise.resolve(); + const rejection = expect(purchasePromise).rejects.toThrow('StoreKit purchase timed out'); + + await vi.advanceTimersByTimeAsync(STOREKIT_PURCHASE_TIMEOUT_MS); + + await rejection; + expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); + expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); + }); +}); + +describe('finishStoreKitTransaction', () => { + it('finishes credit pack transactions as consumable', async () => { + const purchase = makePurchase(); + + await finishStoreKitTransaction(purchase); + + expect(finishTransaction).toHaveBeenCalledWith({ + purchase, + isConsumable: true, + }); + }); +}); diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts index 7354389229..6dadbd21d3 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -3,9 +3,13 @@ import { finishTransaction, initConnection, type Purchase, + purchaseErrorListener, + purchaseUpdatedListener, requestPurchase, } from 'expo-iap'; +export const STOREKIT_PURCHASE_TIMEOUT_MS = 2 * 60_000; + export type StoreKitProduct = { id: string; title: string; @@ -28,24 +32,94 @@ export async function fetchStoreKitProducts(productIds: string[]): Promise { - await initConnection(); - const purchaseResult = await requestPurchase({ - request: { apple: { sku: productId } }, - type: 'in-app', - }); - const purchase = Array.isArray(purchaseResult) ? purchaseResult[0] : purchaseResult; - if (!purchase) { - throw new Error('StoreKit purchase did not return a transaction'); +function purchaseErrorToError(error: { message?: string | null }): Error { + return new Error(error.message ?? 'StoreKit purchase failed'); +} + +function toStoreKitPurchaseResult(productId: string, purchase: Purchase): StoreKitPurchaseResult { + if (purchase.productId !== productId) { + throw new Error(`StoreKit returned transaction for unexpected product ${purchase.productId}`); } const transactionJws = purchase.purchaseToken; if (!transactionJws) { throw new Error('StoreKit purchase did not include a signed transaction JWS'); } - return { productId, transactionJws, nativeTransaction: purchase }; } +export async function purchaseStoreKitProduct(productId: string): Promise { + await initConnection(); + + return new Promise((resolve, reject) => { + let settled = false; + let timeout: ReturnType | null = null; + let purchaseSubscription: { remove: () => void } | null = null; + let errorSubscription: { remove: () => void } | null = null; + + const cleanup = () => { + purchaseSubscription?.remove(); + errorSubscription?.remove(); + if (timeout) { + clearTimeout(timeout); + } + }; + + const rejectOnce = (error: unknown) => { + if (settled) { + return; + } + settled = true; + cleanup(); + reject(error instanceof Error ? error : new Error('StoreKit purchase failed')); + }; + + const resolveOnce = (purchase: Purchase) => { + if (settled) { + return; + } + try { + const result = toStoreKitPurchaseResult(productId, purchase); + settled = true; + cleanup(); + resolve(result); + } catch (error) { + rejectOnce(error); + } + }; + + timeout = setTimeout(() => { + rejectOnce(new Error('StoreKit purchase timed out')); + }, STOREKIT_PURCHASE_TIMEOUT_MS); + + purchaseSubscription = purchaseUpdatedListener(purchase => { + if (purchase.productId !== productId) { + return; + } + resolveOnce(purchase); + }); + + // Native purchase errors are delivered through expo-iap's event callback. + // eslint-disable-next-line promise/prefer-await-to-callbacks + errorSubscription = purchaseErrorListener(error => { + if (error.productId && error.productId !== productId) { + return; + } + rejectOnce(purchaseErrorToError(error)); + }); + + void (async () => { + try { + await requestPurchase({ + request: { apple: { sku: productId } }, + type: 'in-app', + }); + } catch (error) { + rejectOnce(error); + } + })(); + }); +} + export async function finishStoreKitTransaction(nativeTransaction: Purchase): Promise { await finishTransaction({ purchase: nativeTransaction, isConsumable: true }); } diff --git a/apps/mobile/vitest.config.ts b/apps/mobile/vitest.config.ts index 892908c4d3..f2b8c92fa1 100644 --- a/apps/mobile/vitest.config.ts +++ b/apps/mobile/vitest.config.ts @@ -13,6 +13,8 @@ export default defineConfig({ environment: 'node', include: [ 'src/lib/*.test.ts', + 'src/lib/apple-iap/**/*.test.ts', + 'src/lib/apple-iap/**/*.test.tsx', 'src/lib/onboarding/**/*.test.ts', 'src/components/**/*.test.ts', ], From a1403549894ac0c4cb05556d887fd91a12d83603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 18:25:06 +0200 Subject: [PATCH 18/34] chore(mobile): align expo sdk dependencies --- apps/mobile/metro.config.js | 2 +- apps/mobile/package.json | 65 +- pnpm-lock.yaml | 1567 +++++++++++++++++------------------ 3 files changed, 818 insertions(+), 816 deletions(-) diff --git a/apps/mobile/metro.config.js b/apps/mobile/metro.config.js index e74b48f511..741cfdd799 100644 --- a/apps/mobile/metro.config.js +++ b/apps/mobile/metro.config.js @@ -11,7 +11,7 @@ const cloudAgentSdkPath = path.resolve(webSrc, 'lib', 'cloud-agent-sdk'); const config = getSentryExpoConfig(__dirname); // Allow Metro to resolve workspace files and pnpm's real package paths -config.watchFolders = [monorepoRoot]; +config.watchFolders = [...new Set([...(config.watchFolders || []), monorepoRoot])]; // Let SDK dependencies (jotai, zod, etc.) resolve from the monorepo root node_modules config.resolver.nodeModulesPaths = [ diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 7ced05aa52..fd1e6abc62 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -31,7 +31,7 @@ "@react-native-community/netinfo": "11.5.2", "@rn-primitives/portal": "^1.3.0", "@rn-primitives/slot": "^1.2.0", - "@sentry/react-native": "~7.11.0", + "@sentry/react-native": "~8.10.0", "@shopify/flash-list": "2.0.2", "@tailwindcss/postcss": "^4.2.2", "@tanstack/react-query": "catalog:", @@ -39,40 +39,40 @@ "@trpc/tanstack-react-query": "catalog:", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "expo": "~55.0.12", - "expo-apple-authentication": "~55.0.12", - "expo-application": "~55.0.13", - "expo-asset": "~55.0.13", - "expo-audio": "~55.0.12", + "expo": "~55.0.23", + "expo-apple-authentication": "~55.0.13", + "expo-application": "~55.0.14", + "expo-asset": "~55.0.17", + "expo-audio": "~55.0.14", "expo-blur": "~55.0.14", - "expo-build-properties": "~55.0.12", - "expo-clipboard": "~55.0.12", - "expo-constants": "~55.0.12", + "expo-build-properties": "~55.0.13", + "expo-clipboard": "~55.0.13", + "expo-constants": "~55.0.16", "expo-crypto": "~55.0.14", - "expo-dev-client": "~55.0.23", - "expo-document-picker": "~55.0.12", - "expo-font": "~55.0.6", - "expo-haptics": "~55.0.13", + "expo-dev-client": "~55.0.32", + "expo-document-picker": "~55.0.13", + "expo-font": "~55.0.7", + "expo-haptics": "~55.0.14", "expo-iap": "^4.2.4", - "expo-image": "~55.0.8", - "expo-image-picker": "~55.0.17", - "expo-insights": "55.0.15", - "expo-linking": "~55.0.11", - "expo-location": "~55.1.8", - "expo-notifications": "~55.0.17", - "expo-router": "~55.0.11", - "expo-secure-store": "~55.0.12", - "expo-sharing": "~55.0.17", - "expo-splash-screen": "~55.0.16", - "expo-status-bar": "~55.0.5", - "expo-tracking-transparency": "~55.0.12", - "expo-video": "~55.0.14", - "expo-web-browser": "~55.0.13", + "expo-image": "~55.0.10", + "expo-image-picker": "~55.0.20", + "expo-insights": "55.0.16", + "expo-linking": "~55.0.15", + "expo-location": "~55.1.9", + "expo-notifications": "~55.0.22", + "expo-router": "~55.0.14", + "expo-secure-store": "~55.0.13", + "expo-sharing": "~55.0.18", + "expo-splash-screen": "~55.0.20", + "expo-status-bar": "~55.0.6", + "expo-tracking-transparency": "~55.0.13", + "expo-video": "~55.0.16", + "expo-web-browser": "~55.0.15", "jotai": "^2.18.1", "lucide-react-native": "^1.7.0", "nativewind": "5.0.0-preview.3", "react": "19.2.0", - "react-native": "0.83.4", + "react-native": "0.83.6", "react-native-appsflyer": "^6.17.9", "react-native-css": "3.0.6", "react-native-gesture-handler": "~2.30.0", @@ -81,7 +81,7 @@ "react-native-safe-area-context": "~5.6.2", "react-native-screens": "~4.23.0", "react-native-svg": "15.15.3", - "react-native-worklets": "0.7.2", + "react-native-worklets": "0.7.4", "sonner-native": "^0.23.1", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.2", @@ -101,5 +101,12 @@ "injected": true } }, + "expo": { + "install": { + "exclude": [ + "@sentry/react-native" + ] + } + }, "private": true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c7643dad5..56fb9dde39 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -155,19 +155,19 @@ importers: version: link:../../packages/trpc '@react-native-community/netinfo': specifier: 11.5.2 - version: 11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 11.5.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@rn-primitives/portal': specifier: ^1.3.0 - version: 1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) + version: 1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) '@rn-primitives/slot': specifier: ^1.2.0 - version: 1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 1.2.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@sentry/react-native': - specifier: ~7.11.0 - version: 7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~8.10.0 + version: 8.10.0(@expo/env@2.1.2)(dotenv@17.3.1)(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@shopify/flash-list': specifier: 2.0.2 - version: 2.0.2(@babel/runtime@7.29.2)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 2.0.2(@babel/runtime@7.29.2)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -187,137 +187,137 @@ importers: specifier: ^2.1.1 version: 2.1.1 expo: - specifier: ~55.0.12 - version: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + specifier: ~55.0.23 + version: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-apple-authentication: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) - expo-application: specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12) + version: 55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-application: + specifier: ~55.0.14 + version: 55.0.14(expo@55.0.23) expo-asset: - specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.17 + version: 55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-audio: - specifier: ~55.0.12 - version: 55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.14 + version: 55.0.14(expo-asset@55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-blur: specifier: ~55.0.14 - version: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 55.0.14(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-build-properties: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.23) expo-clipboard: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-constants: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + specifier: ~55.0.16 + version: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) expo-crypto: specifier: ~55.0.14 - version: 55.0.14(expo@55.0.12) + version: 55.0.14(expo@55.0.23) expo-dev-client: - specifier: ~55.0.23 - version: 55.0.23(expo@55.0.12)(typescript@5.9.3) + specifier: ~55.0.32 + version: 55.0.32(expo@55.0.23) expo-document-picker: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.23) expo-font: - specifier: ~55.0.6 - version: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.7 + version: 55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-haptics: - specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12) + specifier: ~55.0.14 + version: 55.0.14(expo@55.0.23) expo-iap: specifier: ^4.2.4 - version: 4.2.4(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 4.2.4(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-image: - specifier: ~55.0.8 - version: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.10 + version: 55.0.10(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-image-picker: - specifier: ~55.0.17 - version: 55.0.17(expo@55.0.12) + specifier: ~55.0.20 + version: 55.0.20(expo@55.0.23) expo-insights: - specifier: 55.0.15 - version: 55.0.15(expo@55.0.12) + specifier: 55.0.16 + version: 55.0.16(expo@55.0.23) expo-linking: - specifier: ~55.0.11 - version: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.15 + version: 55.0.15(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-location: - specifier: ~55.1.8 - version: 55.1.8(expo@55.0.12)(typescript@5.9.3) + specifier: ~55.1.9 + version: 55.1.9(expo@55.0.23)(typescript@5.9.3) expo-notifications: - specifier: ~55.0.17 - version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.22 + version: 55.0.22(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-router: - specifier: ~55.0.11 - version: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) + specifier: ~55.0.14 + version: 55.0.14(3108cc3b583b2b3cde65eb2e75099aa2) expo-secure-store: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.23) expo-sharing: - specifier: ~55.0.17 - version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.18 + version: 55.0.18(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-splash-screen: - specifier: ~55.0.16 - version: 55.0.16(expo@55.0.12)(typescript@5.9.3) + specifier: ~55.0.20 + version: 55.0.20(expo@55.0.23)(typescript@5.9.3) expo-status-bar: - specifier: ~55.0.5 - version: 55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.6 + version: 55.0.6(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-tracking-transparency: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) expo-video: - specifier: ~55.0.14 - version: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: ~55.0.16 + version: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-web-browser: - specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + specifier: ~55.0.15 + version: 55.0.15(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) jotai: specifier: ^2.18.1 version: 2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.0) lucide-react-native: specifier: ^1.7.0 - version: 1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 1.7.0(react-native-svg@15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) nativewind: specifier: 5.0.0-preview.3 - version: 5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2) + version: 5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2) react: specifier: 19.2.0 version: 19.2.0 react-native: - specifier: 0.83.4 - version: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + specifier: 0.83.6 + version: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) react-native-appsflyer: specifier: ^6.17.9 version: 6.17.9 react-native-css: specifier: 3.0.6 - version: 3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 3.0.6(@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-gesture-handler: specifier: ~2.30.0 - version: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 2.30.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-marked: specifier: ^8.0.1 - version: 8.0.1(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 8.0.1(react-native-svg@15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-reanimated: specifier: 4.2.1 - version: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 4.2.1(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-safe-area-context: specifier: ~5.6.2 - version: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-screens: specifier: ~4.23.0 - version: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-svg: specifier: 15.15.3 - version: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + version: 15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-worklets: - specifier: 0.7.2 - version: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + specifier: 0.7.4 + version: 0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sonner-native: specifier: ^0.23.1 - version: 0.23.1(53175ba88151f39b99a3b76a61c65c1d) + version: 0.23.1(e2671c59cdfc41694eb0da90c4eaaa5b) tailwind-merge: specifier: ^3.5.0 version: 3.5.0 @@ -3896,8 +3896,8 @@ packages: '@expo-google-fonts/material-symbols@0.4.27': resolution: {integrity: sha512-cnb3DZnWUWpezGFkJ8y4MT5f/lw6FcgDzeJzic+T+vpQHLHG1cg3SC3i1w1i8Bk4xKR4HPY3t9iIRNvtr5ml8A==} - '@expo/cli@55.0.22': - resolution: {integrity: sha512-tq6lkS50edbfbKGUkgUmrOZ6JwRZrQY1fFVTrrtakkMFIbNtMTsImFsDpV8nstQM88DvsA9hb2W5cxRStPtIWw==} + '@expo/cli@55.0.29': + resolution: {integrity: sha512-r2dXQ82e/3nwxS7faLRL6HBD8UWDo/IyptQ0Vg6Z5Bgyp2Kd24h8xPn3RHfY3LLJ3wfEXglf4E79/Dqkm1Z6WA==} hasBin: true peerDependencies: expo: '*' @@ -3918,14 +3918,14 @@ packages: '@expo/config-types@55.0.5': resolution: {integrity: sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg==} - '@expo/config@55.0.13': - resolution: {integrity: sha512-mO6le0JXEk7whsIb5E7rT36wOtdcLRFlApc7eLCOyu24uQUvWKk00HSEPVjiOuMd7EgYz/8JBPCA+Rb96uNjIg==} + '@expo/config@55.0.16': + resolution: {integrity: sha512-H5dpQv5TfyZDNheZAWO3SmP10diGWZwN5QOUsArkDJih0QKNtahQBOmrV2xbhgln/nrUGoy41U/ZIY/MEx63Ug==} '@expo/devcert@1.2.1': resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==} - '@expo/devtools@55.0.2': - resolution: {integrity: sha512-4VsFn9MUriocyuhyA+ycJP3TJhUsOFHDc270l9h3LhNpXMf6wvIdGcA0QzXkZtORXmlDybWXRP2KT1k36HcQkA==} + '@expo/devtools@55.0.3': + resolution: {integrity: sha512-KoIDgo0NoXeWLsIcOdZqtAG/1LlsM+JL0DA3bo0vCYaOYTBLXi/ZvRBqa20Ub8D2vKLNa+FgRQW0gRg04Ps1Pg==} peerDependencies: react: '*' react-native: '*' @@ -3935,50 +3935,50 @@ packages: react-native: optional: true - '@expo/dom-webview@55.0.5': - resolution: {integrity: sha512-lt3uxYOCk3wmWvtOOvsC35CKGbDAOx5C2EaY8SH1JVSfBzqmF8Cs0Xp1MPxncDPMyxpMiWx5SvvV/iLF1rJU4A==} + '@expo/dom-webview@55.0.6': + resolution: {integrity: sha512-ZNm8tiNEZysxrr36J0x4mOCGyJDcaIvL/3tMxBz0VJIJDcV19xjuJAhJQxHovu+jKx6s9tRyEAINa1mdrzV39g==} peerDependencies: expo: '*' react: '*' react-native: '*' - '@expo/env@2.1.1': - resolution: {integrity: sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg==} + '@expo/env@2.1.2': + resolution: {integrity: sha512-RJtGFfj/ygO/6zcVbV3cckHf4THcEkv5IZft1GjCB3dfT6axvzvIwXE9EiQqQYmGHcQ+ZrvC8xZcIhiHba0pYg==} engines: {node: '>=20.12.0'} - '@expo/fingerprint@0.16.6': - resolution: {integrity: sha512-nRITNbnu3RKSHPvKVehrSU4KG2VY9V8nvULOHBw98ukHCAU4bGrU5APvcblOkX3JAap+xEHsg/mZvqlvkLInmQ==} + '@expo/fingerprint@0.16.7': + resolution: {integrity: sha512-BH8sicYOqZ1iBMwCVEGIz6uTTfylosjc49FoMmCYIzKOiYdiVehsfoYBwyfxwWIiya1VMhm1gv0cgOP8fxHpDw==} hasBin: true - '@expo/image-utils@0.8.12': - resolution: {integrity: sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==} - - '@expo/image-utils@0.8.13': - resolution: {integrity: sha512-1I//yBQeTY6p0u1ihqGNDAr35EbSG8uFEupFrIF0jd++h9EWH33521yZJU1yE+mwGlzCb61g3ehu78siMhXBlA==} + '@expo/image-utils@0.8.14': + resolution: {integrity: sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==} '@expo/json-file@10.0.13': resolution: {integrity: sha512-pX/XjQn7tgNw6zuuV2ikmegmwe/S7uiwhrs2wXrANMkq7ozrA+JcZwgW9Q/8WZgciBzfAhNp5hnackHcrmapQA==} - '@expo/local-build-cache-provider@55.0.9': - resolution: {integrity: sha512-MbRqLuZCzfxkiWMbNy5Kxx3ivji8b0W4DshXEwD5XZlfRrVb8CdShztpNM3UR6IiKJUqFQp6BmCjAx90ptIyWg==} + '@expo/json-file@10.0.14': + resolution: {integrity: sha512-yWwBFywFv+SxkJp/pIzzA416JVYflNUh7pqQzgaA6nXDqRyK7KfrqVzk8PdUfDnqbBcaZZxpzNssfQZzp5KHrA==} + + '@expo/local-build-cache-provider@55.0.12': + resolution: {integrity: sha512-Wqhe7ajt6lyIEQvqDC1zm0MQ1RqQLlM9awCepY9pz+tm9rvhuxGPZTSddWeD8k4kolinBlDbLDFnNi06XgaDWQ==} - '@expo/log-box@55.0.10': - resolution: {integrity: sha512-7jdikExgIrCIF5e3P1qMwcUZ2tcxrNdVqE9Y8kNMUHqZ+ipMlin+SiZwJKHM1+am4CYGjhdyrzbnIpvEcLDYcg==} + '@expo/log-box@55.0.12': + resolution: {integrity: sha512-f9ARS8J60cq3LLNdIqmUjYwyerBzVS5Ecp7KjIf3GOIPjW0571rkcwLz4/U18l/1DeSkSzIkYsNl2TC9oTdWaQ==} peerDependencies: expo: '*' react: '*' react-native: '*' - '@expo/metro-config@55.0.14': - resolution: {integrity: sha512-s9tD8eTANTEh9j0mHreMYNRzfxfqc0dpfCbJ0oi3S2X11T75xQifppABKBGvzntw3nZ6O/QRJZykomXnLe8u0A==} + '@expo/metro-config@55.0.20': + resolution: {integrity: sha512-dUv0simEyPbN2wbOjI+BdEZyXdghgCZD0+3rrA1WxXZN1lRofUx6g2+Nik2Qg61v/BXFrCTh8reYEzQPzHOhdQ==} peerDependencies: expo: '*' peerDependenciesMeta: expo: optional: true - '@expo/metro-runtime@55.0.9': - resolution: {integrity: sha512-H37b2Mc/8GiQbwtUFzUTxA3KsAMZu00SRg/RhbHa9xVE7J0n5ZX4NHy0LJEFAbkzTb1TUy1hLpo3oEKnG+rLyg==} + '@expo/metro-runtime@55.0.11': + resolution: {integrity: sha512-4KKi/jGrIEXi2YGu0hYTVr0CEeRJy5SXbCrz9+KDZkuD3ROwKNpM1DBawni5rhPVovFnR323HBck9GaxhnfrRw==} peerDependencies: expo: '*' react: '*' @@ -3988,21 +3988,21 @@ packages: react-dom: optional: true - '@expo/metro@55.0.0': - resolution: {integrity: sha512-wohGl+4y17rGHU+lq8UqC5neOXL/HOThorDYXTMbOcBL1jYwcK11MBc151gDMpjpgdVUzgHne0H5RfCIhIN4hA==} + '@expo/metro@55.1.1': + resolution: {integrity: sha512-/wfXo5hTuAVpVLG/4hzlmD9NBGJkzkmBEMm/4VICajYRbj7y8OmqqPWbbymzHiBiHB6tI9BnsyXpQM6zVZEECg==} - '@expo/osascript@2.4.2': - resolution: {integrity: sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==} + '@expo/osascript@2.4.3': + resolution: {integrity: sha512-wbuj3EebM7W9hN/Wp4xTzKd6rQ2zKJzAxkFxkOOwyysLp0HOAgQ4/5RINyoS241pZUX2rUHq7mAJ7pcCQ8U0Ow==} engines: {node: '>=12'} - '@expo/package-manager@1.10.4': - resolution: {integrity: sha512-y9Mr4Kmpk4abAVZrNNPCdzOZr8nLLyi18p1SXr0RCVA8IfzqZX/eY4H+50a0HTmXqIsPZrQdcdb4I3ekMS9GvQ==} + '@expo/package-manager@1.10.5': + resolution: {integrity: sha512-nCP9Mebfl3jvOr0/P6VAuyah6PAtun+aihIL2zAtuE8uSe94JWkVZ7051i0MUVO+y3gFpBqnr8IIH5ch+VJjHA==} - '@expo/plist@0.5.2': - resolution: {integrity: sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==} + '@expo/plist@0.5.3': + resolution: {integrity: sha512-jz5oPcPDd3fygwVxwSwmO6wodTwm0Qa14NUyPy0ka7H8sFmCtNZUI2+DzVe/EXjOhq1FbEjrwl89gdlWYOnVjQ==} - '@expo/prebuild-config@55.0.13': - resolution: {integrity: sha512-3a0vS6dHhVEs8B9Sqz6OIdCZ52S7SWuvLxNTQ+LE66g8OJ5b8xW6kGSCK0Z2bWBFoYfAbZzitLaBi8oBKOVqkw==} + '@expo/prebuild-config@55.0.17': + resolution: {integrity: sha512-Mcs+dg4Ripu0yCtzf66KZr18PehI1O8HxzJw+G5SUF8VWX+ic99aci1PltvmydWepLwTQL6ykmpXicAUA31IqA==} peerDependencies: expo: '*' @@ -4011,31 +4011,23 @@ packages: peerDependencies: react: '>=18.0.0' - '@expo/require-utils@55.0.3': - resolution: {integrity: sha512-TS1m5tW45q4zoaTlt6DwmdYHxvFTIxoLrTHKOFrIirHIqIXnHCzpceg8wumiBi+ZXSaGY2gobTbfv+WVhJY6Fw==} + '@expo/require-utils@55.0.5': + resolution: {integrity: sha512-U4K/CQ2VpXuwfNGsN+daKmYOt15hCP8v/pXaYH6eut7kdYZo6SfJ1yr67BIcJ+1Gzzs+QzTxswAZChKpXmceyw==} peerDependencies: typescript: ^5.0.0 || ^5.0.0-0 peerDependenciesMeta: typescript: optional: true - '@expo/require-utils@55.0.4': - resolution: {integrity: sha512-JAANvXqV7MOysWeVWgaiDzikoyDjJWOV/ulOW60Zb3kXJfrx2oZOtGtDXDFKD1mXuahQgoM5QOjuZhF7gFRNjA==} + '@expo/router-server@55.0.16': + resolution: {integrity: sha512-LvAdrm039nQBG+95+ff5Rc4CsBuoc/giDhjQrgxB9lKJqC/ZTq1xbwfEZFNq6yokX6fOCs/vlxdhmSkOjMIrvg==} peerDependencies: - typescript: ^5.0.0 || ^5.0.0-0 - peerDependenciesMeta: - typescript: - optional: true - - '@expo/router-server@55.0.13': - resolution: {integrity: sha512-AoxfxJYkAIMey8YqAohFovp4M4DjzoCDH9ampVN/ZKt+bzXkTIFmWEinQ5mpMfHdfIWaumvxQbohgoo6D5xUZA==} - peerDependencies: - '@expo/metro-runtime': ^55.0.9 + '@expo/metro-runtime': ^55.0.11 expo: '*' - expo-constants: ^55.0.11 - expo-font: ^55.0.6 + expo-constants: ^55.0.16 + expo-font: ^55.0.7 expo-router: '*' - expo-server: ^55.0.7 + expo-server: ^55.0.9 react: '*' react-dom: '*' react-server-dom-webpack: ~19.0.1 || ~19.1.2 || ~19.2.1 @@ -4049,8 +4041,8 @@ packages: react-server-dom-webpack: optional: true - '@expo/schema-utils@55.0.3': - resolution: {integrity: sha512-l9KHVjTo6MvoeyvwNr6AjckGJm8NIcqZ3QSAh51cWozXW9v2AUjyCyqYtFtyntLWRZ0x/ByYJishpQo4ZQq45Q==} + '@expo/schema-utils@55.0.4': + resolution: {integrity: sha512-65IdeeE8dAZR3n3J5Eq7LYiQ8BFGeEYCWPBCzycvafL7PkskbCyIclTQarRwf/HXFoRvezKCjaLwy/8v9Prk6g==} '@expo/sdk-runtime-versions@1.0.0': resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==} @@ -6442,24 +6434,24 @@ packages: react: '*' react-native: '>=0.59' - '@react-native/assets-registry@0.83.4': - resolution: {integrity: sha512-aqKtpbJDSQeSX/Dwv0yMe1/Rd2QfXi12lnyZDXNn/OEKz59u6+LuPBVgO/9CRyclHmdlvwg8c7PJ9eX2ZMnjWg==} + '@react-native/assets-registry@0.83.6': + resolution: {integrity: sha512-iljb4ue1yWJ3EhySz7EjV6CzSVrI2uNtR8BI2jzP5+QS5E4Cl3fdIJRmVwDEx1pu8uE97PGEusGRHnoaZ9Q3jg==} engines: {node: '>= 20.19.4'} - '@react-native/babel-plugin-codegen@0.83.4': - resolution: {integrity: sha512-UFsK+c1rvT84XZfzpmwKePsc5nTr5LK7hh18TI0DooNlVcztDbMDsQZpDnhO/gmk7aTbWEqO5AB3HJ7tvGp+Jg==} + '@react-native/babel-plugin-codegen@0.83.6': + resolution: {integrity: sha512-qfRXsHGeucT5c6mK+8Q7v4Ly3zmygfVmFlEtkiq7q07W1OTreld6nib4rJ/DBEeNiKBoBTuHjWliYGNuDjLFQA==} engines: {node: '>= 20.19.4'} - '@react-native/babel-preset@0.83.4': - resolution: {integrity: sha512-SXPFn3Jp4gOzlBDnDOKPzMfxQPKJMYJs05EmEeFB/6km46xZ9l+2YKXwAwxfNhHnmwNf98U/bnVndU95I0TMCw==} + '@react-native/babel-preset@0.83.6': + resolution: {integrity: sha512-4/fXFDUvGOObETZq4+SUFkafld6OGgQWut5cQiqVghlhCB5z/p2lVhPgEUr/aTxTzeS3AmN+ztC+GpYPQ7tsTw==} engines: {node: '>= 20.19.4'} - '@react-native/codegen@0.83.4': - resolution: {integrity: sha512-CJ7XutzIqJPz3Lp/5TOiRWlU/JAjTboMT1BHNLSXjYHXwTmgHM3iGEbpCOtBMjWvsojRTJyRO/G3ghInIIXEYg==} + '@react-native/codegen@0.83.6': + resolution: {integrity: sha512-doB/Pq6Cf6IjF3wlQXTIiZOnsX9X8mEEk+CdGfyuCwZjWrf7IB8KaZEXXckJmfUcIwvJ9u/a72ZoTTCIoxAc9A==} engines: {node: '>= 20.19.4'} - '@react-native/community-cli-plugin@0.83.4': - resolution: {integrity: sha512-8os0weQEnjUhWy7Db881+JKRwNHVGM40VtTRvltAyA/YYkrGg4kPCqiTybMxQDEcF3rnviuxHyI+ITiglfmgmQ==} + '@react-native/community-cli-plugin@0.83.6': + resolution: {integrity: sha512-Mko6mywoHYJmpBnjwAC95vQWaUUh//71knFadH0BrhHDq2m7i/IrpLwcQsPAy8855ucXflBs5zQyGTpNbPBAaw==} engines: {node: '>= 20.19.4'} peerDependencies: '@react-native-community/cli': '*' @@ -6470,31 +6462,31 @@ packages: '@react-native/metro-config': optional: true - '@react-native/debugger-frontend@0.83.4': - resolution: {integrity: sha512-mCE2s/S7SEjax3gZb6LFAraAI3x13gRVWJWqT0HIm71e4ITObENNTDuMw4mvZ/wr4Gz2wv4FcBH5/Nla9LXOcg==} + '@react-native/debugger-frontend@0.83.6': + resolution: {integrity: sha512-TyWXEpAjVundrc87fPWg91piOUg75+X9iutcfDe7cO3NrAEYCsl7Z09rKHuiAGkxfG9/rFD13dPsYIixUFkSFA==} engines: {node: '>= 20.19.4'} - '@react-native/debugger-shell@0.83.4': - resolution: {integrity: sha512-FtAnrvXqy1xeZ+onwilvxEeeBsvBlhtfrHVIC2R/BOJAK9TbKEtFfjio0wsn3DQIm+UZq48DSa+p9jJZ2aJUww==} + '@react-native/debugger-shell@0.83.6': + resolution: {integrity: sha512-684TJMBCU0l0ZjJWzrnK0HH+ERaM9KLyxyArE1k7BrP+gVl4X9GO0Pi94RoInOxvW/nyV65sOU6Ip1F3ygS0cg==} engines: {node: '>= 20.19.4'} - '@react-native/dev-middleware@0.83.4': - resolution: {integrity: sha512-3s9nXZc/kj986nI2RPqxiIJeTS3o7pvZDxbHu7GE9WVIGX9YucA1l/tEiXd7BAm3TBFOfefDOT08xD46wH+R3Q==} + '@react-native/dev-middleware@0.83.6': + resolution: {integrity: sha512-22xoddLTelpcVnF385SNH2hdP7X2av5pu7yRl/WnM5jBznbcl0+M9Ce94cj+WVeomsoUF/vlfuB0Ooy+RMlRiA==} engines: {node: '>= 20.19.4'} - '@react-native/gradle-plugin@0.83.4': - resolution: {integrity: sha512-AhaSWw2k3eMKqZ21IUdM7rpyTYOpAfsBbIIiom1QQii3QccX0uW2AWTcRhfuWRxqr2faGFaOBYedWl2fzp5hgw==} + '@react-native/gradle-plugin@0.83.6': + resolution: {integrity: sha512-5prXv7WWR1RgZ/kWGZP+mi7/y/IE2ymfOHIZO5Pv14tMOmRAcQSgSYogcRmOiWw5mJs2K0UFeMiQD49ZO9oCug==} engines: {node: '>= 20.19.4'} - '@react-native/js-polyfills@0.83.4': - resolution: {integrity: sha512-wYUdv0rt4MjhKhQloO1AnGDXhZQOFZHDxm86dEtEA0WcsCdVrFdRULFM+rKUC/QQtJW2rS6WBqtBusgtrsDADg==} + '@react-native/js-polyfills@0.83.6': + resolution: {integrity: sha512-VSev0LV2i5X0ibduHBSLqKj0YU2F+waCgjl2uvaGHMGCSV1ZRKNFX/vJFqvLwjvdzLbkAZoFT1Rg7k7jDv44UA==} engines: {node: '>= 20.19.4'} - '@react-native/normalize-colors@0.83.4': - resolution: {integrity: sha512-9ezxaHjxqTkTOLg62SGg7YhFaE+fxa/jlrWP0nwf7eGFHlGOiTAaRR2KUfiN3K05e+EMbEhgcH/c7bgaXeGyJw==} + '@react-native/normalize-colors@0.83.6': + resolution: {integrity: sha512-bTM24b5v4qN3h52oflnv+OujFORn/kVi06WaWhnQQw14/ycilPqIsqsa+DpIBqdBrXxvLa9fXtCRrQtGATZCEw==} - '@react-native/virtualized-lists@0.83.4': - resolution: {integrity: sha512-vNF/8kokMW8JEjG4n+j7veLTjHRRABlt4CaTS6+wtqzvWxCJHNIC8fhCqrDPn9fIn8sNePd8DyiFVX5L9TBBRA==} + '@react-native/virtualized-lists@0.83.6': + resolution: {integrity: sha512-gNSFXeb4P7qHtauLvl+zESroULIyX6Ltpvau3dhwy/QmfanBv0KUcrIU/7aVXxtWcXgp+54oWJyu2LIrsZ9+LQ==} engines: {node: '>= 20.19.4'} peerDependencies: '@types/react': ^19.2.0 @@ -6896,54 +6888,54 @@ packages: resolution: {integrity: sha512-xwMkyXgr7xgPsP0w79nzCwRHYi9jzj9ps4Im7xWGK8AKKE4eox39tMZOdRtpDbvXQlrs9fh64ZC0w/yZZDM/9g==} engines: {node: '>=18'} - '@sentry-internal/browser-utils@10.37.0': - resolution: {integrity: sha512-rqdESYaVio9Ktz55lhUhtBsBUCF3wvvJuWia5YqoHDd+egyIfwWxITTAa0TSEyZl7283A4WNHNl0hyeEMblmfA==} - engines: {node: '>=18'} - '@sentry-internal/browser-utils@10.43.0': resolution: {integrity: sha512-8zYTnzhAPvNkVH1Irs62wl0J/c+0QcJ62TonKnzpSFUUD3V5qz8YDZbjIDGfxy+1EB9fO0sxtddKCzwTHF/MbQ==} engines: {node: '>=18'} - '@sentry-internal/feedback@10.37.0': - resolution: {integrity: sha512-P0PVlfrDvfvCYg2KPIS7YUG/4i6ZPf8z1MicXx09C9Cz9W9UhSBh/nii13eBdDtLav2BFMKhvaFMcghXHX03Hw==} + '@sentry-internal/browser-utils@10.51.0': + resolution: {integrity: sha512-lNKBS4P7RUvf1niojXQWe9bU3gnBUCbST4Dj0pSiyat1N96cXVyHkeE+uGxowD0RrVWhs+kGHiVX3FcmRWF6sA==} engines: {node: '>=18'} '@sentry-internal/feedback@10.43.0': resolution: {integrity: sha512-YoXuwluP6eOcQxTeTtaWb090++MrLyWOVsUTejzUQQ6LFL13Jwt+bDPF1kvBugMq4a7OHw/UNKQfd6//rZMn2g==} engines: {node: '>=18'} - '@sentry-internal/replay-canvas@10.37.0': - resolution: {integrity: sha512-PyIYSbjLs+L5essYV0MyIsh4n5xfv2eV7l0nhUoPJv9Bak3kattQY3tholOj0EP3SgKgb+8HSZnmazgF++Hbog==} + '@sentry-internal/feedback@10.51.0': + resolution: {integrity: sha512-bCM95bcpphx28e6aU0bwRLxOgwosYsdNzezM1sM0pVOkb0TB3hDFRamramVDK+/Hp1o8qmRxS4c5w/A7YBZGkA==} engines: {node: '>=18'} '@sentry-internal/replay-canvas@10.43.0': resolution: {integrity: sha512-ZIw1UNKOFXo1LbPCJPMAx9xv7D8TMZQusLDUgb6BsPQJj0igAuwd7KRGTkjjgnrwBp2O/sxcQFRhQhknWk7QPg==} engines: {node: '>=18'} - '@sentry-internal/replay@10.37.0': - resolution: {integrity: sha512-snuk12ZaDerxesSnetNIwKoth/51R0y/h3eXD/bGtXp+hnSkeXN5HanI/RJl297llRjn4zJYRShW9Nx86Ay0Dw==} + '@sentry-internal/replay-canvas@10.51.0': + resolution: {integrity: sha512-8PW1Pp+Yl3lPwYqhBCr5SgkuhDanu9ZLzUqD2bPKL/ElqbM2eDVIWxq4z4ZzePrmZa6IcCjTv6sVQJ7Z4dLyLA==} engines: {node: '>=18'} '@sentry-internal/replay@10.43.0': resolution: {integrity: sha512-khCXlGrlH1IU7P5zCEAJFestMeH97zDVCekj8OsNNDtN/1BmCJ46k6Xi0EqAUzdJgrOLJeLdoYdgtiIjovZ8Sg==} engines: {node: '>=18'} - '@sentry/babel-plugin-component-annotate@4.8.0': - resolution: {integrity: sha512-cy/9Eipkv23MsEJ4IuB4dNlVwS9UqOzI3Eu+QPake5BVFgPYCX0uP0Tr3Z43Ime6Rb+BiDnWC51AJK9i9afHYw==} - engines: {node: '>= 14'} + '@sentry-internal/replay@10.51.0': + resolution: {integrity: sha512-jCpI5HXSwK6ZT2HX70+mDRciAocHzSiDk4DTgvzV69Wvd+Ei5WLgE+d39eaEPsm8lUC0Ydntb5sJIB6uG9D4bw==} + engines: {node: '>=18'} '@sentry/babel-plugin-component-annotate@5.1.1': resolution: {integrity: sha512-x2wEpBHwsTyTF2rWsLKJlzrRF1TTIGOfX+ngdE+Yd5DBkoS58HwQv824QOviPGQRla4/ypISqAXzjdDPL/zalg==} engines: {node: '>= 18'} - '@sentry/browser@10.37.0': - resolution: {integrity: sha512-kheqJNqGZP5TSBCPv4Vienv1sfZwXKHQDYR+xrdHHYdZqwWuZMJJW/cLO9XjYAe+B9NnJ4UwJOoY4fPvU+HQ1Q==} - engines: {node: '>=18'} + '@sentry/babel-plugin-component-annotate@5.2.1': + resolution: {integrity: sha512-QQ9AL5EXIbSK26ObLVtiU6l3tCUdpGSJ/6VwDkPhC3qvtoksSlcoU9Yzm7XC0NBcvu1N2abL5R7gckKGZ4JewQ==} + engines: {node: '>= 18'} '@sentry/browser@10.43.0': resolution: {integrity: sha512-2V3I3sXi3SMeiZpKixd9ztokSgK27cmvsD9J5oyOyjhGLTW/6QKCwHbKnluMgQMXq20nixQk5zN4wRjRUma3sg==} engines: {node: '>=18'} + '@sentry/browser@10.51.0': + resolution: {integrity: sha512-Zdc0sKfenxUtW/OGhtJ7xHFN44bXR7YqxJ1zBDzlZfW0nTbeTTUZBq9z5NUw6qdS0Vs/i3V4qzAKTbRKWfqSEA==} + engines: {node: '>=18'} + '@sentry/bundler-plugin-core@5.1.1': resolution: {integrity: sha512-F+itpwR9DyQR7gEkrXd2tigREPTvtF5lC8qu6e4anxXYRTui1+dVR0fXNwjpyAZMhIesLfXRN7WY7ggdj7hi0Q==} engines: {node: '>= 18'} @@ -7018,18 +7010,31 @@ packages: '@cloudflare/workers-types': optional: true - '@sentry/core@10.37.0': - resolution: {integrity: sha512-hkRz7S4gkKLgPf+p3XgVjVm7tAfvcEPZxeACCC6jmoeKhGkzN44nXwLiqqshJ25RMcSrhfFvJa/FlBg6zupz7g==} - engines: {node: '>=18'} - '@sentry/core@10.43.0': resolution: {integrity: sha512-l0SszQAPiQGWl/ferw8GP3ALyHXiGiRKJaOvNmhGO+PrTQyZTZ6OYyPnGijAFRg58dE1V3RCH/zw5d2xSUIiNg==} engines: {node: '>=18'} + '@sentry/core@10.51.0': + resolution: {integrity: sha512-Y45V/YXvVLEXmOdkbD1oG1gkRWFi9guCEGg3PlIlIpRjAbZUrvLGgjRJIc1E7XpSzmOnWbs5BbUxMv4PDaPj2w==} + engines: {node: '>=18'} + '@sentry/core@9.47.1': resolution: {integrity: sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==} engines: {node: '>=18'} + '@sentry/expo-upload-sourcemaps@8.10.0': + resolution: {integrity: sha512-9nca3zuzeohl77Hspkox0CcpCQz11gvplgJMktD0fVLrHKBLW9/KTtAOBSez7FfXe2e8FbF7cd5/Cb5EHyJjpw==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@expo/env': '*' + dotenv: '*' + peerDependenciesMeta: + '@expo/env': + optional: true + dotenv: + optional: true + '@sentry/nextjs@10.43.0': resolution: {integrity: sha512-SmybDiZdI4c7GQYvi+HNBKbnKOmIaiqsLj67vVVV0tN6A1iX9OrP5jldxawzrd9wn5oXDhHSyzJmyKwdOu7/MQ==} engines: {node: '>=18'} @@ -7077,8 +7082,8 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 '@opentelemetry/semantic-conventions': ^1.39.0 - '@sentry/react-native@7.11.0': - resolution: {integrity: sha512-OiDaLCAGpRN18YG/o7IIwLhU0Xpb0tYKQ5QxkGHiwb+L3VHn+MqGCGfITYNdhqr06HHMvu9Lysm+UJxaNmGaJg==} + '@sentry/react-native@8.10.0': + resolution: {integrity: sha512-Pfr7h1unqMsE87UMwaUIZ26VjX7SSsitBLpK4gHeIwYmuXn+qfdYUmme6RnoLlL5IPzu8pCLoRNCvdAJy6eTgw==} hasBin: true peerDependencies: expo: '>=49.0.0' @@ -7088,20 +7093,20 @@ packages: expo: optional: true - '@sentry/react@10.37.0': - resolution: {integrity: sha512-XLnXJOHgsCeVAVBbO+9AuGlZWnCxLQHLOmKxpIr8wjE3g7dHibtug6cv8JLx78O4dd7aoCqv2TTyyKY9FLJ2EQ==} + '@sentry/react@10.43.0': + resolution: {integrity: sha512-shvErEpJ41i0Q3lIZl0CDWYQ7m8yHLi7ECG0gFvN8zf8pEdl5grQIOoe3t/GIUzcpCcor16F148ATmKJJypc/Q==} engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x - '@sentry/react@10.43.0': - resolution: {integrity: sha512-shvErEpJ41i0Q3lIZl0CDWYQ7m8yHLi7ECG0gFvN8zf8pEdl5grQIOoe3t/GIUzcpCcor16F148ATmKJJypc/Q==} + '@sentry/react@10.51.0': + resolution: {integrity: sha512-RRHHqjNvjji6ebIqdlAr453AkST8Vm4cxdu1vWm772IgbzTO7Jx46Cj6Bt2/GjMyH0YLE5euDaAOQhFMmpvAOw==} engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x - '@sentry/types@10.37.0': - resolution: {integrity: sha512-umpnUKRC0AAbJrADg6SlFtqN2yzf7NHciCF9lkHau+ax2PIZ/NDmoG4RQujFVflVaVoD60Ly2t+CcPnYIWMPlw==} + '@sentry/types@10.51.0': + resolution: {integrity: sha512-/0nTcXk82RKtGGv0mxmY56o+BE85lBuSWG9chtSEfeypvxHFyWn3D7td9rPmjboDMtytC24cYbUzx55jb2OjQA==} engines: {node: '>=18'} '@sentry/vercel-edge@10.43.0': @@ -8209,6 +8214,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} @@ -8836,12 +8842,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 || ^8.0.0-0 - babel-preset-expo@55.0.16: - resolution: {integrity: sha512-WHeXG4QbYA809O5e6YcPhYVck/sxtTPF0InQjKiFfPnOkeb2Q/DHQcRQL0dFWOu4VeUUMyEiHeKtKA442Cg8+g==} + babel-preset-expo@55.0.21: + resolution: {integrity: sha512-anXoUZBcxydLdVs2L+r3bWKGUvZv2FtgOl8xRJ12i/YfKICBpwTGZWSTiEYTqBByZ6GkA3mE9+3TW97X2ocFTQ==} peerDependencies: '@babel/runtime': ^7.20.0 expo: '*' - expo-widgets: ^55.0.12 + expo-widgets: ^55.0.17 react-refresh: '>=0.14.0 <1.0.0' peerDependenciesMeta: '@babel/runtime': @@ -9826,8 +9832,8 @@ packages: resolution: {integrity: sha512-2l0gsPOLPs5t6GFZfQZKnL1OJNYFcuC/ETWsW4VtKVD/tg4ICa9x+jb9bkPffkMdRpRpuUaO/fKkHCBeiCKh8g==} engines: {node: '>=18'} - dnssd-advertise@1.1.3: - resolution: {integrity: sha512-XENsHi3MBzWOCAXif3yZvU1Ah0l+nhJj1sjWL6TnOAYKvGiFhbTx32xHN7+wLMLUOCj7Nr0evADWG4R8JtqCDA==} + dnssd-advertise@1.1.4: + resolution: {integrity: sha512-AmGyK9WpNf06WeP5TjHZq/wNzP76OuEeaiTlKr9E/EEelYLczywUKoqRz+DPRq/ErssjT4lU+/W7wzJW+7K/ZA==} doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} @@ -10318,26 +10324,26 @@ packages: resolution: {integrity: sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - expo-apple-authentication@55.0.12: - resolution: {integrity: sha512-agfdz+9UfK6KVTqfn4EilmI5KJJT/v5ZooKWCq1YGSx+W8RlrXQenhH09QPPQ2FfMLyQu1ytZqehY5hIwF2vzg==} + expo-apple-authentication@55.0.13: + resolution: {integrity: sha512-Qvh3DmhXqhtWOe7BC9e7UVApR3XS1qE7+68tVLqb3KI/sET7QV9KT5JgOJogWmmCJVxA/kaot0M136yvW1pdWA==} peerDependencies: expo: '*' react-native: '*' - expo-application@55.0.13: - resolution: {integrity: sha512-mIx0Cxn4hSEuadb/eu/FBvATZRjISb4yEpUrP4xHYgK/RYuS4Fu/dXbE43sh8TZVqAFro0QGonpoPHLgQiSAsQ==} + expo-application@55.0.14: + resolution: {integrity: sha512-NgqDIt3eCf4aVLp1L6AcEanCYoyJeuBsGrgGSzOIvxAsOvp5X3SYKW3ROgpKUnLQEKMWlzwETpjsUGszcqkk8g==} peerDependencies: expo: '*' - expo-asset@55.0.13: - resolution: {integrity: sha512-XDtshd8GZujYEmC84B3Gj+dCStvjcoywCyHrhO5K68J3CwkauIxyNeOLFlIX/U9FXtCuEykv14Lhz7xCcn1RWA==} + expo-asset@55.0.17: + resolution: {integrity: sha512-pK9HHJuFqjE8kDUcbMFsZj3Cz8WdXpvZHZmYl7ouFQp59P83BvHln6VnqPDGlO+/4929G0Lm8ZUzbONuNRhi9w==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-audio@55.0.12: - resolution: {integrity: sha512-S192nhgNtvamDf+GCweeIXs8J057uOSEa89y/9xz5OufYQGDAxCcyyffGBIueyHoP3t36hCUnvJjpMJksOEdKQ==} + expo-audio@55.0.14: + resolution: {integrity: sha512-Biy6ffKXrnKHgcWSVWLKVdWLNhV/pj1JWJeotY6nDR6fVe8mjXQDCvi6EbaSFPdffVHym6UB2siKzWUNSnG+kQ==} peerDependencies: expo: '*' expo-asset: '*' @@ -10351,20 +10357,20 @@ packages: react: '*' react-native: '*' - expo-build-properties@55.0.12: - resolution: {integrity: sha512-PUK0uPxFESZTegqFk+v3V9HWRhjIgvkImoHAgXU22xAyzfrdPnWKCwesyd88rdhGdSc/7lGFmIB7bOYKi2vjkQ==} + expo-build-properties@55.0.13: + resolution: {integrity: sha512-UYZhUKyh7YQhbJdkBvo68WUQ7fOtZeSV7F8kfYkjEiN/ADRHG0WfEIiddvGfi9cH/5iwpptv/+Lu5cx6uvfegA==} peerDependencies: expo: '*' - expo-clipboard@55.0.12: - resolution: {integrity: sha512-DaLjhidJvpkAovzrMUv9LN9OZhiBpwqBOTFeTStRSLiMSwX4QWS0wjqRE2A0v8YnIgjSPrZxLXHLmRJ6TEceow==} + expo-clipboard@55.0.13: + resolution: {integrity: sha512-PrOmmuVsGW4bAkNQmGKtxMXj3invsfN+jfIKmQxHwE/dn7ODqwFWviUTa+PMUjP3XZmYCDLyu/i0GLeu7HF9Ew==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-constants@55.0.12: - resolution: {integrity: sha512-e2oxzvPyBv0t51o/lNuiiBtYFQcv3rWnTUvIH0GXRjHkg8LHHePly1vJ5oGg5KO2v8qprleDp9g6s5YD0MIUtQ==} + expo-constants@55.0.16: + resolution: {integrity: sha512-Z15/No94UHoogD+pulxjudGAeOHTEIWZgb/vnX48Wx5D+apWTeCbnKxQZZtGQlosvduYL5kaic2/W8U+NHfBQQ==} peerDependencies: expo: '*' react-native: '*' @@ -10374,13 +10380,13 @@ packages: peerDependencies: expo: '*' - expo-dev-client@55.0.23: - resolution: {integrity: sha512-Gy5H2kwQkGU97LFqylc6zcUMUl8uP5EYsRcM6lqzp/Ag9w27QuwtibznxTyctEdzap5Z2+kEnrlYj/eRDn8MWQ==} + expo-dev-client@55.0.32: + resolution: {integrity: sha512-rfZ0Xpgbw3RPymkivvLSQ2Koqefj+oVOReqNLN3JXDlqdC2jOr3MCqfTaJs5VFNzFKk7pOPyE60jh03UdvsHCQ==} peerDependencies: expo: '*' - expo-dev-launcher@55.0.24: - resolution: {integrity: sha512-B3YyKF0Kw1LLuMew7QtjRPF3wj1fhPar/GSGDemBdRSnQn3oEpfLxRG+sX8lCqHq94ihztwgUc1HWShyfZ8/Sg==} + expo-dev-launcher@55.0.33: + resolution: {integrity: sha512-WZsTtyEVgCBMj3vlgbDSKbYbUbAwijNhJY9jBqqlmbPLHtLE+Wc6nCTafb0dWY6+Si+afF98lvPyz6WSAu59uA==} peerDependencies: expo: '*' @@ -10389,41 +10395,41 @@ packages: peerDependencies: expo: '*' - expo-dev-menu@55.0.20: - resolution: {integrity: sha512-CW1ff2i0zCZrnGnZZ6CPGwrafwryPWHZYy7NsKRIHpEJgymruh5Lsyf50Wq936FJ+VH073dmpzpw5ocY7pEdyA==} + expo-dev-menu@55.0.27: + resolution: {integrity: sha512-Il+kkIXlPDfZ/Z3ZquV1r5niECEByJObUMkB24c0B4N4693f0SDoKyyaRqcGRsRCVXW9r0eAoTeEnXl1revQdA==} peerDependencies: expo: '*' - expo-document-picker@55.0.12: - resolution: {integrity: sha512-AyekhUmKD2VjD2y5sOyQh4TBlCaYb5XKzxpXuYpIZzTIQuKb/TdecqxpjwdDH/rtdZvjEWG9ZWRCxDFkLIP1wA==} + expo-document-picker@55.0.13: + resolution: {integrity: sha512-IhswJElhdzs3fKDEKW8KXYRoFkWGEsXRMYAZT46Yo56zqqy8yQXrczo33RSwD2hFzNQBdLT97SJL9N311UyS3g==} peerDependencies: expo: '*' expo-eas-client@55.0.5: resolution: {integrity: sha512-wRagCeSbSnSGVXgP7V+qiGfXzZ9hTVKWvKIOP7lwrX3MIEenNmNlO4D3RVC3aNU2GhmO3ZCZIIEre80KZoUUHA==} - expo-file-system@55.0.15: - resolution: {integrity: sha512-GEo0CzfmRfR7nOjp5p4Tb9XWtgPxDIYRiQws79DpBQsX15UsCdDw7/se3aFO6NyZuGFx/85KsdD7SPGphbE/jw==} + expo-file-system@55.0.19: + resolution: {integrity: sha512-c4smCbMqELLI3YQrGpw21MwZIREXM2e53vQD/+KWQcae1q+hgw8J2TroEqcQ/jVOtFpZYVvyVfgu4HDKNEKmNw==} peerDependencies: expo: '*' react-native: '*' - expo-font@55.0.6: - resolution: {integrity: sha512-x9czUA3UQWjIwa0ZUEs/eWJNqB4mAue/m4ltESlNPLZhHL0nWWqIfsyHmklTLFH7mVfcHSJvew6k+pR2FE1zVw==} + expo-font@55.0.7: + resolution: {integrity: sha512-oH39Xb+3i6Y69b7YRP+P+5WLx7621t+ep/RAgLwJJYpTjs7CnSohUG+873rEtqsTAuQGi63ms7x9ZeHj1E9LYw==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-glass-effect@55.0.10: - resolution: {integrity: sha512-5kL/jATvgJWdrqPdxixrECJqD2l8cfQ4ALr1DK7qi9XkyI97ejXvUjB2VsfEePNy3Fg+/VwzA3n3L7Nv3tAPkw==} + expo-glass-effect@55.0.11: + resolution: {integrity: sha512-wqq7GUOqSkfoFJzreZvBG0jzjsq5c582m3glhWSjcmIuByxXXWp6j6GY6hyFuYKzpOXhbuvusVxGCQi0yWnp3g==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-haptics@55.0.13: - resolution: {integrity: sha512-mfchTuKX6aiR3CEn1NyUviSnp9NwunuBlx2p5XIQymvCBwDxUddJlrStz5gMPUb6phUS+1YSH5O2S+IyFgqFjA==} + expo-haptics@55.0.14: + resolution: {integrity: sha512-KjDItBsA9mi1f5nRwf8g1wOdfEcLHwvEdt5Jl1sMCDETR/homcGOl+F3QIiPOl/PRlbGVieQsjTtF4DGtHOj6g==} peerDependencies: expo: '*' @@ -10439,13 +10445,13 @@ packages: peerDependencies: expo: '*' - expo-image-picker@55.0.17: - resolution: {integrity: sha512-oCayiw6ZMKDnUGVPFhQ1j0Cg0ZvzSDWwuVm0QSX+AkdqBuRv/n3SB3ZTVW2M+lR6zU/aTtVTduqlNnVyv4CrhA==} + expo-image-picker@55.0.20: + resolution: {integrity: sha512-lfWt/0rPWdKz8AdDEGmGHZIJSNlVc720Dlx5bfou10FU16ZV5wAbTU63nm2jkXd8hbXke4a/2Ha1dzxCVA+LQQ==} peerDependencies: expo: '*' - expo-image@55.0.8: - resolution: {integrity: sha512-fNdvdYVcGn3g1x6o5AXHKzk4xX8U6rg2W9vFdE1pQO80kWCNReh003ypqSrGy4dD+zA8FtZjrNF3oMDGnPpIGQ==} + expo-image@55.0.10: + resolution: {integrity: sha512-We+vq/Z8jy8zmGxcOP8vrhiWkkwyXFdSks8cSlPi0bpu6D0Ei6l9Nj2xHWCD+yoENh92aCEe1+QRujAwXbogGA==} peerDependencies: expo: '*' react: '*' @@ -10455,62 +10461,66 @@ packages: react-native-web: optional: true - expo-insights@55.0.15: - resolution: {integrity: sha512-K2sp1rE6ZKfbd2ZfVW7zj5FCkH4sylwyZoC28I0OV/d+WOtJWyulmec+GRZP/zIhEee+Wgnqp1yNU4mYIqw4XQ==} + expo-insights@55.0.16: + resolution: {integrity: sha512-3BPe3lcufconTBywT0Zil83ZOsEXX47AqeaPPLr2gridYtiKOSqDtLDd9EKEK1D+p9u4LL3QFAz8J9crdQyc4Q==} peerDependencies: expo: '*' expo-json-utils@55.0.2: resolution: {integrity: sha512-QJMOZOPOG7CTnKcrdVaiummn2va1MCO56z++eyWkDv3GBRODldM6MFMDf/jTREWthFc2Nxo6TuyWRrEV9S6n/Q==} - expo-keep-awake@55.0.6: - resolution: {integrity: sha512-acJjeHqkNxMVckEcJhGQeIksqqsarscSHJtT559bNgyiM4r14dViQ66su7bb6qDVeBt0K7z3glXI1dHVck1Zgg==} + expo-keep-awake@55.0.8: + resolution: {integrity: sha512-PfIpMfM+STOBwkR5XOE+yVtER86c44MD+W8QD8JxuO0sT9pF7Y1SJYakWlpvX8xsGA+bjKLxftm9403s9kQhKA==} peerDependencies: expo: '*' react: '*' - expo-linking@55.0.11: - resolution: {integrity: sha512-qVKOeaFZvaJl99mB1gle0AWaC+36t4SxIIf23rkqyjEs/ZJtt7Zr2NKcQpzNhxUyWms8CSKTAlMO1k9Hx9z9zw==} + expo-linking@55.0.15: + resolution: {integrity: sha512-/RQh2vkNqV8Bim9Owm/evVqn2fqTvCDYHkpYPoSKbLAdydSGdHC2xZNw7Odl4wu1i1/3L4Xz//LKd3NsPWYWBQ==} peerDependencies: react: '*' react-native: '*' - expo-location@55.1.8: - resolution: {integrity: sha512-mEExFf84nmWLwi14GFfUsFLrCm10gbcqFn9EPXpuruQ28YMtJWgCD+jJtESYPQkYF44N21fVok3T28fLuCqydA==} + expo-location@55.1.9: + resolution: {integrity: sha512-PIH9/qeyhtGh190FyIJNZYHXZOoi42SbVHY9IoTMBmqWLHf1BJyGhPpFlaLBSCjxObqfVZmrWsN5dtjueSwYQA==} peerDependencies: expo: '*' - expo-manifests@55.0.14: - resolution: {integrity: sha512-l2+fYFkZBR/hbd//LfKz5qBaUAQfC1kWdnqNr3HCa7vGNYcGKA4aMSTXZAJ0SEo1lkO26yz5cEFMGjYPbAAg0g==} + expo-manifests@55.0.16: + resolution: {integrity: sha512-BR9BPcNsSnCKlQ/d7ECywr+2T54+bTSr26HjRjSua949o4mO/iPIrLjK0lOAa1oIczju6a6oUFckZD2OljxP0g==} peerDependencies: expo: '*' - expo-modules-autolinking@55.0.15: - resolution: {integrity: sha512-89WNHlSo+hmH8O7sEHDgOpb3MyHON/NmDIl+LiEGMiHHHSrSbU10DSglYWKUk68yjQebxkmfzXcEghbous3LcA==} + expo-modules-autolinking@55.0.21: + resolution: {integrity: sha512-P9KsJgOwI7JVwxmGfRvcXkXO4LNRvHRdWmb4ukLmX15G/vZ7b6SM17yiYkPceWq1F5KeeZ11KFjEcl0y17xy7w==} hasBin: true - expo-modules-core@55.0.21: - resolution: {integrity: sha512-JGMREOmVHeHR3FdHqYWFtwJt2o6w9cXOCZ7al3x4cCcM9ihMpleze44SDYh3yfPo+BgWT3HCbpTunIsfNMMyPA==} + expo-modules-core@55.0.25: + resolution: {integrity: sha512-yXpfg7aHLbuqoXocK34Vua6Aey5SCyqLygAsXAMbul9P8vfBjLpaOPiTJ5cLVF7Drfq8ownqVJO6qpGEtZ6GOw==} peerDependencies: react: '*' react-native: '*' + react-native-worklets: ^0.7.4 || ^0.8.0 + peerDependenciesMeta: + react-native-worklets: + optional: true - expo-notifications@55.0.17: - resolution: {integrity: sha512-Z2tRL9HcwpN8rS3cIPZyT/S7EWvVEVUeWf595LU0gksLu63VVCyrGynosUAo8Z8e0ePLXMhwVoIwYSvS3Tr5dw==} + expo-notifications@55.0.22: + resolution: {integrity: sha512-Rwvsp/lAEXfDYBxkQZpaLF9ZB25cJ/yfHhD/ESclbPesN0nbQBZ/5rGb1xS/saANtkStbEGfDlA80uHh2zEpsA==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-router@55.0.11: - resolution: {integrity: sha512-LmOLTPPYW9IS9pNqw5RbH2QH+rIxvQ69FHBbtchFIrjrAl9V/cs0cNS1Vn7X6SdyjIvxUOErhg1iUcl1Fdcsmw==} + expo-router@55.0.14: + resolution: {integrity: sha512-rOn/wosp2hAPM+O2o41hnarbP5Zqv9UkHWa31KoSoiOme1tpmZd2yc93XtRAtzP0P5E5xzqq7a2rbEAarpP5XA==} peerDependencies: - '@expo/log-box': 55.0.10 + '@expo/log-box': 55.0.12 '@react-navigation/drawer': ^7.9.4 '@testing-library/react-native': '>= 13.2.0' expo: '*' - expo-constants: ^55.0.12 - expo-linking: ^55.0.11 + expo-constants: ^55.0.16 + expo-linking: ^55.0.15 react: '*' react-dom: '*' react-native: '*' @@ -10536,8 +10546,8 @@ packages: react-server-dom-webpack: optional: true - expo-secure-store@55.0.12: - resolution: {integrity: sha512-8xL9/x94wqHGeeSIpQ90cnunoTH2uW4Qj1NOIx1sY/rhmOKd2TFLmhHJlDYUe7/1aABGX4b18gJ1SD3/HdlOlw==} + expo-secure-store@55.0.13: + resolution: {integrity: sha512-I6r0JNO1Fd4o0Gu7Ixiic7s89lqgdUHq17uBH9y1f/AntoyKn71TdtYJH82RgfsBbu5qNVzrwImmvlANyOlITQ==} peerDependencies: expo: '*' @@ -10545,62 +10555,62 @@ packages: resolution: {integrity: sha512-ISuax1AQ7cpM5RAqcu8gVcoLL0ZKskJ5OLoMWmdITBe9nYjTucjdGyBq817YkIvTcj1pAUwx+9toUT7l/V7thA==} engines: {node: '>=20'} - expo-server@55.0.7: - resolution: {integrity: sha512-Cc1btFyPsD9P4DT2xd1pG/uR96TLVMx0W+dPm9Gjk1uDV9xuzvMcUsY7nf9bt4U5pGyWWkCXmPJcKwWfdl51Pw==} + expo-server@55.0.9: + resolution: {integrity: sha512-N5Ipn1NwqaJzEm+G97o0Jbe4g/th3R/16N1DabnYryXKCiZwDkK13/w3VfGkQN9LOOaBP+JIRxGf4M8lQKPzyA==} engines: {node: '>=20.16.0'} - expo-sharing@55.0.17: - resolution: {integrity: sha512-m9dAPCTn3FfIhnfJNhR640aUbixX57SYUREvMmrFfLezvW4svUXSU0LSOQqQuGS+OgZmX7ZoqNLJPDaQFy9Rag==} + expo-sharing@55.0.18: + resolution: {integrity: sha512-Tqy4LXRLw/UEg5mT7BKhx8y4ReNz8fVldvhHJV5cesH3kRgEerHkYxVwid2vd7v34KnNp0RH1OqUyDlzZTQ9AQ==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-splash-screen@55.0.16: - resolution: {integrity: sha512-k0GuXde9QNB7AVwwpJ/BVnSOliLDJy9qC0k7QlOSdbLH4HR1YhX1kWVhL6Yq68vZ7qpHl5WQZv1DDk3SxOaExg==} + expo-splash-screen@55.0.20: + resolution: {integrity: sha512-WI5T0dutiZhxsqlF+jhEP4JRpQNILLlP8IpmKehsnV53Cncv6AQrKE7y1sOWwDyC2m2GBufZ/Vwam1RMt2EfmA==} peerDependencies: expo: '*' - expo-status-bar@55.0.5: - resolution: {integrity: sha512-qb0c3rJO2b7CC0gUVGi1JYp92oLenWdYGyk8l4YQs6U+uaXUTPv6aaFa3KkT2HON10re3AxxPNJci8rsz6kPxg==} + expo-status-bar@55.0.6: + resolution: {integrity: sha512-ijOUptfdiqYt7rObZ6jrPQ8sE5YN/8MxKCIJx0b7TY4nGkSJxhPIxeoW4GXcXCA8mTQ9PiOHH/ThLZgRVZvUlQ==} peerDependencies: react: '*' react-native: '*' - expo-symbols@55.0.7: - resolution: {integrity: sha512-y4ALLbncSGQzhFLw1PaIBbO39xzaw3ie249HmK6zK/WLJYfw4Z/9UU4iPKO3KCE4FyCKIzd+yRsvzvlri23YrQ==} + expo-symbols@55.0.8: + resolution: {integrity: sha512-Dg6BTu+fCWukdlh+3XYIr6NbqJWmK4aAQ6i6BInKnWU0ALuzVUJcMDq8Lk9bHok2hOh3OhzJqlCqEoBXPInIVQ==} peerDependencies: expo: '*' expo-font: '*' react: '*' react-native: '*' - expo-tracking-transparency@55.0.12: - resolution: {integrity: sha512-lr12u4/jo8ZiP68OxAlfKv+39FopJA0xzlobFMgrp85tlKHRm58N4Y7mNacfK4a7QERsVNzT5DIWa4UWuykBDQ==} + expo-tracking-transparency@55.0.13: + resolution: {integrity: sha512-GfkKjmIufOQn1TzvUOP3s21V4roZWBlUwI0U+JC/7JVAdVMScEq3QonYdrjE9CPDarqon/g6726uftbqSLpzBA==} peerDependencies: expo: '*' react-native: '*' - expo-updates-interface@55.1.5: - resolution: {integrity: sha512-YOk9vhplWi0djoeqxMlEQgcDFeOGhnj4dWU0v1QvF5RqpqwLGdx780E0k3zL85xw6LXljVN78d6g8z51qIZu5g==} + expo-updates-interface@55.1.6: + resolution: {integrity: sha512-evxNpagCkjT3lE6bGV570TFzRtKuIuLY8I37RYHoriXCJ+ZKCN1hbmklK29uAixya+BxGpeTI2K4FqYeJLvfrw==} peerDependencies: expo: '*' - expo-video@55.0.14: - resolution: {integrity: sha512-/dBtnL7z3E6zykMTJnmOPZjyiubK6OzcFaTKPP3yP5KJE2Xf5F6N6kH7e0PvmesUJXJxoB6FNs/N1ZoCgvaqSg==} + expo-video@55.0.16: + resolution: {integrity: sha512-sarOgIIe+3QwDrQkLyE6KghLLJTijuBuRvBhP2RdQex3ntFHqz/ie2Gv149PHewdPdDM4I5Lycnes9Ky3SW8qg==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-web-browser@55.0.13: - resolution: {integrity: sha512-phzsFucUw0uHm0f2f4tJ7ZO3vYnGm0Y7izyWDD71TjP8pyMsvNOh5RKJGLUqk1diSrAFUbHKZYdt6D2b30deiw==} + expo-web-browser@55.0.15: + resolution: {integrity: sha512-6hwZQob3EF+RWwZ+IvWLZjj2wI1frqx21+m/uzBqdUEHUhp2cVJi7kmxDolDmrve+ZldryZi1qfN78ALdvjHSA==} peerDependencies: expo: '*' react-native: '*' - expo@55.0.12: - resolution: {integrity: sha512-O3lp+HOydF4LUSbi9gF1c+ly4FkLB9FSyJZ1Zatt12oClraB2FUe/W8J4tq5ERqKLeRzsrVVt319hMTQgwNEUQ==} + expo@55.0.23: + resolution: {integrity: sha512-b+lKwfzJzFiSm9G0wVGWw3c2YoZyubbl9gHOF1ZFuK8FqtxSge8pDDJMuEFmTi14dbKwh/tirB7MiORq54r7CQ==} hasBin: true peerDependencies: '@expo/dom-webview': '*' @@ -10697,8 +10707,8 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} - fetch-nodeshim@0.4.9: - resolution: {integrity: sha512-XIQWlB2A4RZ7NebXWGxS0uDMdvRHkiUDTghBVJKFg9yEOd45w/PP8cZANuPf2H08W6Cor3+2n7Q6TTZgAS3Fkw==} + fetch-nodeshim@0.4.10: + resolution: {integrity: sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w==} fetch-to-node@2.1.0: resolution: {integrity: sha512-Wq05j6LE1GrWpT2t1YbCkyFY6xKRJq3hx/oRJdWEJpZlik3g25MmdJS6RFm49iiMJw6zpZuBOrgihOgy2jGyAA==} @@ -11064,8 +11074,8 @@ packages: hermes-estree@0.32.1: resolution: {integrity: sha512-ne5hkuDxheNBAikDjqvCZCwihnz0vVu9YsBzAEO1puiyFR4F1+PAz/SiPHSsNTuOveCYGRMX8Xbx4LOubeC0Qg==} - hermes-estree@0.33.3: - resolution: {integrity: sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==} + hermes-estree@0.35.0: + resolution: {integrity: sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==} hermes-parser@0.32.0: resolution: {integrity: sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==} @@ -11073,8 +11083,8 @@ packages: hermes-parser@0.32.1: resolution: {integrity: sha512-175dz634X/W5AiwrpLdoMl/MOb17poLHyIqgyExlE8D9zQ1OPnoORnGMB5ltRKnpvQzBjMYvT2rN/sHeIfZW5Q==} - hermes-parser@0.33.3: - resolution: {integrity: sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==} + hermes-parser@0.35.0: + resolution: {integrity: sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==} hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} @@ -11910,8 +11920,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - lan-network@0.2.0: - resolution: {integrity: sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw==} + lan-network@0.2.1: + resolution: {integrity: sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==} hasBin: true lazystream@1.0.1: @@ -12281,61 +12291,61 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - metro-babel-transformer@0.83.5: - resolution: {integrity: sha512-d9FfmgUEVejTiSb7bkQeLRGl6aeno2UpuPm3bo3rCYwxewj03ymvOn8s8vnS4fBqAPQ+cE9iQM40wh7nGXR+eA==} + metro-babel-transformer@0.83.7: + resolution: {integrity: sha512-sBqBkt6kNut/88bv+Ucvm4yqdPetbvAEsHzi3MAgJEifOSYYzX5Z5Kgw3TFOrwf/mHJTOBG2ONlaMHoyfP15TA==} engines: {node: '>=20.19.4'} - metro-cache-key@0.83.5: - resolution: {integrity: sha512-Ycl8PBajB7bhbAI7Rt0xEyiF8oJ0RWX8EKkolV1KfCUlC++V/GStMSGpPLwnnBZXZWkCC5edBPzv1Hz1Yi0Euw==} + metro-cache-key@0.83.7: + resolution: {integrity: sha512-W1c2Nmx8MiJTJt+eWhMO08z9VKi3kZOaz99IYGdqeqDgY9j+yZjXl62rUav4Di0heZfh4/n2s722PqRL1OODeg==} engines: {node: '>=20.19.4'} - metro-cache@0.83.5: - resolution: {integrity: sha512-oH+s4U+IfZyg8J42bne2Skc90rcuESIYf86dYittcdWQtPfcaFXWpByPyTuWk3rR1Zz3Eh5HOrcVImfEhhJLng==} + metro-cache@0.83.7: + resolution: {integrity: sha512-E9SRePXQ1Zvlj79VcOk57q7VC7rMHMFQ+jhmPHBiq+dJ0bJB5BL87lWZF6oh5X76Cci5tpDuQNaDwwuSCToEeg==} engines: {node: '>=20.19.4'} - metro-config@0.83.5: - resolution: {integrity: sha512-JQ/PAASXH7yczgV6OCUSRhZYME+NU8NYjI2RcaG5ga4QfQ3T/XdiLzpSb3awWZYlDCcQb36l4Vl7i0Zw7/Tf9w==} + metro-config@0.83.7: + resolution: {integrity: sha512-83mjWFbFOt2GeJ6pFIum5mSnc1uTsZJAtD8o4ej0s4NVsYsA7fB+pHvTfHhFrpeMONaobu2riKavkPei05Er/Q==} engines: {node: '>=20.19.4'} - metro-core@0.83.5: - resolution: {integrity: sha512-YcVcLCrf0ed4mdLa82Qob0VxYqfhmlRxUS8+TO4gosZo/gLwSvtdeOjc/Vt0pe/lvMNrBap9LlmvZM8FIsMgJQ==} + metro-core@0.83.7: + resolution: {integrity: sha512-6yn3w1wnltT6RQl7p7YES2l95ArC+mWrOssEiH8p5/DDrJS65/szf9LsC9JrBv8c5DdvSY3V3f0GRYg0Ox7hCg==} engines: {node: '>=20.19.4'} - metro-file-map@0.83.5: - resolution: {integrity: sha512-ZEt8s3a1cnYbn40nyCD+CsZdYSlwtFh2kFym4lo+uvfM+UMMH+r/BsrC6rbNClSrt+B7rU9T+Te/sh/NL8ZZKQ==} + metro-file-map@0.83.7: + resolution: {integrity: sha512-+j0F1m+FQYVAQ6syf+mwhIPV5GoFQrkInX8bppuc50IzNsZbMrp8R5H/Sx/K2daQ3YEa9F/XwkeZT8gzJfgeCw==} engines: {node: '>=20.19.4'} - metro-minify-terser@0.83.5: - resolution: {integrity: sha512-Toe4Md1wS1PBqbvB0cFxBzKEVyyuYTUb0sgifAZh/mSvLH84qA1NAWik9sISWatzvfWf3rOGoUoO5E3f193a3Q==} + metro-minify-terser@0.83.7: + resolution: {integrity: sha512-MfJar2IS4tBRuLb9svwb0Gu5l9BsH+pcRm8eGcEi/wy8MzZinfinh5dFLt2nWkocnulIgtGB5NkFDdbXqMXKhQ==} engines: {node: '>=20.19.4'} - metro-resolver@0.83.5: - resolution: {integrity: sha512-7p3GtzVUpbAweJeCcUJihJeOQl1bDuimO5ueo1K0BUpUtR41q5EilbQ3klt16UTPPMpA+tISWBtsrqU556mY1A==} + metro-resolver@0.83.7: + resolution: {integrity: sha512-WSJIENlMcoSsuz66IfBHOkgfp3KJt2UW2TnEHPf1b8pIG2eEXNOVmo2+03A0H17WY2XGXWgxL0CG7FAopqgB1A==} engines: {node: '>=20.19.4'} - metro-runtime@0.83.5: - resolution: {integrity: sha512-f+b3ue9AWTVlZe2Xrki6TAoFtKIqw30jwfk7GQ1rDUBQaE0ZQ+NkiMEtb9uwH7uAjJ87U7Tdx1Jg1OJqUfEVlA==} + metro-runtime@0.83.7: + resolution: {integrity: sha512-9GKkJURaB2iyYoEExKnedzAHzxmKtSi+k0tsZUvMoU27tBZJElchYt7JH/Ai/XzYAI9lCAaV7u5HZSI8J5Z+wQ==} engines: {node: '>=20.19.4'} - metro-source-map@0.83.5: - resolution: {integrity: sha512-VT9bb2KO2/4tWY9Z2yeZqTUao7CicKAOps9LUg2aQzsz+04QyuXL3qgf1cLUVRjA/D6G5u1RJAlN1w9VNHtODQ==} + metro-source-map@0.83.7: + resolution: {integrity: sha512-JgA1h7oc1a1jydBe1GhVFsUoMYo3wLPk7oRA32rjlDsq+sP2JLt9x2p2lWbNSxTm/u8NV4VRid3hvEJgcX8tKw==} engines: {node: '>=20.19.4'} - metro-symbolicate@0.83.5: - resolution: {integrity: sha512-EMIkrjNRz/hF+p0RDdxoE60+dkaTLPN3vaaGkFmX5lvFdO6HPfHA/Ywznzkev+za0VhPQ5KSdz49/MALBRteHA==} + metro-symbolicate@0.83.7: + resolution: {integrity: sha512-g4suyxw20WOHWI680c+Kq4wC/NF+Hx5pRH9afrMp+sMTxqLeKcPR1Xf4wMhsjlbvx7LbIREdke6q928jEjvJWw==} engines: {node: '>=20.19.4'} hasBin: true - metro-transform-plugins@0.83.5: - resolution: {integrity: sha512-KxYKzZL+lt3Os5H2nx7YkbkWVduLZL5kPrE/Yq+Prm/DE1VLhpfnO6HtPs8vimYFKOa58ncl60GpoX0h7Wm0Vw==} + metro-transform-plugins@0.83.7: + resolution: {integrity: sha512-Ss0FpBiZDjX2kwhukMDl5sNdYK8T/06IPqxNE4H6PTlRlfs9q11cef13c/xESY/Pm4VCkp1yJUZO3kXzvMxQFA==} engines: {node: '>=20.19.4'} - metro-transform-worker@0.83.5: - resolution: {integrity: sha512-8N4pjkNXc6ytlP9oAM6MwqkvUepNSW39LKYl9NjUMpRDazBQ7oBpQDc8Sz4aI8jnH6AGhF7s1m/ayxkN1t04yA==} + metro-transform-worker@0.83.7: + resolution: {integrity: sha512-UegCo7ygB2fT64mRK2nbAjQVJ1zSwIIHy8d96jJv2nKZFDaViYBiughEdu5HM/Ceq0WN3LZrZk3zhl9aoiLYFw==} engines: {node: '>=20.19.4'} - metro@0.83.5: - resolution: {integrity: sha512-BgsXevY1MBac/3ZYv/RfNFf/4iuW9X7f4H8ZNkiH+r667HD9sVujxcmu4jvEzGCAm4/WyKdZCuyhAcyhTHOucQ==} + metro@0.83.7: + resolution: {integrity: sha512-SPaPEyvTsTmd0LpT7RaZciQyDw2i/JB7+iY9L5VfBo72+psescFxBqpI1TL9dnL+pmnfkU+l/J1mEEGLeF65EQ==} engines: {node: '>=20.19.4'} hasBin: true @@ -12609,8 +12619,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multitars@0.2.4: - resolution: {integrity: sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg==} + multitars@1.0.0: + resolution: {integrity: sha512-H/J4fMLedtudftaYMOg7ajzLYgT3/rwbWVJbqr/iUgB8DQztn38ys5HOqI1CzSxx8QhXXwOOnnBvd4v3jG5+Mg==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -12779,8 +12789,8 @@ packages: oauth@0.9.15: resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} - ob1@0.83.5: - resolution: {integrity: sha512-vNKPYC8L5ycVANANpF/S+WZHpfnRWKx/F3AYP4QMn6ZJTh+l2HOrId0clNkEmua58NB9vmI9Qh7YOoV/4folYg==} + ob1@0.83.7: + resolution: {integrity: sha512-9M5kpuOLyTPogMtZiQUIxdAZxl7Dxs6tVBbJErSumsqGMuhVSoUbkfeZ3XNPpLpwBBtqY5QDUzGwggLHX3slQg==} engines: {node: '>=20.19.4'} object-assign@4.1.1: @@ -13542,15 +13552,15 @@ packages: react: '*' react-native: '*' - react-native-worklets@0.7.2: - resolution: {integrity: sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog==} + react-native-worklets@0.7.4: + resolution: {integrity: sha512-NYOdM1MwBb3n+AtMqy1tFy3Mn8DliQtd8sbzAVRf9Gc+uvQ0zRfxN7dS8ZzoyX7t6cyQL5THuGhlnX+iFlQTag==} peerDependencies: '@babel/core': '*' react: '*' react-native: '*' - react-native@0.83.4: - resolution: {integrity: sha512-H5Wco3UJyY6zZsjoBayY8RM9uiAEQ3FeG4G2NAt+lr9DO43QeqPlVe9xxxYEukMkEmeIhNjR70F6bhXuWArOMQ==} + react-native@0.83.6: + resolution: {integrity: sha512-H513+8VzviNFXOdPnStRzX9S3/jiJGg++QZ1zd+ROyAvBEKqFqKUPHH0d82y3QyRPct5qKjdOa7J6vNehCvXYA==} engines: {node: '>= 20.19.4'} hasBin: true peerDependencies: @@ -17676,29 +17686,29 @@ snapshots: '@expo-google-fonts/material-symbols@0.4.27': {} - '@expo/cli@55.0.22(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + '@expo/cli@55.0.29(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-constants@55.0.16)(expo-font@55.0.7)(expo-router@55.0.14)(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@expo/code-signing-certificates': 0.0.6 - '@expo/config': 55.0.13(typescript@5.9.3) + '@expo/config': 55.0.16(typescript@5.9.3) '@expo/config-plugins': 55.0.8 '@expo/devcert': 1.2.1 - '@expo/env': 2.1.1 - '@expo/image-utils': 0.8.12 - '@expo/json-file': 10.0.13 - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) - '@expo/osascript': 2.4.2 - '@expo/package-manager': 1.10.4 - '@expo/plist': 0.5.2 - '@expo/prebuild-config': 55.0.13(expo@55.0.12)(typescript@5.9.3) - '@expo/require-utils': 55.0.3(typescript@5.9.3) - '@expo/router-server': 55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) - '@expo/schema-utils': 55.0.3 + '@expo/env': 2.1.2 + '@expo/image-utils': 0.8.14(typescript@5.9.3) + '@expo/json-file': 10.0.14 + '@expo/log-box': 55.0.12(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro': 55.1.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/osascript': 2.4.3 + '@expo/package-manager': 1.10.5 + '@expo/plist': 0.5.3 + '@expo/prebuild-config': 55.0.17(expo@55.0.23)(typescript@5.9.3) + '@expo/require-utils': 55.0.5(typescript@5.9.3) + '@expo/router-server': 55.0.16(@expo/metro-runtime@55.0.11)(expo-constants@55.0.16)(expo-font@55.0.7)(expo-router@55.0.14)(expo-server@55.0.9)(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) + '@expo/schema-utils': 55.0.4 '@expo/spawn-async': 1.7.2 '@expo/ws-tunnel': 1.0.6 '@expo/xcpretty': 4.4.1 - '@react-native/dev-middleware': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/dev-middleware': 0.83.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) accepts: 1.3.8 arg: 5.0.2 better-opn: 3.0.2 @@ -17709,14 +17719,14 @@ snapshots: compression: 1.8.1 connect: 3.7.0 debug: 4.4.3 - dnssd-advertise: 1.1.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-server: 55.0.7 - fetch-nodeshim: 0.4.9 + dnssd-advertise: 1.1.4 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-server: 55.0.9 + fetch-nodeshim: 0.4.10 getenv: 2.0.0 glob: 13.0.6 - lan-network: 0.2.0 - multitars: 0.2.4 + lan-network: 0.2.1 + multitars: 1.0.0 node-forge: 1.3.3 npm-package-arg: 11.0.3 ora: 3.4.0 @@ -17737,8 +17747,8 @@ snapshots: ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 3.25.76 optionalDependencies: - expo-router: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo-router: 55.0.14(3108cc3b583b2b3cde65eb2e75099aa2) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@expo/metro-runtime' - bufferutil @@ -17759,7 +17769,7 @@ snapshots: dependencies: '@expo/config-types': 55.0.5 '@expo/json-file': 10.0.13 - '@expo/plist': 0.5.2 + '@expo/plist': 0.5.3 '@expo/sdk-runtime-versions': 1.0.0 chalk: 4.1.2 debug: 4.4.3 @@ -17775,16 +17785,15 @@ snapshots: '@expo/config-types@55.0.5': {} - '@expo/config@55.0.13(typescript@5.9.3)': + '@expo/config@55.0.16(typescript@5.9.3)': dependencies: '@expo/config-plugins': 55.0.8 '@expo/config-types': 55.0.5 - '@expo/json-file': 10.0.13 - '@expo/require-utils': 55.0.3(typescript@5.9.3) + '@expo/json-file': 10.0.14 + '@expo/require-utils': 55.0.5(typescript@5.9.3) deepmerge: 4.3.1 getenv: 2.0.0 glob: 13.0.6 - resolve-from: 5.0.0 resolve-workspace-root: 2.0.1 semver: 7.7.4 slugify: 1.6.8 @@ -17799,20 +17808,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/devtools@55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@expo/devtools@55.0.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: chalk: 4.1.2 optionalDependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - '@expo/dom-webview@55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@expo/dom-webview@55.0.6(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - '@expo/env@2.1.1': + '@expo/env@2.1.2': dependencies: chalk: 4.1.2 debug: 4.4.3 @@ -17820,9 +17829,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/fingerprint@0.16.6': + '@expo/fingerprint@0.16.7': dependencies: - '@expo/env': 2.1.1 + '@expo/env': 2.1.2 '@expo/spawn-async': 1.7.2 arg: 5.0.2 chalk: 4.1.2 @@ -17836,19 +17845,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/image-utils@0.8.12': + '@expo/image-utils@0.8.14(typescript@5.9.3)': dependencies: - '@expo/spawn-async': 1.7.2 - chalk: 4.1.2 - getenv: 2.0.0 - jimp-compact: 0.16.1 - parse-png: 2.1.0 - resolve-from: 5.0.0 - semver: 7.7.4 - - '@expo/image-utils@0.8.13(typescript@5.9.3)': - dependencies: - '@expo/require-utils': 55.0.4(typescript@5.9.3) + '@expo/require-utils': 55.0.5(typescript@5.9.3) '@expo/spawn-async': 1.7.2 chalk: 4.1.2 getenv: 2.0.0 @@ -17864,32 +17863,37 @@ snapshots: '@babel/code-frame': 7.29.0 json5: 2.2.3 - '@expo/local-build-cache-provider@55.0.9(typescript@5.9.3)': + '@expo/json-file@10.0.14': + dependencies: + '@babel/code-frame': 7.29.0 + json5: 2.2.3 + + '@expo/local-build-cache-provider@55.0.12(typescript@5.9.3)': dependencies: - '@expo/config': 55.0.13(typescript@5.9.3) + '@expo/config': 55.0.16(typescript@5.9.3) chalk: 4.1.2 transitivePeerDependencies: - supports-color - typescript - '@expo/log-box@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@expo/log-box@55.0.12(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/dom-webview': 55.0.6(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) anser: 1.4.10 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 - '@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6)': + '@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 '@babel/generator': 7.29.1 - '@expo/config': 55.0.13(typescript@5.9.3) - '@expo/env': 2.1.1 - '@expo/json-file': 10.0.13 - '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/config': 55.0.16(typescript@5.9.3) + '@expo/env': 2.1.2 + '@expo/json-file': 10.0.14 + '@expo/metro': 55.1.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@expo/spawn-async': 1.7.2 browserslist: 4.28.1 chalk: 4.1.2 @@ -17903,76 +17907,76 @@ snapshots: postcss: 8.4.49 resolve-from: 5.0.0 optionalDependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color - typescript - utf-8-validate - '@expo/metro-runtime@55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@expo/metro-runtime@55.0.11(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/log-box': 55.0.12(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) anser: 1.4.10 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) pretty-format: 29.7.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 whatwg-fetch: 3.6.20 optionalDependencies: react-dom: 19.2.4(react@19.2.0) - '@expo/metro@55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': - dependencies: - metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-babel-transformer: 0.83.5 - metro-cache: 0.83.5 - metro-cache-key: 0.83.5 - metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.83.5 - metro-file-map: 0.83.5 - metro-minify-terser: 0.83.5 - metro-resolver: 0.83.5 - metro-runtime: 0.83.5 - metro-source-map: 0.83.5 - metro-symbolicate: 0.83.5 - metro-transform-plugins: 0.83.5 - metro-transform-worker: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro@55.1.1(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + metro: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.83.7 + metro-cache: 0.83.7 + metro-cache-key: 0.83.7 + metro-config: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-core: 0.83.7 + metro-file-map: 0.83.7 + metro-minify-terser: 0.83.7 + metro-resolver: 0.83.7 + metro-runtime: 0.83.7 + metro-source-map: 0.83.7 + metro-symbolicate: 0.83.7 + metro-transform-plugins: 0.83.7 + metro-transform-worker: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@expo/osascript@2.4.2': + '@expo/osascript@2.4.3': dependencies: '@expo/spawn-async': 1.7.2 - '@expo/package-manager@1.10.4': + '@expo/package-manager@1.10.5': dependencies: - '@expo/json-file': 10.0.13 + '@expo/json-file': 10.0.14 '@expo/spawn-async': 1.7.2 chalk: 4.1.2 npm-package-arg: 11.0.3 ora: 3.4.0 resolve-workspace-root: 2.0.1 - '@expo/plist@0.5.2': + '@expo/plist@0.5.3': dependencies: '@xmldom/xmldom': 0.8.11 base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@55.0.13(expo@55.0.12)(typescript@5.9.3)': + '@expo/prebuild-config@55.0.17(expo@55.0.23)(typescript@5.9.3)': dependencies: - '@expo/config': 55.0.13(typescript@5.9.3) + '@expo/config': 55.0.16(typescript@5.9.3) '@expo/config-plugins': 55.0.8 '@expo/config-types': 55.0.5 - '@expo/image-utils': 0.8.12 - '@expo/json-file': 10.0.13 - '@react-native/normalize-colors': 0.83.4 + '@expo/image-utils': 0.8.14(typescript@5.9.3) + '@expo/json-file': 10.0.14 + '@react-native/normalize-colors': 0.83.6 debug: 4.4.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) resolve-from: 5.0.0 semver: 7.7.4 xml2js: 0.6.0 @@ -17988,7 +17992,7 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@expo/require-utils@55.0.3(typescript@5.9.3)': + '@expo/require-utils@55.0.5(typescript@5.9.3)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -17998,32 +18002,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/require-utils@55.0.4(typescript@5.9.3)': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.0 - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react@19.2.0)': + '@expo/router-server@55.0.16(@expo/metro-runtime@55.0.11)(expo-constants@55.0.16)(expo-font@55.0.7)(expo-router@55.0.14)(expo-server@55.0.9)(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react@19.2.0)': dependencies: debug: 4.4.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-server: 55.0.7 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-font: 55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-server: 55.0.9 react: 19.2.0 optionalDependencies: - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-router: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) + '@expo/metro-runtime': 55.0.11(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-router: 55.0.14(3108cc3b583b2b3cde65eb2e75099aa2) react-dom: 19.2.4(react@19.2.0) transitivePeerDependencies: - supports-color - '@expo/schema-utils@55.0.3': {} + '@expo/schema-utils@55.0.4': {} '@expo/sdk-runtime-versions@1.0.0': {} @@ -18033,11 +18027,11 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@expo/vector-icons@15.1.1(expo-font@55.0.7)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-font: 55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@expo/ws-tunnel@1.0.6': {} @@ -18664,11 +18658,11 @@ snapshots: '@jsamr/counter-style@2.0.2': {} - '@jsamr/react-native-li@2.3.1(@jsamr/counter-style@2.0.2)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@jsamr/react-native-li@2.3.1(@jsamr/counter-style@2.0.2)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: '@jsamr/counter-style': 2.0.2 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@kilocode/kilo-chat-hooks@file:packages/kilo-chat-hooks(@tanstack/react-query@5.90.21(react@19.2.0))(react@19.2.0)': dependencies: @@ -20723,21 +20717,21 @@ snapshots: dependencies: react: 19.2.4 - '@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-native-community/netinfo@11.5.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - '@react-native/assets-registry@0.83.4': {} + '@react-native/assets-registry@0.83.6': {} - '@react-native/babel-plugin-codegen@0.83.4': + '@react-native/babel-plugin-codegen@0.83.6': dependencies: '@babel/traverse': 7.29.0 - '@react-native/codegen': 0.83.4 + '@react-native/codegen': 0.83.6 transitivePeerDependencies: - supports-color - '@react-native/babel-preset@0.83.4': + '@react-native/babel-preset@0.83.6': dependencies: '@babel/core': 7.29.0 '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) @@ -20780,14 +20774,14 @@ snapshots: '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) '@babel/template': 7.28.6 - '@react-native/babel-plugin-codegen': 0.83.4 + '@react-native/babel-plugin-codegen': 0.83.6 babel-plugin-syntax-hermes-parser: 0.32.0 babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.0) react-refresh: 0.14.2 transitivePeerDependencies: - supports-color - '@react-native/codegen@0.83.4': + '@react-native/codegen@0.83.6': dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.0 @@ -20799,32 +20793,32 @@ snapshots: transitivePeerDependencies: - supports-color - '@react-native/community-cli-plugin@0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@react-native/community-cli-plugin@0.83.6(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - '@react-native/dev-middleware': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/dev-middleware': 0.83.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) debug: 4.4.3 invariant: 2.2.4 - metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.83.5 + metro: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-config: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-core: 0.83.7 semver: 7.7.4 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@react-native/debugger-frontend@0.83.4': {} + '@react-native/debugger-frontend@0.83.6': {} - '@react-native/debugger-shell@0.83.4': + '@react-native/debugger-shell@0.83.6': dependencies: cross-spawn: 7.0.6 fb-dotslash: 0.5.8 - '@react-native/dev-middleware@0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@react-native/dev-middleware@0.83.6(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@isaacs/ttlcache': 1.4.1 - '@react-native/debugger-frontend': 0.83.4 - '@react-native/debugger-shell': 0.83.4 + '@react-native/debugger-frontend': 0.83.6 + '@react-native/debugger-shell': 0.83.6 chrome-launcher: 0.15.2 chromium-edge-launcher: 0.2.0 connect: 3.7.0 @@ -20839,30 +20833,30 @@ snapshots: - supports-color - utf-8-validate - '@react-native/gradle-plugin@0.83.4': {} + '@react-native/gradle-plugin@0.83.6': {} - '@react-native/js-polyfills@0.83.4': {} + '@react-native/js-polyfills@0.83.6': {} - '@react-native/normalize-colors@0.83.4': {} + '@react-native/normalize-colors@0.83.6': {} - '@react-native/virtualized-lists@0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-native/virtualized-lists@0.83.6(@types/react@19.2.14)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) optionalDependencies: '@types/react': 19.2.14 - '@react-navigation/bottom-tabs@7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-navigation/bottom-tabs@7.15.8(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sf-symbols-typescript: 2.2.0 transitivePeerDependencies: - '@react-native-masked-view/masked-view' @@ -20879,38 +20873,38 @@ snapshots: use-latest-callback: 0.2.6(react@19.2.0) use-sync-external-store: 1.6.0(react@19.2.0) - '@react-navigation/elements@2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-navigation/elements@2.9.13(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) use-latest-callback: 0.2.6(react@19.2.0) use-sync-external-store: 1.6.0(react@19.2.0) - '@react-navigation/native-stack@7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-navigation/native-stack@7.14.5(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sf-symbols-typescript: 2.2.0 warn-once: 0.1.1 transitivePeerDependencies: - '@react-native-masked-view/masked-view' - '@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: '@react-navigation/core': 7.16.1(react@19.2.0) escape-string-regexp: 4.0.0 fast-deep-equal: 3.1.3 nanoid: 3.3.11 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) use-latest-callback: 0.2.6(react@19.2.0) '@react-navigation/routers@7.5.3': @@ -20949,22 +20943,22 @@ snapshots: react: 19.2.4 react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1) - '@rn-primitives/portal@1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0))': + '@rn-primitives/portal@1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0))': dependencies: react: 19.2.0 zustand: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) optionalDependencies: - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@types/react' - immer - use-sync-external-store - '@rn-primitives/slot@1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@rn-primitives/slot@1.2.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: react: 19.2.0 optionalDependencies: - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@rocicorp/resolver@1.0.2': {} @@ -21144,53 +21138,45 @@ snapshots: transitivePeerDependencies: - encoding - '@sentry-internal/browser-utils@10.37.0': - dependencies: - '@sentry/core': 10.37.0 - '@sentry-internal/browser-utils@10.43.0': dependencies: '@sentry/core': 10.43.0 - '@sentry-internal/feedback@10.37.0': + '@sentry-internal/browser-utils@10.51.0': dependencies: - '@sentry/core': 10.37.0 + '@sentry/core': 10.51.0 '@sentry-internal/feedback@10.43.0': dependencies: '@sentry/core': 10.43.0 - '@sentry-internal/replay-canvas@10.37.0': + '@sentry-internal/feedback@10.51.0': dependencies: - '@sentry-internal/replay': 10.37.0 - '@sentry/core': 10.37.0 + '@sentry/core': 10.51.0 '@sentry-internal/replay-canvas@10.43.0': dependencies: '@sentry-internal/replay': 10.43.0 '@sentry/core': 10.43.0 - '@sentry-internal/replay@10.37.0': + '@sentry-internal/replay-canvas@10.51.0': dependencies: - '@sentry-internal/browser-utils': 10.37.0 - '@sentry/core': 10.37.0 + '@sentry-internal/replay': 10.51.0 + '@sentry/core': 10.51.0 '@sentry-internal/replay@10.43.0': dependencies: '@sentry-internal/browser-utils': 10.43.0 '@sentry/core': 10.43.0 - '@sentry/babel-plugin-component-annotate@4.8.0': {} + '@sentry-internal/replay@10.51.0': + dependencies: + '@sentry-internal/browser-utils': 10.51.0 + '@sentry/core': 10.51.0 '@sentry/babel-plugin-component-annotate@5.1.1': {} - '@sentry/browser@10.37.0': - dependencies: - '@sentry-internal/browser-utils': 10.37.0 - '@sentry-internal/feedback': 10.37.0 - '@sentry-internal/replay': 10.37.0 - '@sentry-internal/replay-canvas': 10.37.0 - '@sentry/core': 10.37.0 + '@sentry/babel-plugin-component-annotate@5.2.1': {} '@sentry/browser@10.43.0': dependencies: @@ -21200,6 +21186,14 @@ snapshots: '@sentry-internal/replay-canvas': 10.43.0 '@sentry/core': 10.43.0 + '@sentry/browser@10.51.0': + dependencies: + '@sentry-internal/browser-utils': 10.51.0 + '@sentry-internal/feedback': 10.51.0 + '@sentry-internal/replay': 10.51.0 + '@sentry-internal/replay-canvas': 10.51.0 + '@sentry/core': 10.51.0 + '@sentry/bundler-plugin-core@5.1.1': dependencies: '@babel/core': 7.29.0 @@ -21266,12 +21260,19 @@ snapshots: optionalDependencies: '@cloudflare/workers-types': 4.20260430.1 - '@sentry/core@10.37.0': {} - '@sentry/core@10.43.0': {} + '@sentry/core@10.51.0': {} + '@sentry/core@9.47.1': {} + '@sentry/expo-upload-sourcemaps@8.10.0(@expo/env@2.1.2)(dotenv@17.3.1)': + dependencies: + '@sentry/cli': 3.3.4 + optionalDependencies: + '@expo/env': 2.1.2 + dotenv: 17.3.1 + '@sentry/nextjs@10.43.0(@opentelemetry/context-async-hooks@2.6.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4))': dependencies: '@opentelemetry/api': 1.9.0 @@ -21383,24 +21384,22 @@ snapshots: '@opentelemetry/semantic-conventions': 1.40.0 '@sentry/core': 10.43.0 - '@sentry/react-native@7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@sentry/react-native@8.10.0(@expo/env@2.1.2)(dotenv@17.3.1)(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@sentry/babel-plugin-component-annotate': 4.8.0 - '@sentry/browser': 10.37.0 + '@sentry/babel-plugin-component-annotate': 5.2.1 + '@sentry/browser': 10.51.0 '@sentry/cli': 3.3.4 - '@sentry/core': 10.37.0 - '@sentry/react': 10.37.0(react@19.2.0) - '@sentry/types': 10.37.0 + '@sentry/core': 10.51.0 + '@sentry/expo-upload-sourcemaps': 8.10.0(@expo/env@2.1.2)(dotenv@17.3.1) + '@sentry/react': 10.51.0(react@19.2.0) + '@sentry/types': 10.51.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) optionalDependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - - '@sentry/react@10.37.0(react@19.2.0)': - dependencies: - '@sentry/browser': 10.37.0 - '@sentry/core': 10.37.0 - react: 19.2.0 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - '@expo/env' + - dotenv '@sentry/react@10.43.0(react@19.2.4)': dependencies: @@ -21408,9 +21407,15 @@ snapshots: '@sentry/core': 10.43.0 react: 19.2.4 - '@sentry/types@10.37.0': + '@sentry/react@10.51.0(react@19.2.0)': + dependencies: + '@sentry/browser': 10.51.0 + '@sentry/core': 10.51.0 + react: 19.2.0 + + '@sentry/types@10.51.0': dependencies: - '@sentry/core': 10.37.0 + '@sentry/core': 10.51.0 '@sentry/vercel-edge@10.43.0': dependencies: @@ -21434,11 +21439,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@shopify/flash-list@2.0.2(@babel/runtime@7.29.2)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': + '@shopify/flash-list@2.0.2(@babel/runtime@7.29.2)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: '@babel/runtime': 7.29.2 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) tslib: 2.8.1 '@sideway/address@4.1.5': @@ -23747,7 +23752,7 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) - babel-preset-expo@55.0.16(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.12)(react-refresh@0.14.2): + babel-preset-expo@55.0.21(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.23)(react-refresh@0.14.2): dependencies: '@babel/generator': 7.29.1 '@babel/helper-module-imports': 7.28.6 @@ -23765,7 +23770,7 @@ snapshots: '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@react-native/babel-preset': 0.83.4 + '@react-native/babel-preset': 0.83.6 babel-plugin-react-compiler: 1.0.0 babel-plugin-react-native-web: 0.21.2 babel-plugin-syntax-hermes-parser: 0.32.1 @@ -23775,7 +23780,7 @@ snapshots: resolve-from: 5.0.0 optionalDependencies: '@babel/runtime': 7.29.2 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@babel/core' - supports-color @@ -24813,7 +24818,7 @@ snapshots: - bufferutil - utf-8-validate - dnssd-advertise@1.1.3: {} + dnssd-advertise@1.1.4: {} doctrine@3.0.0: dependencies: @@ -25273,190 +25278,177 @@ snapshots: jest-mock: 30.3.0 jest-util: 30.3.0 - expo-apple-authentication@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): + expo-apple-authentication@55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-application@55.0.13(expo@55.0.12): + expo-application@55.0.14(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): + expo-asset@55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): dependencies: - '@expo/image-utils': 0.8.12 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + '@expo/image-utils': 0.8.14(typescript@5.9.3) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-audio@55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-audio@55.0.14(expo-asset@55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-asset: 55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-blur@55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-blur@55.0.14(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-build-properties@55.0.12(expo@55.0.12): + expo-build-properties@55.0.13(expo@55.0.23): dependencies: - '@expo/schema-utils': 55.0.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/schema-utils': 55.0.4 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) resolve-from: 5.0.0 semver: 7.7.4 - expo-clipboard@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-clipboard@55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-constants@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3): + expo-constants@55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - '@expo/config': 55.0.13(typescript@5.9.3) - '@expo/env': 2.1.1 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + '@expo/env': 2.1.2 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - - typescript - expo-crypto@55.0.14(expo@55.0.12): + expo-crypto@55.0.14(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-dev-client@55.0.23(expo@55.0.12)(typescript@5.9.3): + expo-dev-client@55.0.32(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-dev-launcher: 55.0.24(expo@55.0.12)(typescript@5.9.3) - expo-dev-menu: 55.0.20(expo@55.0.12) - expo-dev-menu-interface: 55.0.2(expo@55.0.12) - expo-manifests: 55.0.14(expo@55.0.12)(typescript@5.9.3) - expo-updates-interface: 55.1.5(expo@55.0.12) - transitivePeerDependencies: - - supports-color - - typescript + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-dev-launcher: 55.0.33(expo@55.0.23) + expo-dev-menu: 55.0.27(expo@55.0.23) + expo-dev-menu-interface: 55.0.2(expo@55.0.23) + expo-manifests: 55.0.16(expo@55.0.23) + expo-updates-interface: 55.1.6(expo@55.0.23) - expo-dev-launcher@55.0.24(expo@55.0.12)(typescript@5.9.3): + expo-dev-launcher@55.0.33(expo@55.0.23): dependencies: - '@expo/schema-utils': 55.0.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-dev-menu: 55.0.20(expo@55.0.12) - expo-manifests: 55.0.14(expo@55.0.12)(typescript@5.9.3) - transitivePeerDependencies: - - supports-color - - typescript + '@expo/schema-utils': 55.0.4 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-dev-menu: 55.0.27(expo@55.0.23) + expo-manifests: 55.0.16(expo@55.0.23) - expo-dev-menu-interface@55.0.2(expo@55.0.12): + expo-dev-menu-interface@55.0.2(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-dev-menu@55.0.20(expo@55.0.12): + expo-dev-menu@55.0.27(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-dev-menu-interface: 55.0.2(expo@55.0.12) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-dev-menu-interface: 55.0.2(expo@55.0.23) - expo-document-picker@55.0.12(expo@55.0.12): + expo-document-picker@55.0.13(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-eas-client@55.0.5: {} - expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): + expo-file-system@55.0.19(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-font@55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-font@55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) fontfaceobserver: 2.3.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-glass-effect@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-glass-effect@55.0.11(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-haptics@55.0.13(expo@55.0.12): + expo-haptics@55.0.14(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-iap@4.2.4(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-iap@4.2.4(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-image-loader@55.0.0(expo@55.0.12): + expo-image-loader@55.0.0(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-image-picker@55.0.17(expo@55.0.12): + expo-image-picker@55.0.20(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-image-loader: 55.0.0(expo@55.0.12) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-image-loader: 55.0.0(expo@55.0.23) - expo-image@55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-image@55.0.10(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - expo-insights@55.0.15(expo@55.0.12): + expo-insights@55.0.16(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-eas-client: 55.0.5 expo-json-utils@55.0.2: {} - expo-keep-awake@55.0.6(expo@55.0.12)(react@19.2.0): + expo-keep-awake@55.0.8(expo@55.0.23)(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - expo-linking@55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): + expo-linking@55.0.15(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - expo - supports-color - - typescript - expo-location@55.1.8(expo@55.0.12)(typescript@5.9.3): + expo-location@55.1.9(expo@55.0.23)(typescript@5.9.3): dependencies: - '@expo/image-utils': 0.8.13(typescript@5.9.3) - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/image-utils': 0.8.14(typescript@5.9.3) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-manifests@55.0.14(expo@55.0.12)(typescript@5.9.3): + expo-manifests@55.0.16(expo@55.0.23): dependencies: - '@expo/config': 55.0.13(typescript@5.9.3) - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-json-utils: 55.0.2 - transitivePeerDependencies: - - supports-color - - typescript - expo-modules-autolinking@55.0.15(typescript@5.9.3): + expo-modules-autolinking@55.0.21(typescript@5.9.3): dependencies: - '@expo/require-utils': 55.0.3(typescript@5.9.3) + '@expo/require-utils': 55.0.5(typescript@5.9.3) '@expo/spawn-async': 1.7.2 chalk: 4.1.2 commander: 7.2.0 @@ -25464,56 +25456,58 @@ snapshots: - supports-color - typescript - expo-modules-core@55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-modules-core@55.0.25(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + optionalDependencies: + react-native-worklets: 0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-notifications@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): + expo-notifications@55.0.22(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): dependencies: - '@expo/image-utils': 0.8.12 + '@expo/image-utils': 0.8.14(typescript@5.9.3) abort-controller: 3.0.0 badgin: 1.2.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-application: 55.0.13(expo@55.0.12) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-application: 55.0.14(expo@55.0.23) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-router@55.0.11(19d76ea0d0b88bce60b3b715cef8728d): + expo-router@55.0.14(3108cc3b583b2b3cde65eb2e75099aa2): dependencies: - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/schema-utils': 55.0.3 + '@expo/log-box': 55.0.12(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro-runtime': 55.0.11(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/schema-utils': 55.0.4 '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.0) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) - '@react-navigation/bottom-tabs': 7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@react-navigation/native-stack': 7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/bottom-tabs': 7.15.8(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native-stack': 7.14.5(@react-navigation/native@7.1.33(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) client-only: 0.0.1 debug: 4.4.3 escape-string-regexp: 4.0.0 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) - expo-glass-effect: 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-image: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-linking: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) - expo-server: 55.0.7 - expo-symbols: 55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-glass-effect: 55.0.11(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-image: 55.0.10(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-linking: 55.0.15(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-server: 55.0.9 + expo-symbols: 55.0.8(expo-font@55.0.7)(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) fast-deep-equal: 3.1.3 invariant: 2.2.4 nanoid: 3.3.11 query-string: 7.1.3 react: 19.2.0 react-fast-compare: 3.2.2 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-safe-area-context: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) semver: 7.6.3 server-only: 0.0.1 sf-symbols-typescript: 2.2.0 @@ -25522,8 +25516,8 @@ snapshots: vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) optionalDependencies: react-dom: 19.2.4(react@19.2.0) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-gesture-handler: 2.30.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) transitivePeerDependencies: - '@react-native-masked-view/masked-view' - '@types/react' @@ -25531,9 +25525,9 @@ snapshots: - expo-font - supports-color - expo-secure-store@55.0.12(expo@55.0.12): + expo-secure-store@55.0.13(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-server-sdk@6.1.0(patch_hash=7850520582b5b394397b35d1ea195192fe78589d8a6a748fe15177b818c4ed0b): dependencies: @@ -25541,98 +25535,99 @@ snapshots: promise-retry: 2.0.1 undici: 7.24.3 - expo-server@55.0.7: {} + expo-server@55.0.9: {} - expo-sharing@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-sharing@55.0.18(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@expo/config-plugins': 55.0.8 '@expo/config-types': 55.0.5 - '@expo/plist': 0.5.2 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/plist': 0.5.3 + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - expo-splash-screen@55.0.16(expo@55.0.12)(typescript@5.9.3): + expo-splash-screen@55.0.20(expo@55.0.23)(typescript@5.9.3): dependencies: - '@expo/prebuild-config': 55.0.13(expo@55.0.12)(typescript@5.9.3) - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/prebuild-config': 55.0.17(expo@55.0.23)(typescript@5.9.3) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-status-bar@55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-status-bar@55.0.6(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-symbols@55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-symbols@55.0.8(expo-font@55.0.7)(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@expo-google-fonts/material-symbols': 0.4.27 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-font: 55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - expo-tracking-transparency@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): + expo-tracking-transparency@55.0.13(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-updates-interface@55.1.5(expo@55.0.12): + expo-updates-interface@55.1.6(expo@55.0.23): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-video@55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + expo-video@55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): + expo-web-browser@55.0.15(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + expo: 55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo@55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6): + expo@55.0.23(@babel/core@7.29.0)(@expo/dom-webview@55.0.6)(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-router@55.0.14)(react-dom@19.2.4(react@19.2.0))(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6): dependencies: '@babel/runtime': 7.29.2 - '@expo/cli': 55.0.22(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - '@expo/config': 55.0.13(typescript@5.9.3) + '@expo/cli': 55.0.29(@expo/metro-runtime@55.0.11)(bufferutil@4.1.0)(expo-constants@55.0.16)(expo-font@55.0.7)(expo-router@55.0.14)(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/config': 55.0.16(typescript@5.9.3) '@expo/config-plugins': 55.0.8 - '@expo/devtools': 55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/fingerprint': 0.16.6 - '@expo/local-build-cache-provider': 55.0.9(typescript@5.9.3) - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) - '@expo/vector-icons': 15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/devtools': 55.0.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/fingerprint': 0.16.7 + '@expo/local-build-cache-provider': 55.0.12(typescript@5.9.3) + '@expo/log-box': 55.0.12(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro': 55.1.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/vector-icons': 15.1.1(expo-font@55.0.7)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@ungap/structured-clone': 1.3.0 - babel-preset-expo: 55.0.16(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.12)(react-refresh@0.14.2) - expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) - expo-file-system: 55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-keep-awake: 55.0.6(expo@55.0.12)(react@19.2.0) - expo-modules-autolinking: 55.0.15(typescript@5.9.3) - expo-modules-core: 55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + babel-preset-expo: 55.0.21(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.23)(react-refresh@0.14.2) + expo-asset: 55.0.17(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.16(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-file-system: 55.0.19(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-font: 55.0.7(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-keep-awake: 55.0.8(expo@55.0.23)(react@19.2.0) + expo-modules-autolinking: 55.0.21(typescript@5.9.3) + expo-modules-core: 55.0.25(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) pretty-format: 29.7.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) react-refresh: 0.14.2 whatwg-url-minimum: 0.1.1 optionalDependencies: - '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/dom-webview': 55.0.6(expo@55.0.23)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro-runtime': 55.0.11(expo@55.0.23)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) transitivePeerDependencies: - '@babel/core' - bufferutil - expo-router - expo-widgets - react-dom + - react-native-worklets - react-server-dom-webpack - supports-color - typescript @@ -25743,7 +25738,7 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - fetch-nodeshim@0.4.9: {} + fetch-nodeshim@0.4.10: {} fetch-to-node@2.1.0: {} @@ -26180,7 +26175,7 @@ snapshots: hermes-estree@0.32.1: {} - hermes-estree@0.33.3: {} + hermes-estree@0.35.0: {} hermes-parser@0.32.0: dependencies: @@ -26190,9 +26185,9 @@ snapshots: dependencies: hermes-estree: 0.32.1 - hermes-parser@0.33.3: + hermes-parser@0.35.0: dependencies: - hermes-estree: 0.33.3 + hermes-estree: 0.35.0 hmac-drbg@1.0.1: dependencies: @@ -27567,7 +27562,7 @@ snapshots: yaml: 2.8.2 zod: 4.3.6 - lan-network@0.2.0: {} + lan-network@0.2.1: {} lazystream@1.0.1: dependencies: @@ -27724,11 +27719,11 @@ snapshots: dependencies: yallist: 4.0.0 - lucide-react-native@1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + lucide-react-native@1.7.0(react-native-svg@15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-svg: 15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) lucide-react@0.552.0(react@19.2.4): dependencies: @@ -28021,50 +28016,51 @@ snapshots: merge2@1.4.1: {} - metro-babel-transformer@0.83.5: + metro-babel-transformer@0.83.7: dependencies: '@babel/core': 7.29.0 flow-enums-runtime: 0.0.6 - hermes-parser: 0.33.3 + hermes-parser: 0.35.0 + metro-cache-key: 0.83.7 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color - metro-cache-key@0.83.5: + metro-cache-key@0.83.7: dependencies: flow-enums-runtime: 0.0.6 - metro-cache@0.83.5: + metro-cache@0.83.7: dependencies: exponential-backoff: 3.1.3 flow-enums-runtime: 0.0.6 https-proxy-agent: 7.0.6 - metro-core: 0.83.5 + metro-core: 0.83.7 transitivePeerDependencies: - supports-color - metro-config@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro-config@0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: connect: 3.7.0 flow-enums-runtime: 0.0.6 jest-validate: 29.7.0 - metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-cache: 0.83.5 - metro-core: 0.83.5 - metro-runtime: 0.83.5 + metro: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-cache: 0.83.7 + metro-core: 0.83.7 + metro-runtime: 0.83.7 yaml: 2.8.2 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - metro-core@0.83.5: + metro-core@0.83.7: dependencies: flow-enums-runtime: 0.0.6 lodash.throttle: 4.1.1 - metro-resolver: 0.83.5 + metro-resolver: 0.83.7 - metro-file-map@0.83.5: + metro-file-map@0.83.7: dependencies: debug: 4.4.3 fb-watchman: 2.0.2 @@ -28078,46 +28074,46 @@ snapshots: transitivePeerDependencies: - supports-color - metro-minify-terser@0.83.5: + metro-minify-terser@0.83.7: dependencies: flow-enums-runtime: 0.0.6 terser: 5.46.0 - metro-resolver@0.83.5: + metro-resolver@0.83.7: dependencies: flow-enums-runtime: 0.0.6 - metro-runtime@0.83.5: + metro-runtime@0.83.7: dependencies: '@babel/runtime': 7.29.2 flow-enums-runtime: 0.0.6 - metro-source-map@0.83.5: + metro-source-map@0.83.7: dependencies: '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-symbolicate: 0.83.5 + metro-symbolicate: 0.83.7 nullthrows: 1.1.1 - ob1: 0.83.5 + ob1: 0.83.7 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color - metro-symbolicate@0.83.5: + metro-symbolicate@0.83.7: dependencies: flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-source-map: 0.83.5 + metro-source-map: 0.83.7 nullthrows: 1.1.1 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color - metro-transform-plugins@0.83.5: + metro-transform-plugins@0.83.7: dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 @@ -28128,27 +28124,27 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-worker@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro-transform-worker@0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 '@babel/parser': 7.29.0 '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 - metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-babel-transformer: 0.83.5 - metro-cache: 0.83.5 - metro-cache-key: 0.83.5 - metro-minify-terser: 0.83.5 - metro-source-map: 0.83.5 - metro-transform-plugins: 0.83.5 + metro: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.83.7 + metro-cache: 0.83.7 + metro-cache-key: 0.83.7 + metro-minify-terser: 0.83.7 + metro-source-map: 0.83.7 + metro-transform-plugins: 0.83.7 nullthrows: 1.1.1 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - metro@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro@0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -28158,31 +28154,30 @@ snapshots: '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 accepts: 2.0.0 - chalk: 4.1.2 ci-info: 2.0.0 connect: 3.7.0 debug: 4.4.3 error-stack-parser: 2.1.4 flow-enums-runtime: 0.0.6 graceful-fs: 4.2.11 - hermes-parser: 0.33.3 + hermes-parser: 0.35.0 image-size: 1.2.1 invariant: 2.2.4 jest-worker: 29.7.0 jsc-safe-url: 0.2.4 lodash.throttle: 4.1.1 - metro-babel-transformer: 0.83.5 - metro-cache: 0.83.5 - metro-cache-key: 0.83.5 - metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.83.5 - metro-file-map: 0.83.5 - metro-resolver: 0.83.5 - metro-runtime: 0.83.5 - metro-source-map: 0.83.5 - metro-symbolicate: 0.83.5 - metro-transform-plugins: 0.83.5 - metro-transform-worker: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.83.7 + metro-cache: 0.83.7 + metro-cache-key: 0.83.7 + metro-config: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-core: 0.83.7 + metro-file-map: 0.83.7 + metro-resolver: 0.83.7 + metro-runtime: 0.83.7 + metro-source-map: 0.83.7 + metro-symbolicate: 0.83.7 + metro-transform-plugins: 0.83.7 + metro-transform-worker: 0.83.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) mime-types: 3.0.2 nullthrows: 1.1.1 serialize-error: 2.1.0 @@ -28644,15 +28639,15 @@ snapshots: ms@2.1.3: {} - multitars@0.2.4: {} + multitars@1.0.0: {} nanoid@3.3.11: {} napi-postinstall@0.3.4: {} - nativewind@5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2): + nativewind@5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2): dependencies: - react-native-css: 3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-css: 3.0.6(@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) tailwindcss: 4.2.2 tailwindcss-safe-area: 1.3.0(tailwindcss@4.2.2) @@ -28840,7 +28835,7 @@ snapshots: oauth@0.9.15: {} - ob1@0.83.5: + ob1@0.83.7: dependencies: flow-enums-runtime: 0.0.6 @@ -29651,9 +29646,9 @@ snapshots: react-native-appsflyer@6.17.9: {} - react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-css@3.0.6(@expo/metro-config@55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/metro-config': 55.0.20(bufferutil@4.1.0)(expo@55.0.23)(typescript@5.9.3)(utf-8-validate@6.0.6) '@types/debug': 4.1.12 babel-plugin-react-compiler: 19.1.0-rc.3 colorjs.io: 0.6.0-alpha.1 @@ -29661,75 +29656,75 @@ snapshots: debug: 4.4.3 lightningcss: 1.30.1 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-gesture-handler@2.30.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@egjs/hammerjs': 2.0.17 hoist-non-react-statics: 3.3.2 invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge@1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-is-edge-to-edge@1.2.1(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge@1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-is-edge-to-edge@1.3.1(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-marked@8.0.1(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-marked@8.0.1(react-native-svg@15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@jsamr/counter-style': 2.0.2 - '@jsamr/react-native-li': 2.3.1(@jsamr/counter-style@2.0.2)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@jsamr/react-native-li': 2.3.1(@jsamr/counter-style@2.0.2)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) github-slugger: 2.0.0 html-entities: 2.6.0 marked: 17.0.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-reanimated-table: 0.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-reanimated-table: 0.0.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-svg: 15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) svg-parser: 2.0.4 - react-native-reanimated-table@0.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-reanimated-table@0.0.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-reanimated@4.2.1(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge: 1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-worklets: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.2.1(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-worklets: 0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) semver: 7.7.3 - react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-safe-area-context@5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-screens@4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 react-freeze: 1.0.4(react@19.2.0) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) warn-once: 0.1.1 - react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-svg@15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: css-select: 5.2.2 css-tree: 1.1.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) warn-once: 0.1.1 - react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): + react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) @@ -29743,21 +29738,21 @@ snapshots: '@babel/preset-typescript': 7.27.1(@babel/core@7.29.0) convert-source-map: 2.0.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) semver: 7.7.3 transitivePeerDependencies: - supports-color - react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6): + react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6): dependencies: '@jest/create-cache-key-function': 29.7.0 - '@react-native/assets-registry': 0.83.4 - '@react-native/codegen': 0.83.4 - '@react-native/community-cli-plugin': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@react-native/gradle-plugin': 0.83.4 - '@react-native/js-polyfills': 0.83.4 - '@react-native/normalize-colors': 0.83.4 - '@react-native/virtualized-lists': 0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-native/assets-registry': 0.83.6 + '@react-native/codegen': 0.83.6 + '@react-native/community-cli-plugin': 0.83.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/gradle-plugin': 0.83.6 + '@react-native/js-polyfills': 0.83.6 + '@react-native/normalize-colors': 0.83.6 + '@react-native/virtualized-lists': 0.83.6(@types/react@19.2.14)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 @@ -29771,8 +29766,8 @@ snapshots: invariant: 2.2.4 jest-environment-node: 29.7.0 memoize-one: 5.2.1 - metro-runtime: 0.83.5 - metro-source-map: 0.83.5 + metro-runtime: 0.83.7 + metro-source-map: 0.83.7 nullthrows: 1.1.1 pretty-format: 29.7.0 promise: 8.3.0 @@ -30556,15 +30551,15 @@ snapshots: smol-toml@1.6.0: {} - sonner-native@0.23.1(53175ba88151f39b99a3b76a61c65c1d): + sonner-native@0.23.1(e2671c59cdfc41694eb0da90c4eaaa5b): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native: 0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-gesture-handler: 2.30.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.4(@babel/core@7.29.0)(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-safe-area-context: 5.6.2(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-svg: 15.15.3(react-native@0.83.6(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sonner@2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: From 507082335f9853b868895a8a297f23b4a02414b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 18:47:16 +0200 Subject: [PATCH 19/34] fix(mobile): recover unfinished apple credit purchases --- .../apple-credit-purchase-sheet.tsx | 67 ++++++++++++++++++- .../mobile/src/lib/apple-iap/storekit.test.ts | 37 ++++++++++ apps/mobile/src/lib/apple-iap/storekit.ts | 19 ++++++ .../use-apple-credit-purchase.test.tsx | 40 ++++++++++- .../apple-iap/use-apple-credit-purchase.ts | 27 ++++++-- 5 files changed, 181 insertions(+), 9 deletions(-) diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx index 344e1d811d..16aea204f1 100644 --- a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx +++ b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx @@ -1,5 +1,5 @@ import { ShoppingBag, X } from 'lucide-react-native'; -import { useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { ActivityIndicator, Modal, Pressable, View } from 'react-native'; import { toast } from 'sonner-native'; @@ -27,9 +27,70 @@ export function AppleCreditPurchaseSheet({ }: Readonly) { const colors = useThemeColors(); const { products, isLoading, isError, refetch } = useAppleCreditProducts(); - const { purchaseProduct, isPending } = useAppleCreditPurchase(); + const { purchaseProduct, recoverUnfinishedPurchases, isPending } = useAppleCreditPurchase(); const [activeProductId, setActiveProductId] = useState(null); const [purchaseError, setPurchaseError] = useState(null); + const [isRecovering, setIsRecovering] = useState(false); + const [recoveryProductIdsKey, setRecoveryProductIdsKey] = useState(null); + const recoveryRunRef = useRef(0); + const productIds = useMemo(() => products.map(product => product.id), [products]); + const productIdsKey = productIds.join('\u0000'); + + useEffect(() => { + if (!visible) { + setRecoveryProductIdsKey(null); + recoveryRunRef.current += 1; + return undefined; + } + if ( + isLoading || + isError || + productIds.length === 0 || + recoveryProductIdsKey === productIdsKey + ) { + return undefined; + } + + const recoveryRunId = recoveryRunRef.current + 1; + recoveryRunRef.current = recoveryRunId; + const isCurrentRecoveryRun = () => recoveryRunRef.current === recoveryRunId; + setRecoveryProductIdsKey(productIdsKey); + setIsRecovering(true); + setPurchaseError(null); + + void (async () => { + try { + const recoveredPurchases = await recoverUnfinishedPurchases(productIds); + if (isCurrentRecoveryRun() && recoveredPurchases.length > 0) { + toast.success('Previous purchase completed'); + onPurchaseSuccess(); + } + } catch (error) { + if (isCurrentRecoveryRun()) { + setPurchaseError( + error instanceof Error ? error.message : 'Failed to complete previous purchase.' + ); + } + } finally { + if (isCurrentRecoveryRun()) { + setIsRecovering(false); + } + } + })(); + + return () => { + recoveryRunRef.current += 1; + }; + }, [ + isError, + isLoading, + onPurchaseSuccess, + productIds, + productIdsKey, + recoverUnfinishedPurchases, + recoveryProductIdsKey, + visible, + ]); const handlePurchase = async (product: AppleCreditDisplayProduct) => { setActiveProductId(product.id); @@ -94,7 +155,7 @@ export function AppleCreditPurchaseSheet({ key={product.id} variant="secondary" className="h-auto items-start justify-between px-4 py-3" - disabled={isPending || activeProductId !== null} + disabled={isPending || isRecovering || activeProductId !== null} onPress={() => { void handlePurchase(product); }} diff --git a/apps/mobile/src/lib/apple-iap/storekit.test.ts b/apps/mobile/src/lib/apple-iap/storekit.test.ts index 305867b7cc..5389780696 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.test.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { finishTransaction, + getAvailablePurchases, initConnection, type Purchase, type PurchaseError, @@ -11,6 +12,7 @@ import { import { finishStoreKitTransaction, + getUnfinishedStoreKitPurchases, purchaseStoreKitProduct, STOREKIT_PURCHASE_TIMEOUT_MS, } from './storekit'; @@ -39,6 +41,7 @@ function makePurchase(overrides: Partial = {}): Purchase { vi.mock('expo-iap', () => ({ finishTransaction: vi.fn(), + getAvailablePurchases: vi.fn(), initConnection: vi.fn(), purchaseErrorListener: vi.fn((listener: (error: PurchaseError) => void) => { listenerState.onPurchaseError = listener; @@ -66,6 +69,7 @@ beforeEach(() => { }) ); vi.mocked(finishTransaction).mockResolvedValue(undefined); + vi.mocked(getAvailablePurchases).mockResolvedValue([]); }); describe('purchaseStoreKitProduct', () => { @@ -178,3 +182,36 @@ describe('finishStoreKitTransaction', () => { }); }); }); + +describe('getUnfinishedStoreKitPurchases', () => { + it('returns unfinished purchases for requested products with signed transaction JWS values', async () => { + vi.mocked(getAvailablePurchases).mockResolvedValue([ + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.small.999', + purchaseToken: 'small-pending-transaction', + }), + makePurchase({ + productId: 'com.kilocode.kiloapp.credits.large.4999', + purchaseToken: 'large-pending-transaction', + }), + ]); + + const purchases = await getUnfinishedStoreKitPurchases([ + 'com.kilocode.kiloapp.credits.small.999', + ]); + + expect(getAvailablePurchases).toHaveBeenCalledWith({ + alsoPublishToEventListenerIOS: false, + onlyIncludeActiveItemsIOS: false, + }); + expect(purchases).toEqual([ + { + productId: 'com.kilocode.kiloapp.credits.small.999', + transactionJws: 'small-pending-transaction', + nativeTransaction: expect.objectContaining({ + productId: 'com.kilocode.kiloapp.credits.small.999', + }), + }, + ]); + }); +}); diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts index 6dadbd21d3..b8b4eb25ee 100644 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ b/apps/mobile/src/lib/apple-iap/storekit.ts @@ -1,6 +1,7 @@ import { fetchProducts, finishTransaction, + getAvailablePurchases, initConnection, type Purchase, purchaseErrorListener, @@ -120,6 +121,24 @@ export async function purchaseStoreKitProduct(productId: string): Promise { + await initConnection(); + const productIdSet = new Set(productIds); + const purchases = await getAvailablePurchases({ + alsoPublishToEventListenerIOS: false, + onlyIncludeActiveItemsIOS: false, + }); + + return purchases.flatMap(purchase => { + if (!productIdSet.has(purchase.productId)) { + return []; + } + return [toStoreKitPurchaseResult(purchase.productId, purchase)]; + }); +} + export async function finishStoreKitTransaction(nativeTransaction: Purchase): Promise { await finishTransaction({ purchase: nativeTransaction, isConsumable: true }); } diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx index 0d0aa9e716..4d5ff7403c 100644 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx @@ -2,7 +2,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { useAppleCreditProducts } from './use-apple-credit-products'; import { useAppleCreditPurchase } from './use-apple-credit-purchase'; -import { finishStoreKitTransaction, purchaseStoreKitProduct } from './storekit'; +import { + finishStoreKitTransaction, + getUnfinishedStoreKitPurchases, + purchaseStoreKitProduct, +} from './storekit'; const testState = vi.hoisted(() => ({ backendProducts: [ @@ -14,6 +18,7 @@ const testState = vi.hoisted(() => ({ }, ], invalidations: [] as unknown[], + mutationInputs: [] as unknown[], mutationResult: { creditedCents: 699, creditedMicrodollars: 6_990_000, @@ -33,6 +38,7 @@ const testState = vi.hoisted(() => ({ const mocks = vi.hoisted(() => ({ finishStoreKitTransaction: vi.fn(), fetchStoreKitProducts: vi.fn(), + getUnfinishedStoreKitPurchases: vi.fn(), purchaseStoreKitProduct: vi.fn(), })); @@ -50,7 +56,8 @@ vi.mock('@tanstack/react-query', () => ({ useMutation: () => ({ error: null, isPending: false, - mutateAsync: async () => { + mutateAsync: async (input: unknown) => { + testState.mutationInputs.push(input); if (testState.mutationShouldReject) { await Promise.resolve(); throw new Error('Backend rejected purchase'); @@ -98,6 +105,7 @@ vi.mock('@/lib/trpc', () => ({ beforeEach(() => { testState.invalidations = []; + testState.mutationInputs = []; testState.mutationShouldReject = false; testState.mutationResult = { creditedCents: 699, @@ -107,6 +115,7 @@ beforeEach(() => { testState.platform = 'ios'; vi.clearAllMocks(); mocks.fetchStoreKitProducts.mockResolvedValue(testState.storeKitProducts); + mocks.getUnfinishedStoreKitPurchases.mockResolvedValue([]); mocks.purchaseStoreKitProduct.mockResolvedValue({ productId: 'com.kilocode.kiloapp.credits.small.999', transactionJws: 'signed-transaction', @@ -162,4 +171,31 @@ describe('useAppleCreditPurchase', () => { expect(finishStoreKitTransaction).not.toHaveBeenCalled(); }); + + it('completes and finishes recovered unfinished StoreKit purchases', async () => { + mocks.getUnfinishedStoreKitPurchases.mockResolvedValue([ + { + productId: 'com.kilocode.kiloapp.credits.small.999', + transactionJws: 'pending-signed-transaction', + nativeTransaction: { id: 'pending-native-transaction' }, + }, + ]); + + const results = await useAppleCreditPurchase().recoverUnfinishedPurchases([ + 'com.kilocode.kiloapp.credits.small.999', + ]); + + expect(getUnfinishedStoreKitPurchases).toHaveBeenCalledWith([ + 'com.kilocode.kiloapp.credits.small.999', + ]); + expect(testState.mutationInputs).toEqual([{ transactionJws: 'pending-signed-transaction' }]); + expect(results).toEqual([ + { + creditedCents: 699, + creditedMicrodollars: 6_990_000, + alreadyProcessed: false, + }, + ]); + expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'pending-native-transaction' }); + }); }); diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts index 72d54dc3db..73c3c50000 100644 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts +++ b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts @@ -1,7 +1,12 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useTRPC } from '@/lib/trpc'; -import { finishStoreKitTransaction, purchaseStoreKitProduct } from './storekit'; +import { + finishStoreKitTransaction, + getUnfinishedStoreKitPurchases, + purchaseStoreKitProduct, + type StoreKitPurchaseResult, +} from './storekit'; export function useAppleCreditPurchase() { const trpc = useTRPC(); @@ -10,8 +15,7 @@ export function useAppleCreditPurchase() { trpc.user.completeAppleCreditPurchase.mutationOptions() ); - const purchaseProduct = async (productId: string) => { - const purchase = await purchaseStoreKitProduct(productId); + const completePurchase = async (purchase: StoreKitPurchaseResult) => { const result = await completeAppleCreditPurchase.mutateAsync({ transactionJws: purchase.transactionJws, }); @@ -21,9 +25,24 @@ export function useAppleCreditPurchase() { return result; }; + const purchaseProduct = async (productId: string) => { + const purchase = await purchaseStoreKitProduct(productId); + return completePurchase(purchase); + }; + + const recoverUnfinishedPurchases = async (productIds: string[]) => { + const purchases = await getUnfinishedStoreKitPurchases(productIds); + const completionPromises = []; + for (const purchase of purchases) { + completionPromises.push(completePurchase(purchase)); + } + return Promise.all(completionPromises); + }; + return { - purchaseProduct, isPending: completeAppleCreditPurchase.isPending, error: completeAppleCreditPurchase.error, + purchaseProduct, + recoverUnfinishedPurchases, }; } From 0fc605a021afd0aadc70bc4690a567b621ddb02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 19:17:01 +0200 Subject: [PATCH 20/34] fix(kilo-pass): remove one-time apple credit purchases --- .../apple-credit-purchase-sheet.test.ts | 44 - .../apple-credit-purchase-sheet.tsx | 197 - .../components/apple-credit-purchase-utils.ts | 16 - .../src/components/profile-credits-card.tsx | 38 +- .../mobile/src/lib/apple-iap/storekit.test.ts | 217 - apps/mobile/src/lib/apple-iap/storekit.ts | 144 - apps/mobile/src/lib/apple-iap/types.ts | 13 - .../apple-iap/use-apple-credit-products.ts | 62 - .../use-apple-credit-purchase.test.tsx | 201 - .../apple-iap/use-apple-credit-purchase.ts | 48 - .../api/apple/iap/notifications/route.test.ts | 15 - .../app/api/apple/iap/notifications/route.ts | 30 - .../src/lib/apple-iap/notifications.test.ts | 78 - apps/web/src/lib/apple-iap/notifications.ts | 53 - apps/web/src/lib/apple-iap/products.test.ts | 43 - apps/web/src/lib/apple-iap/products.ts | 50 - apps/web/src/lib/apple-iap/purchases.test.ts | 160 - apps/web/src/lib/apple-iap/purchases.ts | 147 - apps/web/src/lib/apple-iap/types.ts | 24 - apps/web/src/lib/apple-iap/verifier.ts | 107 - apps/web/src/routers/user-router.test.ts | 30 - apps/web/src/routers/user-router.ts | 15 - .../src/migrations/0115_amazing_scrambler.sql | 50 - .../db/src/migrations/meta/0115_snapshot.json | 19144 ---------------- packages/db/src/migrations/meta/_journal.json | 9 +- packages/db/src/schema.test.ts | 5 - packages/db/src/schema.ts | 89 - 27 files changed, 3 insertions(+), 21026 deletions(-) delete mode 100644 apps/mobile/src/components/apple-credit-purchase-sheet.test.ts delete mode 100644 apps/mobile/src/components/apple-credit-purchase-sheet.tsx delete mode 100644 apps/mobile/src/components/apple-credit-purchase-utils.ts delete mode 100644 apps/mobile/src/lib/apple-iap/storekit.test.ts delete mode 100644 apps/mobile/src/lib/apple-iap/storekit.ts delete mode 100644 apps/mobile/src/lib/apple-iap/types.ts delete mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts delete mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx delete mode 100644 apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts delete mode 100644 apps/web/src/app/api/apple/iap/notifications/route.test.ts delete mode 100644 apps/web/src/app/api/apple/iap/notifications/route.ts delete mode 100644 apps/web/src/lib/apple-iap/notifications.test.ts delete mode 100644 apps/web/src/lib/apple-iap/notifications.ts delete mode 100644 apps/web/src/lib/apple-iap/products.test.ts delete mode 100644 apps/web/src/lib/apple-iap/products.ts delete mode 100644 apps/web/src/lib/apple-iap/purchases.test.ts delete mode 100644 apps/web/src/lib/apple-iap/purchases.ts delete mode 100644 apps/web/src/lib/apple-iap/types.ts delete mode 100644 apps/web/src/lib/apple-iap/verifier.ts delete mode 100644 packages/db/src/migrations/0115_amazing_scrambler.sql delete mode 100644 packages/db/src/migrations/meta/0115_snapshot.json diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts b/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts deleted file mode 100644 index 76f1bc782f..0000000000 --- a/apps/mobile/src/components/apple-credit-purchase-sheet.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { - formatAppleCreditAmount, - getAppleCreditProductButtonText, - shouldShowAppleCreditPurchaseEntry, -} from './apple-credit-purchase-utils'; - -describe('Apple credit purchase sheet helpers', () => { - it('hides the buy entry point for organization balances', () => { - expect( - shouldShowAppleCreditPurchaseEntry({ - platform: 'ios', - selectedOrgId: 'org-1', - }) - ).toBe(false); - }); - - it('hides the buy entry point outside iOS', () => { - expect( - shouldShowAppleCreditPurchaseEntry({ - platform: 'android', - selectedOrgId: undefined, - }) - ).toBe(false); - }); - - it('shows the credited amount and localized Apple price', () => { - expect( - getAppleCreditProductButtonText({ - id: 'com.kilocode.kiloapp.credits.small.999', - tier: 'small', - creditedCents: 699, - creditedMicrodollars: 6_990_000, - title: 'Small Credit Pack', - localizedPrice: '$9.99', - }) - ).toBe('$6.99 credits - Pay $9.99'); - }); - - it('formats credited amounts for retryable purchase rows', () => { - expect(formatAppleCreditAmount(3499)).toBe('$34.99 credits'); - }); -}); diff --git a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx b/apps/mobile/src/components/apple-credit-purchase-sheet.tsx deleted file mode 100644 index 16aea204f1..0000000000 --- a/apps/mobile/src/components/apple-credit-purchase-sheet.tsx +++ /dev/null @@ -1,197 +0,0 @@ -import { ShoppingBag, X } from 'lucide-react-native'; -import { useEffect, useMemo, useRef, useState } from 'react'; -import { ActivityIndicator, Modal, Pressable, View } from 'react-native'; -import { toast } from 'sonner-native'; - -import { Button } from '@/components/ui/button'; -import { Text } from '@/components/ui/text'; -import { useAppleCreditProducts } from '@/lib/apple-iap/use-apple-credit-products'; -import { useAppleCreditPurchase } from '@/lib/apple-iap/use-apple-credit-purchase'; -import { useThemeColors } from '@/lib/hooks/use-theme-colors'; -import { type AppleCreditDisplayProduct } from '@/lib/apple-iap/types'; -import { - formatAppleCreditAmount, - getAppleCreditProductButtonText, -} from '@/components/apple-credit-purchase-utils'; - -type AppleCreditPurchaseSheetProps = { - visible: boolean; - onClose: () => void; - onPurchaseSuccess: () => void; -}; - -export function AppleCreditPurchaseSheet({ - visible, - onClose, - onPurchaseSuccess, -}: Readonly) { - const colors = useThemeColors(); - const { products, isLoading, isError, refetch } = useAppleCreditProducts(); - const { purchaseProduct, recoverUnfinishedPurchases, isPending } = useAppleCreditPurchase(); - const [activeProductId, setActiveProductId] = useState(null); - const [purchaseError, setPurchaseError] = useState(null); - const [isRecovering, setIsRecovering] = useState(false); - const [recoveryProductIdsKey, setRecoveryProductIdsKey] = useState(null); - const recoveryRunRef = useRef(0); - const productIds = useMemo(() => products.map(product => product.id), [products]); - const productIdsKey = productIds.join('\u0000'); - - useEffect(() => { - if (!visible) { - setRecoveryProductIdsKey(null); - recoveryRunRef.current += 1; - return undefined; - } - if ( - isLoading || - isError || - productIds.length === 0 || - recoveryProductIdsKey === productIdsKey - ) { - return undefined; - } - - const recoveryRunId = recoveryRunRef.current + 1; - recoveryRunRef.current = recoveryRunId; - const isCurrentRecoveryRun = () => recoveryRunRef.current === recoveryRunId; - setRecoveryProductIdsKey(productIdsKey); - setIsRecovering(true); - setPurchaseError(null); - - void (async () => { - try { - const recoveredPurchases = await recoverUnfinishedPurchases(productIds); - if (isCurrentRecoveryRun() && recoveredPurchases.length > 0) { - toast.success('Previous purchase completed'); - onPurchaseSuccess(); - } - } catch (error) { - if (isCurrentRecoveryRun()) { - setPurchaseError( - error instanceof Error ? error.message : 'Failed to complete previous purchase.' - ); - } - } finally { - if (isCurrentRecoveryRun()) { - setIsRecovering(false); - } - } - })(); - - return () => { - recoveryRunRef.current += 1; - }; - }, [ - isError, - isLoading, - onPurchaseSuccess, - productIds, - productIdsKey, - recoverUnfinishedPurchases, - recoveryProductIdsKey, - visible, - ]); - - const handlePurchase = async (product: AppleCreditDisplayProduct) => { - setActiveProductId(product.id); - setPurchaseError(null); - try { - await purchaseProduct(product.id); - toast.success(`${formatAppleCreditAmount(product.creditedCents)} added`); - onPurchaseSuccess(); - onClose(); - } catch (error) { - setPurchaseError(error instanceof Error ? error.message : 'Purchase failed. Try again.'); - } finally { - setActiveProductId(null); - } - }; - - return ( - - - - { - event.stopPropagation(); - }} - > - - - - Buy Credits - - - - - {isLoading && ( - - - - )} - - {isError && ( - { - void refetch(); - }} - > - - Failed to load products. Tap to retry. - - - )} - - {!isLoading && !isError && ( - - {products.map(product => { - const isActive = activeProductId === product.id; - return ( - - ); - })} - {products.length === 0 && ( - - Credit packs are unavailable. - - )} - - )} - - {purchaseError && ( - - {purchaseError} - - )} - - - - ); -} diff --git a/apps/mobile/src/components/apple-credit-purchase-utils.ts b/apps/mobile/src/components/apple-credit-purchase-utils.ts deleted file mode 100644 index bfafe2d0c8..0000000000 --- a/apps/mobile/src/components/apple-credit-purchase-utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { type AppleCreditDisplayProduct } from '@/lib/apple-iap/types'; - -export function formatAppleCreditAmount(creditedCents: number): string { - return `$${(creditedCents / 100).toFixed(2)} credits`; -} - -export function getAppleCreditProductButtonText(product: AppleCreditDisplayProduct): string { - return `${formatAppleCreditAmount(product.creditedCents)} - Pay ${product.localizedPrice}`; -} - -export function shouldShowAppleCreditPurchaseEntry(params: { - platform: string; - selectedOrgId: string | undefined; -}): boolean { - return params.platform === 'ios' && params.selectedOrgId === undefined; -} diff --git a/apps/mobile/src/components/profile-credits-card.tsx b/apps/mobile/src/components/profile-credits-card.tsx index ce87947352..a0e475a2eb 100644 --- a/apps/mobile/src/components/profile-credits-card.tsx +++ b/apps/mobile/src/components/profile-credits-card.tsx @@ -1,14 +1,10 @@ import { useActionSheet } from '@expo/react-native-action-sheet'; import { keepPreviousData, useQuery } from '@tanstack/react-query'; -import { ChevronDown, ShoppingBag } from 'lucide-react-native'; -import { useState } from 'react'; -import { ActivityIndicator, Platform, Pressable, View } from 'react-native'; +import { ChevronDown } from 'lucide-react-native'; +import { ActivityIndicator, Pressable, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'; -import { AppleCreditPurchaseSheet } from '@/components/apple-credit-purchase-sheet'; -import { shouldShowAppleCreditPurchaseEntry } from '@/components/apple-credit-purchase-utils'; -import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { Text } from '@/components/ui/text'; import { useThemeColors } from '@/lib/hooks/use-theme-colors'; @@ -27,7 +23,6 @@ export function CreditsCard({ orgs }: Readonly) { const { bottom } = useSafeAreaInsets(); const { organizationId, setOrganizationId } = useOrganization(); const selectedOrgId = organizationId ?? undefined; - const [purchaseSheetVisible, setPurchaseSheetVisible] = useState(false); const { data: balance, @@ -68,10 +63,6 @@ export function CreditsCard({ orgs }: Readonly) { : 'Personal'; const hasOrgs = orgs && orgs.length > 0; - const showAppleCreditPurchase = shouldShowAppleCreditPurchaseEntry({ - platform: Platform.OS, - selectedOrgId, - }); const openPicker = () => { if (!orgs || orgs.length === 0) { @@ -155,31 +146,6 @@ export function CreditsCard({ orgs }: Readonly) { {balanceFetching && } )} - - {showAppleCreditPurchase && ( - - )} - - { - setPurchaseSheetVisible(false); - }} - onPurchaseSuccess={() => { - void refetchBalance(); - }} - /> ); } diff --git a/apps/mobile/src/lib/apple-iap/storekit.test.ts b/apps/mobile/src/lib/apple-iap/storekit.test.ts deleted file mode 100644 index 5389780696..0000000000 --- a/apps/mobile/src/lib/apple-iap/storekit.test.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { - finishTransaction, - getAvailablePurchases, - initConnection, - type Purchase, - type PurchaseError, - purchaseErrorListener, - purchaseUpdatedListener, - requestPurchase, -} from 'expo-iap'; - -import { - finishStoreKitTransaction, - getUnfinishedStoreKitPurchases, - purchaseStoreKitProduct, - STOREKIT_PURCHASE_TIMEOUT_MS, -} from './storekit'; - -const listenerState = vi.hoisted(() => ({ - onPurchase: null as ((purchase: Purchase) => void) | null, - onPurchaseError: null as ((error: PurchaseError) => void) | null, - purchaseErrorRemove: vi.fn(), - purchaseRemove: vi.fn(), -})); - -function makePurchase(overrides: Partial = {}): Purchase { - return { - id: 'transaction-id', - isAutoRenewing: false, - platform: 'ios', - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseState: 'purchased', - purchaseToken: 'signed-transaction-jws', - quantity: 1, - store: 'apple', - transactionDate: Date.now(), - ...overrides, - }; -} - -vi.mock('expo-iap', () => ({ - finishTransaction: vi.fn(), - getAvailablePurchases: vi.fn(), - initConnection: vi.fn(), - purchaseErrorListener: vi.fn((listener: (error: PurchaseError) => void) => { - listenerState.onPurchaseError = listener; - return { remove: listenerState.purchaseErrorRemove }; - }), - purchaseUpdatedListener: vi.fn((listener: (purchase: Purchase) => void) => { - listenerState.onPurchase = listener; - return { remove: listenerState.purchaseRemove }; - }), - requestPurchase: vi.fn(), -})); - -beforeEach(() => { - vi.useRealTimers(); - listenerState.onPurchase = null; - listenerState.onPurchaseError = null; - listenerState.purchaseErrorRemove.mockClear(); - listenerState.purchaseRemove.mockClear(); - vi.clearAllMocks(); - vi.mocked(initConnection).mockResolvedValue(true); - vi.mocked(requestPurchase).mockResolvedValue( - makePurchase({ - productId: 'ignored-return-value', - purchaseToken: 'ignored-token', - }) - ); - vi.mocked(finishTransaction).mockResolvedValue(undefined); - vi.mocked(getAvailablePurchases).mockResolvedValue([]); -}); - -describe('purchaseStoreKitProduct', () => { - it('resolves from purchaseUpdatedListener instead of requestPurchase return value', async () => { - const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); - await Promise.resolve(); - - expect(vi.mocked(purchaseUpdatedListener).mock.invocationCallOrder[0]).toBeLessThan( - vi.mocked(requestPurchase).mock.invocationCallOrder[0] ?? 0 - ); - expect(vi.mocked(purchaseErrorListener).mock.invocationCallOrder[0]).toBeLessThan( - vi.mocked(requestPurchase).mock.invocationCallOrder[0] ?? 0 - ); - expect(requestPurchase).toHaveBeenCalledWith({ - request: { apple: { sku: 'com.kilocode.kiloapp.credits.small.999' } }, - type: 'in-app', - }); - - listenerState.onPurchase?.( - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseToken: 'listener-signed-transaction', - }) - ); - - await expect(purchasePromise).resolves.toMatchObject({ - productId: 'com.kilocode.kiloapp.credits.small.999', - transactionJws: 'listener-signed-transaction', - }); - expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); - expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); - }); - - it('ignores purchaseUpdatedListener events for other products', async () => { - const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); - await Promise.resolve(); - - listenerState.onPurchase?.( - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.large.4999', - purchaseToken: 'wrong-product-token', - }) - ); - listenerState.onPurchase?.( - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseToken: 'right-product-token', - }) - ); - - await expect(purchasePromise).resolves.toMatchObject({ - transactionJws: 'right-product-token', - }); - }); - - it('rejects when the matching purchase is missing a signed transaction JWS', async () => { - const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); - await Promise.resolve(); - - listenerState.onPurchase?.( - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseToken: null, - }) - ); - - await expect(purchasePromise).rejects.toThrow( - 'StoreKit purchase did not include a signed transaction JWS' - ); - }); - - it('rejects when purchaseErrorListener receives an error', async () => { - const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); - await Promise.resolve(); - - listenerState.onPurchaseError?.({ - code: 'user-cancelled' as PurchaseError['code'], - message: 'User cancelled purchase', - productId: 'com.kilocode.kiloapp.credits.small.999', - }); - - await expect(purchasePromise).rejects.toThrow('User cancelled purchase'); - expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); - expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); - }); - - it('rejects if StoreKit never emits a purchase event', async () => { - vi.useFakeTimers(); - const purchasePromise = purchaseStoreKitProduct('com.kilocode.kiloapp.credits.small.999'); - await Promise.resolve(); - const rejection = expect(purchasePromise).rejects.toThrow('StoreKit purchase timed out'); - - await vi.advanceTimersByTimeAsync(STOREKIT_PURCHASE_TIMEOUT_MS); - - await rejection; - expect(listenerState.purchaseRemove).toHaveBeenCalledTimes(1); - expect(listenerState.purchaseErrorRemove).toHaveBeenCalledTimes(1); - }); -}); - -describe('finishStoreKitTransaction', () => { - it('finishes credit pack transactions as consumable', async () => { - const purchase = makePurchase(); - - await finishStoreKitTransaction(purchase); - - expect(finishTransaction).toHaveBeenCalledWith({ - purchase, - isConsumable: true, - }); - }); -}); - -describe('getUnfinishedStoreKitPurchases', () => { - it('returns unfinished purchases for requested products with signed transaction JWS values', async () => { - vi.mocked(getAvailablePurchases).mockResolvedValue([ - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseToken: 'small-pending-transaction', - }), - makePurchase({ - productId: 'com.kilocode.kiloapp.credits.large.4999', - purchaseToken: 'large-pending-transaction', - }), - ]); - - const purchases = await getUnfinishedStoreKitPurchases([ - 'com.kilocode.kiloapp.credits.small.999', - ]); - - expect(getAvailablePurchases).toHaveBeenCalledWith({ - alsoPublishToEventListenerIOS: false, - onlyIncludeActiveItemsIOS: false, - }); - expect(purchases).toEqual([ - { - productId: 'com.kilocode.kiloapp.credits.small.999', - transactionJws: 'small-pending-transaction', - nativeTransaction: expect.objectContaining({ - productId: 'com.kilocode.kiloapp.credits.small.999', - }), - }, - ]); - }); -}); diff --git a/apps/mobile/src/lib/apple-iap/storekit.ts b/apps/mobile/src/lib/apple-iap/storekit.ts deleted file mode 100644 index b8b4eb25ee..0000000000 --- a/apps/mobile/src/lib/apple-iap/storekit.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { - fetchProducts, - finishTransaction, - getAvailablePurchases, - initConnection, - type Purchase, - purchaseErrorListener, - purchaseUpdatedListener, - requestPurchase, -} from 'expo-iap'; - -export const STOREKIT_PURCHASE_TIMEOUT_MS = 2 * 60_000; - -export type StoreKitProduct = { - id: string; - title: string; - localizedPrice: string; -}; - -export type StoreKitPurchaseResult = { - productId: string; - transactionJws: string; - nativeTransaction: Purchase; -}; - -export async function fetchStoreKitProducts(productIds: string[]): Promise { - await initConnection(); - const products = await fetchProducts({ skus: productIds, type: 'in-app' }); - return (products ?? []).map(product => ({ - id: product.id, - title: product.title, - localizedPrice: product.displayPrice, - })); -} - -function purchaseErrorToError(error: { message?: string | null }): Error { - return new Error(error.message ?? 'StoreKit purchase failed'); -} - -function toStoreKitPurchaseResult(productId: string, purchase: Purchase): StoreKitPurchaseResult { - if (purchase.productId !== productId) { - throw new Error(`StoreKit returned transaction for unexpected product ${purchase.productId}`); - } - const transactionJws = purchase.purchaseToken; - if (!transactionJws) { - throw new Error('StoreKit purchase did not include a signed transaction JWS'); - } - return { productId, transactionJws, nativeTransaction: purchase }; -} - -export async function purchaseStoreKitProduct(productId: string): Promise { - await initConnection(); - - return new Promise((resolve, reject) => { - let settled = false; - let timeout: ReturnType | null = null; - let purchaseSubscription: { remove: () => void } | null = null; - let errorSubscription: { remove: () => void } | null = null; - - const cleanup = () => { - purchaseSubscription?.remove(); - errorSubscription?.remove(); - if (timeout) { - clearTimeout(timeout); - } - }; - - const rejectOnce = (error: unknown) => { - if (settled) { - return; - } - settled = true; - cleanup(); - reject(error instanceof Error ? error : new Error('StoreKit purchase failed')); - }; - - const resolveOnce = (purchase: Purchase) => { - if (settled) { - return; - } - try { - const result = toStoreKitPurchaseResult(productId, purchase); - settled = true; - cleanup(); - resolve(result); - } catch (error) { - rejectOnce(error); - } - }; - - timeout = setTimeout(() => { - rejectOnce(new Error('StoreKit purchase timed out')); - }, STOREKIT_PURCHASE_TIMEOUT_MS); - - purchaseSubscription = purchaseUpdatedListener(purchase => { - if (purchase.productId !== productId) { - return; - } - resolveOnce(purchase); - }); - - // Native purchase errors are delivered through expo-iap's event callback. - // eslint-disable-next-line promise/prefer-await-to-callbacks - errorSubscription = purchaseErrorListener(error => { - if (error.productId && error.productId !== productId) { - return; - } - rejectOnce(purchaseErrorToError(error)); - }); - - void (async () => { - try { - await requestPurchase({ - request: { apple: { sku: productId } }, - type: 'in-app', - }); - } catch (error) { - rejectOnce(error); - } - })(); - }); -} - -export async function getUnfinishedStoreKitPurchases( - productIds: string[] -): Promise { - await initConnection(); - const productIdSet = new Set(productIds); - const purchases = await getAvailablePurchases({ - alsoPublishToEventListenerIOS: false, - onlyIncludeActiveItemsIOS: false, - }); - - return purchases.flatMap(purchase => { - if (!productIdSet.has(purchase.productId)) { - return []; - } - return [toStoreKitPurchaseResult(purchase.productId, purchase)]; - }); -} - -export async function finishStoreKitTransaction(nativeTransaction: Purchase): Promise { - await finishTransaction({ purchase: nativeTransaction, isConsumable: true }); -} diff --git a/apps/mobile/src/lib/apple-iap/types.ts b/apps/mobile/src/lib/apple-iap/types.ts deleted file mode 100644 index a74506a38c..0000000000 --- a/apps/mobile/src/lib/apple-iap/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -export type AppleCreditProductTier = 'small' | 'medium' | 'large'; - -export type BackendAppleCreditProduct = { - id: string; - tier: AppleCreditProductTier; - creditedCents: number; - creditedMicrodollars: number; -}; - -export type AppleCreditDisplayProduct = BackendAppleCreditProduct & { - localizedPrice: string; - title: string; -}; diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts deleted file mode 100644 index 76a085ad72..0000000000 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-products.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import { Platform } from 'react-native'; - -import { useTRPC } from '@/lib/trpc'; -import { fetchStoreKitProducts } from './storekit'; -import { type AppleCreditDisplayProduct, type BackendAppleCreditProduct } from './types'; - -export function joinAppleCreditProducts( - backendProducts: BackendAppleCreditProduct[] | undefined, - storeKitProducts: { id: string; title: string; localizedPrice: string }[] | undefined -): AppleCreditDisplayProduct[] { - const storeKitById = new Map((storeKitProducts ?? []).map(product => [product.id, product])); - return (backendProducts ?? []).flatMap(product => { - const storeKitProduct = storeKitById.get(product.id); - if (!storeKitProduct) { - return []; - } - return [ - { - ...product, - title: storeKitProduct.title, - localizedPrice: storeKitProduct.localizedPrice, - }, - ]; - }); -} - -export function useAppleCreditProducts() { - const trpc = useTRPC(); - const isIos = Platform.OS === 'ios'; - - const backendProducts = useQuery( - trpc.user.getAppleCreditProducts.queryOptions(undefined, { - enabled: isIos, - staleTime: 5 * 60_000, - }) - ); - const productIds = backendProducts.data?.products.map(product => product.id) ?? []; - - const storeKitProducts = useQuery({ - queryKey: ['apple-credit-storekit-products', productIds], - queryFn: async () => { - const products = await fetchStoreKitProducts(productIds); - return products; - }, - enabled: isIos && productIds.length > 0, - staleTime: 5 * 60_000, - }); - - return { - products: isIos - ? joinAppleCreditProducts(backendProducts.data?.products, storeKitProducts.data) - : [], - isLoading: isIos && (backendProducts.isLoading || storeKitProducts.isLoading), - isFetching: isIos && (backendProducts.isFetching || storeKitProducts.isFetching), - isError: isIos && (backendProducts.isError || storeKitProducts.isError), - refetch: async () => { - await backendProducts.refetch(); - await storeKitProducts.refetch(); - }, - }; -} diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx deleted file mode 100644 index 4d5ff7403c..0000000000 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.test.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; - -import { useAppleCreditProducts } from './use-apple-credit-products'; -import { useAppleCreditPurchase } from './use-apple-credit-purchase'; -import { - finishStoreKitTransaction, - getUnfinishedStoreKitPurchases, - purchaseStoreKitProduct, -} from './storekit'; - -const testState = vi.hoisted(() => ({ - backendProducts: [ - { - id: 'com.kilocode.kiloapp.credits.small.999', - tier: 'small' as const, - creditedCents: 699, - creditedMicrodollars: 6_990_000, - }, - ], - invalidations: [] as unknown[], - mutationInputs: [] as unknown[], - mutationResult: { - creditedCents: 699, - creditedMicrodollars: 6_990_000, - alreadyProcessed: false, - }, - mutationShouldReject: false, - platform: 'ios', - storeKitProducts: [ - { - id: 'com.kilocode.kiloapp.credits.small.999', - title: 'Small Credit Pack', - localizedPrice: '$9.99', - }, - ], -})); - -const mocks = vi.hoisted(() => ({ - finishStoreKitTransaction: vi.fn(), - fetchStoreKitProducts: vi.fn(), - getUnfinishedStoreKitPurchases: vi.fn(), - purchaseStoreKitProduct: vi.fn(), -})); - -vi.mock('react-native', () => ({ - Platform: { - get OS() { - return testState.platform; - }, - }, -})); - -vi.mock('./storekit', () => mocks); - -vi.mock('@tanstack/react-query', () => ({ - useMutation: () => ({ - error: null, - isPending: false, - mutateAsync: async (input: unknown) => { - testState.mutationInputs.push(input); - if (testState.mutationShouldReject) { - await Promise.resolve(); - throw new Error('Backend rejected purchase'); - } - const result = await Promise.resolve(testState.mutationResult); - return result; - }, - }), - useQuery: (options: { queryKey?: unknown[] }) => { - const isStoreKitQuery = options.queryKey?.[0] === 'apple-credit-storekit-products'; - return { - data: isStoreKitQuery ? testState.storeKitProducts : { products: testState.backendProducts }, - isError: false, - isFetching: false, - isLoading: false, - refetch: vi.fn(), - }; - }, - useQueryClient: () => ({ - invalidateQueries: async (filter: unknown) => { - testState.invalidations.push(filter); - await Promise.resolve(); - }, - }), -})); - -vi.mock('@/lib/trpc', () => ({ - useTRPC: () => ({ - user: { - completeAppleCreditPurchase: { - mutationOptions: () => ({}), - }, - getAppleCreditProducts: { - queryOptions: () => ({ queryKey: ['user', 'getAppleCreditProducts'] }), - }, - getContextBalance: { - pathFilter: () => ({ queryKey: ['user', 'getContextBalance'] }), - }, - getCreditBlocks: { - pathFilter: () => ({ queryKey: ['user', 'getCreditBlocks'] }), - }, - }, - }), -})); - -beforeEach(() => { - testState.invalidations = []; - testState.mutationInputs = []; - testState.mutationShouldReject = false; - testState.mutationResult = { - creditedCents: 699, - creditedMicrodollars: 6_990_000, - alreadyProcessed: false, - }; - testState.platform = 'ios'; - vi.clearAllMocks(); - mocks.fetchStoreKitProducts.mockResolvedValue(testState.storeKitProducts); - mocks.getUnfinishedStoreKitPurchases.mockResolvedValue([]); - mocks.purchaseStoreKitProduct.mockResolvedValue({ - productId: 'com.kilocode.kiloapp.credits.small.999', - transactionJws: 'signed-transaction', - nativeTransaction: { id: 'native-transaction' }, - }); - mocks.finishStoreKitTransaction.mockResolvedValue(undefined); -}); - -describe('useAppleCreditProducts', () => { - it('returns no products outside iOS', () => { - testState.platform = 'android'; - - expect(useAppleCreditProducts().products).toEqual([]); - }); -}); - -describe('useAppleCreditPurchase', () => { - it('finishes the StoreKit transaction after backend success', async () => { - const result = await useAppleCreditPurchase().purchaseProduct( - 'com.kilocode.kiloapp.credits.small.999' - ); - - expect(result.alreadyProcessed).toBe(false); - expect(purchaseStoreKitProduct).toHaveBeenCalledWith('com.kilocode.kiloapp.credits.small.999'); - expect(testState.invalidations).toEqual([ - { queryKey: ['user', 'getContextBalance'] }, - { queryKey: ['user', 'getCreditBlocks'] }, - ]); - expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'native-transaction' }); - }); - - it('finishes the StoreKit transaction after already-processed backend success', async () => { - testState.mutationResult = { - creditedCents: 699, - creditedMicrodollars: 6_990_000, - alreadyProcessed: true, - }; - - const result = await useAppleCreditPurchase().purchaseProduct( - 'com.kilocode.kiloapp.credits.small.999' - ); - - expect(result.alreadyProcessed).toBe(true); - expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'native-transaction' }); - }); - - it('does not finish the StoreKit transaction when backend completion fails', async () => { - testState.mutationShouldReject = true; - - await expect( - useAppleCreditPurchase().purchaseProduct('com.kilocode.kiloapp.credits.small.999') - ).rejects.toThrow('Backend rejected purchase'); - - expect(finishStoreKitTransaction).not.toHaveBeenCalled(); - }); - - it('completes and finishes recovered unfinished StoreKit purchases', async () => { - mocks.getUnfinishedStoreKitPurchases.mockResolvedValue([ - { - productId: 'com.kilocode.kiloapp.credits.small.999', - transactionJws: 'pending-signed-transaction', - nativeTransaction: { id: 'pending-native-transaction' }, - }, - ]); - - const results = await useAppleCreditPurchase().recoverUnfinishedPurchases([ - 'com.kilocode.kiloapp.credits.small.999', - ]); - - expect(getUnfinishedStoreKitPurchases).toHaveBeenCalledWith([ - 'com.kilocode.kiloapp.credits.small.999', - ]); - expect(testState.mutationInputs).toEqual([{ transactionJws: 'pending-signed-transaction' }]); - expect(results).toEqual([ - { - creditedCents: 699, - creditedMicrodollars: 6_990_000, - alreadyProcessed: false, - }, - ]); - expect(finishStoreKitTransaction).toHaveBeenCalledWith({ id: 'pending-native-transaction' }); - }); -}); diff --git a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts b/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts deleted file mode 100644 index 73c3c50000..0000000000 --- a/apps/mobile/src/lib/apple-iap/use-apple-credit-purchase.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query'; - -import { useTRPC } from '@/lib/trpc'; -import { - finishStoreKitTransaction, - getUnfinishedStoreKitPurchases, - purchaseStoreKitProduct, - type StoreKitPurchaseResult, -} from './storekit'; - -export function useAppleCreditPurchase() { - const trpc = useTRPC(); - const queryClient = useQueryClient(); - const completeAppleCreditPurchase = useMutation( - trpc.user.completeAppleCreditPurchase.mutationOptions() - ); - - const completePurchase = async (purchase: StoreKitPurchaseResult) => { - const result = await completeAppleCreditPurchase.mutateAsync({ - transactionJws: purchase.transactionJws, - }); - await queryClient.invalidateQueries(trpc.user.getContextBalance.pathFilter()); - await queryClient.invalidateQueries(trpc.user.getCreditBlocks.pathFilter()); - await finishStoreKitTransaction(purchase.nativeTransaction); - return result; - }; - - const purchaseProduct = async (productId: string) => { - const purchase = await purchaseStoreKitProduct(productId); - return completePurchase(purchase); - }; - - const recoverUnfinishedPurchases = async (productIds: string[]) => { - const purchases = await getUnfinishedStoreKitPurchases(productIds); - const completionPromises = []; - for (const purchase of purchases) { - completionPromises.push(completePurchase(purchase)); - } - return Promise.all(completionPromises); - }; - - return { - isPending: completeAppleCreditPurchase.isPending, - error: completeAppleCreditPurchase.error, - purchaseProduct, - recoverUnfinishedPurchases, - }; -} diff --git a/apps/web/src/app/api/apple/iap/notifications/route.test.ts b/apps/web/src/app/api/apple/iap/notifications/route.test.ts deleted file mode 100644 index 6932880421..0000000000 --- a/apps/web/src/app/api/apple/iap/notifications/route.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { POST } from './route'; - -describe('Apple IAP notification route', () => { - it('rejects missing signedPayload', async () => { - const response = await POST( - new Request('https://kilo.test/api/apple/iap/notifications', { - method: 'POST', - body: JSON.stringify({}), - }) - ); - - await expect(response.text()).resolves.toBe('Missing signedPayload'); - expect(response.status).toBe(400); - }); -}); diff --git a/apps/web/src/app/api/apple/iap/notifications/route.ts b/apps/web/src/app/api/apple/iap/notifications/route.ts deleted file mode 100644 index ae33de5f43..0000000000 --- a/apps/web/src/app/api/apple/iap/notifications/route.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { NextResponse } from 'next/server'; -import { captureException } from '@sentry/nextjs'; -import { z } from 'zod'; -import { processAppleIapNotification } from '@/lib/apple-iap/notifications'; - -const AppleIapNotificationRequestSchema = z.object({ - signedPayload: z.string().min(1), -}); - -export async function POST(req: Request): Promise> { - let body: unknown; - try { - body = await req.json(); - } catch { - return new NextResponse('Invalid JSON', { status: 400 }); - } - - const parsedBody = AppleIapNotificationRequestSchema.safeParse(body); - if (!parsedBody.success) { - return new NextResponse('Missing signedPayload', { status: 400 }); - } - - try { - await processAppleIapNotification({ signedPayload: parsedBody.data.signedPayload }); - return new NextResponse('OK', { status: 200 }); - } catch (error) { - captureException(error, { tags: { source: 'apple_iap_notification' } }); - return new NextResponse('Apple notification processing failed', { status: 400 }); - } -} diff --git a/apps/web/src/lib/apple-iap/notifications.test.ts b/apps/web/src/lib/apple-iap/notifications.test.ts deleted file mode 100644 index 14ff871fa4..0000000000 --- a/apps/web/src/lib/apple-iap/notifications.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { db } from '@/lib/drizzle'; -import { processAppleCreditPurchase } from './purchases'; -import { processAppleIapNotification } from './notifications'; -import { insertTestUser } from '@/tests/helpers/user.helper'; -import { apple_iap_notifications, credit_transactions, kilocode_users } from '@kilocode/db/schema'; -import { eq } from 'drizzle-orm'; - -const transaction = { - transactionId: 'apple-notification-txn-1', - originalTransactionId: 'apple-notification-original-1', - bundleId: 'com.kilocode.kiloapp', - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseDate: Date.UTC(2026, 0, 1), - environment: 'Sandbox' as const, -}; - -describe('processAppleIapNotification', () => { - it('records duplicate notification UUIDs idempotently', async () => { - const notification = { - notificationUUID: 'notification-duplicate-1', - notificationType: 'DID_RENEW', - data: { environment: 'Sandbox' as const }, - }; - - const first = await processAppleIapNotification({ - signedPayload: 'signed-notification', - verifyNotification: async () => notification, - }); - const second = await processAppleIapNotification({ - signedPayload: 'signed-notification', - verifyNotification: async () => notification, - }); - - expect(first).toEqual({ duplicate: false, reversed: false }); - expect(second).toEqual({ duplicate: true, reversed: false }); - }); - - it('reverses a refund notification once', async () => { - const user = await insertTestUser({ total_microdollars_acquired: 0 }); - await processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => transaction, - }); - - const result = await processAppleIapNotification({ - signedPayload: 'signed-refund-notification', - verifyNotification: async () => ({ - notificationUUID: 'notification-refund-1', - notificationType: 'REFUND', - data: { - environment: 'Sandbox', - signedTransactionInfo: 'signed-transaction', - }, - }), - verifyTransaction: async () => transaction, - }); - - expect(result).toEqual({ duplicate: false, reversed: true }); - - const updatedUser = await db.query.kilocode_users.findFirst({ - where: eq(kilocode_users.id, user.id), - }); - expect(updatedUser?.total_microdollars_acquired).toBe(0); - - const transactions = await db.query.credit_transactions.findMany({ - where: eq(credit_transactions.kilo_user_id, user.id), - }); - expect(transactions.map(t => t.amount_microdollars).sort((a, b) => a - b)).toEqual([ - -6_990_000, 6_990_000, - ]); - - const storedNotification = await db.query.apple_iap_notifications.findFirst({ - where: eq(apple_iap_notifications.notification_uuid, 'notification-refund-1'), - }); - expect(storedNotification?.processed_at).toBeTruthy(); - }); -}); diff --git a/apps/web/src/lib/apple-iap/notifications.ts b/apps/web/src/lib/apple-iap/notifications.ts deleted file mode 100644 index b1943dea1c..0000000000 --- a/apps/web/src/lib/apple-iap/notifications.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { apple_iap_notifications } from '@kilocode/db/schema'; -import { db } from '@/lib/drizzle'; -import { eq } from 'drizzle-orm'; -import { verifyAppleNotificationJws, verifyAppleTransactionJws } from './verifier'; -import { reverseAppleCreditPurchase } from './purchases'; -import type { AppleDecodedNotification, AppleDecodedTransaction } from './types'; - -const REVERSAL_NOTIFICATION_TYPES = new Set(['REFUND', 'REVOKE', 'CONSUMPTION_REQUEST']); - -export async function processAppleIapNotification(params: { - signedPayload: string; - verifyNotification?: (signedPayload: string) => Promise; - verifyTransaction?: (transactionJws: string) => Promise; -}): Promise<{ duplicate: boolean; reversed: boolean }> { - const verifyNotification = params.verifyNotification ?? verifyAppleNotificationJws; - const verifyTransaction = params.verifyTransaction ?? verifyAppleTransactionJws; - const notification = await verifyNotification(params.signedPayload); - const signedTransactionInfo = notification.data?.signedTransactionInfo; - const transaction = signedTransactionInfo ? await verifyTransaction(signedTransactionInfo) : null; - - const insert = await db - .insert(apple_iap_notifications) - .values({ - notification_uuid: notification.notificationUUID, - notification_type: notification.notificationType, - subtype: notification.subtype ?? null, - environment: notification.data?.environment ?? transaction?.environment ?? 'Sandbox', - apple_transaction_id: transaction?.transactionId ?? null, - apple_original_transaction_id: transaction?.originalTransactionId ?? null, - signed_payload_jws: params.signedPayload, - }) - .onConflictDoNothing(); - - if ((insert.rowCount ?? 0) === 0) { - return { duplicate: true, reversed: false }; - } - - let reversed = false; - if (transaction && REVERSAL_NOTIFICATION_TYPES.has(notification.notificationType)) { - const result = await reverseAppleCreditPurchase({ - appleTransactionId: transaction.transactionId, - reversalReason: notification.notificationType === 'REFUND' ? 'refunded' : 'revoked', - }); - reversed = result.reversed; - } - - await db - .update(apple_iap_notifications) - .set({ processed_at: new Date().toISOString() }) - .where(eq(apple_iap_notifications.notification_uuid, notification.notificationUUID)); - - return { duplicate: false, reversed }; -} diff --git a/apps/web/src/lib/apple-iap/products.test.ts b/apps/web/src/lib/apple-iap/products.test.ts deleted file mode 100644 index 2a4c332f40..0000000000 --- a/apps/web/src/lib/apple-iap/products.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { APPLE_IAP_CREDIT_PRODUCTS, getEnabledAppleCreditProducts } from './products'; - -describe('Apple IAP products', () => { - it('defines the three v1 products with credited amounts', () => { - expect(APPLE_IAP_CREDIT_PRODUCTS).toEqual([ - { - id: 'com.kilocode.kiloapp.credits.small.999', - tier: 'small', - grossPriceCents: 999, - creditedCents: 699, - creditedMicrodollars: 6_990_000, - enabled: true, - }, - { - id: 'com.kilocode.kiloapp.credits.medium.1999', - tier: 'medium', - grossPriceCents: 1999, - creditedCents: 1399, - creditedMicrodollars: 13_990_000, - enabled: true, - }, - { - id: 'com.kilocode.kiloapp.credits.large.4999', - tier: 'large', - grossPriceCents: 4999, - creditedCents: 3499, - creditedMicrodollars: 34_990_000, - enabled: true, - }, - ]); - }); - - it('returns only enabled products for clients', () => { - expect(getEnabledAppleCreditProducts()).toEqual( - APPLE_IAP_CREDIT_PRODUCTS.map(product => ({ - id: product.id, - tier: product.tier, - creditedCents: product.creditedCents, - creditedMicrodollars: product.creditedMicrodollars, - })) - ); - }); -}); diff --git a/apps/web/src/lib/apple-iap/products.ts b/apps/web/src/lib/apple-iap/products.ts deleted file mode 100644 index 4d2e2166b8..0000000000 --- a/apps/web/src/lib/apple-iap/products.ts +++ /dev/null @@ -1,50 +0,0 @@ -export type AppleCreditProductTier = 'small' | 'medium' | 'large'; - -export type AppleCreditProduct = { - id: string; - tier: AppleCreditProductTier; - grossPriceCents: number; - creditedCents: number; - creditedMicrodollars: number; - enabled: boolean; -}; - -export const APPLE_IAP_CREDIT_PRODUCTS = [ - { - id: 'com.kilocode.kiloapp.credits.small.999', - tier: 'small', - grossPriceCents: 999, - creditedCents: 699, - creditedMicrodollars: 6_990_000, - enabled: true, - }, - { - id: 'com.kilocode.kiloapp.credits.medium.1999', - tier: 'medium', - grossPriceCents: 1999, - creditedCents: 1399, - creditedMicrodollars: 13_990_000, - enabled: true, - }, - { - id: 'com.kilocode.kiloapp.credits.large.4999', - tier: 'large', - grossPriceCents: 4999, - creditedCents: 3499, - creditedMicrodollars: 34_990_000, - enabled: true, - }, -] as const satisfies readonly AppleCreditProduct[]; - -export function getAppleCreditProduct(productId: string): AppleCreditProduct | null { - return APPLE_IAP_CREDIT_PRODUCTS.find(product => product.id === productId) ?? null; -} - -export function getEnabledAppleCreditProducts() { - return APPLE_IAP_CREDIT_PRODUCTS.filter(product => product.enabled).map(product => ({ - id: product.id, - tier: product.tier, - creditedCents: product.creditedCents, - creditedMicrodollars: product.creditedMicrodollars, - })); -} diff --git a/apps/web/src/lib/apple-iap/purchases.test.ts b/apps/web/src/lib/apple-iap/purchases.test.ts deleted file mode 100644 index 0b0c1e3d35..0000000000 --- a/apps/web/src/lib/apple-iap/purchases.test.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { db } from '@/lib/drizzle'; -import { processAppleCreditPurchase, reverseAppleCreditPurchase } from './purchases'; -import { apple_iap_purchases, credit_transactions, kilocode_users } from '@kilocode/db/schema'; -import { insertTestUser } from '@/tests/helpers/user.helper'; -import { eq } from 'drizzle-orm'; - -function makeTransaction(transactionId: string) { - return { - ...baseTransaction, - transactionId, - originalTransactionId: `${transactionId}-original`, - }; -} - -const baseTransaction = { - transactionId: 'apple-txn-base', - originalTransactionId: 'apple-original-1', - bundleId: 'com.kilocode.kiloapp', - productId: 'com.kilocode.kiloapp.credits.small.999', - purchaseDate: Date.UTC(2026, 0, 1), - environment: 'Sandbox' as const, - appAccountToken: undefined, -}; - -describe('processAppleCreditPurchase', () => { - it('grants configured credits for a valid purchase', async () => { - const user = await insertTestUser({ total_microdollars_acquired: 0 }); - - const result = await processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-grant'), - }); - - expect(result).toEqual({ - creditedCents: 699, - creditedMicrodollars: 6_990_000, - alreadyProcessed: false, - }); - - const updatedUser = await db.query.kilocode_users.findFirst({ - where: eq(kilocode_users.id, user.id), - }); - expect(updatedUser?.total_microdollars_acquired).toBe(6_990_000); - - const purchase = await db.query.apple_iap_purchases.findFirst({ - where: eq(apple_iap_purchases.apple_transaction_id, 'apple-txn-grant'), - }); - expect(purchase?.credit_transaction_id).toBeTruthy(); - }); - - it('does not double grant duplicate submissions by the owning user', async () => { - const user = await insertTestUser({ total_microdollars_acquired: 0 }); - - await processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-duplicate-owner'), - }); - const replay = await processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-duplicate-owner'), - }); - - expect(replay.alreadyProcessed).toBe(true); - - const updatedUser = await db.query.kilocode_users.findFirst({ - where: eq(kilocode_users.id, user.id), - }); - expect(updatedUser?.total_microdollars_acquired).toBe(6_990_000); - }); - - it('rejects duplicate transaction submitted by a different user', async () => { - const owner = await insertTestUser(); - const attacker = await insertTestUser(); - - await processAppleCreditPurchase({ - user: owner, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-duplicate-other-user'), - }); - - await expect( - processAppleCreditPurchase({ - user: attacker, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-duplicate-other-user'), - }) - ).rejects.toThrow('Apple transaction already belongs to another user'); - }); - - it('rejects unknown product IDs', async () => { - const user = await insertTestUser(); - - await expect( - processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => ({ ...baseTransaction, productId: 'unknown' }), - }) - ).rejects.toThrow('Apple product is not enabled'); - }); - - it('rejects wrong bundle IDs', async () => { - const user = await insertTestUser(); - - await expect( - processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => ({ ...baseTransaction, bundleId: 'com.example.other' }), - }) - ).rejects.toThrow('Apple transaction bundle mismatch'); - }); - - it('rejects revoked transactions at completion time', async () => { - const user = await insertTestUser(); - - await expect( - processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => ({ ...baseTransaction, revocationDate: Date.now() }), - }) - ).rejects.toThrow('Apple transaction has been revoked'); - }); - - it('reverses refunds and allows negative balance', async () => { - const user = await insertTestUser({ - total_microdollars_acquired: 0, - microdollars_used: 1_000_000, - }); - - await processAppleCreditPurchase({ - user, - transactionJws: 'signed-transaction', - verifyTransaction: async () => makeTransaction('apple-txn-refund'), - }); - await reverseAppleCreditPurchase({ - appleTransactionId: 'apple-txn-refund', - reversalReason: 'refunded', - }); - - const updatedUser = await db.query.kilocode_users.findFirst({ - where: eq(kilocode_users.id, user.id), - }); - expect(updatedUser?.total_microdollars_acquired).toBe(0); - expect( - (updatedUser?.total_microdollars_acquired ?? 0) - (updatedUser?.microdollars_used ?? 0) - ).toBe(-1_000_000); - - const transactions = await db.query.credit_transactions.findMany({ - where: eq(credit_transactions.kilo_user_id, user.id), - }); - expect(transactions.map(t => t.amount_microdollars).sort((a, b) => a - b)).toEqual([ - -6_990_000, 6_990_000, - ]); - }); -}); diff --git a/apps/web/src/lib/apple-iap/purchases.ts b/apps/web/src/lib/apple-iap/purchases.ts deleted file mode 100644 index 2a2f5c5265..0000000000 --- a/apps/web/src/lib/apple-iap/purchases.ts +++ /dev/null @@ -1,147 +0,0 @@ -import type { User } from '@kilocode/db/schema'; -import { apple_iap_purchases, credit_transactions, kilocode_users } from '@kilocode/db/schema'; -import { db, type DrizzleTransaction } from '@/lib/drizzle'; -import { eq, sql } from 'drizzle-orm'; -import { getAppleCreditProduct } from './products'; -import type { AppleDecodedTransaction } from './types'; -import { verifyAppleTransactionJws } from './verifier'; - -const EXPECTED_BUNDLE_ID = 'com.kilocode.kiloapp'; - -type ProcessAppleCreditPurchaseParams = { - user: User; - transactionJws: string; - verifyTransaction?: (transactionJws: string) => Promise; -}; - -export type ProcessAppleCreditPurchaseResult = { - creditedCents: number; - creditedMicrodollars: number; - alreadyProcessed: boolean; -}; - -function assertValidTransaction(transaction: AppleDecodedTransaction) { - if (transaction.bundleId !== EXPECTED_BUNDLE_ID) { - throw new Error('Apple transaction bundle mismatch'); - } - if (transaction.revocationDate) { - throw new Error('Apple transaction has been revoked'); - } - const product = getAppleCreditProduct(transaction.productId); - if (!product || !product.enabled) { - throw new Error('Apple product is not enabled'); - } - return product; -} - -export async function processAppleCreditPurchase({ - user, - transactionJws, - verifyTransaction = verifyAppleTransactionJws, -}: ProcessAppleCreditPurchaseParams): Promise { - const transaction = await verifyTransaction(transactionJws); - const product = assertValidTransaction(transaction); - - return db.transaction(async tx => { - const existing = await tx.query.apple_iap_purchases.findFirst({ - where: eq(apple_iap_purchases.apple_transaction_id, transaction.transactionId), - }); - - if (existing) { - if (existing.kilo_user_id !== user.id) { - throw new Error('Apple transaction already belongs to another user'); - } - return { - creditedCents: existing.credited_cents, - creditedMicrodollars: existing.credited_microdollars, - alreadyProcessed: true, - }; - } - - const creditTransactionId = crypto.randomUUID(); - await tx.insert(credit_transactions).values({ - id: creditTransactionId, - kilo_user_id: user.id, - is_free: false, - amount_microdollars: product.creditedMicrodollars, - description: 'Top-up via Apple', - original_baseline_microdollars_used: user.microdollars_used, - }); - - await tx.insert(apple_iap_purchases).values({ - kilo_user_id: user.id, - apple_transaction_id: transaction.transactionId, - apple_original_transaction_id: transaction.originalTransactionId, - apple_web_order_line_item_id: transaction.webOrderLineItemId ?? null, - product_id: transaction.productId, - environment: transaction.environment, - bundle_id: transaction.bundleId, - purchase_date: new Date(transaction.purchaseDate).toISOString(), - gross_price_cents: product.grossPriceCents, - credited_cents: product.creditedCents, - credited_microdollars: product.creditedMicrodollars, - signed_transaction_jws: transactionJws, - status: 'granted', - credit_transaction_id: creditTransactionId, - }); - - await incrementUserAcquiredCredits(tx, user.id, product.creditedMicrodollars); - - return { - creditedCents: product.creditedCents, - creditedMicrodollars: product.creditedMicrodollars, - alreadyProcessed: false, - }; - }); -} - -async function incrementUserAcquiredCredits( - tx: DrizzleTransaction, - userId: string, - amountMicrodollars: number -) { - const result = await tx - .update(kilocode_users) - .set({ - total_microdollars_acquired: sql`${kilocode_users.total_microdollars_acquired} + ${amountMicrodollars}`, - }) - .where(eq(kilocode_users.id, userId)); - if ((result.rowCount ?? 0) === 0) { - throw new Error(`Failed to update Apple IAP credit balance for user ${userId}`); - } -} - -export async function reverseAppleCreditPurchase(params: { - appleTransactionId: string; - reversalReason: 'refunded' | 'revoked'; -}): Promise<{ reversed: boolean }> { - return db.transaction(async tx => { - const purchase = await tx.query.apple_iap_purchases.findFirst({ - where: eq(apple_iap_purchases.apple_transaction_id, params.appleTransactionId), - }); - if (!purchase) return { reversed: false }; - if (purchase.refund_credit_transaction_id) return { reversed: false }; - - const refundCreditTransactionId = crypto.randomUUID(); - await tx.insert(credit_transactions).values({ - id: refundCreditTransactionId, - kilo_user_id: purchase.kilo_user_id, - is_free: false, - amount_microdollars: -purchase.credited_microdollars, - description: `Apple top-up ${params.reversalReason}`, - original_transaction_id: purchase.credit_transaction_id, - }); - - await tx - .update(apple_iap_purchases) - .set({ - status: params.reversalReason === 'refunded' ? 'refunded' : 'revoked', - refunded_at: new Date().toISOString(), - refund_credit_transaction_id: refundCreditTransactionId, - }) - .where(eq(apple_iap_purchases.id, purchase.id)); - - await incrementUserAcquiredCredits(tx, purchase.kilo_user_id, -purchase.credited_microdollars); - return { reversed: true }; - }); -} diff --git a/apps/web/src/lib/apple-iap/types.ts b/apps/web/src/lib/apple-iap/types.ts deleted file mode 100644 index 69540f1ae8..0000000000 --- a/apps/web/src/lib/apple-iap/types.ts +++ /dev/null @@ -1,24 +0,0 @@ -export type AppleIapEnvironment = 'Sandbox' | 'Production'; - -export type AppleDecodedTransaction = { - transactionId: string; - originalTransactionId: string; - webOrderLineItemId?: string; - bundleId: string; - productId: string; - purchaseDate: number; - revocationDate?: number; - appAccountToken?: string; - environment: AppleIapEnvironment; - type?: string; -}; - -export type AppleDecodedNotification = { - notificationUUID: string; - notificationType: string; - subtype?: string; - data?: { - environment?: AppleIapEnvironment; - signedTransactionInfo?: string; - }; -}; diff --git a/apps/web/src/lib/apple-iap/verifier.ts b/apps/web/src/lib/apple-iap/verifier.ts deleted file mode 100644 index a7d06e8a76..0000000000 --- a/apps/web/src/lib/apple-iap/verifier.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { - Environment, - SignedDataVerifier, - type JWSTransactionDecodedPayload, - type ResponseBodyV2DecodedPayload, -} from '@apple/app-store-server-library'; -import { getEnvVariable } from '@/lib/dotenvx'; -import type { - AppleDecodedNotification, - AppleDecodedTransaction, - AppleIapEnvironment, -} from './types'; - -const BUNDLE_ID = 'com.kilocode.kiloapp'; - -function requiredEnv(name: string): string { - const value = getEnvVariable(name); - if (!value) throw new Error(`${name} is not set`); - return value; -} - -function getAppleEnvironment(): Environment { - return requiredEnv('APPLE_IAP_ENVIRONMENT') === 'Production' - ? Environment.PRODUCTION - : Environment.SANDBOX; -} - -function getAppleAppAppleId(): number | undefined { - const value = getEnvVariable('APPLE_APP_APPLE_ID'); - return value ? Number(value) : undefined; -} - -function getAppleRootCertificates(): Buffer[] { - const pemBundle = requiredEnv('APPLE_ROOT_CERTIFICATES_PEM'); - return pemBundle - .split('-----END CERTIFICATE-----') - .map(part => part.trim()) - .filter(Boolean) - .map(part => Buffer.from(`${part}\n-----END CERTIFICATE-----\n`)); -} - -function createVerifier(): SignedDataVerifier { - return new SignedDataVerifier( - getAppleRootCertificates(), - true, - getAppleEnvironment(), - BUNDLE_ID, - getAppleAppAppleId() - ); -} - -function normalizeEnvironment(environment: string | undefined): AppleIapEnvironment { - if (environment === 'Production') return 'Production'; - return 'Sandbox'; -} - -export async function verifyAppleTransactionJws( - transactionJws: string -): Promise { - const decoded = (await createVerifier().verifyAndDecodeTransaction( - transactionJws - )) as JWSTransactionDecodedPayload; - - if (!decoded.transactionId || !decoded.originalTransactionId || !decoded.bundleId) { - throw new Error('Apple transaction payload missing required identifiers'); - } - if (!decoded.productId || !decoded.purchaseDate) { - throw new Error('Apple transaction payload missing purchase fields'); - } - - return { - transactionId: decoded.transactionId, - originalTransactionId: decoded.originalTransactionId, - webOrderLineItemId: decoded.webOrderLineItemId, - bundleId: decoded.bundleId, - productId: decoded.productId, - purchaseDate: decoded.purchaseDate, - revocationDate: decoded.revocationDate, - appAccountToken: decoded.appAccountToken, - environment: normalizeEnvironment(decoded.environment), - type: decoded.type, - }; -} - -export async function verifyAppleNotificationJws( - signedPayload: string -): Promise { - const decoded = (await createVerifier().verifyAndDecodeNotification( - signedPayload - )) as ResponseBodyV2DecodedPayload; - - if (!decoded.notificationUUID || !decoded.notificationType) { - throw new Error('Apple notification payload missing required identifiers'); - } - - return { - notificationUUID: decoded.notificationUUID, - notificationType: decoded.notificationType, - subtype: decoded.subtype, - data: decoded.data - ? { - environment: normalizeEnvironment(decoded.data.environment), - signedTransactionInfo: decoded.data.signedTransactionInfo, - } - : undefined, - }; -} diff --git a/apps/web/src/routers/user-router.test.ts b/apps/web/src/routers/user-router.test.ts index 94734b8487..5585567d49 100644 --- a/apps/web/src/routers/user-router.test.ts +++ b/apps/web/src/routers/user-router.test.ts @@ -274,36 +274,6 @@ describe('user router - submitCustomerSource', () => { }); }); -describe('user router - Apple IAP credits', () => { - it('returns enabled Apple credit products', async () => { - const user = await insertTestUser(); - const caller = await createCallerForUser(user.id); - - await expect(caller.user.getAppleCreditProducts()).resolves.toEqual({ - products: [ - { - id: 'com.kilocode.kiloapp.credits.small.999', - tier: 'small', - creditedCents: 699, - creditedMicrodollars: 6_990_000, - }, - { - id: 'com.kilocode.kiloapp.credits.medium.1999', - tier: 'medium', - creditedCents: 1399, - creditedMicrodollars: 13_990_000, - }, - { - id: 'com.kilocode.kiloapp.credits.large.4999', - tier: 'large', - creditedCents: 3499, - creditedMicrodollars: 34_990_000, - }, - ], - }); - }); -}); - describe('user router - skipCustomerSource', () => { beforeAll(async () => { skipTestUser = await insertTestUser({ diff --git a/apps/web/src/routers/user-router.ts b/apps/web/src/routers/user-router.ts index 300157ee5c..f6eb3ba0d6 100644 --- a/apps/web/src/routers/user-router.ts +++ b/apps/web/src/routers/user-router.ts @@ -38,8 +38,6 @@ import { getCreditBlocks } from '@/lib/getCreditBlocks'; import { getBalanceForUser } from '@/lib/user.balance'; import { getBalanceAndOrgSettings } from '@/lib/organizations/organization-usage'; import { revokeWebSessions } from '@/lib/web-session-revocation'; -import { getEnabledAppleCreditProducts } from '@/lib/apple-iap/products'; -import { processAppleCreditPurchase } from '@/lib/apple-iap/purchases'; const ACCOUNT_DELETION_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour @@ -356,19 +354,6 @@ export const userRouter = createTRPCRouter({ return { balance, isDepleted: balance <= 0 }; }), - getAppleCreditProducts: baseProcedure.query(() => { - return { products: getEnabledAppleCreditProducts() }; - }), - - completeAppleCreditPurchase: baseProcedure - .input(z.object({ transactionJws: z.string().min(1) })) - .mutation(async ({ ctx, input }) => { - return processAppleCreditPurchase({ - user: ctx.user, - transactionJws: input.transactionJws, - }); - }), - getAutocompleteMetrics: baseProcedure .input(AutocompleteMetricsInputSchema) .output(AutocompleteMetricsOutputSchema) diff --git a/packages/db/src/migrations/0115_amazing_scrambler.sql b/packages/db/src/migrations/0115_amazing_scrambler.sql deleted file mode 100644 index 5d33103df6..0000000000 --- a/packages/db/src/migrations/0115_amazing_scrambler.sql +++ /dev/null @@ -1,50 +0,0 @@ -CREATE TABLE "apple_iap_notifications" ( - "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, - "notification_uuid" text NOT NULL, - "notification_type" text NOT NULL, - "subtype" text, - "environment" text NOT NULL, - "apple_transaction_id" text, - "apple_original_transaction_id" text, - "signed_payload_jws" text NOT NULL, - "processed_at" timestamp with time zone, - "created_at" timestamp with time zone DEFAULT now() NOT NULL, - CONSTRAINT "apple_iap_notifications_environment_check" CHECK ("apple_iap_notifications"."environment" IN ('Sandbox', 'Production')) -); ---> statement-breakpoint -CREATE TABLE "apple_iap_purchases" ( - "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, - "kilo_user_id" text NOT NULL, - "apple_transaction_id" text NOT NULL, - "apple_original_transaction_id" text NOT NULL, - "apple_web_order_line_item_id" text, - "product_id" text NOT NULL, - "environment" text NOT NULL, - "bundle_id" text NOT NULL, - "purchase_date" timestamp with time zone NOT NULL, - "gross_price_cents" integer NOT NULL, - "credited_cents" integer NOT NULL, - "credited_microdollars" bigint NOT NULL, - "signed_transaction_jws" text NOT NULL, - "status" text NOT NULL, - "credit_transaction_id" uuid NOT NULL, - "refunded_at" timestamp with time zone, - "refund_credit_transaction_id" uuid, - "created_at" timestamp with time zone DEFAULT now() NOT NULL, - "updated_at" timestamp with time zone DEFAULT now() NOT NULL, - CONSTRAINT "apple_iap_purchases_status_check" CHECK ("apple_iap_purchases"."status" IN ('granted', 'refunded', 'revoked')), - CONSTRAINT "apple_iap_purchases_environment_check" CHECK ("apple_iap_purchases"."environment" IN ('Sandbox', 'Production')), - CONSTRAINT "apple_iap_purchases_credited_positive_check" CHECK ("apple_iap_purchases"."credited_cents" > 0) -); ---> statement-breakpoint -ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk" FOREIGN KEY ("kilo_user_id") REFERENCES "public"."kilocode_users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk" FOREIGN KEY ("credit_transaction_id") REFERENCES "public"."credit_transactions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "apple_iap_purchases" ADD CONSTRAINT "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk" FOREIGN KEY ("refund_credit_transaction_id") REFERENCES "public"."credit_transactions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -CREATE UNIQUE INDEX "UQ_apple_iap_notifications_uuid" ON "apple_iap_notifications" USING btree ("notification_uuid");--> statement-breakpoint -CREATE INDEX "IDX_apple_iap_notifications_transaction_id" ON "apple_iap_notifications" USING btree ("apple_transaction_id");--> statement-breakpoint -CREATE INDEX "IDX_apple_iap_notifications_original_transaction_id" ON "apple_iap_notifications" USING btree ("apple_original_transaction_id");--> statement-breakpoint -CREATE UNIQUE INDEX "UQ_apple_iap_purchases_transaction_id" ON "apple_iap_purchases" USING btree ("apple_transaction_id");--> statement-breakpoint -CREATE UNIQUE INDEX "UQ_apple_iap_purchases_credit_transaction_id" ON "apple_iap_purchases" USING btree ("credit_transaction_id");--> statement-breakpoint -CREATE UNIQUE INDEX "UQ_apple_iap_purchases_refund_credit_transaction_id" ON "apple_iap_purchases" USING btree ("refund_credit_transaction_id") WHERE "apple_iap_purchases"."refund_credit_transaction_id" is not null;--> statement-breakpoint -CREATE INDEX "IDX_apple_iap_purchases_user_id" ON "apple_iap_purchases" USING btree ("kilo_user_id");--> statement-breakpoint -CREATE INDEX "IDX_apple_iap_purchases_original_transaction_id" ON "apple_iap_purchases" USING btree ("apple_original_transaction_id"); \ No newline at end of file diff --git a/packages/db/src/migrations/meta/0115_snapshot.json b/packages/db/src/migrations/meta/0115_snapshot.json deleted file mode 100644 index 5407eb7de1..0000000000 --- a/packages/db/src/migrations/meta/0115_snapshot.json +++ /dev/null @@ -1,19144 +0,0 @@ -{ - "id": "41340d66-6132-4f01-b848-ea197b8dc15b", - "prevId": "cd0d7b9b-c7a1-41d2-a29e-b62696cba715", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.agent_configs": { - "name": "agent_configs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "agent_type": { - "name": "agent_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "config": { - "name": "config", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - }, - "is_enabled": { - "name": "is_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "runtime_state": { - "name": "runtime_state", - "type": "jsonb", - "primaryKey": false, - "notNull": false, - "default": "'{}'::jsonb" - }, - "created_by": { - "name": "created_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_agent_configs_org_id": { - "name": "IDX_agent_configs_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_agent_configs_owned_by_user_id": { - "name": "IDX_agent_configs_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_agent_configs_agent_type": { - "name": "IDX_agent_configs_agent_type", - "columns": [ - { - "expression": "agent_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_agent_configs_platform": { - "name": "IDX_agent_configs_platform", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "agent_configs_owned_by_organization_id_organizations_id_fk": { - "name": "agent_configs_owned_by_organization_id_organizations_id_fk", - "tableFrom": "agent_configs", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "agent_configs_owned_by_user_id_kilocode_users_id_fk": { - "name": "agent_configs_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "agent_configs", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_agent_configs_org_agent_platform": { - "name": "UQ_agent_configs_org_agent_platform", - "nullsNotDistinct": false, - "columns": [ - "owned_by_organization_id", - "agent_type", - "platform" - ] - }, - "UQ_agent_configs_user_agent_platform": { - "name": "UQ_agent_configs_user_agent_platform", - "nullsNotDistinct": false, - "columns": [ - "owned_by_user_id", - "agent_type", - "platform" - ] - } - }, - "policies": {}, - "checkConstraints": { - "agent_configs_owner_check": { - "name": "agent_configs_owner_check", - "value": "(\n (\"agent_configs\".\"owned_by_user_id\" IS NOT NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_configs\".\"owned_by_user_id\" IS NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "agent_configs_agent_type_check": { - "name": "agent_configs_agent_type_check", - "value": "\"agent_configs\".\"agent_type\" IN ('code_review', 'auto_triage', 'auto_fix', 'security_scan')" - } - }, - "isRLSEnabled": false - }, - "public.agent_environment_profile_commands": { - "name": "agent_environment_profile_commands", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "profile_id": { - "name": "profile_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "sequence": { - "name": "sequence", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "command": { - "name": "command", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_agent_env_profile_commands_profile_id": { - "name": "IDX_agent_env_profile_commands_profile_id", - "columns": [ - { - "expression": "profile_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk": { - "name": "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk", - "tableFrom": "agent_environment_profile_commands", - "tableTo": "agent_environment_profiles", - "columnsFrom": [ - "profile_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_agent_env_profile_commands_profile_sequence": { - "name": "UQ_agent_env_profile_commands_profile_sequence", - "nullsNotDistinct": false, - "columns": [ - "profile_id", - "sequence" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.agent_environment_profile_repo_bindings": { - "name": "agent_environment_profile_repo_bindings", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'github'" - }, - "profile_id": { - "name": "profile_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_agent_env_profile_repo_bindings_user": { - "name": "UQ_agent_env_profile_repo_bindings_user", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_agent_env_profile_repo_bindings_org": { - "name": "UQ_agent_env_profile_repo_bindings_org", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk": { - "name": "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk", - "tableFrom": "agent_environment_profile_repo_bindings", - "tableTo": "agent_environment_profiles", - "columnsFrom": [ - "profile_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk": { - "name": "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk", - "tableFrom": "agent_environment_profile_repo_bindings", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk": { - "name": "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "agent_environment_profile_repo_bindings", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "agent_env_profile_repo_bindings_owner_check": { - "name": "agent_env_profile_repo_bindings_owner_check", - "value": "(\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.agent_environment_profile_vars": { - "name": "agent_environment_profile_vars", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "profile_id": { - "name": "profile_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "is_secret": { - "name": "is_secret", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_agent_env_profile_vars_profile_id": { - "name": "IDX_agent_env_profile_vars_profile_id", - "columns": [ - { - "expression": "profile_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk": { - "name": "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk", - "tableFrom": "agent_environment_profile_vars", - "tableTo": "agent_environment_profiles", - "columnsFrom": [ - "profile_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_agent_env_profile_vars_profile_key": { - "name": "UQ_agent_env_profile_vars_profile_key", - "nullsNotDistinct": false, - "columns": [ - "profile_id", - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.agent_environment_profiles": { - "name": "agent_environment_profiles", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_default": { - "name": "is_default", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_agent_env_profiles_org_name": { - "name": "UQ_agent_env_profiles_org_name", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profiles\".\"owned_by_organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_agent_env_profiles_user_name": { - "name": "UQ_agent_env_profiles_user_name", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profiles\".\"owned_by_user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_agent_env_profiles_org_default": { - "name": "UQ_agent_env_profiles_org_default", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_agent_env_profiles_user_default": { - "name": "UQ_agent_env_profiles_user_default", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_agent_env_profiles_org_id": { - "name": "IDX_agent_env_profiles_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_agent_env_profiles_user_id": { - "name": "IDX_agent_env_profiles_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "agent_environment_profiles_owned_by_organization_id_organizations_id_fk": { - "name": "agent_environment_profiles_owned_by_organization_id_organizations_id_fk", - "tableFrom": "agent_environment_profiles", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk": { - "name": "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "agent_environment_profiles", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "agent_env_profiles_owner_check": { - "name": "agent_env_profiles_owner_check", - "value": "(\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.api_kind": { - "name": "api_kind", - "schema": "", - "columns": { - "api_kind_id": { - "name": "api_kind_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "api_kind": { - "name": "api_kind", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_api_kind": { - "name": "UQ_api_kind", - "columns": [ - { - "expression": "api_kind", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.api_request_log": { - "name": "api_request_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "bigserial", - "primaryKey": true, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status_code": { - "name": "status_code", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "request": { - "name": "request", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "response": { - "name": "response", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "error": { - "name": "error", - "type": "jsonb", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_api_request_log_created_at": { - "name": "idx_api_request_log_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app_builder_feedback": { - "name": "app_builder_feedback", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "project_id": { - "name": "project_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "preview_status": { - "name": "preview_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_streaming": { - "name": "is_streaming", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "message_count": { - "name": "message_count", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "feedback_text": { - "name": "feedback_text", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "recent_messages": { - "name": "recent_messages", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_app_builder_feedback_created_at": { - "name": "IDX_app_builder_feedback_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_feedback_kilo_user_id": { - "name": "IDX_app_builder_feedback_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_feedback_project_id": { - "name": "IDX_app_builder_feedback_project_id", - "columns": [ - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "app_builder_feedback_kilo_user_id_kilocode_users_id_fk": { - "name": "app_builder_feedback_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "app_builder_feedback", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - }, - "app_builder_feedback_project_id_app_builder_projects_id_fk": { - "name": "app_builder_feedback_project_id_app_builder_projects_id_fk", - "tableFrom": "app_builder_feedback", - "tableTo": "app_builder_projects", - "columnsFrom": [ - "project_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app_builder_project_sessions": { - "name": "app_builder_project_sessions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "project_id": { - "name": "project_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "ended_at": { - "name": "ended_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "reason": { - "name": "reason", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "worker_version": { - "name": "worker_version", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'v2'" - } - }, - "indexes": { - "IDX_app_builder_project_sessions_project_id": { - "name": "IDX_app_builder_project_sessions_project_id", - "columns": [ - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "app_builder_project_sessions_project_id_app_builder_projects_id_fk": { - "name": "app_builder_project_sessions_project_id_app_builder_projects_id_fk", - "tableFrom": "app_builder_project_sessions", - "tableTo": "app_builder_projects", - "columnsFrom": [ - "project_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_app_builder_project_sessions_cloud_agent_session_id": { - "name": "UQ_app_builder_project_sessions_cloud_agent_session_id", - "nullsNotDistinct": false, - "columns": [ - "cloud_agent_session_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app_builder_projects": { - "name": "app_builder_projects", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "created_by_user_id": { - "name": "created_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model_id": { - "name": "model_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "template": { - "name": "template", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "deployment_id": { - "name": "deployment_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "last_message_at": { - "name": "last_message_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "git_repo_full_name": { - "name": "git_repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "git_platform_integration_id": { - "name": "git_platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "migrated_at": { - "name": "migrated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_app_builder_projects_created_by_user_id": { - "name": "IDX_app_builder_projects_created_by_user_id", - "columns": [ - { - "expression": "created_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_projects_owned_by_user_id": { - "name": "IDX_app_builder_projects_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_projects_owned_by_organization_id": { - "name": "IDX_app_builder_projects_owned_by_organization_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_projects_created_at": { - "name": "IDX_app_builder_projects_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_app_builder_projects_last_message_at": { - "name": "IDX_app_builder_projects_last_message_at", - "columns": [ - { - "expression": "last_message_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "app_builder_projects_owned_by_user_id_kilocode_users_id_fk": { - "name": "app_builder_projects_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "app_builder_projects", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "app_builder_projects_owned_by_organization_id_organizations_id_fk": { - "name": "app_builder_projects_owned_by_organization_id_organizations_id_fk", - "tableFrom": "app_builder_projects", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "app_builder_projects_deployment_id_deployments_id_fk": { - "name": "app_builder_projects_deployment_id_deployments_id_fk", - "tableFrom": "app_builder_projects", - "tableTo": "deployments", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk": { - "name": "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "app_builder_projects", - "tableTo": "platform_integrations", - "columnsFrom": [ - "git_platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "app_builder_projects_owner_check": { - "name": "app_builder_projects_owner_check", - "value": "(\n (\"app_builder_projects\".\"owned_by_user_id\" IS NOT NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NULL) OR\n (\"app_builder_projects\".\"owned_by_user_id\" IS NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.app_min_versions": { - "name": "app_min_versions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "ios_min_version": { - "name": "ios_min_version", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'1.0.0'" - }, - "android_min_version": { - "name": "android_min_version", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'1.0.0'" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app_reported_messages": { - "name": "app_reported_messages", - "schema": "", - "columns": { - "report_id": { - "name": "report_id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "report_type": { - "name": "report_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "signature": { - "name": "signature", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "message": { - "name": "message", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "cli_session_id": { - "name": "cli_session_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "mode": { - "name": "mode", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "app_reported_messages_cli_session_id_cli_sessions_session_id_fk": { - "name": "app_reported_messages_cli_session_id_cli_sessions_session_id_fk", - "tableFrom": "app_reported_messages", - "tableTo": "cli_sessions", - "columnsFrom": [ - "cli_session_id" - ], - "columnsTo": [ - "session_id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.apple_iap_notifications": { - "name": "apple_iap_notifications", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "notification_uuid": { - "name": "notification_uuid", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "notification_type": { - "name": "notification_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subtype": { - "name": "subtype", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "environment": { - "name": "environment", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "apple_transaction_id": { - "name": "apple_transaction_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "apple_original_transaction_id": { - "name": "apple_original_transaction_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "signed_payload_jws": { - "name": "signed_payload_jws", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "processed_at": { - "name": "processed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_apple_iap_notifications_uuid": { - "name": "UQ_apple_iap_notifications_uuid", - "columns": [ - { - "expression": "notification_uuid", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_apple_iap_notifications_transaction_id": { - "name": "IDX_apple_iap_notifications_transaction_id", - "columns": [ - { - "expression": "apple_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_apple_iap_notifications_original_transaction_id": { - "name": "IDX_apple_iap_notifications_original_transaction_id", - "columns": [ - { - "expression": "apple_original_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "apple_iap_notifications_environment_check": { - "name": "apple_iap_notifications_environment_check", - "value": "\"apple_iap_notifications\".\"environment\" IN ('Sandbox', 'Production')" - } - }, - "isRLSEnabled": false - }, - "public.apple_iap_purchases": { - "name": "apple_iap_purchases", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "apple_transaction_id": { - "name": "apple_transaction_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "apple_original_transaction_id": { - "name": "apple_original_transaction_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "apple_web_order_line_item_id": { - "name": "apple_web_order_line_item_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "product_id": { - "name": "product_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "environment": { - "name": "environment", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "bundle_id": { - "name": "bundle_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "purchase_date": { - "name": "purchase_date", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "gross_price_cents": { - "name": "gross_price_cents", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "credited_cents": { - "name": "credited_cents", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "credited_microdollars": { - "name": "credited_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "signed_transaction_jws": { - "name": "signed_transaction_jws", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "credit_transaction_id": { - "name": "credit_transaction_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "refunded_at": { - "name": "refunded_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "refund_credit_transaction_id": { - "name": "refund_credit_transaction_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_apple_iap_purchases_transaction_id": { - "name": "UQ_apple_iap_purchases_transaction_id", - "columns": [ - { - "expression": "apple_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_apple_iap_purchases_credit_transaction_id": { - "name": "UQ_apple_iap_purchases_credit_transaction_id", - "columns": [ - { - "expression": "credit_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_apple_iap_purchases_refund_credit_transaction_id": { - "name": "UQ_apple_iap_purchases_refund_credit_transaction_id", - "columns": [ - { - "expression": "refund_credit_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"apple_iap_purchases\".\"refund_credit_transaction_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_apple_iap_purchases_user_id": { - "name": "IDX_apple_iap_purchases_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_apple_iap_purchases_original_transaction_id": { - "name": "IDX_apple_iap_purchases_original_transaction_id", - "columns": [ - { - "expression": "apple_original_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk": { - "name": "apple_iap_purchases_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "apple_iap_purchases", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk": { - "name": "apple_iap_purchases_credit_transaction_id_credit_transactions_id_fk", - "tableFrom": "apple_iap_purchases", - "tableTo": "credit_transactions", - "columnsFrom": [ - "credit_transaction_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk": { - "name": "apple_iap_purchases_refund_credit_transaction_id_credit_transactions_id_fk", - "tableFrom": "apple_iap_purchases", - "tableTo": "credit_transactions", - "columnsFrom": [ - "refund_credit_transaction_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "apple_iap_purchases_status_check": { - "name": "apple_iap_purchases_status_check", - "value": "\"apple_iap_purchases\".\"status\" IN ('granted', 'refunded', 'revoked')" - }, - "apple_iap_purchases_environment_check": { - "name": "apple_iap_purchases_environment_check", - "value": "\"apple_iap_purchases\".\"environment\" IN ('Sandbox', 'Production')" - }, - "apple_iap_purchases_credited_positive_check": { - "name": "apple_iap_purchases_credited_positive_check", - "value": "\"apple_iap_purchases\".\"credited_cents\" > 0" - } - }, - "isRLSEnabled": false - }, - "public.auto_fix_tickets": { - "name": "auto_fix_tickets", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "triage_ticket_id": { - "name": "triage_ticket_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'github'" - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_number": { - "name": "issue_number", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "issue_url": { - "name": "issue_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_title": { - "name": "issue_title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_body": { - "name": "issue_body", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "issue_author": { - "name": "issue_author", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_labels": { - "name": "issue_labels", - "type": "text[]", - "primaryKey": false, - "notNull": false, - "default": "'{}'" - }, - "trigger_source": { - "name": "trigger_source", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'label'" - }, - "review_comment_id": { - "name": "review_comment_id", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "review_comment_body": { - "name": "review_comment_body", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "file_path": { - "name": "file_path", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "line_number": { - "name": "line_number", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "diff_hunk": { - "name": "diff_hunk", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "pr_head_ref": { - "name": "pr_head_ref", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "classification": { - "name": "classification", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "confidence": { - "name": "confidence", - "type": "numeric(3, 2)", - "primaryKey": false, - "notNull": false - }, - "intent_summary": { - "name": "intent_summary", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "related_files": { - "name": "related_files", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cli_session_id": { - "name": "cli_session_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "pr_number": { - "name": "pr_number", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "pr_url": { - "name": "pr_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "pr_branch": { - "name": "pr_branch", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_auto_fix_tickets_repo_issue": { - "name": "UQ_auto_fix_tickets_repo_issue", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "issue_number", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"auto_fix_tickets\".\"trigger_source\" = 'label'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_auto_fix_tickets_repo_review_comment": { - "name": "UQ_auto_fix_tickets_repo_review_comment", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "review_comment_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"auto_fix_tickets\".\"review_comment_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_owned_by_org": { - "name": "IDX_auto_fix_tickets_owned_by_org", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_owned_by_user": { - "name": "IDX_auto_fix_tickets_owned_by_user", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_status": { - "name": "IDX_auto_fix_tickets_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_created_at": { - "name": "IDX_auto_fix_tickets_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_triage_ticket_id": { - "name": "IDX_auto_fix_tickets_triage_ticket_id", - "columns": [ - { - "expression": "triage_ticket_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_fix_tickets_session_id": { - "name": "IDX_auto_fix_tickets_session_id", - "columns": [ - { - "expression": "session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auto_fix_tickets_owned_by_organization_id_organizations_id_fk": { - "name": "auto_fix_tickets_owned_by_organization_id_organizations_id_fk", - "tableFrom": "auto_fix_tickets", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk": { - "name": "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "auto_fix_tickets", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk": { - "name": "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "auto_fix_tickets", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk": { - "name": "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk", - "tableFrom": "auto_fix_tickets", - "tableTo": "auto_triage_tickets", - "columnsFrom": [ - "triage_ticket_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk": { - "name": "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk", - "tableFrom": "auto_fix_tickets", - "tableTo": "cli_sessions", - "columnsFrom": [ - "cli_session_id" - ], - "columnsTo": [ - "session_id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "auto_fix_tickets_owner_check": { - "name": "auto_fix_tickets_owner_check", - "value": "(\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "auto_fix_tickets_status_check": { - "name": "auto_fix_tickets_status_check", - "value": "\"auto_fix_tickets\".\"status\" IN ('pending', 'running', 'completed', 'failed', 'cancelled')" - }, - "auto_fix_tickets_classification_check": { - "name": "auto_fix_tickets_classification_check", - "value": "\"auto_fix_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'unclear')" - }, - "auto_fix_tickets_confidence_check": { - "name": "auto_fix_tickets_confidence_check", - "value": "\"auto_fix_tickets\".\"confidence\" >= 0 AND \"auto_fix_tickets\".\"confidence\" <= 1" - }, - "auto_fix_tickets_trigger_source_check": { - "name": "auto_fix_tickets_trigger_source_check", - "value": "\"auto_fix_tickets\".\"trigger_source\" IN ('label', 'review_comment')" - } - }, - "isRLSEnabled": false - }, - "public.auto_model": { - "name": "auto_model", - "schema": "", - "columns": { - "auto_model_id": { - "name": "auto_model_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "auto_model": { - "name": "auto_model", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_auto_model": { - "name": "UQ_auto_model", - "columns": [ - { - "expression": "auto_model", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auto_top_up_configs": { - "name": "auto_top_up_configs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "created_by_user_id": { - "name": "created_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "stripe_payment_method_id": { - "name": "stripe_payment_method_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "amount_cents": { - "name": "amount_cents", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 5000 - }, - "last_auto_top_up_at": { - "name": "last_auto_top_up_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "attempt_started_at": { - "name": "attempt_started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "disabled_reason": { - "name": "disabled_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_auto_top_up_configs_owned_by_user_id": { - "name": "UQ_auto_top_up_configs_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_auto_top_up_configs_owned_by_organization_id": { - "name": "UQ_auto_top_up_configs_owned_by_organization_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk": { - "name": "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "auto_top_up_configs", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "auto_top_up_configs_owned_by_organization_id_organizations_id_fk": { - "name": "auto_top_up_configs_owned_by_organization_id_organizations_id_fk", - "tableFrom": "auto_top_up_configs", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "auto_top_up_configs_exactly_one_owner": { - "name": "auto_top_up_configs_exactly_one_owner", - "value": "(\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NULL) OR (\"auto_top_up_configs\".\"owned_by_user_id\" IS NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL)" - } - }, - "isRLSEnabled": false - }, - "public.auto_triage_tickets": { - "name": "auto_triage_tickets", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'github'" - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_number": { - "name": "issue_number", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "issue_url": { - "name": "issue_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_title": { - "name": "issue_title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_body": { - "name": "issue_body", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "issue_author": { - "name": "issue_author", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_type": { - "name": "issue_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "issue_labels": { - "name": "issue_labels", - "type": "text[]", - "primaryKey": false, - "notNull": false, - "default": "'{}'" - }, - "classification": { - "name": "classification", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "confidence": { - "name": "confidence", - "type": "numeric(3, 2)", - "primaryKey": false, - "notNull": false - }, - "intent_summary": { - "name": "intent_summary", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "related_files": { - "name": "related_files", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "is_duplicate": { - "name": "is_duplicate", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "duplicate_of_ticket_id": { - "name": "duplicate_of_ticket_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "similarity_score": { - "name": "similarity_score", - "type": "numeric(3, 2)", - "primaryKey": false, - "notNull": false - }, - "qdrant_point_id": { - "name": "qdrant_point_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "should_auto_fix": { - "name": "should_auto_fix", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "action_taken": { - "name": "action_taken", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "action_metadata": { - "name": "action_metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_auto_triage_tickets_repo_issue": { - "name": "UQ_auto_triage_tickets_repo_issue", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "issue_number", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_owned_by_org": { - "name": "IDX_auto_triage_tickets_owned_by_org", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_owned_by_user": { - "name": "IDX_auto_triage_tickets_owned_by_user", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_status": { - "name": "IDX_auto_triage_tickets_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_created_at": { - "name": "IDX_auto_triage_tickets_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_qdrant_point_id": { - "name": "IDX_auto_triage_tickets_qdrant_point_id", - "columns": [ - { - "expression": "qdrant_point_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_owner_status_created": { - "name": "IDX_auto_triage_tickets_owner_status_created", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_user_status_created": { - "name": "IDX_auto_triage_tickets_user_status_created", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_auto_triage_tickets_repo_classification": { - "name": "IDX_auto_triage_tickets_repo_classification", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "classification", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auto_triage_tickets_owned_by_organization_id_organizations_id_fk": { - "name": "auto_triage_tickets_owned_by_organization_id_organizations_id_fk", - "tableFrom": "auto_triage_tickets", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk": { - "name": "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "auto_triage_tickets", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk": { - "name": "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "auto_triage_tickets", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk": { - "name": "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk", - "tableFrom": "auto_triage_tickets", - "tableTo": "auto_triage_tickets", - "columnsFrom": [ - "duplicate_of_ticket_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "auto_triage_tickets_owner_check": { - "name": "auto_triage_tickets_owner_check", - "value": "(\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "auto_triage_tickets_issue_type_check": { - "name": "auto_triage_tickets_issue_type_check", - "value": "\"auto_triage_tickets\".\"issue_type\" IN ('issue', 'pull_request')" - }, - "auto_triage_tickets_classification_check": { - "name": "auto_triage_tickets_classification_check", - "value": "\"auto_triage_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'duplicate', 'unclear')" - }, - "auto_triage_tickets_confidence_check": { - "name": "auto_triage_tickets_confidence_check", - "value": "\"auto_triage_tickets\".\"confidence\" >= 0 AND \"auto_triage_tickets\".\"confidence\" <= 1" - }, - "auto_triage_tickets_similarity_score_check": { - "name": "auto_triage_tickets_similarity_score_check", - "value": "\"auto_triage_tickets\".\"similarity_score\" >= 0 AND \"auto_triage_tickets\".\"similarity_score\" <= 1" - }, - "auto_triage_tickets_status_check": { - "name": "auto_triage_tickets_status_check", - "value": "\"auto_triage_tickets\".\"status\" IN ('pending', 'analyzing', 'actioned', 'failed', 'skipped')" - }, - "auto_triage_tickets_action_taken_check": { - "name": "auto_triage_tickets_action_taken_check", - "value": "\"auto_triage_tickets\".\"action_taken\" IN ('pr_created', 'comment_posted', 'closed_duplicate', 'needs_clarification')" - } - }, - "isRLSEnabled": false - }, - "public.bot_request_cloud_agent_sessions": { - "name": "bot_request_cloud_agent_sessions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "bot_request_id": { - "name": "bot_request_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "spawn_group_id": { - "name": "spawn_group_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kilo_session_id": { - "name": "kilo_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "execution_id": { - "name": "execution_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'running'" - }, - "mode": { - "name": "mode", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "github_repo": { - "name": "github_repo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "gitlab_project": { - "name": "gitlab_project", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "callback_step": { - "name": "callback_step", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "final_message": { - "name": "final_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "final_message_fetched_at": { - "name": "final_message_fetched_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "final_message_error": { - "name": "final_message_error", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "terminal_at": { - "name": "terminal_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "continuation_started_at": { - "name": "continuation_started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_bot_request_cas_cloud_agent_session_id": { - "name": "UQ_bot_request_cas_cloud_agent_session_id", - "columns": [ - { - "expression": "cloud_agent_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_request_cas_bot_request_id": { - "name": "IDX_bot_request_cas_bot_request_id", - "columns": [ - { - "expression": "bot_request_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_request_cas_bot_request_id_spawn_group_id": { - "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id", - "columns": [ - { - "expression": "bot_request_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "spawn_group_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_request_cas_bot_request_id_spawn_group_id_status": { - "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id_status", - "columns": [ - { - "expression": "bot_request_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "spawn_group_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk": { - "name": "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk", - "tableFrom": "bot_request_cloud_agent_sessions", - "tableTo": "bot_requests", - "columnsFrom": [ - "bot_request_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.bot_requests": { - "name": "bot_requests", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "created_by": { - "name": "created_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform_thread_id": { - "name": "platform_thread_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform_message_id": { - "name": "platform_message_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_message": { - "name": "user_message", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model_used": { - "name": "model_used", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "steps": { - "name": "steps", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "response_time_ms": { - "name": "response_time_ms", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_bot_requests_created_at": { - "name": "IDX_bot_requests_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_requests_created_by": { - "name": "IDX_bot_requests_created_by", - "columns": [ - { - "expression": "created_by", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_requests_organization_id": { - "name": "IDX_bot_requests_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_requests_platform_integration_id": { - "name": "IDX_bot_requests_platform_integration_id", - "columns": [ - { - "expression": "platform_integration_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_bot_requests_status": { - "name": "IDX_bot_requests_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "bot_requests_created_by_kilocode_users_id_fk": { - "name": "bot_requests_created_by_kilocode_users_id_fk", - "tableFrom": "bot_requests", - "tableTo": "kilocode_users", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "bot_requests_organization_id_organizations_id_fk": { - "name": "bot_requests_organization_id_organizations_id_fk", - "tableFrom": "bot_requests", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "bot_requests_platform_integration_id_platform_integrations_id_fk": { - "name": "bot_requests_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "bot_requests", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.byok_api_keys": { - "name": "byok_api_keys", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "provider_id": { - "name": "provider_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "encrypted_api_key": { - "name": "encrypted_api_key", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "is_enabled": { - "name": "is_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_by": { - "name": "created_by", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "IDX_byok_api_keys_organization_id": { - "name": "IDX_byok_api_keys_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_byok_api_keys_kilo_user_id": { - "name": "IDX_byok_api_keys_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_byok_api_keys_provider_id": { - "name": "IDX_byok_api_keys_provider_id", - "columns": [ - { - "expression": "provider_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "byok_api_keys_organization_id_organizations_id_fk": { - "name": "byok_api_keys_organization_id_organizations_id_fk", - "tableFrom": "byok_api_keys", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "byok_api_keys_kilo_user_id_kilocode_users_id_fk": { - "name": "byok_api_keys_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "byok_api_keys", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_byok_api_keys_org_provider": { - "name": "UQ_byok_api_keys_org_provider", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "provider_id" - ] - }, - "UQ_byok_api_keys_user_provider": { - "name": "UQ_byok_api_keys_user_provider", - "nullsNotDistinct": false, - "columns": [ - "kilo_user_id", - "provider_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "byok_api_keys_owner_check": { - "name": "byok_api_keys_owner_check", - "value": "(\n (\"byok_api_keys\".\"kilo_user_id\" IS NOT NULL AND \"byok_api_keys\".\"organization_id\" IS NULL) OR\n (\"byok_api_keys\".\"kilo_user_id\" IS NULL AND \"byok_api_keys\".\"organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.cli_sessions": { - "name": "cli_sessions", - "schema": "", - "columns": { - "session_id": { - "name": "session_id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_on_platform": { - "name": "created_on_platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'unknown'" - }, - "api_conversation_history_blob_url": { - "name": "api_conversation_history_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "task_metadata_blob_url": { - "name": "task_metadata_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ui_messages_blob_url": { - "name": "ui_messages_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "git_state_blob_url": { - "name": "git_state_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "git_url": { - "name": "git_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "forked_from": { - "name": "forked_from", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "parent_session_id": { - "name": "parent_session_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "last_mode": { - "name": "last_mode", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_model": { - "name": "last_model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "version": { - "name": "version", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_cli_sessions_kilo_user_id": { - "name": "IDX_cli_sessions_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_created_at": { - "name": "IDX_cli_sessions_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_updated_at": { - "name": "IDX_cli_sessions_updated_at", - "columns": [ - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_organization_id": { - "name": "IDX_cli_sessions_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_user_updated": { - "name": "IDX_cli_sessions_user_updated", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "cli_sessions_kilo_user_id_kilocode_users_id_fk": { - "name": "cli_sessions_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "cli_sessions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "restrict", - "onUpdate": "no action" - }, - "cli_sessions_forked_from_cli_sessions_session_id_fk": { - "name": "cli_sessions_forked_from_cli_sessions_session_id_fk", - "tableFrom": "cli_sessions", - "tableTo": "cli_sessions", - "columnsFrom": [ - "forked_from" - ], - "columnsTo": [ - "session_id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "cli_sessions_parent_session_id_cli_sessions_session_id_fk": { - "name": "cli_sessions_parent_session_id_cli_sessions_session_id_fk", - "tableFrom": "cli_sessions", - "tableTo": "cli_sessions", - "columnsFrom": [ - "parent_session_id" - ], - "columnsTo": [ - "session_id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "cli_sessions_organization_id_organizations_id_fk": { - "name": "cli_sessions_organization_id_organizations_id_fk", - "tableFrom": "cli_sessions", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "cli_sessions_cloud_agent_session_id_unique": { - "name": "cli_sessions_cloud_agent_session_id_unique", - "nullsNotDistinct": false, - "columns": [ - "cloud_agent_session_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.cli_sessions_v2": { - "name": "cli_sessions_v2", - "schema": "", - "columns": { - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "version": { - "name": "version", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "public_id": { - "name": "public_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "parent_session_id": { - "name": "parent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_on_platform": { - "name": "created_on_platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'unknown'" - }, - "git_url": { - "name": "git_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "git_branch": { - "name": "git_branch", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status_updated_at": { - "name": "status_updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_cli_sessions_v2_parent_session_id_kilo_user_id": { - "name": "IDX_cli_sessions_v2_parent_session_id_kilo_user_id", - "columns": [ - { - "expression": "parent_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_cli_sessions_v2_public_id": { - "name": "UQ_cli_sessions_v2_public_id", - "columns": [ - { - "expression": "public_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"cli_sessions_v2\".\"public_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_cli_sessions_v2_cloud_agent_session_id": { - "name": "UQ_cli_sessions_v2_cloud_agent_session_id", - "columns": [ - { - "expression": "cloud_agent_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"cli_sessions_v2\".\"cloud_agent_session_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_v2_organization_id": { - "name": "IDX_cli_sessions_v2_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_v2_kilo_user_id": { - "name": "IDX_cli_sessions_v2_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_v2_created_at": { - "name": "IDX_cli_sessions_v2_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cli_sessions_v2_user_updated": { - "name": "IDX_cli_sessions_v2_user_updated", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk": { - "name": "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "cli_sessions_v2", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "restrict", - "onUpdate": "no action" - }, - "cli_sessions_v2_organization_id_organizations_id_fk": { - "name": "cli_sessions_v2_organization_id_organizations_id_fk", - "tableFrom": "cli_sessions_v2", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "cli_sessions_v2_parent_session_id_kilo_user_id_fk": { - "name": "cli_sessions_v2_parent_session_id_kilo_user_id_fk", - "tableFrom": "cli_sessions_v2", - "tableTo": "cli_sessions_v2", - "columnsFrom": [ - "parent_session_id", - "kilo_user_id" - ], - "columnsTo": [ - "session_id", - "kilo_user_id" - ], - "onDelete": "restrict", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "cli_sessions_v2_session_id_kilo_user_id_pk": { - "name": "cli_sessions_v2_session_id_kilo_user_id_pk", - "columns": [ - "session_id", - "kilo_user_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.cloud_agent_code_reviews": { - "name": "cloud_agent_code_reviews", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "pr_number": { - "name": "pr_number", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "pr_url": { - "name": "pr_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "pr_title": { - "name": "pr_title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "pr_author": { - "name": "pr_author", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "pr_author_github_id": { - "name": "pr_author_github_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "base_ref": { - "name": "base_ref", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "head_ref": { - "name": "head_ref", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "head_sha": { - "name": "head_sha", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'github'" - }, - "platform_project_id": { - "name": "platform_project_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cli_session_id": { - "name": "cli_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "terminal_reason": { - "name": "terminal_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "agent_version": { - "name": "agent_version", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'v1'" - }, - "check_run_id": { - "name": "check_run_id", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "total_tokens_in": { - "name": "total_tokens_in", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "total_tokens_out": { - "name": "total_tokens_out", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "total_cost_musd": { - "name": "total_cost_musd", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_cloud_agent_code_reviews_repo_pr_sha": { - "name": "UQ_cloud_agent_code_reviews_repo_pr_sha", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "pr_number", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "head_sha", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_owned_by_org_id": { - "name": "idx_cloud_agent_code_reviews_owned_by_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_owned_by_user_id": { - "name": "idx_cloud_agent_code_reviews_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_session_id": { - "name": "idx_cloud_agent_code_reviews_session_id", - "columns": [ - { - "expression": "session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_cli_session_id": { - "name": "idx_cloud_agent_code_reviews_cli_session_id", - "columns": [ - { - "expression": "cli_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_status": { - "name": "idx_cloud_agent_code_reviews_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_repo": { - "name": "idx_cloud_agent_code_reviews_repo", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_pr_number": { - "name": "idx_cloud_agent_code_reviews_pr_number", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "pr_number", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_created_at": { - "name": "idx_cloud_agent_code_reviews_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_cloud_agent_code_reviews_pr_author_github_id": { - "name": "idx_cloud_agent_code_reviews_pr_author_github_id", - "columns": [ - { - "expression": "pr_author_github_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk": { - "name": "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk", - "tableFrom": "cloud_agent_code_reviews", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk": { - "name": "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "cloud_agent_code_reviews", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk": { - "name": "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "cloud_agent_code_reviews", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "cloud_agent_code_reviews_owner_check": { - "name": "cloud_agent_code_reviews_owner_check", - "value": "(\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NOT NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NULL) OR\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.cloud_agent_feedback": { - "name": "cloud_agent_feedback", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "repository": { - "name": "repository", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_streaming": { - "name": "is_streaming", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "message_count": { - "name": "message_count", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "feedback_text": { - "name": "feedback_text", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "recent_messages": { - "name": "recent_messages", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_cloud_agent_feedback_created_at": { - "name": "IDX_cloud_agent_feedback_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_feedback_kilo_user_id": { - "name": "IDX_cloud_agent_feedback_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_feedback_cloud_agent_session_id": { - "name": "IDX_cloud_agent_feedback_cloud_agent_session_id", - "columns": [ - { - "expression": "cloud_agent_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk": { - "name": "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "cloud_agent_feedback", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - }, - "cloud_agent_feedback_organization_id_organizations_id_fk": { - "name": "cloud_agent_feedback_organization_id_organizations_id_fk", - "tableFrom": "cloud_agent_feedback", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.cloud_agent_webhook_triggers": { - "name": "cloud_agent_webhook_triggers", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "trigger_id": { - "name": "trigger_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "target_type": { - "name": "target_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'cloud_agent'" - }, - "kiloclaw_instance_id": { - "name": "kiloclaw_instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "activation_mode": { - "name": "activation_mode", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'webhook'" - }, - "cron_expression": { - "name": "cron_expression", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cron_timezone": { - "name": "cron_timezone", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'UTC'" - }, - "github_repo": { - "name": "github_repo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "profile_id": { - "name": "profile_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_cloud_agent_webhook_triggers_user_trigger": { - "name": "UQ_cloud_agent_webhook_triggers_user_trigger", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "trigger_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"cloud_agent_webhook_triggers\".\"user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_cloud_agent_webhook_triggers_org_trigger": { - "name": "UQ_cloud_agent_webhook_triggers_org_trigger", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "trigger_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"cloud_agent_webhook_triggers\".\"organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_webhook_triggers_user": { - "name": "IDX_cloud_agent_webhook_triggers_user", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_webhook_triggers_org": { - "name": "IDX_cloud_agent_webhook_triggers_org", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_webhook_triggers_active": { - "name": "IDX_cloud_agent_webhook_triggers_active", - "columns": [ - { - "expression": "is_active", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_cloud_agent_webhook_triggers_profile": { - "name": "IDX_cloud_agent_webhook_triggers_profile", - "columns": [ - { - "expression": "profile_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk": { - "name": "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk", - "tableFrom": "cloud_agent_webhook_triggers", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "cloud_agent_webhook_triggers_organization_id_organizations_id_fk": { - "name": "cloud_agent_webhook_triggers_organization_id_organizations_id_fk", - "tableFrom": "cloud_agent_webhook_triggers", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk": { - "name": "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "cloud_agent_webhook_triggers", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "kiloclaw_instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk": { - "name": "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk", - "tableFrom": "cloud_agent_webhook_triggers", - "tableTo": "agent_environment_profiles", - "columnsFrom": [ - "profile_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "restrict", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "CHK_cloud_agent_webhook_triggers_owner": { - "name": "CHK_cloud_agent_webhook_triggers_owner", - "value": "(\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NULL) OR\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NOT NULL)\n )" - }, - "CHK_cloud_agent_webhook_triggers_cloud_agent_fields": { - "name": "CHK_cloud_agent_webhook_triggers_cloud_agent_fields", - "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'cloud_agent' OR\n (\"cloud_agent_webhook_triggers\".\"github_repo\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"profile_id\" IS NOT NULL)\n )" - }, - "CHK_cloud_agent_webhook_triggers_kiloclaw_fields": { - "name": "CHK_cloud_agent_webhook_triggers_kiloclaw_fields", - "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'kiloclaw_chat' OR\n \"cloud_agent_webhook_triggers\".\"kiloclaw_instance_id\" IS NOT NULL\n )" - }, - "CHK_cloud_agent_webhook_triggers_scheduled_fields": { - "name": "CHK_cloud_agent_webhook_triggers_scheduled_fields", - "value": "(\n \"cloud_agent_webhook_triggers\".\"activation_mode\" != 'scheduled' OR\n \"cloud_agent_webhook_triggers\".\"cron_expression\" IS NOT NULL\n )" - } - }, - "isRLSEnabled": false - }, - "public.code_indexing_manifest": { - "name": "code_indexing_manifest", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "project_id": { - "name": "project_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "git_branch": { - "name": "git_branch", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "file_hash": { - "name": "file_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "file_path": { - "name": "file_path", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "chunk_count": { - "name": "chunk_count", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "total_lines": { - "name": "total_lines", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "total_ai_lines": { - "name": "total_ai_lines", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_code_indexing_manifest_organization_id": { - "name": "IDX_code_indexing_manifest_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_manifest_kilo_user_id": { - "name": "IDX_code_indexing_manifest_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_manifest_project_id": { - "name": "IDX_code_indexing_manifest_project_id", - "columns": [ - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_manifest_file_hash": { - "name": "IDX_code_indexing_manifest_file_hash", - "columns": [ - { - "expression": "file_hash", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_manifest_git_branch": { - "name": "IDX_code_indexing_manifest_git_branch", - "columns": [ - { - "expression": "git_branch", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_manifest_created_at": { - "name": "IDX_code_indexing_manifest_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk": { - "name": "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "code_indexing_manifest", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_code_indexing_manifest_org_user_project_hash_branch": { - "name": "UQ_code_indexing_manifest_org_user_project_hash_branch", - "nullsNotDistinct": true, - "columns": [ - "organization_id", - "kilo_user_id", - "project_id", - "file_path", - "git_branch" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.code_indexing_search": { - "name": "code_indexing_search", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "query": { - "name": "query", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "project_id": { - "name": "project_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_code_indexing_search_organization_id": { - "name": "IDX_code_indexing_search_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_search_kilo_user_id": { - "name": "IDX_code_indexing_search_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_search_project_id": { - "name": "IDX_code_indexing_search_project_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_code_indexing_search_created_at": { - "name": "IDX_code_indexing_search_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "code_indexing_search_kilo_user_id_kilocode_users_id_fk": { - "name": "code_indexing_search_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "code_indexing_search", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.contributor_champion_contributors": { - "name": "contributor_champion_contributors", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "github_login": { - "name": "github_login", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_profile_url": { - "name": "github_profile_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_user_id": { - "name": "github_user_id", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "first_contribution_at": { - "name": "first_contribution_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "last_contribution_at": { - "name": "last_contribution_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "all_time_contributions": { - "name": "all_time_contributions", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "manual_email": { - "name": "manual_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_contributor_champion_contributors_last_contribution_at": { - "name": "IDX_contributor_champion_contributors_last_contribution_at", - "columns": [ - { - "expression": "last_contribution_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_contributor_champion_contributors_manual_email": { - "name": "IDX_contributor_champion_contributors_manual_email", - "columns": [ - { - "expression": "manual_email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_contributor_champion_contributors_github_login": { - "name": "UQ_contributor_champion_contributors_github_login", - "nullsNotDistinct": false, - "columns": [ - "github_login" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.contributor_champion_events": { - "name": "contributor_champion_events", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "contributor_id": { - "name": "contributor_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_pr_number": { - "name": "github_pr_number", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "github_pr_url": { - "name": "github_pr_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_pr_title": { - "name": "github_pr_title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_author_login": { - "name": "github_author_login", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_author_email": { - "name": "github_author_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "merged_at": { - "name": "merged_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_contributor_champion_events_contributor_id": { - "name": "IDX_contributor_champion_events_contributor_id", - "columns": [ - { - "expression": "contributor_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_contributor_champion_events_merged_at": { - "name": "IDX_contributor_champion_events_merged_at", - "columns": [ - { - "expression": "merged_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_contributor_champion_events_author_email": { - "name": "IDX_contributor_champion_events_author_email", - "columns": [ - { - "expression": "github_author_email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk": { - "name": "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk", - "tableFrom": "contributor_champion_events", - "tableTo": "contributor_champion_contributors", - "columnsFrom": [ - "contributor_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_contributor_champion_events_repo_pr": { - "name": "UQ_contributor_champion_events_repo_pr", - "nullsNotDistinct": false, - "columns": [ - "repo_full_name", - "github_pr_number" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.contributor_champion_memberships": { - "name": "contributor_champion_memberships", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "contributor_id": { - "name": "contributor_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "selected_tier": { - "name": "selected_tier", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "enrolled_tier": { - "name": "enrolled_tier", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "enrolled_at": { - "name": "enrolled_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "credit_amount_microdollars": { - "name": "credit_amount_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "credits_last_granted_at": { - "name": "credits_last_granted_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "linked_kilo_user_id": { - "name": "linked_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_contributor_champion_memberships_credits_due": { - "name": "IDX_contributor_champion_memberships_credits_due", - "columns": [ - { - "expression": "credits_last_granted_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NOT NULL AND \"contributor_champion_memberships\".\"credit_amount_microdollars\" > 0", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_contributor_champion_memberships_linked_kilo_user_id": { - "name": "IDX_contributor_champion_memberships_linked_kilo_user_id", - "columns": [ - { - "expression": "linked_kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk": { - "name": "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk", - "tableFrom": "contributor_champion_memberships", - "tableTo": "contributor_champion_contributors", - "columnsFrom": [ - "contributor_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk": { - "name": "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "contributor_champion_memberships", - "tableTo": "kilocode_users", - "columnsFrom": [ - "linked_kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_contributor_champion_memberships_contributor_id": { - "name": "UQ_contributor_champion_memberships_contributor_id", - "nullsNotDistinct": false, - "columns": [ - "contributor_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "contributor_champion_memberships_selected_tier_check": { - "name": "contributor_champion_memberships_selected_tier_check", - "value": "\"contributor_champion_memberships\".\"selected_tier\" IS NULL OR \"contributor_champion_memberships\".\"selected_tier\" IN ('contributor', 'ambassador', 'champion')" - }, - "contributor_champion_memberships_enrolled_tier_check": { - "name": "contributor_champion_memberships_enrolled_tier_check", - "value": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NULL OR \"contributor_champion_memberships\".\"enrolled_tier\" IN ('contributor', 'ambassador', 'champion')" - } - }, - "isRLSEnabled": false - }, - "public.contributor_champion_sync_state": { - "name": "contributor_champion_sync_state", - "schema": "", - "columns": { - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "last_merged_at": { - "name": "last_merged_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "last_synced_at": { - "name": "last_synced_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.credit_campaigns": { - "name": "credit_campaigns", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "credit_category": { - "name": "credit_category", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "amount_microdollars": { - "name": "amount_microdollars", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "credit_expiry_hours": { - "name": "credit_expiry_hours", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "campaign_ends_at": { - "name": "campaign_ends_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "total_redemptions_allowed": { - "name": "total_redemptions_allowed", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_by_kilo_user_id": { - "name": "created_by_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_credit_campaigns_slug": { - "name": "UQ_credit_campaigns_slug", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_credit_campaigns_credit_category": { - "name": "UQ_credit_campaigns_credit_category", - "columns": [ - { - "expression": "credit_category", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "credit_campaigns_slug_format_check": { - "name": "credit_campaigns_slug_format_check", - "value": "\"credit_campaigns\".\"slug\" ~ '^[a-z0-9-]{5,40}$'" - }, - "credit_campaigns_amount_positive_check": { - "name": "credit_campaigns_amount_positive_check", - "value": "\"credit_campaigns\".\"amount_microdollars\" > 0" - }, - "credit_campaigns_credit_expiry_hours_positive_check": { - "name": "credit_campaigns_credit_expiry_hours_positive_check", - "value": "\"credit_campaigns\".\"credit_expiry_hours\" IS NULL OR \"credit_campaigns\".\"credit_expiry_hours\" > 0" - }, - "credit_campaigns_total_redemptions_allowed_positive_check": { - "name": "credit_campaigns_total_redemptions_allowed_positive_check", - "value": "\"credit_campaigns\".\"total_redemptions_allowed\" > 0" - } - }, - "isRLSEnabled": false - }, - "public.credit_transactions": { - "name": "credit_transactions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "amount_microdollars": { - "name": "amount_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expiration_baseline_microdollars_used": { - "name": "expiration_baseline_microdollars_used", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "original_baseline_microdollars_used": { - "name": "original_baseline_microdollars_used", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "is_free": { - "name": "is_free", - "type": "boolean", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "original_transaction_id": { - "name": "original_transaction_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "stripe_payment_id": { - "name": "stripe_payment_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "coinbase_credit_block_id": { - "name": "coinbase_credit_block_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "credit_category": { - "name": "credit_category", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "expiry_date": { - "name": "expiry_date", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "check_category_uniqueness": { - "name": "check_category_uniqueness", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": { - "IDX_credit_transactions_created_at": { - "name": "IDX_credit_transactions_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_is_free": { - "name": "IDX_credit_transactions_is_free", - "columns": [ - { - "expression": "is_free", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_kilo_user_id": { - "name": "IDX_credit_transactions_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_credit_category": { - "name": "IDX_credit_transactions_credit_category", - "columns": [ - { - "expression": "credit_category", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_stripe_payment_id": { - "name": "IDX_credit_transactions_stripe_payment_id", - "columns": [ - { - "expression": "stripe_payment_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_original_transaction_id": { - "name": "IDX_credit_transactions_original_transaction_id", - "columns": [ - { - "expression": "original_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_coinbase_credit_block_id": { - "name": "IDX_credit_transactions_coinbase_credit_block_id", - "columns": [ - { - "expression": "coinbase_credit_block_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_organization_id": { - "name": "IDX_credit_transactions_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_credit_transactions_unique_category": { - "name": "IDX_credit_transactions_unique_category", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "credit_category", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"credit_transactions\".\"check_category_uniqueness\" = TRUE", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_llm2": { - "name": "custom_llm2", - "schema": "", - "columns": { - "public_id": { - "name": "public_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "definition": { - "name": "definition", - "type": "jsonb", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deployment_builds": { - "name": "deployment_builds", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "deployment_id": { - "name": "deployment_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_deployment_builds_deployment_id": { - "name": "idx_deployment_builds_deployment_id", - "columns": [ - { - "expression": "deployment_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployment_builds_status": { - "name": "idx_deployment_builds_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "deployment_builds_deployment_id_deployments_id_fk": { - "name": "deployment_builds_deployment_id_deployments_id_fk", - "tableFrom": "deployment_builds", - "tableTo": "deployments", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deployment_env_vars": { - "name": "deployment_env_vars", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "deployment_id": { - "name": "deployment_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "is_secret": { - "name": "is_secret", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_deployment_env_vars_deployment_id": { - "name": "idx_deployment_env_vars_deployment_id", - "columns": [ - { - "expression": "deployment_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "deployment_env_vars_deployment_id_deployments_id_fk": { - "name": "deployment_env_vars_deployment_id_deployments_id_fk", - "tableFrom": "deployment_env_vars", - "tableTo": "deployments", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_deployment_env_vars_deployment_key": { - "name": "UQ_deployment_env_vars_deployment_key", - "nullsNotDistinct": false, - "columns": [ - "deployment_id", - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deployment_events": { - "name": "deployment_events", - "schema": "", - "columns": { - "build_id": { - "name": "build_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "event_id": { - "name": "event_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "event_type": { - "name": "event_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'log'" - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "payload": { - "name": "payload", - "type": "jsonb", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "idx_deployment_events_build_id": { - "name": "idx_deployment_events_build_id", - "columns": [ - { - "expression": "build_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployment_events_timestamp": { - "name": "idx_deployment_events_timestamp", - "columns": [ - { - "expression": "timestamp", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployment_events_type": { - "name": "idx_deployment_events_type", - "columns": [ - { - "expression": "event_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "deployment_events_build_id_deployment_builds_id_fk": { - "name": "deployment_events_build_id_deployment_builds_id_fk", - "tableFrom": "deployment_events", - "tableTo": "deployment_builds", - "columnsFrom": [ - "build_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "deployment_events_build_id_event_id_pk": { - "name": "deployment_events_build_id_event_id_pk", - "columns": [ - "build_id", - "event_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deployment_threat_detections": { - "name": "deployment_threat_detections", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "deployment_id": { - "name": "deployment_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "build_id": { - "name": "build_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "threat_type": { - "name": "threat_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_deployment_threat_detections_deployment_id": { - "name": "idx_deployment_threat_detections_deployment_id", - "columns": [ - { - "expression": "deployment_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployment_threat_detections_created_at": { - "name": "idx_deployment_threat_detections_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "deployment_threat_detections_deployment_id_deployments_id_fk": { - "name": "deployment_threat_detections_deployment_id_deployments_id_fk", - "tableFrom": "deployment_threat_detections", - "tableTo": "deployments", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "deployment_threat_detections_build_id_deployment_builds_id_fk": { - "name": "deployment_threat_detections_build_id_deployment_builds_id_fk", - "tableFrom": "deployment_threat_detections", - "tableTo": "deployment_builds", - "columnsFrom": [ - "build_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.deployments": { - "name": "deployments", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "created_by_user_id": { - "name": "created_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "deployment_slug": { - "name": "deployment_slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "internal_worker_name": { - "name": "internal_worker_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "repository_source": { - "name": "repository_source", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "branch": { - "name": "branch", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "deployment_url": { - "name": "deployment_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "source_type": { - "name": "source_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'github'" - }, - "git_auth_token": { - "name": "git_auth_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_deployed_at": { - "name": "last_deployed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "last_build_id": { - "name": "last_build_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "threat_status": { - "name": "threat_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_from": { - "name": "created_from", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_deployments_owned_by_user_id": { - "name": "idx_deployments_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployments_owned_by_organization_id": { - "name": "idx_deployments_owned_by_organization_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployments_platform_integration_id": { - "name": "idx_deployments_platform_integration_id", - "columns": [ - { - "expression": "platform_integration_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployments_repository_source_branch": { - "name": "idx_deployments_repository_source_branch", - "columns": [ - { - "expression": "repository_source", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "branch", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_deployments_threat_status_pending": { - "name": "idx_deployments_threat_status_pending", - "columns": [ - { - "expression": "threat_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"deployments\".\"threat_status\" = 'pending_scan'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "deployments_owned_by_user_id_kilocode_users_id_fk": { - "name": "deployments_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "deployments", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "deployments_owned_by_organization_id_organizations_id_fk": { - "name": "deployments_owned_by_organization_id_organizations_id_fk", - "tableFrom": "deployments", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_deployments_deployment_slug": { - "name": "UQ_deployments_deployment_slug", - "nullsNotDistinct": false, - "columns": [ - "deployment_slug" - ] - } - }, - "policies": {}, - "checkConstraints": { - "deployments_owner_check": { - "name": "deployments_owner_check", - "value": "(\n (\"deployments\".\"owned_by_user_id\" IS NOT NULL AND \"deployments\".\"owned_by_organization_id\" IS NULL) OR\n (\"deployments\".\"owned_by_user_id\" IS NULL AND \"deployments\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "deployments_source_type_check": { - "name": "deployments_source_type_check", - "value": "\"deployments\".\"source_type\" IN ('github', 'git', 'app-builder')" - } - }, - "isRLSEnabled": false - }, - "public.device_auth_requests": { - "name": "device_auth_requests", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "code": { - "name": "code", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "approved_at": { - "name": "approved_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ip_address": { - "name": "ip_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_device_auth_requests_code": { - "name": "UQ_device_auth_requests_code", - "columns": [ - { - "expression": "code", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_device_auth_requests_status": { - "name": "IDX_device_auth_requests_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_device_auth_requests_expires_at": { - "name": "IDX_device_auth_requests_expires_at", - "columns": [ - { - "expression": "expires_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_device_auth_requests_kilo_user_id": { - "name": "IDX_device_auth_requests_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "device_auth_requests_kilo_user_id_kilocode_users_id_fk": { - "name": "device_auth_requests_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "device_auth_requests", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.discord_gateway_listener": { - "name": "discord_gateway_listener", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "default": 1 - }, - "listener_id": { - "name": "listener_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.editor_name": { - "name": "editor_name", - "schema": "", - "columns": { - "editor_name_id": { - "name": "editor_name_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "editor_name": { - "name": "editor_name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_editor_name": { - "name": "UQ_editor_name", - "columns": [ - { - "expression": "editor_name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.enrichment_data": { - "name": "enrichment_data", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "github_enrichment_data": { - "name": "github_enrichment_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "linkedin_enrichment_data": { - "name": "linkedin_enrichment_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "clay_enrichment_data": { - "name": "clay_enrichment_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_enrichment_data_user_id": { - "name": "IDX_enrichment_data_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "enrichment_data_user_id_kilocode_users_id_fk": { - "name": "enrichment_data_user_id_kilocode_users_id_fk", - "tableFrom": "enrichment_data", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_enrichment_data_user_id": { - "name": "UQ_enrichment_data_user_id", - "nullsNotDistinct": false, - "columns": [ - "user_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.exa_monthly_usage": { - "name": "exa_monthly_usage", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "month": { - "name": "month", - "type": "date", - "primaryKey": false, - "notNull": true - }, - "total_cost_microdollars": { - "name": "total_cost_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "total_charged_microdollars": { - "name": "total_charged_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "free_allowance_microdollars": { - "name": "free_allowance_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": 10000000 - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_exa_monthly_usage_personal": { - "name": "idx_exa_monthly_usage_personal", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "month", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"exa_monthly_usage\".\"organization_id\" is null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_exa_monthly_usage_org": { - "name": "idx_exa_monthly_usage_org", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "month", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"exa_monthly_usage\".\"organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.exa_usage_log": { - "name": "exa_usage_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": false, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "path": { - "name": "path", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cost_microdollars": { - "name": "cost_microdollars", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "charged_to_balance": { - "name": "charged_to_balance", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_exa_usage_log_user_created": { - "name": "idx_exa_usage_log_user_created", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": { - "exa_usage_log_id_created_at_pk": { - "name": "exa_usage_log_id_created_at_pk", - "columns": [ - "id", - "created_at" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.feature": { - "name": "feature", - "schema": "", - "columns": { - "feature_id": { - "name": "feature_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "feature": { - "name": "feature", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_feature": { - "name": "UQ_feature", - "columns": [ - { - "expression": "feature", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.finish_reason": { - "name": "finish_reason", - "schema": "", - "columns": { - "finish_reason_id": { - "name": "finish_reason_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "finish_reason": { - "name": "finish_reason", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_finish_reason": { - "name": "UQ_finish_reason", - "columns": [ - { - "expression": "finish_reason", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.free_model_usage": { - "name": "free_model_usage", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "ip_address": { - "name": "ip_address", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_free_model_usage_ip_created_at": { - "name": "idx_free_model_usage_ip_created_at", - "columns": [ - { - "expression": "ip_address", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_free_model_usage_created_at": { - "name": "idx_free_model_usage_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_free_model_usage_user_created_at": { - "name": "idx_free_model_usage_user_created_at", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"free_model_usage\".\"kilo_user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.http_ip": { - "name": "http_ip", - "schema": "", - "columns": { - "http_ip_id": { - "name": "http_ip_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "http_ip": { - "name": "http_ip", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_http_ip": { - "name": "UQ_http_ip", - "columns": [ - { - "expression": "http_ip", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.http_user_agent": { - "name": "http_user_agent", - "schema": "", - "columns": { - "http_user_agent_id": { - "name": "http_user_agent_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "http_user_agent": { - "name": "http_user_agent", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_http_user_agent": { - "name": "UQ_http_user_agent", - "columns": [ - { - "expression": "http_user_agent", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.ja4_digest": { - "name": "ja4_digest", - "schema": "", - "columns": { - "ja4_digest_id": { - "name": "ja4_digest_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "ja4_digest": { - "name": "ja4_digest", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_ja4_digest": { - "name": "UQ_ja4_digest", - "columns": [ - { - "expression": "ja4_digest", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kilo_pass_audit_log": { - "name": "kilo_pass_audit_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "kilo_pass_subscription_id": { - "name": "kilo_pass_subscription_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "action": { - "name": "action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "result": { - "name": "result", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "stripe_event_id": { - "name": "stripe_event_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "stripe_invoice_id": { - "name": "stripe_invoice_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "stripe_subscription_id": { - "name": "stripe_subscription_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "related_credit_transaction_id": { - "name": "related_credit_transaction_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "related_monthly_issuance_id": { - "name": "related_monthly_issuance_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "payload_json": { - "name": "payload_json", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - } - }, - "indexes": { - "IDX_kilo_pass_audit_log_created_at": { - "name": "IDX_kilo_pass_audit_log_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_kilo_user_id": { - "name": "IDX_kilo_pass_audit_log_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_kilo_pass_subscription_id": { - "name": "IDX_kilo_pass_audit_log_kilo_pass_subscription_id", - "columns": [ - { - "expression": "kilo_pass_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_action": { - "name": "IDX_kilo_pass_audit_log_action", - "columns": [ - { - "expression": "action", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_result": { - "name": "IDX_kilo_pass_audit_log_result", - "columns": [ - { - "expression": "result", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_idempotency_key": { - "name": "IDX_kilo_pass_audit_log_idempotency_key", - "columns": [ - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_stripe_event_id": { - "name": "IDX_kilo_pass_audit_log_stripe_event_id", - "columns": [ - { - "expression": "stripe_event_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_stripe_invoice_id": { - "name": "IDX_kilo_pass_audit_log_stripe_invoice_id", - "columns": [ - { - "expression": "stripe_invoice_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_stripe_subscription_id": { - "name": "IDX_kilo_pass_audit_log_stripe_subscription_id", - "columns": [ - { - "expression": "stripe_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_related_credit_transaction_id": { - "name": "IDX_kilo_pass_audit_log_related_credit_transaction_id", - "columns": [ - { - "expression": "related_credit_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_audit_log_related_monthly_issuance_id": { - "name": "IDX_kilo_pass_audit_log_related_monthly_issuance_id", - "columns": [ - { - "expression": "related_monthly_issuance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk": { - "name": "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "kilo_pass_audit_log", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - }, - "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { - "name": "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", - "tableFrom": "kilo_pass_audit_log", - "tableTo": "kilo_pass_subscriptions", - "columnsFrom": [ - "kilo_pass_subscription_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - }, - "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk": { - "name": "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk", - "tableFrom": "kilo_pass_audit_log", - "tableTo": "credit_transactions", - "columnsFrom": [ - "related_credit_transaction_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - }, - "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk": { - "name": "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk", - "tableFrom": "kilo_pass_audit_log", - "tableTo": "kilo_pass_issuances", - "columnsFrom": [ - "related_monthly_issuance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "kilo_pass_audit_log_action_check": { - "name": "kilo_pass_audit_log_action_check", - "value": "\"kilo_pass_audit_log\".\"action\" IN ('stripe_webhook_received', 'kilo_pass_invoice_paid_handled', 'base_credits_issued', 'bonus_credits_issued', 'bonus_credits_skipped_idempotent', 'first_month_50pct_promo_issued', 'yearly_monthly_base_cron_started', 'yearly_monthly_base_cron_completed', 'issue_yearly_remaining_credits', 'yearly_monthly_bonus_cron_started', 'yearly_monthly_bonus_cron_completed')" - }, - "kilo_pass_audit_log_result_check": { - "name": "kilo_pass_audit_log_result_check", - "value": "\"kilo_pass_audit_log\".\"result\" IN ('success', 'skipped_idempotent', 'failed')" - } - }, - "isRLSEnabled": false - }, - "public.kilo_pass_issuance_items": { - "name": "kilo_pass_issuance_items", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_pass_issuance_id": { - "name": "kilo_pass_issuance_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "credit_transaction_id": { - "name": "credit_transaction_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "amount_usd": { - "name": "amount_usd", - "type": "numeric(12, 2)", - "primaryKey": false, - "notNull": true - }, - "bonus_percent_applied": { - "name": "bonus_percent_applied", - "type": "numeric(6, 4)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kilo_pass_issuance_items_issuance_id": { - "name": "IDX_kilo_pass_issuance_items_issuance_id", - "columns": [ - { - "expression": "kilo_pass_issuance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_issuance_items_credit_transaction_id": { - "name": "IDX_kilo_pass_issuance_items_credit_transaction_id", - "columns": [ - { - "expression": "credit_transaction_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk": { - "name": "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk", - "tableFrom": "kilo_pass_issuance_items", - "tableTo": "kilo_pass_issuances", - "columnsFrom": [ - "kilo_pass_issuance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk": { - "name": "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk", - "tableFrom": "kilo_pass_issuance_items", - "tableTo": "credit_transactions", - "columnsFrom": [ - "credit_transaction_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "restrict", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kilo_pass_issuance_items_credit_transaction_id_unique": { - "name": "kilo_pass_issuance_items_credit_transaction_id_unique", - "nullsNotDistinct": false, - "columns": [ - "credit_transaction_id" - ] - }, - "UQ_kilo_pass_issuance_items_issuance_kind": { - "name": "UQ_kilo_pass_issuance_items_issuance_kind", - "nullsNotDistinct": false, - "columns": [ - "kilo_pass_issuance_id", - "kind" - ] - } - }, - "policies": {}, - "checkConstraints": { - "kilo_pass_issuance_items_bonus_percent_applied_range_check": { - "name": "kilo_pass_issuance_items_bonus_percent_applied_range_check", - "value": "\"kilo_pass_issuance_items\".\"bonus_percent_applied\" IS NULL OR (\"kilo_pass_issuance_items\".\"bonus_percent_applied\" >= 0 AND \"kilo_pass_issuance_items\".\"bonus_percent_applied\" <= 1)" - }, - "kilo_pass_issuance_items_amount_usd_non_negative_check": { - "name": "kilo_pass_issuance_items_amount_usd_non_negative_check", - "value": "\"kilo_pass_issuance_items\".\"amount_usd\" >= 0" - }, - "kilo_pass_issuance_items_kind_check": { - "name": "kilo_pass_issuance_items_kind_check", - "value": "\"kilo_pass_issuance_items\".\"kind\" IN ('base', 'bonus', 'promo_first_month_50pct')" - } - }, - "isRLSEnabled": false - }, - "public.kilo_pass_issuances": { - "name": "kilo_pass_issuances", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_pass_subscription_id": { - "name": "kilo_pass_subscription_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "issue_month": { - "name": "issue_month", - "type": "date", - "primaryKey": false, - "notNull": true - }, - "source": { - "name": "source", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_invoice_id": { - "name": "stripe_invoice_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_kilo_pass_issuances_stripe_invoice_id": { - "name": "UQ_kilo_pass_issuances_stripe_invoice_id", - "columns": [ - { - "expression": "stripe_invoice_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kilo_pass_issuances\".\"stripe_invoice_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_issuances_subscription_id": { - "name": "IDX_kilo_pass_issuances_subscription_id", - "columns": [ - { - "expression": "kilo_pass_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_issuances_issue_month": { - "name": "IDX_kilo_pass_issuances_issue_month", - "columns": [ - { - "expression": "issue_month", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { - "name": "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", - "tableFrom": "kilo_pass_issuances", - "tableTo": "kilo_pass_subscriptions", - "columnsFrom": [ - "kilo_pass_subscription_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_kilo_pass_issuances_subscription_issue_month": { - "name": "UQ_kilo_pass_issuances_subscription_issue_month", - "nullsNotDistinct": false, - "columns": [ - "kilo_pass_subscription_id", - "issue_month" - ] - } - }, - "policies": {}, - "checkConstraints": { - "kilo_pass_issuances_issue_month_day_one_check": { - "name": "kilo_pass_issuances_issue_month_day_one_check", - "value": "EXTRACT(DAY FROM \"kilo_pass_issuances\".\"issue_month\") = 1" - }, - "kilo_pass_issuances_source_check": { - "name": "kilo_pass_issuances_source_check", - "value": "\"kilo_pass_issuances\".\"source\" IN ('stripe_invoice', 'cron')" - } - }, - "isRLSEnabled": false - }, - "public.kilo_pass_pause_events": { - "name": "kilo_pass_pause_events", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_pass_subscription_id": { - "name": "kilo_pass_subscription_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "paused_at": { - "name": "paused_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "resumes_at": { - "name": "resumes_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "resumed_at": { - "name": "resumed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kilo_pass_pause_events_subscription_id": { - "name": "IDX_kilo_pass_pause_events_subscription_id", - "columns": [ - { - "expression": "kilo_pass_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kilo_pass_pause_events_one_open_per_sub": { - "name": "UQ_kilo_pass_pause_events_one_open_per_sub", - "columns": [ - { - "expression": "kilo_pass_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { - "name": "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", - "tableFrom": "kilo_pass_pause_events", - "tableTo": "kilo_pass_subscriptions", - "columnsFrom": [ - "kilo_pass_subscription_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "kilo_pass_pause_events_resumed_at_after_paused_at_check": { - "name": "kilo_pass_pause_events_resumed_at_after_paused_at_check", - "value": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL OR \"kilo_pass_pause_events\".\"resumed_at\" >= \"kilo_pass_pause_events\".\"paused_at\"" - } - }, - "isRLSEnabled": false - }, - "public.kilo_pass_scheduled_changes": { - "name": "kilo_pass_scheduled_changes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_subscription_id": { - "name": "stripe_subscription_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "from_tier": { - "name": "from_tier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "from_cadence": { - "name": "from_cadence", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "to_tier": { - "name": "to_tier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "to_cadence": { - "name": "to_cadence", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_schedule_id": { - "name": "stripe_schedule_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "effective_at": { - "name": "effective_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kilo_pass_scheduled_changes_kilo_user_id": { - "name": "IDX_kilo_pass_scheduled_changes_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_scheduled_changes_status": { - "name": "IDX_kilo_pass_scheduled_changes_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_scheduled_changes_stripe_subscription_id": { - "name": "IDX_kilo_pass_scheduled_changes_stripe_subscription_id", - "columns": [ - { - "expression": "stripe_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id": { - "name": "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id", - "columns": [ - { - "expression": "stripe_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kilo_pass_scheduled_changes\".\"deleted_at\" is null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_scheduled_changes_effective_at": { - "name": "IDX_kilo_pass_scheduled_changes_effective_at", - "columns": [ - { - "expression": "effective_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_scheduled_changes_deleted_at": { - "name": "IDX_kilo_pass_scheduled_changes_deleted_at", - "columns": [ - { - "expression": "deleted_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk": { - "name": "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "kilo_pass_scheduled_changes", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk": { - "name": "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk", - "tableFrom": "kilo_pass_scheduled_changes", - "tableTo": "kilo_pass_subscriptions", - "columnsFrom": [ - "stripe_subscription_id" - ], - "columnsTo": [ - "stripe_subscription_id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "kilo_pass_scheduled_changes_from_tier_check": { - "name": "kilo_pass_scheduled_changes_from_tier_check", - "value": "\"kilo_pass_scheduled_changes\".\"from_tier\" IN ('tier_19', 'tier_49', 'tier_199')" - }, - "kilo_pass_scheduled_changes_from_cadence_check": { - "name": "kilo_pass_scheduled_changes_from_cadence_check", - "value": "\"kilo_pass_scheduled_changes\".\"from_cadence\" IN ('monthly', 'yearly')" - }, - "kilo_pass_scheduled_changes_to_tier_check": { - "name": "kilo_pass_scheduled_changes_to_tier_check", - "value": "\"kilo_pass_scheduled_changes\".\"to_tier\" IN ('tier_19', 'tier_49', 'tier_199')" - }, - "kilo_pass_scheduled_changes_to_cadence_check": { - "name": "kilo_pass_scheduled_changes_to_cadence_check", - "value": "\"kilo_pass_scheduled_changes\".\"to_cadence\" IN ('monthly', 'yearly')" - }, - "kilo_pass_scheduled_changes_status_check": { - "name": "kilo_pass_scheduled_changes_status_check", - "value": "\"kilo_pass_scheduled_changes\".\"status\" IN ('not_started', 'active', 'completed', 'released', 'canceled')" - } - }, - "isRLSEnabled": false - }, - "public.kilo_pass_subscriptions": { - "name": "kilo_pass_subscriptions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_subscription_id": { - "name": "stripe_subscription_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "tier": { - "name": "tier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cadence": { - "name": "cadence", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cancel_at_period_end": { - "name": "cancel_at_period_end", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "ended_at": { - "name": "ended_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "current_streak_months": { - "name": "current_streak_months", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "next_yearly_issue_at": { - "name": "next_yearly_issue_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kilo_pass_subscriptions_kilo_user_id": { - "name": "IDX_kilo_pass_subscriptions_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_subscriptions_status": { - "name": "IDX_kilo_pass_subscriptions_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilo_pass_subscriptions_cadence": { - "name": "IDX_kilo_pass_subscriptions_cadence", - "columns": [ - { - "expression": "cadence", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk": { - "name": "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "kilo_pass_subscriptions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kilo_pass_subscriptions_stripe_subscription_id_unique": { - "name": "kilo_pass_subscriptions_stripe_subscription_id_unique", - "nullsNotDistinct": false, - "columns": [ - "stripe_subscription_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "kilo_pass_subscriptions_current_streak_months_non_negative_check": { - "name": "kilo_pass_subscriptions_current_streak_months_non_negative_check", - "value": "\"kilo_pass_subscriptions\".\"current_streak_months\" >= 0" - }, - "kilo_pass_subscriptions_tier_check": { - "name": "kilo_pass_subscriptions_tier_check", - "value": "\"kilo_pass_subscriptions\".\"tier\" IN ('tier_19', 'tier_49', 'tier_199')" - }, - "kilo_pass_subscriptions_cadence_check": { - "name": "kilo_pass_subscriptions_cadence_check", - "value": "\"kilo_pass_subscriptions\".\"cadence\" IN ('monthly', 'yearly')" - } - }, - "isRLSEnabled": false - }, - "public.kiloclaw_access_codes": { - "name": "kiloclaw_access_codes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "code": { - "name": "code", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'active'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "redeemed_at": { - "name": "redeemed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_kiloclaw_access_codes_code": { - "name": "UQ_kiloclaw_access_codes_code", - "columns": [ - { - "expression": "code", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_access_codes_user_status": { - "name": "IDX_kiloclaw_access_codes_user_status", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_access_codes_one_active_per_user": { - "name": "UQ_kiloclaw_access_codes_one_active_per_user", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "status = 'active'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_access_codes", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_admin_audit_logs": { - "name": "kiloclaw_admin_audit_logs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "action": { - "name": "action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "actor_id": { - "name": "actor_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_email": { - "name": "actor_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_name": { - "name": "actor_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "target_user_id": { - "name": "target_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "message": { - "name": "message", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kiloclaw_admin_audit_logs_target_user_id": { - "name": "IDX_kiloclaw_admin_audit_logs_target_user_id", - "columns": [ - { - "expression": "target_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_admin_audit_logs_action": { - "name": "IDX_kiloclaw_admin_audit_logs_action", - "columns": [ - { - "expression": "action", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_admin_audit_logs_created_at": { - "name": "IDX_kiloclaw_admin_audit_logs_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_cli_runs": { - "name": "kiloclaw_cli_runs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "initiated_by_admin_id": { - "name": "initiated_by_admin_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "prompt": { - "name": "prompt", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'running'" - }, - "exit_code": { - "name": "exit_code", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "output": { - "name": "output", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_kiloclaw_cli_runs_user_id": { - "name": "IDX_kiloclaw_cli_runs_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_cli_runs_started_at": { - "name": "IDX_kiloclaw_cli_runs_started_at", - "columns": [ - { - "expression": "started_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_cli_runs_instance_id": { - "name": "IDX_kiloclaw_cli_runs_instance_id", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_cli_runs_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_cli_runs_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_cli_runs", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_cli_runs", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk": { - "name": "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_cli_runs", - "tableTo": "kilocode_users", - "columnsFrom": [ - "initiated_by_admin_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_earlybird_purchases": { - "name": "kiloclaw_earlybird_purchases", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_charge_id": { - "name": "stripe_charge_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "manual_payment_id": { - "name": "manual_payment_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount_cents": { - "name": "amount_cents", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_earlybird_purchases", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kiloclaw_earlybird_purchases_user_id_unique": { - "name": "kiloclaw_earlybird_purchases_user_id_unique", - "nullsNotDistinct": false, - "columns": [ - "user_id" - ] - }, - "kiloclaw_earlybird_purchases_stripe_charge_id_unique": { - "name": "kiloclaw_earlybird_purchases_stripe_charge_id_unique", - "nullsNotDistinct": false, - "columns": [ - "stripe_charge_id" - ] - }, - "kiloclaw_earlybird_purchases_manual_payment_id_unique": { - "name": "kiloclaw_earlybird_purchases_manual_payment_id_unique", - "nullsNotDistinct": false, - "columns": [ - "manual_payment_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_email_log": { - "name": "kiloclaw_email_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "email_type": { - "name": "email_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "period_start": { - "name": "period_start", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "'epoch'" - }, - "sent_at": { - "name": "sent_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_kiloclaw_email_log_user_type_global": { - "name": "UQ_kiloclaw_email_log_user_type_global", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "email_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_email_log\".\"instance_id\" is null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_email_log_user_instance_type_period": { - "name": "UQ_kiloclaw_email_log_user_instance_type_period", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "email_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "period_start", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_email_log_type_sent_instance": { - "name": "IDX_kiloclaw_email_log_type_sent_instance", - "columns": [ - { - "expression": "email_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "sent_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_email_log_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_email_log_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_email_log", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_email_log", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_google_oauth_connections": { - "name": "kiloclaw_google_oauth_connections", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'google'" - }, - "account_email": { - "name": "account_email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "account_subject": { - "name": "account_subject", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "oauth_client_id": { - "name": "oauth_client_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "oauth_client_secret_encrypted": { - "name": "oauth_client_secret_encrypted", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "credential_profile": { - "name": "credential_profile", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'kilo_owned'" - }, - "refresh_token_encrypted": { - "name": "refresh_token_encrypted", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scopes": { - "name": "scopes", - "type": "text[]", - "primaryKey": false, - "notNull": true, - "default": "'{}'::text[]" - }, - "grants_by_source": { - "name": "grants_by_source", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - }, - "capabilities": { - "name": "capabilities", - "type": "text[]", - "primaryKey": false, - "notNull": true, - "default": "'{}'::text[]" - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'active'" - }, - "last_error": { - "name": "last_error", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_error_at": { - "name": "last_error_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "connected_at": { - "name": "connected_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_kiloclaw_google_oauth_connections_instance": { - "name": "UQ_kiloclaw_google_oauth_connections_instance", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_google_oauth_connections_status": { - "name": "IDX_kiloclaw_google_oauth_connections_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_google_oauth_connections_provider": { - "name": "IDX_kiloclaw_google_oauth_connections_provider", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_google_oauth_connections", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "kiloclaw_google_oauth_connections_status_check": { - "name": "kiloclaw_google_oauth_connections_status_check", - "value": "\"kiloclaw_google_oauth_connections\".\"status\" IN ('active', 'action_required', 'disconnected')" - }, - "kiloclaw_google_oauth_connections_credential_profile_check": { - "name": "kiloclaw_google_oauth_connections_credential_profile_check", - "value": "\"kiloclaw_google_oauth_connections\".\"credential_profile\" IN ('legacy', 'kilo_owned')" - } - }, - "isRLSEnabled": false - }, - "public.kiloclaw_image_catalog": { - "name": "kiloclaw_image_catalog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "openclaw_version": { - "name": "openclaw_version", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "variant": { - "name": "variant", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'default'" - }, - "image_tag": { - "name": "image_tag", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "image_digest": { - "name": "image_digest", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'available'" - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "updated_by": { - "name": "updated_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "published_at": { - "name": "published_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "synced_at": { - "name": "synced_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "rollout_percent": { - "name": "rollout_percent", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "is_latest": { - "name": "is_latest", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": { - "IDX_kiloclaw_image_catalog_status": { - "name": "IDX_kiloclaw_image_catalog_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_image_catalog_variant": { - "name": "IDX_kiloclaw_image_catalog_variant", - "columns": [ - { - "expression": "variant", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_image_catalog_one_latest_per_variant": { - "name": "UQ_kiloclaw_image_catalog_one_latest_per_variant", - "columns": [ - { - "expression": "variant", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_image_catalog\".\"is_latest\" = true", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_image_catalog_one_candidate_per_variant": { - "name": "UQ_kiloclaw_image_catalog_one_candidate_per_variant", - "columns": [ - { - "expression": "variant", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_image_catalog\".\"is_latest\" = false AND \"kiloclaw_image_catalog\".\"rollout_percent\" > 0 AND \"kiloclaw_image_catalog\".\"status\" = 'available'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kiloclaw_image_catalog_image_tag_unique": { - "name": "kiloclaw_image_catalog_image_tag_unique", - "nullsNotDistinct": false, - "columns": [ - "image_tag" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_inbound_email_aliases": { - "name": "kiloclaw_inbound_email_aliases", - "schema": "", - "columns": { - "alias": { - "name": "alias", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "retired_at": { - "name": "retired_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_kiloclaw_inbound_email_aliases_instance_id": { - "name": "IDX_kiloclaw_inbound_email_aliases_instance_id", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_inbound_email_aliases_active_instance": { - "name": "UQ_kiloclaw_inbound_email_aliases_active_instance", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_inbound_email_aliases\".\"retired_at\" is null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_inbound_email_aliases", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_inbound_email_reserved_aliases": { - "name": "kiloclaw_inbound_email_reserved_aliases", - "schema": "", - "columns": { - "alias": { - "name": "alias", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_instances": { - "name": "kiloclaw_instances", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "sandbox_id": { - "name": "sandbox_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'fly'" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "inbound_email_enabled": { - "name": "inbound_email_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "inactive_trial_stopped_at": { - "name": "inactive_trial_stopped_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "destroyed_at": { - "name": "destroyed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "tracked_image_tag": { - "name": "tracked_image_tag", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "UQ_kiloclaw_instances_active": { - "name": "UQ_kiloclaw_instances_active", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "sandbox_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_instances_active_personal_by_user": { - "name": "IDX_kiloclaw_instances_active_personal_by_user", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_instances\".\"organization_id\" IS NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_instances_active_org_by_user_org": { - "name": "IDX_kiloclaw_instances_active_org_by_user_org", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_instances\".\"organization_id\" IS NOT NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_instances_tracked_image_tag": { - "name": "IDX_kiloclaw_instances_tracked_image_tag", - "columns": [ - { - "expression": "tracked_image_tag", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_instances_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_instances_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_instances", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_instances_organization_id_organizations_id_fk": { - "name": "kiloclaw_instances_organization_id_organizations_id_fk", - "tableFrom": "kiloclaw_instances", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_scheduled_action_notifications": { - "name": "kiloclaw_scheduled_action_notifications", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "target_id": { - "name": "target_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "channel": { - "name": "channel", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'notice'" - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "claimed_at": { - "name": "claimed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "sent_at": { - "name": "sent_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel": { - "name": "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel", - "columns": [ - { - "expression": "target_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "kind", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "channel", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_action_notifications_pending": { - "name": "IDX_kiloclaw_scheduled_action_notifications_pending", - "columns": [ - { - "expression": "target_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_scheduled_action_notifications\".\"status\" = 'pending'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk": { - "name": "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk", - "tableFrom": "kiloclaw_scheduled_action_notifications", - "tableTo": "kiloclaw_scheduled_action_targets", - "columnsFrom": [ - "target_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_scheduled_action_stages": { - "name": "kiloclaw_scheduled_action_stages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "scheduled_action_id": { - "name": "scheduled_action_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "stage_index": { - "name": "stage_index", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "scheduled_at": { - "name": "scheduled_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "notice_sent_at": { - "name": "notice_sent_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "applied_count": { - "name": "applied_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "skipped_count": { - "name": "skipped_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "failed_count": { - "name": "failed_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "UQ_kiloclaw_scheduled_action_stages_parent_index": { - "name": "UQ_kiloclaw_scheduled_action_stages_parent_index", - "columns": [ - { - "expression": "scheduled_action_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "stage_index", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_action_stages_notice_due": { - "name": "IDX_kiloclaw_scheduled_action_stages_notice_due", - "columns": [ - { - "expression": "scheduled_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_scheduled_action_stages\".\"notice_sent_at\" IS NULL AND \"kiloclaw_scheduled_action_stages\".\"status\" = 'pending'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { - "name": "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", - "tableFrom": "kiloclaw_scheduled_action_stages", - "tableTo": "kiloclaw_scheduled_actions", - "columnsFrom": [ - "scheduled_action_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_scheduled_action_targets": { - "name": "kiloclaw_scheduled_action_targets", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "scheduled_action_id": { - "name": "scheduled_action_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "stage_id": { - "name": "stage_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "source_image_tag": { - "name": "source_image_tag", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "target_image_tag": { - "name": "target_image_tag", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "applied_at": { - "name": "applied_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "skip_reason": { - "name": "skip_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "UQ_kiloclaw_scheduled_action_targets_parent_instance": { - "name": "UQ_kiloclaw_scheduled_action_targets_parent_instance", - "columns": [ - { - "expression": "scheduled_action_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_action_targets_stage": { - "name": "IDX_kiloclaw_scheduled_action_targets_stage", - "columns": [ - { - "expression": "stage_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_action_targets_pending_by_instance": { - "name": "IDX_kiloclaw_scheduled_action_targets_pending_by_instance", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_scheduled_action_targets\".\"status\" = 'pending'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { - "name": "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", - "tableFrom": "kiloclaw_scheduled_action_targets", - "tableTo": "kiloclaw_scheduled_actions", - "columnsFrom": [ - "scheduled_action_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk": { - "name": "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk", - "tableFrom": "kiloclaw_scheduled_action_targets", - "tableTo": "kiloclaw_scheduled_action_stages", - "columnsFrom": [ - "stage_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_scheduled_action_targets", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_scheduled_action_targets", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_scheduled_actions": { - "name": "kiloclaw_scheduled_actions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "action_type": { - "name": "action_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "target_image_tag": { - "name": "target_image_tag", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "override_pins": { - "name": "override_pins", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "notice_lead_hours": { - "name": "notice_lead_hours", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 24 - }, - "notice_subject": { - "name": "notice_subject", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "notice_body": { - "name": "notice_body", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "reason": { - "name": "reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'scheduled'" - }, - "created_by": { - "name": "created_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "started_at": { - "name": "started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "completed_at": { - "name": "completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "cancelled_at": { - "name": "cancelled_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "total_count": { - "name": "total_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "applied_count": { - "name": "applied_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "skipped_count": { - "name": "skipped_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "failed_count": { - "name": "failed_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "IDX_kiloclaw_scheduled_actions_status": { - "name": "IDX_kiloclaw_scheduled_actions_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_actions_action_type": { - "name": "IDX_kiloclaw_scheduled_actions_action_type", - "columns": [ - { - "expression": "action_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_scheduled_actions_created_by": { - "name": "IDX_kiloclaw_scheduled_actions_created_by", - "columns": [ - { - "expression": "created_by", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk": { - "name": "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk", - "tableFrom": "kiloclaw_scheduled_actions", - "tableTo": "kiloclaw_image_catalog", - "columnsFrom": [ - "target_image_tag" - ], - "columnsTo": [ - "image_tag" - ], - "onDelete": "restrict", - "onUpdate": "no action" - }, - "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk": { - "name": "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk", - "tableFrom": "kiloclaw_scheduled_actions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kiloclaw_subscription_change_log": { - "name": "kiloclaw_subscription_change_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "subscription_id": { - "name": "subscription_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "actor_type": { - "name": "actor_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "actor_id": { - "name": "actor_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "action": { - "name": "action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "reason": { - "name": "reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "before_state": { - "name": "before_state", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "after_state": { - "name": "after_state", - "type": "jsonb", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_kiloclaw_subscription_change_log_subscription_created_at": { - "name": "IDX_kiloclaw_subscription_change_log_subscription_created_at", - "columns": [ - { - "expression": "subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscription_change_log_created_at": { - "name": "IDX_kiloclaw_subscription_change_log_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk": { - "name": "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk", - "tableFrom": "kiloclaw_subscription_change_log", - "tableTo": "kiloclaw_subscriptions", - "columnsFrom": [ - "subscription_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "kiloclaw_subscription_change_log_actor_type_check": { - "name": "kiloclaw_subscription_change_log_actor_type_check", - "value": "\"kiloclaw_subscription_change_log\".\"actor_type\" IN ('user', 'system')" - }, - "kiloclaw_subscription_change_log_action_check": { - "name": "kiloclaw_subscription_change_log_action_check", - "value": "\"kiloclaw_subscription_change_log\".\"action\" IN ('created', 'status_changed', 'plan_switched', 'period_advanced', 'canceled', 'reactivated', 'suspended', 'destruction_scheduled', 'reassigned', 'backfilled', 'payment_source_changed', 'schedule_changed', 'admin_override')" - } - }, - "isRLSEnabled": false - }, - "public.kiloclaw_subscriptions": { - "name": "kiloclaw_subscriptions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_subscription_id": { - "name": "stripe_subscription_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "stripe_schedule_id": { - "name": "stripe_schedule_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "transferred_to_subscription_id": { - "name": "transferred_to_subscription_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "access_origin": { - "name": "access_origin", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "payment_source": { - "name": "payment_source", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "plan": { - "name": "plan", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scheduled_plan": { - "name": "scheduled_plan", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "scheduled_by": { - "name": "scheduled_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cancel_at_period_end": { - "name": "cancel_at_period_end", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "pending_conversion": { - "name": "pending_conversion", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "trial_started_at": { - "name": "trial_started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "trial_ends_at": { - "name": "trial_ends_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "current_period_start": { - "name": "current_period_start", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "current_period_end": { - "name": "current_period_end", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "credit_renewal_at": { - "name": "credit_renewal_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "commit_ends_at": { - "name": "commit_ends_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "past_due_since": { - "name": "past_due_since", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "suspended_at": { - "name": "suspended_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "destruction_deadline": { - "name": "destruction_deadline", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "auto_resume_requested_at": { - "name": "auto_resume_requested_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "auto_resume_retry_after": { - "name": "auto_resume_retry_after", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "auto_resume_attempt_count": { - "name": "auto_resume_attempt_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "auto_top_up_triggered_for_period": { - "name": "auto_top_up_triggered_for_period", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_kiloclaw_subscriptions_status": { - "name": "IDX_kiloclaw_subscriptions_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_user_id": { - "name": "IDX_kiloclaw_subscriptions_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_user_status": { - "name": "IDX_kiloclaw_subscriptions_user_status", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_transferred_to": { - "name": "IDX_kiloclaw_subscriptions_transferred_to", - "columns": [ - { - "expression": "transferred_to_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_stripe_schedule_id": { - "name": "IDX_kiloclaw_subscriptions_stripe_schedule_id", - "columns": [ - { - "expression": "stripe_schedule_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_auto_resume_retry_after": { - "name": "IDX_kiloclaw_subscriptions_auto_resume_retry_after", - "columns": [ - { - "expression": "auto_resume_retry_after", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_subscriptions_instance": { - "name": "UQ_kiloclaw_subscriptions_instance", - "columns": [ - { - "expression": "instance_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_subscriptions\".\"instance_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kiloclaw_subscriptions_transferred_to": { - "name": "UQ_kiloclaw_subscriptions_transferred_to", - "columns": [ - { - "expression": "transferred_to_subscription_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kiloclaw_subscriptions\".\"transferred_to_subscription_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kiloclaw_subscriptions_earlybird_origin": { - "name": "IDX_kiloclaw_subscriptions_earlybird_origin", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "access_origin", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"kiloclaw_subscriptions\".\"access_origin\" = 'earlybird'", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "kiloclaw_subscriptions_user_id_kilocode_users_id_fk": { - "name": "kiloclaw_subscriptions_user_id_kilocode_users_id_fk", - "tableFrom": "kiloclaw_subscriptions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk": { - "name": "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk", - "tableFrom": "kiloclaw_subscriptions", - "tableTo": "kiloclaw_subscriptions", - "columnsFrom": [ - "transferred_to_subscription_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_subscriptions", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kiloclaw_subscriptions_stripe_subscription_id_unique": { - "name": "kiloclaw_subscriptions_stripe_subscription_id_unique", - "nullsNotDistinct": false, - "columns": [ - "stripe_subscription_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "kiloclaw_subscriptions_plan_check": { - "name": "kiloclaw_subscriptions_plan_check", - "value": "\"kiloclaw_subscriptions\".\"plan\" IN ('trial', 'commit', 'standard')" - }, - "kiloclaw_subscriptions_scheduled_plan_check": { - "name": "kiloclaw_subscriptions_scheduled_plan_check", - "value": "\"kiloclaw_subscriptions\".\"scheduled_plan\" IN ('commit', 'standard')" - }, - "kiloclaw_subscriptions_scheduled_by_check": { - "name": "kiloclaw_subscriptions_scheduled_by_check", - "value": "\"kiloclaw_subscriptions\".\"scheduled_by\" IN ('auto', 'user')" - }, - "kiloclaw_subscriptions_status_check": { - "name": "kiloclaw_subscriptions_status_check", - "value": "\"kiloclaw_subscriptions\".\"status\" IN ('trialing', 'active', 'past_due', 'canceled', 'unpaid')" - }, - "kiloclaw_subscriptions_access_origin_check": { - "name": "kiloclaw_subscriptions_access_origin_check", - "value": "\"kiloclaw_subscriptions\".\"access_origin\" IN ('earlybird')" - }, - "kiloclaw_subscriptions_payment_source_check": { - "name": "kiloclaw_subscriptions_payment_source_check", - "value": "\"kiloclaw_subscriptions\".\"payment_source\" IN ('stripe', 'credits')" - } - }, - "isRLSEnabled": false - }, - "public.kiloclaw_version_pins": { - "name": "kiloclaw_version_pins", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "instance_id": { - "name": "instance_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "image_tag": { - "name": "image_tag", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "pinned_by": { - "name": "pinned_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "reason": { - "name": "reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk": { - "name": "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk", - "tableFrom": "kiloclaw_version_pins", - "tableTo": "kiloclaw_instances", - "columnsFrom": [ - "instance_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk": { - "name": "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk", - "tableFrom": "kiloclaw_version_pins", - "tableTo": "kiloclaw_image_catalog", - "columnsFrom": [ - "image_tag" - ], - "columnsTo": [ - "image_tag" - ], - "onDelete": "restrict", - "onUpdate": "no action" - }, - "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk": { - "name": "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk", - "tableFrom": "kiloclaw_version_pins", - "tableTo": "kilocode_users", - "columnsFrom": [ - "pinned_by" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "kiloclaw_version_pins_instance_id_unique": { - "name": "kiloclaw_version_pins_instance_id_unique", - "nullsNotDistinct": false, - "columns": [ - "instance_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.kilocode_users": { - "name": "kilocode_users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "google_user_email": { - "name": "google_user_email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "google_user_name": { - "name": "google_user_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "google_user_image_url": { - "name": "google_user_image_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "hosted_domain": { - "name": "hosted_domain", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "microdollars_used": { - "name": "microdollars_used", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": "'0'" - }, - "kilo_pass_threshold": { - "name": "kilo_pass_threshold", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "stripe_customer_id": { - "name": "stripe_customer_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "is_admin": { - "name": "is_admin", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "total_microdollars_acquired": { - "name": "total_microdollars_acquired", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": "'0'" - }, - "next_credit_expiration_at": { - "name": "next_credit_expiration_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "has_validation_stytch": { - "name": "has_validation_stytch", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "has_validation_novel_card_with_hold": { - "name": "has_validation_novel_card_with_hold", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "blocked_reason": { - "name": "blocked_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "blocked_at": { - "name": "blocked_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "blocked_by_kilo_user_id": { - "name": "blocked_by_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "api_token_pepper": { - "name": "api_token_pepper", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "web_session_pepper": { - "name": "web_session_pepper", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "auto_top_up_enabled": { - "name": "auto_top_up_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "is_bot": { - "name": "is_bot", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "kiloclaw_early_access": { - "name": "kiloclaw_early_access", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "default_model": { - "name": "default_model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cohorts": { - "name": "cohorts", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - }, - "completed_welcome_form": { - "name": "completed_welcome_form", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "linkedin_url": { - "name": "linkedin_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "github_url": { - "name": "github_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "discord_server_membership_verified_at": { - "name": "discord_server_membership_verified_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "openrouter_upstream_safety_identifier": { - "name": "openrouter_upstream_safety_identifier", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "vercel_downstream_safety_identifier": { - "name": "vercel_downstream_safety_identifier", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "customer_source": { - "name": "customer_source", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "signup_ip": { - "name": "signup_ip", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "account_deletion_requested_at": { - "name": "account_deletion_requested_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "normalized_email": { - "name": "normalized_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "email_domain": { - "name": "email_domain", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_kilocode_users_signup_ip_created_at": { - "name": "IDX_kilocode_users_signup_ip_created_at", - "columns": [ - { - "expression": "signup_ip", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilocode_users_blocked_at": { - "name": "IDX_kilocode_users_blocked_at", - "columns": [ - { - "expression": "blocked_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilocode_users_blocked_by_kilo_user_id": { - "name": "IDX_kilocode_users_blocked_by_kilo_user_id", - "columns": [ - { - "expression": "blocked_by_kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kilocode_users_openrouter_upstream_safety_identifier": { - "name": "UQ_kilocode_users_openrouter_upstream_safety_identifier", - "columns": [ - { - "expression": "openrouter_upstream_safety_identifier", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kilocode_users\".\"openrouter_upstream_safety_identifier\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_kilocode_users_vercel_downstream_safety_identifier": { - "name": "UQ_kilocode_users_vercel_downstream_safety_identifier", - "columns": [ - { - "expression": "vercel_downstream_safety_identifier", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"kilocode_users\".\"vercel_downstream_safety_identifier\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilocode_users_normalized_email": { - "name": "IDX_kilocode_users_normalized_email", - "columns": [ - { - "expression": "normalized_email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_kilocode_users_email_domain": { - "name": "IDX_kilocode_users_email_domain", - "columns": [ - { - "expression": "email_domain", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_b1afacbcf43f2c7c4cb9f7e7faa": { - "name": "UQ_b1afacbcf43f2c7c4cb9f7e7faa", - "nullsNotDistinct": false, - "columns": [ - "google_user_email" - ] - } - }, - "policies": {}, - "checkConstraints": { - "blocked_reason_not_empty": { - "name": "blocked_reason_not_empty", - "value": "length(blocked_reason) > 0" - } - }, - "isRLSEnabled": false - }, - "public.magic_link_tokens": { - "name": "magic_link_tokens", - "schema": "", - "columns": { - "token_hash": { - "name": "token_hash", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "consumed_at": { - "name": "consumed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_magic_link_tokens_email": { - "name": "idx_magic_link_tokens_email", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_magic_link_tokens_expires_at": { - "name": "idx_magic_link_tokens_expires_at", - "columns": [ - { - "expression": "expires_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "check_expires_at_future": { - "name": "check_expires_at_future", - "value": "\"magic_link_tokens\".\"expires_at\" > \"magic_link_tokens\".\"created_at\"" - } - }, - "isRLSEnabled": false - }, - "public.microdollar_usage": { - "name": "microdollar_usage", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cost": { - "name": "cost", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "input_tokens": { - "name": "input_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "output_tokens": { - "name": "output_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "cache_write_tokens": { - "name": "cache_write_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "cache_hit_tokens": { - "name": "cache_hit_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "requested_model": { - "name": "requested_model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cache_discount": { - "name": "cache_discount", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "has_error": { - "name": "has_error", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "abuse_classification": { - "name": "abuse_classification", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "inference_provider": { - "name": "inference_provider", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "project_id": { - "name": "project_id", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_created_at": { - "name": "idx_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_abuse_classification": { - "name": "idx_abuse_classification", - "columns": [ - { - "expression": "abuse_classification", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_kilo_user_id_created_at2": { - "name": "idx_kilo_user_id_created_at2", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_microdollar_usage_organization_id": { - "name": "idx_microdollar_usage_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"microdollar_usage\".\"organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.microdollar_usage_metadata": { - "name": "microdollar_usage_metadata", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "message_id": { - "name": "message_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "http_user_agent_id": { - "name": "http_user_agent_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "http_ip_id": { - "name": "http_ip_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "vercel_ip_city_id": { - "name": "vercel_ip_city_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "vercel_ip_country_id": { - "name": "vercel_ip_country_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "vercel_ip_latitude": { - "name": "vercel_ip_latitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "vercel_ip_longitude": { - "name": "vercel_ip_longitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "ja4_digest_id": { - "name": "ja4_digest_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "user_prompt_prefix": { - "name": "user_prompt_prefix", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "system_prompt_prefix_id": { - "name": "system_prompt_prefix_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "system_prompt_length": { - "name": "system_prompt_length", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "max_tokens": { - "name": "max_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "has_middle_out_transform": { - "name": "has_middle_out_transform", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "status_code": { - "name": "status_code", - "type": "smallint", - "primaryKey": false, - "notNull": false - }, - "upstream_id": { - "name": "upstream_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "finish_reason_id": { - "name": "finish_reason_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "latency": { - "name": "latency", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "moderation_latency": { - "name": "moderation_latency", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "generation_time": { - "name": "generation_time", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "is_byok": { - "name": "is_byok", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "is_user_byok": { - "name": "is_user_byok", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "streamed": { - "name": "streamed", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "cancelled": { - "name": "cancelled", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "editor_name_id": { - "name": "editor_name_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "api_kind_id": { - "name": "api_kind_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "has_tools": { - "name": "has_tools", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "machine_id": { - "name": "machine_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "feature_id": { - "name": "feature_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "mode_id": { - "name": "mode_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "auto_model_id": { - "name": "auto_model_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "market_cost": { - "name": "market_cost", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "is_free": { - "name": "is_free", - "type": "boolean", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_microdollar_usage_metadata_created_at": { - "name": "idx_microdollar_usage_metadata_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk": { - "name": "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "http_user_agent", - "columnsFrom": [ - "http_user_agent_id" - ], - "columnsTo": [ - "http_user_agent_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk": { - "name": "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "http_ip", - "columnsFrom": [ - "http_ip_id" - ], - "columnsTo": [ - "http_ip_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk": { - "name": "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "vercel_ip_city", - "columnsFrom": [ - "vercel_ip_city_id" - ], - "columnsTo": [ - "vercel_ip_city_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk": { - "name": "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "vercel_ip_country", - "columnsFrom": [ - "vercel_ip_country_id" - ], - "columnsTo": [ - "vercel_ip_country_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk": { - "name": "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "ja4_digest", - "columnsFrom": [ - "ja4_digest_id" - ], - "columnsTo": [ - "ja4_digest_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk": { - "name": "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk", - "tableFrom": "microdollar_usage_metadata", - "tableTo": "system_prompt_prefix", - "columnsFrom": [ - "system_prompt_prefix_id" - ], - "columnsTo": [ - "system_prompt_prefix_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.mode": { - "name": "mode", - "schema": "", - "columns": { - "mode_id": { - "name": "mode_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "mode": { - "name": "mode", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_mode": { - "name": "UQ_mode", - "columns": [ - { - "expression": "mode", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.model_stats": { - "name": "model_stats", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "is_featured": { - "name": "is_featured", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "is_stealth": { - "name": "is_stealth", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "is_recommended": { - "name": "is_recommended", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "openrouter_id": { - "name": "openrouter_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "aa_slug": { - "name": "aa_slug", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model_creator": { - "name": "model_creator", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "creator_slug": { - "name": "creator_slug", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "release_date": { - "name": "release_date", - "type": "date", - "primaryKey": false, - "notNull": false - }, - "price_input": { - "name": "price_input", - "type": "numeric(10, 6)", - "primaryKey": false, - "notNull": false - }, - "price_output": { - "name": "price_output", - "type": "numeric(10, 6)", - "primaryKey": false, - "notNull": false - }, - "coding_index": { - "name": "coding_index", - "type": "numeric(5, 2)", - "primaryKey": false, - "notNull": false - }, - "speed_tokens_per_sec": { - "name": "speed_tokens_per_sec", - "type": "numeric(8, 2)", - "primaryKey": false, - "notNull": false - }, - "context_length": { - "name": "context_length", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "max_output_tokens": { - "name": "max_output_tokens", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "input_modalities": { - "name": "input_modalities", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "openrouter_data": { - "name": "openrouter_data", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "benchmarks": { - "name": "benchmarks", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "chart_data": { - "name": "chart_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_model_stats_openrouter_id": { - "name": "IDX_model_stats_openrouter_id", - "columns": [ - { - "expression": "openrouter_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_slug": { - "name": "IDX_model_stats_slug", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_is_active": { - "name": "IDX_model_stats_is_active", - "columns": [ - { - "expression": "is_active", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_creator_slug": { - "name": "IDX_model_stats_creator_slug", - "columns": [ - { - "expression": "creator_slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_price_input": { - "name": "IDX_model_stats_price_input", - "columns": [ - { - "expression": "price_input", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_coding_index": { - "name": "IDX_model_stats_coding_index", - "columns": [ - { - "expression": "coding_index", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_model_stats_context_length": { - "name": "IDX_model_stats_context_length", - "columns": [ - { - "expression": "context_length", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "model_stats_openrouter_id_unique": { - "name": "model_stats_openrouter_id_unique", - "nullsNotDistinct": false, - "columns": [ - "openrouter_id" - ] - }, - "model_stats_slug_unique": { - "name": "model_stats_slug_unique", - "nullsNotDistinct": false, - "columns": [ - "slug" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.models_by_provider": { - "name": "models_by_provider", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "openrouter": { - "name": "openrouter", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "vercel": { - "name": "vercel", - "type": "jsonb", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_audit_logs": { - "name": "organization_audit_logs", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "action": { - "name": "action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "actor_id": { - "name": "actor_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_email": { - "name": "actor_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_name": { - "name": "actor_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "message": { - "name": "message", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_organization_audit_logs_organization_id": { - "name": "IDX_organization_audit_logs_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_audit_logs_action": { - "name": "IDX_organization_audit_logs_action", - "columns": [ - { - "expression": "action", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_audit_logs_actor_id": { - "name": "IDX_organization_audit_logs_actor_id", - "columns": [ - { - "expression": "actor_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_audit_logs_created_at": { - "name": "IDX_organization_audit_logs_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_invitations": { - "name": "organization_invitations", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "invited_by": { - "name": "invited_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "accepted_at": { - "name": "accepted_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_organization_invitations_token": { - "name": "UQ_organization_invitations_token", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_invitations_org_id": { - "name": "IDX_organization_invitations_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_invitations_email": { - "name": "IDX_organization_invitations_email", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_invitations_expires_at": { - "name": "IDX_organization_invitations_expires_at", - "columns": [ - { - "expression": "expires_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_membership_removals": { - "name": "organization_membership_removals", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "removed_at": { - "name": "removed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "removed_by": { - "name": "removed_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "previous_role": { - "name": "previous_role", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "IDX_org_membership_removals_org_id": { - "name": "IDX_org_membership_removals_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_org_membership_removals_user_id": { - "name": "IDX_org_membership_removals_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_org_membership_removals_org_user": { - "name": "UQ_org_membership_removals_org_user", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "kilo_user_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_memberships": { - "name": "organization_memberships", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "joined_at": { - "name": "joined_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "invited_by": { - "name": "invited_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_organization_memberships_org_id": { - "name": "IDX_organization_memberships_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_memberships_user_id": { - "name": "IDX_organization_memberships_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_organization_memberships_org_user": { - "name": "UQ_organization_memberships_org_user", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "kilo_user_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_seats_purchases": { - "name": "organization_seats_purchases", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "subscription_stripe_id": { - "name": "subscription_stripe_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "seat_count": { - "name": "seat_count", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "amount_usd": { - "name": "amount_usd", - "type": "numeric", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "subscription_status": { - "name": "subscription_status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'active'" - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "starts_at": { - "name": "starts_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "billing_cycle": { - "name": "billing_cycle", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'monthly'" - } - }, - "indexes": { - "IDX_organization_seats_org_id": { - "name": "IDX_organization_seats_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_seats_expires_at": { - "name": "IDX_organization_seats_expires_at", - "columns": [ - { - "expression": "expires_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_seats_created_at": { - "name": "IDX_organization_seats_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_seats_updated_at": { - "name": "IDX_organization_seats_updated_at", - "columns": [ - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_seats_starts_at": { - "name": "IDX_organization_seats_starts_at", - "columns": [ - { - "expression": "starts_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_organization_seats_idempotency_key": { - "name": "UQ_organization_seats_idempotency_key", - "nullsNotDistinct": false, - "columns": [ - "idempotency_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_user_limits": { - "name": "organization_user_limits", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "limit_type": { - "name": "limit_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "microdollar_limit": { - "name": "microdollar_limit", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_organization_user_limits_org_id": { - "name": "IDX_organization_user_limits_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_user_limits_user_id": { - "name": "IDX_organization_user_limits_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_organization_user_limits_org_user": { - "name": "UQ_organization_user_limits_org_user", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "kilo_user_id", - "limit_type" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organization_user_usage": { - "name": "organization_user_usage", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "usage_date": { - "name": "usage_date", - "type": "date", - "primaryKey": false, - "notNull": true - }, - "limit_type": { - "name": "limit_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "microdollar_usage": { - "name": "microdollar_usage", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_organization_user_daily_usage_org_id": { - "name": "IDX_organization_user_daily_usage_org_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_organization_user_daily_usage_user_id": { - "name": "IDX_organization_user_daily_usage_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_organization_user_daily_usage_org_user_date": { - "name": "UQ_organization_user_daily_usage_org_user_date", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "kilo_user_id", - "limit_type", - "usage_date" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.organizations": { - "name": "organizations", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "microdollars_used": { - "name": "microdollars_used", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": "'0'" - }, - "microdollars_balance": { - "name": "microdollars_balance", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": "'0'" - }, - "total_microdollars_acquired": { - "name": "total_microdollars_acquired", - "type": "bigint", - "primaryKey": false, - "notNull": true, - "default": "'0'" - }, - "next_credit_expiration_at": { - "name": "next_credit_expiration_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "stripe_customer_id": { - "name": "stripe_customer_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "auto_top_up_enabled": { - "name": "auto_top_up_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "settings": { - "name": "settings", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - }, - "seat_count": { - "name": "seat_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "require_seats": { - "name": "require_seats", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_by_kilo_user_id": { - "name": "created_by_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "sso_domain": { - "name": "sso_domain", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "plan": { - "name": "plan", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'teams'" - }, - "free_trial_end_at": { - "name": "free_trial_end_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "company_domain": { - "name": "company_domain", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_organizations_sso_domain": { - "name": "IDX_organizations_sso_domain", - "columns": [ - { - "expression": "sso_domain", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "organizations_name_not_empty_check": { - "name": "organizations_name_not_empty_check", - "value": "length(trim(\"organizations\".\"name\")) > 0" - } - }, - "isRLSEnabled": false - }, - "public.organization_modes": { - "name": "organization_modes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_by": { - "name": "created_by", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "config": { - "name": "config", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - } - }, - "indexes": { - "IDX_organization_modes_organization_id": { - "name": "IDX_organization_modes_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_organization_modes_org_id_slug": { - "name": "UQ_organization_modes_org_id_slug", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "slug" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.payment_methods": { - "name": "payment_methods", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "stripe_fingerprint": { - "name": "stripe_fingerprint", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "stripe_id": { - "name": "stripe_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last4": { - "name": "last4", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "brand": { - "name": "brand", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_line1": { - "name": "address_line1", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_line2": { - "name": "address_line2", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_city": { - "name": "address_city", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_state": { - "name": "address_state", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_zip": { - "name": "address_zip", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_country": { - "name": "address_country", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "three_d_secure_supported": { - "name": "three_d_secure_supported", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "funding": { - "name": "funding", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "regulated_status": { - "name": "regulated_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "address_line1_check_status": { - "name": "address_line1_check_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "postal_code_check_status": { - "name": "postal_code_check_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_forwarded_for": { - "name": "http_x_forwarded_for", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_city": { - "name": "http_x_vercel_ip_city", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_country": { - "name": "http_x_vercel_ip_country", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_latitude": { - "name": "http_x_vercel_ip_latitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_longitude": { - "name": "http_x_vercel_ip_longitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ja4_digest": { - "name": "http_x_vercel_ja4_digest", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "eligible_for_free_credits": { - "name": "eligible_for_free_credits", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "stripe_data": { - "name": "stripe_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_d7d7fb15569674aaadcfbc0428": { - "name": "IDX_d7d7fb15569674aaadcfbc0428", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_e1feb919d0ab8a36381d5d5138": { - "name": "IDX_e1feb919d0ab8a36381d5d5138", - "columns": [ - { - "expression": "stripe_fingerprint", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_payment_methods_organization_id": { - "name": "IDX_payment_methods_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_29df1b0403df5792c96bbbfdbe6": { - "name": "UQ_29df1b0403df5792c96bbbfdbe6", - "nullsNotDistinct": false, - "columns": [ - "user_id", - "stripe_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.pending_impact_sale_reversals": { - "name": "pending_impact_sale_reversals", - "schema": "", - "columns": { - "stripe_charge_id": { - "name": "stripe_charge_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "dispute_id": { - "name": "dispute_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "amount": { - "name": "amount", - "type": "real", - "primaryKey": false, - "notNull": true - }, - "currency": { - "name": "currency", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "event_date": { - "name": "event_date", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "attempt_count": { - "name": "attempt_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "last_attempt_at": { - "name": "last_attempt_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "pending_impact_sale_reversals_attempt_count_non_negative_check": { - "name": "pending_impact_sale_reversals_attempt_count_non_negative_check", - "value": "\"pending_impact_sale_reversals\".\"attempt_count\" >= 0" - } - }, - "isRLSEnabled": false - }, - "public.platform_integrations": { - "name": "platform_integrations", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_by_user_id": { - "name": "created_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "integration_type": { - "name": "integration_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform_installation_id": { - "name": "platform_installation_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_account_id": { - "name": "platform_account_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_account_login": { - "name": "platform_account_login", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "permissions": { - "name": "permissions", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "scopes": { - "name": "scopes", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "repository_access": { - "name": "repository_access", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "repositories": { - "name": "repositories", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "repositories_synced_at": { - "name": "repositories_synced_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "kilo_requester_user_id": { - "name": "kilo_requester_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_requester_account_id": { - "name": "platform_requester_account_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "integration_status": { - "name": "integration_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "suspended_at": { - "name": "suspended_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "suspended_by": { - "name": "suspended_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "github_app_type": { - "name": "github_app_type", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'standard'" - }, - "installed_at": { - "name": "installed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_platform_integrations_owned_by_org_platform_inst": { - "name": "UQ_platform_integrations_owned_by_org_platform_inst", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform_installation_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"platform_integrations\".\"owned_by_organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_platform_integrations_owned_by_user_platform_inst": { - "name": "UQ_platform_integrations_owned_by_user_platform_inst", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform_installation_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"platform_integrations\".\"owned_by_user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_platform_integrations_slack_platform_inst": { - "name": "UQ_platform_integrations_slack_platform_inst", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform_installation_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"platform_integrations\".\"platform\" = 'slack' AND \"platform_integrations\".\"platform_installation_id\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_owned_by_org_id": { - "name": "IDX_platform_integrations_owned_by_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_owned_by_user_id": { - "name": "IDX_platform_integrations_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_platform_inst_id": { - "name": "IDX_platform_integrations_platform_inst_id", - "columns": [ - { - "expression": "platform_installation_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_platform": { - "name": "IDX_platform_integrations_platform", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_owned_by_org_platform": { - "name": "IDX_platform_integrations_owned_by_org_platform", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_owned_by_user_platform": { - "name": "IDX_platform_integrations_owned_by_user_platform", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_integration_status": { - "name": "IDX_platform_integrations_integration_status", - "columns": [ - { - "expression": "integration_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_kilo_requester": { - "name": "IDX_platform_integrations_kilo_requester", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "kilo_requester_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "integration_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_platform_integrations_platform_requester": { - "name": "IDX_platform_integrations_platform_requester", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "platform_requester_account_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "integration_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "platform_integrations_owned_by_organization_id_organizations_id_fk": { - "name": "platform_integrations_owned_by_organization_id_organizations_id_fk", - "tableFrom": "platform_integrations", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "platform_integrations_owned_by_user_id_kilocode_users_id_fk": { - "name": "platform_integrations_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "platform_integrations", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "platform_integrations_owner_check": { - "name": "platform_integrations_owner_check", - "value": "(\n (\"platform_integrations\".\"owned_by_user_id\" IS NOT NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NULL) OR\n (\"platform_integrations\".\"owned_by_user_id\" IS NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.referral_code_usages": { - "name": "referral_code_usages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "referring_kilo_user_id": { - "name": "referring_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "redeeming_kilo_user_id": { - "name": "redeeming_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "code": { - "name": "code", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "amount_usd": { - "name": "amount_usd", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "paid_at": { - "name": "paid_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_referral_code_usages_redeeming_kilo_user_id": { - "name": "IDX_referral_code_usages_redeeming_kilo_user_id", - "columns": [ - { - "expression": "redeeming_kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_referral_code_usages_redeeming_user_id_code": { - "name": "UQ_referral_code_usages_redeeming_user_id_code", - "nullsNotDistinct": false, - "columns": [ - "redeeming_kilo_user_id", - "referring_kilo_user_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.referral_codes": { - "name": "referral_codes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "code": { - "name": "code", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "max_redemptions": { - "name": "max_redemptions", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 10 - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_referral_codes_kilo_user_id": { - "name": "UQ_referral_codes_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_referral_codes_code": { - "name": "IDX_referral_codes_code", - "columns": [ - { - "expression": "code", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.security_advisor_check_catalog": { - "name": "security_advisor_check_catalog", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "check_id": { - "name": "check_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "severity": { - "name": "severity", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "explanation": { - "name": "explanation", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "risk": { - "name": "risk", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "security_advisor_check_catalog_check_id_unique": { - "name": "security_advisor_check_catalog_check_id_unique", - "nullsNotDistinct": false, - "columns": [ - "check_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "security_advisor_check_catalog_severity_check": { - "name": "security_advisor_check_catalog_severity_check", - "value": "\"security_advisor_check_catalog\".\"severity\" in ('critical', 'warn', 'info')" - } - }, - "isRLSEnabled": false - }, - "public.security_advisor_content": { - "name": "security_advisor_content", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "key": { - "name": "key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "security_advisor_content_key_unique": { - "name": "security_advisor_content_key_unique", - "nullsNotDistinct": false, - "columns": [ - "key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.security_advisor_kiloclaw_coverage": { - "name": "security_advisor_kiloclaw_coverage", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "area": { - "name": "area", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "summary": { - "name": "summary", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "detail": { - "name": "detail", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "match_check_ids": { - "name": "match_check_ids", - "type": "text[]", - "primaryKey": false, - "notNull": true, - "default": "'{}'::text[]" - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "security_advisor_kiloclaw_coverage_area_unique": { - "name": "security_advisor_kiloclaw_coverage_area_unique", - "nullsNotDistinct": false, - "columns": [ - "area" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.security_advisor_scans": { - "name": "security_advisor_scans", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_method": { - "name": "source_method", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "plugin_version": { - "name": "plugin_version", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "openclaw_version": { - "name": "openclaw_version", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "public_ip": { - "name": "public_ip", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "findings_critical": { - "name": "findings_critical", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "findings_warn": { - "name": "findings_warn", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "findings_info": { - "name": "findings_info", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_security_advisor_scans_user_created_at": { - "name": "idx_security_advisor_scans_user_created_at", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_advisor_scans_created_at": { - "name": "idx_security_advisor_scans_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_advisor_scans_platform": { - "name": "idx_security_advisor_scans_platform", - "columns": [ - { - "expression": "source_platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.security_analysis_owner_state": { - "name": "security_analysis_owner_state", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "auto_analysis_enabled_at": { - "name": "auto_analysis_enabled_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "blocked_until": { - "name": "blocked_until", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "block_reason": { - "name": "block_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "consecutive_actor_resolution_failures": { - "name": "consecutive_actor_resolution_failures", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "last_actor_resolution_failure_at": { - "name": "last_actor_resolution_failure_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_security_analysis_owner_state_org_owner": { - "name": "UQ_security_analysis_owner_state_org_owner", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"security_analysis_owner_state\".\"owned_by_organization_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_security_analysis_owner_state_user_owner": { - "name": "UQ_security_analysis_owner_state_user_owner", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"security_analysis_owner_state\".\"owned_by_user_id\" is not null", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk": { - "name": "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk", - "tableFrom": "security_analysis_owner_state", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk": { - "name": "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "security_analysis_owner_state", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "security_analysis_owner_state_owner_check": { - "name": "security_analysis_owner_state_owner_check", - "value": "(\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "security_analysis_owner_state_block_reason_check": { - "name": "security_analysis_owner_state_block_reason_check", - "value": "\"security_analysis_owner_state\".\"block_reason\" IS NULL OR \"security_analysis_owner_state\".\"block_reason\" IN ('INSUFFICIENT_CREDITS', 'ACTOR_RESOLUTION_FAILED', 'OPERATOR_PAUSE')" - } - }, - "isRLSEnabled": false - }, - "public.security_analysis_queue": { - "name": "security_analysis_queue", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "finding_id": { - "name": "finding_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "queue_status": { - "name": "queue_status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "severity_rank": { - "name": "severity_rank", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "queued_at": { - "name": "queued_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "claimed_at": { - "name": "claimed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "claimed_by_job_id": { - "name": "claimed_by_job_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "claim_token": { - "name": "claim_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attempt_count": { - "name": "attempt_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "reopen_requeue_count": { - "name": "reopen_requeue_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "next_retry_at": { - "name": "next_retry_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "failure_code": { - "name": "failure_code", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_error_redacted": { - "name": "last_error_redacted", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_security_analysis_queue_finding_id": { - "name": "UQ_security_analysis_queue_finding_id", - "columns": [ - { - "expression": "finding_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_claim_path_org": { - "name": "idx_security_analysis_queue_claim_path_org", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "severity_rank", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "queued_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_claim_path_user": { - "name": "idx_security_analysis_queue_claim_path_user", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "severity_rank", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "queued_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_in_flight_org": { - "name": "idx_security_analysis_queue_in_flight_org", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "queue_status", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "claimed_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_in_flight_user": { - "name": "idx_security_analysis_queue_in_flight_user", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "queue_status", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "claimed_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_lag_dashboards": { - "name": "idx_security_analysis_queue_lag_dashboards", - "columns": [ - { - "expression": "queued_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_pending_reconciliation": { - "name": "idx_security_analysis_queue_pending_reconciliation", - "columns": [ - { - "expression": "claimed_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" = 'pending'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_running_reconciliation": { - "name": "idx_security_analysis_queue_running_reconciliation", - "columns": [ - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"queue_status\" = 'running'", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_analysis_queue_failure_trend": { - "name": "idx_security_analysis_queue_failure_trend", - "columns": [ - { - "expression": "failure_code", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_analysis_queue\".\"failure_code\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "security_analysis_queue_finding_id_security_findings_id_fk": { - "name": "security_analysis_queue_finding_id_security_findings_id_fk", - "tableFrom": "security_analysis_queue", - "tableTo": "security_findings", - "columnsFrom": [ - "finding_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_analysis_queue_owned_by_organization_id_organizations_id_fk": { - "name": "security_analysis_queue_owned_by_organization_id_organizations_id_fk", - "tableFrom": "security_analysis_queue", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk": { - "name": "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "security_analysis_queue", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "security_analysis_queue_owner_check": { - "name": "security_analysis_queue_owner_check", - "value": "(\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NOT NULL)\n )" - }, - "security_analysis_queue_status_check": { - "name": "security_analysis_queue_status_check", - "value": "\"security_analysis_queue\".\"queue_status\" IN ('queued', 'pending', 'running', 'failed', 'completed')" - }, - "security_analysis_queue_claim_token_required_check": { - "name": "security_analysis_queue_claim_token_required_check", - "value": "\"security_analysis_queue\".\"queue_status\" NOT IN ('pending', 'running') OR \"security_analysis_queue\".\"claim_token\" IS NOT NULL" - }, - "security_analysis_queue_attempt_count_non_negative_check": { - "name": "security_analysis_queue_attempt_count_non_negative_check", - "value": "\"security_analysis_queue\".\"attempt_count\" >= 0" - }, - "security_analysis_queue_reopen_requeue_count_non_negative_check": { - "name": "security_analysis_queue_reopen_requeue_count_non_negative_check", - "value": "\"security_analysis_queue\".\"reopen_requeue_count\" >= 0" - }, - "security_analysis_queue_severity_rank_check": { - "name": "security_analysis_queue_severity_rank_check", - "value": "\"security_analysis_queue\".\"severity_rank\" IN (0, 1, 2, 3)" - }, - "security_analysis_queue_failure_code_check": { - "name": "security_analysis_queue_failure_code_check", - "value": "\"security_analysis_queue\".\"failure_code\" IS NULL OR \"security_analysis_queue\".\"failure_code\" IN (\n 'NETWORK_TIMEOUT',\n 'UPSTREAM_5XX',\n 'TEMP_TOKEN_FAILURE',\n 'START_CALL_AMBIGUOUS',\n 'REQUEUE_TEMPORARY_PRECONDITION',\n 'ACTOR_RESOLUTION_FAILED',\n 'GITHUB_TOKEN_UNAVAILABLE',\n 'INVALID_CONFIG',\n 'MISSING_OWNERSHIP',\n 'PERMISSION_DENIED_PERMANENT',\n 'UNSUPPORTED_SEVERITY',\n 'INSUFFICIENT_CREDITS',\n 'STATE_GUARD_REJECTED',\n 'SKIPPED_ALREADY_IN_PROGRESS',\n 'SKIPPED_NO_LONGER_ELIGIBLE',\n 'REOPEN_LOOP_GUARD',\n 'RUN_LOST'\n )" - } - }, - "isRLSEnabled": false - }, - "public.security_audit_log": { - "name": "security_audit_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_id": { - "name": "actor_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_email": { - "name": "actor_email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "actor_name": { - "name": "actor_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "action": { - "name": "action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "resource_type": { - "name": "resource_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "before_state": { - "name": "before_state", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "after_state": { - "name": "after_state", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_security_audit_log_org_created": { - "name": "IDX_security_audit_log_org_created", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_security_audit_log_user_created": { - "name": "IDX_security_audit_log_user_created", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_security_audit_log_resource": { - "name": "IDX_security_audit_log_resource", - "columns": [ - { - "expression": "resource_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "resource_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_security_audit_log_actor": { - "name": "IDX_security_audit_log_actor", - "columns": [ - { - "expression": "actor_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_security_audit_log_action": { - "name": "IDX_security_audit_log_action", - "columns": [ - { - "expression": "action", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "security_audit_log_owned_by_organization_id_organizations_id_fk": { - "name": "security_audit_log_owned_by_organization_id_organizations_id_fk", - "tableFrom": "security_audit_log", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_audit_log_owned_by_user_id_kilocode_users_id_fk": { - "name": "security_audit_log_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "security_audit_log", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "security_audit_log_owner_check": { - "name": "security_audit_log_owner_check", - "value": "(\"security_audit_log\".\"owned_by_user_id\" IS NOT NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NULL) OR (\"security_audit_log\".\"owned_by_user_id\" IS NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NOT NULL)" - }, - "security_audit_log_action_check": { - "name": "security_audit_log_action_check", - "value": "\"security_audit_log\".\"action\" IN ('security.finding.created', 'security.finding.status_change', 'security.finding.dismissed', 'security.finding.auto_dismissed', 'security.finding.analysis_started', 'security.finding.analysis_completed', 'security.finding.deleted', 'security.config.enabled', 'security.config.disabled', 'security.config.updated', 'security.sync.triggered', 'security.sync.completed', 'security.audit_log.exported')" - } - }, - "isRLSEnabled": false - }, - "public.security_findings": { - "name": "security_findings", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "repo_full_name": { - "name": "repo_full_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source": { - "name": "source", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_id": { - "name": "source_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "severity": { - "name": "severity", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "ghsa_id": { - "name": "ghsa_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cve_id": { - "name": "cve_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "package_name": { - "name": "package_name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "package_ecosystem": { - "name": "package_ecosystem", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "vulnerable_version_range": { - "name": "vulnerable_version_range", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "patched_version": { - "name": "patched_version", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "manifest_path": { - "name": "manifest_path", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'open'" - }, - "ignored_reason": { - "name": "ignored_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ignored_by": { - "name": "ignored_by", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "fixed_at": { - "name": "fixed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "sla_due_at": { - "name": "sla_due_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "dependabot_html_url": { - "name": "dependabot_html_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cwe_ids": { - "name": "cwe_ids", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "cvss_score": { - "name": "cvss_score", - "type": "numeric(3, 1)", - "primaryKey": false, - "notNull": false - }, - "dependency_scope": { - "name": "dependency_scope", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cli_session_id": { - "name": "cli_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "analysis_status": { - "name": "analysis_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "analysis_started_at": { - "name": "analysis_started_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "analysis_completed_at": { - "name": "analysis_completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "analysis_error": { - "name": "analysis_error", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "analysis": { - "name": "analysis", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "raw_data": { - "name": "raw_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "first_detected_at": { - "name": "first_detected_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_synced_at": { - "name": "last_synced_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_security_findings_org_id": { - "name": "idx_security_findings_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_user_id": { - "name": "idx_security_findings_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_repo": { - "name": "idx_security_findings_repo", - "columns": [ - { - "expression": "repo_full_name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_severity": { - "name": "idx_security_findings_severity", - "columns": [ - { - "expression": "severity", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_status": { - "name": "idx_security_findings_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_package": { - "name": "idx_security_findings_package", - "columns": [ - { - "expression": "package_name", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_sla_due_at": { - "name": "idx_security_findings_sla_due_at", - "columns": [ - { - "expression": "sla_due_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_session_id": { - "name": "idx_security_findings_session_id", - "columns": [ - { - "expression": "session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_cli_session_id": { - "name": "idx_security_findings_cli_session_id", - "columns": [ - { - "expression": "cli_session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_analysis_status": { - "name": "idx_security_findings_analysis_status", - "columns": [ - { - "expression": "analysis_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_org_analysis_in_flight": { - "name": "idx_security_findings_org_analysis_in_flight", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "analysis_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_security_findings_user_analysis_in_flight": { - "name": "idx_security_findings_user_analysis_in_flight", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "analysis_status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "security_findings_owned_by_organization_id_organizations_id_fk": { - "name": "security_findings_owned_by_organization_id_organizations_id_fk", - "tableFrom": "security_findings", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_findings_owned_by_user_id_kilocode_users_id_fk": { - "name": "security_findings_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "security_findings", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "security_findings_platform_integration_id_platform_integrations_id_fk": { - "name": "security_findings_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "security_findings", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "uq_security_findings_source": { - "name": "uq_security_findings_source", - "nullsNotDistinct": false, - "columns": [ - "repo_full_name", - "source", - "source_id" - ] - } - }, - "policies": {}, - "checkConstraints": { - "security_findings_owner_check": { - "name": "security_findings_owner_check", - "value": "(\n (\"security_findings\".\"owned_by_user_id\" IS NOT NULL AND \"security_findings\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_findings\".\"owned_by_user_id\" IS NULL AND \"security_findings\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.shared_cli_sessions": { - "name": "shared_cli_sessions", - "schema": "", - "columns": { - "share_id": { - "name": "share_id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "session_id": { - "name": "session_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "shared_state": { - "name": "shared_state", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'public'" - }, - "api_conversation_history_blob_url": { - "name": "api_conversation_history_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "task_metadata_blob_url": { - "name": "task_metadata_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ui_messages_blob_url": { - "name": "ui_messages_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "git_state_blob_url": { - "name": "git_state_blob_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_shared_cli_sessions_session_id": { - "name": "IDX_shared_cli_sessions_session_id", - "columns": [ - { - "expression": "session_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_shared_cli_sessions_created_at": { - "name": "IDX_shared_cli_sessions_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "shared_cli_sessions_session_id_cli_sessions_session_id_fk": { - "name": "shared_cli_sessions_session_id_cli_sessions_session_id_fk", - "tableFrom": "shared_cli_sessions", - "tableTo": "cli_sessions", - "columnsFrom": [ - "session_id" - ], - "columnsTo": [ - "session_id" - ], - "onDelete": "set null", - "onUpdate": "no action" - }, - "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk": { - "name": "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "shared_cli_sessions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "restrict", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "shared_cli_sessions_shared_state_check": { - "name": "shared_cli_sessions_shared_state_check", - "value": "\"shared_cli_sessions\".\"shared_state\" IN ('public', 'organization')" - } - }, - "isRLSEnabled": false - }, - "public.slack_bot_requests": { - "name": "slack_bot_requests", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform_integration_id": { - "name": "platform_integration_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "slack_team_id": { - "name": "slack_team_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slack_team_name": { - "name": "slack_team_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "slack_channel_id": { - "name": "slack_channel_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slack_user_id": { - "name": "slack_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "slack_thread_ts": { - "name": "slack_thread_ts", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "event_type": { - "name": "event_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "user_message": { - "name": "user_message", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "user_message_truncated": { - "name": "user_message_truncated", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "error_message": { - "name": "error_message", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "response_time_ms": { - "name": "response_time_ms", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "model_used": { - "name": "model_used", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "tool_calls_made": { - "name": "tool_calls_made", - "type": "text[]", - "primaryKey": false, - "notNull": false - }, - "cloud_agent_session_id": { - "name": "cloud_agent_session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_slack_bot_requests_created_at": { - "name": "idx_slack_bot_requests_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_slack_team_id": { - "name": "idx_slack_bot_requests_slack_team_id", - "columns": [ - { - "expression": "slack_team_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_owned_by_org_id": { - "name": "idx_slack_bot_requests_owned_by_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_owned_by_user_id": { - "name": "idx_slack_bot_requests_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_status": { - "name": "idx_slack_bot_requests_status", - "columns": [ - { - "expression": "status", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_event_type": { - "name": "idx_slack_bot_requests_event_type", - "columns": [ - { - "expression": "event_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_slack_bot_requests_team_created": { - "name": "idx_slack_bot_requests_team_created", - "columns": [ - { - "expression": "slack_team_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "slack_bot_requests_owned_by_organization_id_organizations_id_fk": { - "name": "slack_bot_requests_owned_by_organization_id_organizations_id_fk", - "tableFrom": "slack_bot_requests", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk": { - "name": "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "slack_bot_requests", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "slack_bot_requests_platform_integration_id_platform_integrations_id_fk": { - "name": "slack_bot_requests_platform_integration_id_platform_integrations_id_fk", - "tableFrom": "slack_bot_requests", - "tableTo": "platform_integrations", - "columnsFrom": [ - "platform_integration_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "slack_bot_requests_owner_check": { - "name": "slack_bot_requests_owner_check", - "value": "(\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NOT NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NOT NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL)\n )" - } - }, - "isRLSEnabled": false - }, - "public.source_embeddings": { - "name": "source_embeddings", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "project_id": { - "name": "project_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "file_path": { - "name": "file_path", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "file_hash": { - "name": "file_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "start_line": { - "name": "start_line", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "end_line": { - "name": "end_line", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "git_branch": { - "name": "git_branch", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'main'" - }, - "is_base_branch": { - "name": "is_base_branch", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_source_embeddings_organization_id": { - "name": "IDX_source_embeddings_organization_id", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_kilo_user_id": { - "name": "IDX_source_embeddings_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_project_id": { - "name": "IDX_source_embeddings_project_id", - "columns": [ - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_created_at": { - "name": "IDX_source_embeddings_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_updated_at": { - "name": "IDX_source_embeddings_updated_at", - "columns": [ - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_file_path_lower": { - "name": "IDX_source_embeddings_file_path_lower", - "columns": [ - { - "expression": "LOWER(\"file_path\")", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_git_branch": { - "name": "IDX_source_embeddings_git_branch", - "columns": [ - { - "expression": "git_branch", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_source_embeddings_org_project_branch": { - "name": "IDX_source_embeddings_org_project_branch", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "project_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "git_branch", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "source_embeddings_organization_id_organizations_id_fk": { - "name": "source_embeddings_organization_id_organizations_id_fk", - "tableFrom": "source_embeddings", - "tableTo": "organizations", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "source_embeddings_kilo_user_id_kilocode_users_id_fk": { - "name": "source_embeddings_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "source_embeddings", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_source_embeddings_org_project_branch_file_lines": { - "name": "UQ_source_embeddings_org_project_branch_file_lines", - "nullsNotDistinct": false, - "columns": [ - "organization_id", - "project_id", - "git_branch", - "file_path", - "start_line", - "end_line" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.stytch_fingerprints": { - "name": "stytch_fingerprints", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "visitor_fingerprint": { - "name": "visitor_fingerprint", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "browser_fingerprint": { - "name": "browser_fingerprint", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "browser_id": { - "name": "browser_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "hardware_fingerprint": { - "name": "hardware_fingerprint", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "network_fingerprint": { - "name": "network_fingerprint", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "visitor_id": { - "name": "visitor_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "verdict_action": { - "name": "verdict_action", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "detected_device_type": { - "name": "detected_device_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "is_authentic_device": { - "name": "is_authentic_device", - "type": "boolean", - "primaryKey": false, - "notNull": true - }, - "reasons": { - "name": "reasons", - "type": "text[]", - "primaryKey": false, - "notNull": true, - "default": "'{\"\"}'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "status_code": { - "name": "status_code", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "fingerprint_data": { - "name": "fingerprint_data", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "kilo_free_tier_allowed": { - "name": "kilo_free_tier_allowed", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "http_x_forwarded_for": { - "name": "http_x_forwarded_for", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_city": { - "name": "http_x_vercel_ip_city", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_country": { - "name": "http_x_vercel_ip_country", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_latitude": { - "name": "http_x_vercel_ip_latitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_longitude": { - "name": "http_x_vercel_ip_longitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ja4_digest": { - "name": "http_x_vercel_ja4_digest", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_user_agent": { - "name": "http_user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_fingerprint_data": { - "name": "idx_fingerprint_data", - "columns": [ - { - "expression": "fingerprint_data", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_hardware_fingerprint": { - "name": "idx_hardware_fingerprint", - "columns": [ - { - "expression": "hardware_fingerprint", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_kilo_user_id": { - "name": "idx_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_reasons": { - "name": "idx_reasons", - "columns": [ - { - "expression": "reasons", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_verdict_action": { - "name": "idx_verdict_action", - "columns": [ - { - "expression": "verdict_action", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_visitor_fingerprint": { - "name": "idx_visitor_fingerprint", - "columns": [ - { - "expression": "visitor_fingerprint", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.system_prompt_prefix": { - "name": "system_prompt_prefix", - "schema": "", - "columns": { - "system_prompt_prefix_id": { - "name": "system_prompt_prefix_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "system_prompt_prefix": { - "name": "system_prompt_prefix", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_system_prompt_prefix": { - "name": "UQ_system_prompt_prefix", - "columns": [ - { - "expression": "system_prompt_prefix", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.transactional_email_log": { - "name": "transactional_email_log", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "email_type": { - "name": "email_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "sent_at": { - "name": "sent_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_transactional_email_log_type_idempotency_key": { - "name": "UQ_transactional_email_log_type_idempotency_key", - "columns": [ - { - "expression": "email_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_transactional_email_log_user_id": { - "name": "IDX_transactional_email_log_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "transactional_email_log_user_id_kilocode_users_id_fk": { - "name": "transactional_email_log_user_id_kilocode_users_id_fk", - "tableFrom": "transactional_email_log", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_admin_notes": { - "name": "user_admin_notes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "note_content": { - "name": "note_content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "admin_kilo_user_id": { - "name": "admin_kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_34517df0b385234babc38fe81b": { - "name": "IDX_34517df0b385234babc38fe81b", - "columns": [ - { - "expression": "admin_kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_ccbde98c4c14046daa5682ec4f": { - "name": "IDX_ccbde98c4c14046daa5682ec4f", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_d0270eb24ef6442d65a0b7853c": { - "name": "IDX_d0270eb24ef6442d65a0b7853c", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_affiliate_attributions": { - "name": "user_affiliate_attributions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "tracking_id": { - "name": "tracking_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_user_affiliate_attributions_user_id": { - "name": "IDX_user_affiliate_attributions_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "user_affiliate_attributions_user_id_kilocode_users_id_fk": { - "name": "user_affiliate_attributions_user_id_kilocode_users_id_fk", - "tableFrom": "user_affiliate_attributions", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_user_affiliate_attributions_user_provider": { - "name": "UQ_user_affiliate_attributions_user_provider", - "nullsNotDistinct": false, - "columns": [ - "user_id", - "provider" - ] - } - }, - "policies": {}, - "checkConstraints": { - "user_affiliate_attributions_provider_check": { - "name": "user_affiliate_attributions_provider_check", - "value": "\"user_affiliate_attributions\".\"provider\" IN ('impact')" - } - }, - "isRLSEnabled": false - }, - "public.user_affiliate_events": { - "name": "user_affiliate_events", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "event_type": { - "name": "event_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dedupe_key": { - "name": "dedupe_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "parent_event_id": { - "name": "parent_event_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "delivery_state": { - "name": "delivery_state", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'queued'" - }, - "payload_json": { - "name": "payload_json", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "stripe_charge_id": { - "name": "stripe_charge_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "impact_action_id": { - "name": "impact_action_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "impact_submission_uri": { - "name": "impact_submission_uri", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "attempt_count": { - "name": "attempt_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "next_retry_at": { - "name": "next_retry_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "claimed_at": { - "name": "claimed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_user_affiliate_events_claim_path": { - "name": "IDX_user_affiliate_events_claim_path", - "columns": [ - { - "expression": "delivery_state", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", - "asc": true, - "isExpression": true, - "nulls": "last" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_affiliate_events_parent_event_id": { - "name": "IDX_user_affiliate_events_parent_event_id", - "columns": [ - { - "expression": "parent_event_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_affiliate_events_provider_event_type_charge": { - "name": "IDX_user_affiliate_events_provider_event_type_charge", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "event_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "stripe_charge_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "user_affiliate_events_user_id_kilocode_users_id_fk": { - "name": "user_affiliate_events_user_id_kilocode_users_id_fk", - "tableFrom": "user_affiliate_events", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "user_affiliate_events_parent_event_id_fk": { - "name": "user_affiliate_events_parent_event_id_fk", - "tableFrom": "user_affiliate_events", - "tableTo": "user_affiliate_events", - "columnsFrom": [ - "parent_event_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_user_affiliate_events_dedupe_key": { - "name": "UQ_user_affiliate_events_dedupe_key", - "nullsNotDistinct": false, - "columns": [ - "dedupe_key" - ] - } - }, - "policies": {}, - "checkConstraints": { - "user_affiliate_events_provider_check": { - "name": "user_affiliate_events_provider_check", - "value": "\"user_affiliate_events\".\"provider\" IN ('impact')" - }, - "user_affiliate_events_event_type_check": { - "name": "user_affiliate_events_event_type_check", - "value": "\"user_affiliate_events\".\"event_type\" IN ('signup', 'trial_start', 'trial_end', 'sale', 'sale_reversal')" - }, - "user_affiliate_events_delivery_state_check": { - "name": "user_affiliate_events_delivery_state_check", - "value": "\"user_affiliate_events\".\"delivery_state\" IN ('queued', 'blocked', 'sending', 'delivered', 'failed')" - }, - "user_affiliate_events_attempt_count_non_negative_check": { - "name": "user_affiliate_events_attempt_count_non_negative_check", - "value": "\"user_affiliate_events\".\"attempt_count\" >= 0" - } - }, - "isRLSEnabled": false - }, - "public.user_auth_provider": { - "name": "user_auth_provider", - "schema": "", - "columns": { - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "avatar_url": { - "name": "avatar_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "display_name": { - "name": "display_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "hosted_domain": { - "name": "hosted_domain", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_user_auth_provider_kilo_user_id": { - "name": "IDX_user_auth_provider_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_auth_provider_hosted_domain": { - "name": "IDX_user_auth_provider_hosted_domain", - "columns": [ - { - "expression": "hosted_domain", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": { - "user_auth_provider_provider_provider_account_id_pk": { - "name": "user_auth_provider_provider_provider_account_id_pk", - "columns": [ - "provider", - "provider_account_id" - ] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_feedback": { - "name": "user_feedback", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "feedback_text": { - "name": "feedback_text", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "feedback_for": { - "name": "feedback_for", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'unknown'" - }, - "feedback_batch": { - "name": "feedback_batch", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "source": { - "name": "source", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'unknown'" - }, - "context_json": { - "name": "context_json", - "type": "jsonb", - "primaryKey": false, - "notNull": true, - "default": "'{}'::jsonb" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_user_feedback_created_at": { - "name": "IDX_user_feedback_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_feedback_kilo_user_id": { - "name": "IDX_user_feedback_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_feedback_feedback_for": { - "name": "IDX_user_feedback_feedback_for", - "columns": [ - { - "expression": "feedback_for", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_feedback_feedback_batch": { - "name": "IDX_user_feedback_feedback_batch", - "columns": [ - { - "expression": "feedback_batch", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_feedback_source": { - "name": "IDX_user_feedback_source", - "columns": [ - { - "expression": "source", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "user_feedback_kilo_user_id_kilocode_users_id_fk": { - "name": "user_feedback_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "user_feedback", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "set null", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_period_cache": { - "name": "user_period_cache", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "cache_type": { - "name": "cache_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "period_type": { - "name": "period_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "period_key": { - "name": "period_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data": { - "name": "data", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "computed_at": { - "name": "computed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "version": { - "name": "version", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "shared_url_token": { - "name": "shared_url_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "shared_at": { - "name": "shared_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "IDX_user_period_cache_kilo_user_id": { - "name": "IDX_user_period_cache_kilo_user_id", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_user_period_cache": { - "name": "UQ_user_period_cache", - "columns": [ - { - "expression": "kilo_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "cache_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "period_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "period_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_period_cache_lookup": { - "name": "IDX_user_period_cache_lookup", - "columns": [ - { - "expression": "cache_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "period_type", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "period_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "UQ_user_period_cache_share_token": { - "name": "UQ_user_period_cache_share_token", - "columns": [ - { - "expression": "shared_url_token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"user_period_cache\".\"shared_url_token\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "user_period_cache_kilo_user_id_kilocode_users_id_fk": { - "name": "user_period_cache_kilo_user_id_kilocode_users_id_fk", - "tableFrom": "user_period_cache", - "tableTo": "kilocode_users", - "columnsFrom": [ - "kilo_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "user_period_cache_period_type_check": { - "name": "user_period_cache_period_type_check", - "value": "\"user_period_cache\".\"period_type\" IN ('year', 'quarter', 'month', 'week', 'custom')" - } - }, - "isRLSEnabled": false - }, - "public.user_push_tokens": { - "name": "user_push_tokens", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "UQ_user_push_tokens_token": { - "name": "UQ_user_push_tokens_token", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_user_push_tokens_user_id": { - "name": "IDX_user_push_tokens_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "user_push_tokens_user_id_kilocode_users_id_fk": { - "name": "user_push_tokens_user_id_kilocode_users_id_fk", - "tableFrom": "user_push_tokens", - "tableTo": "kilocode_users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.vercel_ip_city": { - "name": "vercel_ip_city", - "schema": "", - "columns": { - "vercel_ip_city_id": { - "name": "vercel_ip_city_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "vercel_ip_city": { - "name": "vercel_ip_city", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_vercel_ip_city": { - "name": "UQ_vercel_ip_city", - "columns": [ - { - "expression": "vercel_ip_city", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.vercel_ip_country": { - "name": "vercel_ip_country", - "schema": "", - "columns": { - "vercel_ip_country_id": { - "name": "vercel_ip_country_id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "vercel_ip_country": { - "name": "vercel_ip_country", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "UQ_vercel_ip_country": { - "name": "UQ_vercel_ip_country", - "columns": [ - { - "expression": "vercel_ip_country", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.webhook_events": { - "name": "webhook_events", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "pg_catalog.gen_random_uuid()" - }, - "owned_by_organization_id": { - "name": "owned_by_organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "owned_by_user_id": { - "name": "owned_by_user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "platform": { - "name": "platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "event_type": { - "name": "event_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "event_action": { - "name": "event_action", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "payload": { - "name": "payload", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "headers": { - "name": "headers", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "processed": { - "name": "processed", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "processed_at": { - "name": "processed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "handlers_triggered": { - "name": "handlers_triggered", - "type": "text[]", - "primaryKey": false, - "notNull": true, - "default": "'{}'" - }, - "errors": { - "name": "errors", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "event_signature": { - "name": "event_signature", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "IDX_webhook_events_owned_by_org_id": { - "name": "IDX_webhook_events_owned_by_org_id", - "columns": [ - { - "expression": "owned_by_organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_webhook_events_owned_by_user_id": { - "name": "IDX_webhook_events_owned_by_user_id", - "columns": [ - { - "expression": "owned_by_user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_webhook_events_platform": { - "name": "IDX_webhook_events_platform", - "columns": [ - { - "expression": "platform", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_webhook_events_event_type": { - "name": "IDX_webhook_events_event_type", - "columns": [ - { - "expression": "event_type", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "IDX_webhook_events_created_at": { - "name": "IDX_webhook_events_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "webhook_events_owned_by_organization_id_organizations_id_fk": { - "name": "webhook_events_owned_by_organization_id_organizations_id_fk", - "tableFrom": "webhook_events", - "tableTo": "organizations", - "columnsFrom": [ - "owned_by_organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "webhook_events_owned_by_user_id_kilocode_users_id_fk": { - "name": "webhook_events_owned_by_user_id_kilocode_users_id_fk", - "tableFrom": "webhook_events", - "tableTo": "kilocode_users", - "columnsFrom": [ - "owned_by_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "UQ_webhook_events_signature": { - "name": "UQ_webhook_events_signature", - "nullsNotDistinct": false, - "columns": [ - "event_signature" - ] - } - }, - "policies": {}, - "checkConstraints": { - "webhook_events_owner_check": { - "name": "webhook_events_owner_check", - "value": "(\n (\"webhook_events\".\"owned_by_user_id\" IS NOT NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NULL) OR\n (\"webhook_events\".\"owned_by_user_id\" IS NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NOT NULL)\n )" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": { - "public.microdollar_usage_view": { - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "kilo_user_id": { - "name": "kilo_user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "message_id": { - "name": "message_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cost": { - "name": "cost", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "input_tokens": { - "name": "input_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "output_tokens": { - "name": "output_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "cache_write_tokens": { - "name": "cache_write_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "cache_hit_tokens": { - "name": "cache_hit_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "http_x_forwarded_for": { - "name": "http_x_forwarded_for", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_city": { - "name": "http_x_vercel_ip_city", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_country": { - "name": "http_x_vercel_ip_country", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_latitude": { - "name": "http_x_vercel_ip_latitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ip_longitude": { - "name": "http_x_vercel_ip_longitude", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "http_x_vercel_ja4_digest": { - "name": "http_x_vercel_ja4_digest", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "requested_model": { - "name": "requested_model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_prompt_prefix": { - "name": "user_prompt_prefix", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "system_prompt_prefix": { - "name": "system_prompt_prefix", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "system_prompt_length": { - "name": "system_prompt_length", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "http_user_agent": { - "name": "http_user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "cache_discount": { - "name": "cache_discount", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "max_tokens": { - "name": "max_tokens", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "has_middle_out_transform": { - "name": "has_middle_out_transform", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "has_error": { - "name": "has_error", - "type": "boolean", - "primaryKey": false, - "notNull": true - }, - "abuse_classification": { - "name": "abuse_classification", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "inference_provider": { - "name": "inference_provider", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "project_id": { - "name": "project_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "status_code": { - "name": "status_code", - "type": "smallint", - "primaryKey": false, - "notNull": false - }, - "upstream_id": { - "name": "upstream_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "finish_reason": { - "name": "finish_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "latency": { - "name": "latency", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "moderation_latency": { - "name": "moderation_latency", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "generation_time": { - "name": "generation_time", - "type": "real", - "primaryKey": false, - "notNull": false - }, - "is_byok": { - "name": "is_byok", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "is_user_byok": { - "name": "is_user_byok", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "streamed": { - "name": "streamed", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "cancelled": { - "name": "cancelled", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "editor_name": { - "name": "editor_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "api_kind": { - "name": "api_kind", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "has_tools": { - "name": "has_tools", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "machine_id": { - "name": "machine_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "feature": { - "name": "feature", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_id": { - "name": "session_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "mode": { - "name": "mode", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "auto_model": { - "name": "auto_model", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "market_cost": { - "name": "market_cost", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "is_free": { - "name": "is_free", - "type": "boolean", - "primaryKey": false, - "notNull": false - } - }, - "definition": "\n SELECT\n mu.id,\n mu.kilo_user_id,\n meta.message_id,\n mu.cost,\n mu.input_tokens,\n mu.output_tokens,\n mu.cache_write_tokens,\n mu.cache_hit_tokens,\n mu.created_at,\n ip.http_ip AS http_x_forwarded_for,\n city.vercel_ip_city AS http_x_vercel_ip_city,\n country.vercel_ip_country AS http_x_vercel_ip_country,\n meta.vercel_ip_latitude AS http_x_vercel_ip_latitude,\n meta.vercel_ip_longitude AS http_x_vercel_ip_longitude,\n ja4.ja4_digest AS http_x_vercel_ja4_digest,\n mu.provider,\n mu.model,\n mu.requested_model,\n meta.user_prompt_prefix,\n spp.system_prompt_prefix,\n meta.system_prompt_length,\n ua.http_user_agent,\n mu.cache_discount,\n meta.max_tokens,\n meta.has_middle_out_transform,\n mu.has_error,\n mu.abuse_classification,\n mu.organization_id,\n mu.inference_provider,\n mu.project_id,\n meta.status_code,\n meta.upstream_id,\n frfr.finish_reason,\n meta.latency,\n meta.moderation_latency,\n meta.generation_time,\n meta.is_byok,\n meta.is_user_byok,\n meta.streamed,\n meta.cancelled,\n edit.editor_name,\n ak.api_kind,\n meta.has_tools,\n meta.machine_id,\n feat.feature,\n meta.session_id,\n md.mode,\n am.auto_model,\n meta.market_cost,\n meta.is_free\n FROM \"microdollar_usage\" mu\n LEFT JOIN \"microdollar_usage_metadata\" meta ON mu.id = meta.id\n LEFT JOIN \"http_ip\" ip ON meta.http_ip_id = ip.http_ip_id\n LEFT JOIN \"vercel_ip_city\" city ON meta.vercel_ip_city_id = city.vercel_ip_city_id\n LEFT JOIN \"vercel_ip_country\" country ON meta.vercel_ip_country_id = country.vercel_ip_country_id\n LEFT JOIN \"ja4_digest\" ja4 ON meta.ja4_digest_id = ja4.ja4_digest_id\n LEFT JOIN \"system_prompt_prefix\" spp ON meta.system_prompt_prefix_id = spp.system_prompt_prefix_id\n LEFT JOIN \"http_user_agent\" ua ON meta.http_user_agent_id = ua.http_user_agent_id\n LEFT JOIN \"finish_reason\" frfr ON meta.finish_reason_id = frfr.finish_reason_id\n LEFT JOIN \"editor_name\" edit ON meta.editor_name_id = edit.editor_name_id\n LEFT JOIN \"api_kind\" ak ON meta.api_kind_id = ak.api_kind_id\n LEFT JOIN \"feature\" feat ON meta.feature_id = feat.feature_id\n LEFT JOIN \"mode\" md ON meta.mode_id = md.mode_id\n LEFT JOIN \"auto_model\" am ON meta.auto_model_id = am.auto_model_id\n", - "name": "microdollar_usage_view", - "schema": "public", - "isExisting": false, - "materialized": false - } - }, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json index 748eb41d1b..9ffedee20e 100644 --- a/packages/db/src/migrations/meta/_journal.json +++ b/packages/db/src/migrations/meta/_journal.json @@ -806,13 +806,6 @@ "when": 1778050833487, "tag": "0114_steep_hercules", "breakpoints": true - }, - { - "idx": 115, - "version": "7", - "when": 1778071256277, - "tag": "0115_amazing_scrambler", - "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/packages/db/src/schema.test.ts b/packages/db/src/schema.test.ts index 761bbdd4bf..860645307e 100644 --- a/packages/db/src/schema.test.ts +++ b/packages/db/src/schema.test.ts @@ -6,11 +6,6 @@ import * as schema from './schema'; import { SCHEMA_CHECK_ENUMS } from './schema'; describe('database schema', () => { - it('includes Apple IAP purchase and notification tables', () => { - expect(Object.hasOwn(schema, 'apple_iap_purchases')).toBe(true); - expect(Object.hasOwn(schema, 'apple_iap_notifications')).toBe(true); - }); - it("should be up to date with migrations (run 'pnpm drizzle generate' if this fails)", async () => { const migrationsDir = './packages/db/src/migrations'; diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index 51d301a1d7..d6bdfb58fb 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -194,95 +194,6 @@ export const credit_transactions = pgTable( export type CreditTransaction = typeof credit_transactions.$inferSelect; -export const apple_iap_purchases = pgTable( - 'apple_iap_purchases', - { - id: uuid() - .default(sql`pg_catalog.gen_random_uuid()`) - .primaryKey() - .notNull(), - kilo_user_id: text() - .notNull() - .references(() => kilocode_users.id), - apple_transaction_id: text().notNull(), - apple_original_transaction_id: text().notNull(), - apple_web_order_line_item_id: text(), - product_id: text().notNull(), - environment: text().notNull(), - bundle_id: text().notNull(), - purchase_date: timestamp({ withTimezone: true, mode: 'string' }).notNull(), - gross_price_cents: integer().notNull(), - credited_cents: integer().notNull(), - credited_microdollars: bigint({ mode: 'number' }).notNull(), - signed_transaction_jws: text().notNull(), - status: text().notNull(), - credit_transaction_id: uuid() - .notNull() - .references(() => credit_transactions.id), - refunded_at: timestamp({ withTimezone: true, mode: 'string' }), - refund_credit_transaction_id: uuid().references(() => credit_transactions.id), - created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), - updated_at: timestamp({ withTimezone: true, mode: 'string' }) - .defaultNow() - .notNull() - .$onUpdateFn(() => sql`now()`), - }, - table => [ - uniqueIndex('UQ_apple_iap_purchases_transaction_id').on(table.apple_transaction_id), - uniqueIndex('UQ_apple_iap_purchases_credit_transaction_id').on(table.credit_transaction_id), - uniqueIndex('UQ_apple_iap_purchases_refund_credit_transaction_id') - .on(table.refund_credit_transaction_id) - .where(isNotNull(table.refund_credit_transaction_id)), - index('IDX_apple_iap_purchases_user_id').on(table.kilo_user_id), - index('IDX_apple_iap_purchases_original_transaction_id').on( - table.apple_original_transaction_id - ), - check( - 'apple_iap_purchases_status_check', - sql`${table.status} IN ('granted', 'refunded', 'revoked')` - ), - check( - 'apple_iap_purchases_environment_check', - sql`${table.environment} IN ('Sandbox', 'Production')` - ), - check('apple_iap_purchases_credited_positive_check', sql`${table.credited_cents} > 0`), - ] -); - -export type AppleIapPurchase = typeof apple_iap_purchases.$inferSelect; - -export const apple_iap_notifications = pgTable( - 'apple_iap_notifications', - { - id: uuid() - .default(sql`pg_catalog.gen_random_uuid()`) - .primaryKey() - .notNull(), - notification_uuid: text().notNull(), - notification_type: text().notNull(), - subtype: text(), - environment: text().notNull(), - apple_transaction_id: text(), - apple_original_transaction_id: text(), - signed_payload_jws: text().notNull(), - processed_at: timestamp({ withTimezone: true, mode: 'string' }), - created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), - }, - table => [ - uniqueIndex('UQ_apple_iap_notifications_uuid').on(table.notification_uuid), - index('IDX_apple_iap_notifications_transaction_id').on(table.apple_transaction_id), - index('IDX_apple_iap_notifications_original_transaction_id').on( - table.apple_original_transaction_id - ), - check( - 'apple_iap_notifications_environment_check', - sql`${table.environment} IN ('Sandbox', 'Production')` - ), - ] -); - -export type AppleIapNotification = typeof apple_iap_notifications.$inferSelect; - export const credit_campaigns = pgTable( 'credit_campaigns', { From 18aaf7321f7415009847c93e179b95a6094162f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 19:33:02 +0200 Subject: [PATCH 21/34] feat(kilo-pass): add app store subscriptions --- apps/mobile/src/components/home/greeting.tsx | 26 - .../kilo-pass/kilo-pass-subscription-card.tsx | 67 + .../kilo-pass-subscription-sheet.tsx | 112 + .../src/components/profile-credits-card.tsx | 2 + .../src/lib/kilo-pass/store-products.test.ts | 48 + .../src/lib/kilo-pass/store-products.ts | 51 + .../kilo-pass/use-store-kilo-pass-products.ts | 44 + .../use-store-kilo-pass-purchase.test.tsx | 130 + .../kilo-pass/use-store-kilo-pass-purchase.ts | 88 + apps/mobile/vitest.config.ts | 2 + .../apple/notifications/route.test.ts | 57 + .../kilo-pass/apple/notifications/route.ts | 25 + .../apple-store-notifications.test.ts | 115 + .../kilo-pass/apple-store-notifications.ts | 192 + .../kilo-pass/apple-store-verifier.test.ts | 59 + .../src/lib/kilo-pass/apple-store-verifier.ts | 152 + apps/web/src/lib/kilo-pass/enums.ts | 1 + apps/web/src/lib/kilo-pass/issuance.ts | 31 +- .../lib/kilo-pass/mobile-store-products.ts | 98 + apps/web/src/lib/kilo-pass/state.ts | 18 +- .../store-subscription-completion.test.ts | 139 + .../store-subscription-completion.ts | 228 + .../store-subscription-products.test.ts | 26 + .../kilo-pass/stripe-handlers-invoice-paid.ts | 5 + .../stripe-handlers-subscription-events.ts | 14 +- apps/web/src/routers/kilo-pass-router.ts | 118 +- .../0115_productive_captain_cross.sql | 50 + .../db/src/migrations/meta/0115_snapshot.json | 19125 ++++++++++++++++ packages/db/src/migrations/meta/_journal.json | 9 +- packages/db/src/schema-types.ts | 14 + packages/db/src/schema.test.ts | 19 +- packages/db/src/schema.ts | 105 +- 32 files changed, 21126 insertions(+), 44 deletions(-) create mode 100644 apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx create mode 100644 apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx create mode 100644 apps/mobile/src/lib/kilo-pass/store-products.test.ts create mode 100644 apps/mobile/src/lib/kilo-pass/store-products.ts create mode 100644 apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-products.ts create mode 100644 apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx create mode 100644 apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts create mode 100644 apps/web/src/app/api/kilo-pass/apple/notifications/route.test.ts create mode 100644 apps/web/src/app/api/kilo-pass/apple/notifications/route.ts create mode 100644 apps/web/src/lib/kilo-pass/apple-store-notifications.test.ts create mode 100644 apps/web/src/lib/kilo-pass/apple-store-notifications.ts create mode 100644 apps/web/src/lib/kilo-pass/apple-store-verifier.test.ts create mode 100644 apps/web/src/lib/kilo-pass/apple-store-verifier.ts create mode 100644 apps/web/src/lib/kilo-pass/mobile-store-products.ts create mode 100644 apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts create mode 100644 apps/web/src/lib/kilo-pass/store-subscription-completion.ts create mode 100644 apps/web/src/lib/kilo-pass/store-subscription-products.test.ts create mode 100644 packages/db/src/migrations/0115_productive_captain_cross.sql create mode 100644 packages/db/src/migrations/meta/0115_snapshot.json diff --git a/apps/mobile/src/components/home/greeting.tsx b/apps/mobile/src/components/home/greeting.tsx index 1f4b739189..8d9e02ac40 100644 --- a/apps/mobile/src/components/home/greeting.tsx +++ b/apps/mobile/src/components/home/greeting.tsx @@ -1,13 +1,3 @@ -import { View } from 'react-native'; - -import { Text } from '@/components/ui/text'; - -type GreetingProps = { - title: string; - eyebrow?: string; - subtitle?: string; -}; - function timeOfDay(hour: number): 'morning' | 'afternoon' | 'evening' { if (hour < 12) { return 'morning'; @@ -22,19 +12,3 @@ export function buildTimedGreeting(firstName: string | null): string { const period = timeOfDay(new Date().getHours()); return firstName ? `Good ${period}, ${firstName}` : `Good ${period}`; } - -export function Greeting({ title, eyebrow, subtitle }: Readonly) { - return ( - - {eyebrow ? {eyebrow} : null} - - {title} - {subtitle ? ( - - {` ${subtitle}`} - - ) : null} - - - ); -} diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx new file mode 100644 index 0000000000..eae8a0c343 --- /dev/null +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx @@ -0,0 +1,67 @@ +import { useState } from 'react'; +import { Platform, Pressable, View } from 'react-native'; +import { ShieldCheck } from 'lucide-react-native'; +import { useQuery } from '@tanstack/react-query'; + +import { Text } from '@/components/ui/text'; +import { KiloPassSubscriptionSheet } from '@/components/kilo-pass/kilo-pass-subscription-sheet'; +import { useThemeColors } from '@/lib/hooks/use-theme-colors'; +import { useTRPC } from '@/lib/trpc'; +import { useStoreKiloPassProducts } from '@/lib/kilo-pass/use-store-kilo-pass-products'; +import { useStoreKiloPassPurchase } from '@/lib/kilo-pass/use-store-kilo-pass-purchase'; + +export function KiloPassSubscriptionCard() { + const [sheetVisible, setSheetVisible] = useState(false); + const colors = useThemeColors(); + const trpc = useTRPC(); + const stateQuery = useQuery(trpc.kiloPass.getState.queryOptions()); + const productsQuery = useStoreKiloPassProducts(); + const purchase = useStoreKiloPassPurchase(); + + if (Platform.OS !== 'ios') { + return null; + } + + const subscription = stateQuery.data?.subscription; + const title = subscription ? 'Kilo Pass active' : 'Kilo Pass'; + const description = subscription + ? `$${subscription.currentPeriodBaseCreditsUsd.toFixed(0)} monthly credits` + : 'Subscribe with your App Store account'; + + return ( + <> + { + setSheetVisible(true); + }} + > + + + + + + {title} + {description} + + + {subscription ? 'Manage' : 'Subscribe'} + + + + + { + setSheetVisible(false); + }} + onPurchase={product => { + void purchase.purchase(product); + }} + /> + + ); +} diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx new file mode 100644 index 0000000000..9d52723ce4 --- /dev/null +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx @@ -0,0 +1,112 @@ +import { Check, X } from 'lucide-react-native'; +import { ActivityIndicator, Modal, Pressable, View } from 'react-native'; + +import { Button } from '@/components/ui/button'; +import { Skeleton } from '@/components/ui/skeleton'; +import { Text } from '@/components/ui/text'; +import { useThemeColors } from '@/lib/hooks/use-theme-colors'; +import { type AppStoreKiloPassProduct } from '@/lib/kilo-pass/store-products'; + +type KiloPassSubscriptionSheetProps = { + visible: boolean; + products: AppStoreKiloPassProduct[]; + isLoading: boolean; + isPurchasing: boolean; + onClose: () => void; + onPurchase: (product: AppStoreKiloPassProduct) => void; +}; + +function formatTier(product: AppStoreKiloPassProduct): string { + return `$${product.webMonthlyPriceUsd}/mo credits`; +} + +function formatCadence(product: AppStoreKiloPassProduct): string { + return product.cadence === 'yearly' ? 'Yearly' : 'Monthly'; +} + +export function KiloPassSubscriptionSheet({ + visible, + products, + isLoading, + isPurchasing, + onClose, + onPurchase, +}: Readonly) { + const colors = useThemeColors(); + + return ( + + + + + + + Kilo Pass + App Store subscription + + + + + + + + {isLoading && + [0, 1, 2].map(index => ( + + ))} + + {!isLoading && + products.map(product => ( + { + onPurchase(product); + }} + > + + + + {formatTier(product)} · {formatCadence(product)} + + + Same Kilo Pass credits and bonus progress as web. + + + {product.displayPrice} + + + + + Credits are added after store validation. + + + + ))} + + + + + + + ); +} diff --git a/apps/mobile/src/components/profile-credits-card.tsx b/apps/mobile/src/components/profile-credits-card.tsx index a0e475a2eb..97317fd8d0 100644 --- a/apps/mobile/src/components/profile-credits-card.tsx +++ b/apps/mobile/src/components/profile-credits-card.tsx @@ -5,6 +5,7 @@ import { ActivityIndicator, Pressable, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'; +import { KiloPassSubscriptionCard } from '@/components/kilo-pass/kilo-pass-subscription-card'; import { Skeleton } from '@/components/ui/skeleton'; import { Text } from '@/components/ui/text'; import { useThemeColors } from '@/lib/hooks/use-theme-colors'; @@ -146,6 +147,7 @@ export function CreditsCard({ orgs }: Readonly) { {balanceFetching && } )} + {!selectedOrgId && } ); } diff --git a/apps/mobile/src/lib/kilo-pass/store-products.test.ts b/apps/mobile/src/lib/kilo-pass/store-products.test.ts new file mode 100644 index 0000000000..daf131472b --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/store-products.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, it } from 'vitest'; + +import { joinAppStoreKiloPassProducts } from './store-products'; + +describe('joinAppStoreKiloPassProducts', () => { + it('joins backend Apple product ids to localized App Store subscription metadata', () => { + const products = joinAppStoreKiloPassProducts({ + backendProducts: [ + { + tier: 'tier_19', + cadence: 'monthly', + appleProductId: 'kilopass.tier19.monthly.v1', + googleProductId: 'kilopass_tier19', + googleBasePlanId: 'monthly-v1', + webMonthlyPriceUsd: 19, + suggestedStoreMonthlyPriceUsd: 24.7, + }, + { + tier: 'tier_49', + cadence: 'monthly', + appleProductId: 'kilopass.tier49.monthly.v1', + googleProductId: 'kilopass_tier49', + googleBasePlanId: 'monthly-v1', + webMonthlyPriceUsd: 49, + suggestedStoreMonthlyPriceUsd: 63.7, + }, + ], + storeProducts: [ + { + id: 'kilopass.tier19.monthly.v1', + displayPrice: '$24.99', + title: 'Kilo Pass 19', + description: 'Kilo Pass', + }, + ], + }); + + expect(products).toEqual([ + expect.objectContaining({ + tier: 'tier_19', + cadence: 'monthly', + appleProductId: 'kilopass.tier19.monthly.v1', + displayPrice: '$24.99', + title: 'Kilo Pass 19', + }), + ]); + }); +}); diff --git a/apps/mobile/src/lib/kilo-pass/store-products.ts b/apps/mobile/src/lib/kilo-pass/store-products.ts new file mode 100644 index 0000000000..eb2a2bf46e --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/store-products.ts @@ -0,0 +1,51 @@ +import { type inferRouterOutputs, type RootRouter } from '@kilocode/trpc'; +import { type ProductSubscription } from 'expo-iap'; + +type RouterOutputs = inferRouterOutputs; + +type BackendStoreKiloPassProductOutput = + RouterOutputs['kiloPass']['getMobileStoreProducts']['products'][number]; + +export type BackendStoreKiloPassProduct = Omit< + BackendStoreKiloPassProductOutput, + 'tier' | 'cadence' +> & { + tier: `${BackendStoreKiloPassProductOutput['tier']}`; + cadence: `${BackendStoreKiloPassProductOutput['cadence']}`; +}; + +type MinimalStoreProduct = Pick< + ProductSubscription, + 'id' | 'displayPrice' | 'title' | 'description' +>; + +export type AppStoreKiloPassProduct = BackendStoreKiloPassProduct & { + displayPrice: string; + title: string; + description: string; + storeProduct: ProductSubscription | MinimalStoreProduct; +}; + +export function joinAppStoreKiloPassProducts(params: { + backendProducts: readonly BackendStoreKiloPassProduct[]; + storeProducts: readonly (ProductSubscription | MinimalStoreProduct)[]; +}): AppStoreKiloPassProduct[] { + const storeById = new Map(params.storeProducts.map(product => [product.id, product])); + + return params.backendProducts.flatMap(backendProduct => { + const storeProduct = storeById.get(backendProduct.appleProductId); + if (!storeProduct) { + return []; + } + + return [ + { + ...backendProduct, + displayPrice: storeProduct.displayPrice, + title: storeProduct.title, + description: storeProduct.description, + storeProduct, + }, + ]; + }); +} diff --git a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-products.ts b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-products.ts new file mode 100644 index 0000000000..aaa30e265a --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-products.ts @@ -0,0 +1,44 @@ +import { useEffect, useMemo } from 'react'; +import { Platform } from 'react-native'; +import { useQuery } from '@tanstack/react-query'; +import { useIAP } from 'expo-iap'; +import { toast } from 'sonner-native'; + +import { useTRPC } from '@/lib/trpc'; +import { joinAppStoreKiloPassProducts } from './store-products'; + +export function useStoreKiloPassProducts() { + const trpc = useTRPC(); + const productsQuery = useQuery(trpc.kiloPass.getMobileStoreProducts.queryOptions()); + const iap = useIAP({ + onError: error => { + toast.error(error.message); + }, + }); + + const backendProducts = useMemo( + () => productsQuery.data?.products ?? [], + [productsQuery.data?.products] + ); + + useEffect(() => { + if (!iap.connected || Platform.OS !== 'ios' || backendProducts.length === 0) { + return; + } + + void iap.fetchProducts({ + skus: backendProducts.map(product => product.appleProductId), + type: 'subs', + }); + }, [backendProducts, iap]); + + return { + products: joinAppStoreKiloPassProducts({ + backendProducts, + storeProducts: iap.subscriptions, + }), + isLoading: productsQuery.isLoading || (iap.connected && iap.subscriptions.length === 0), + isError: productsQuery.isError, + refetch: productsQuery.refetch, + }; +} diff --git a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx new file mode 100644 index 0000000000..3277841705 --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx @@ -0,0 +1,130 @@ +import { type Purchase } from 'expo-iap'; +import { describe, expect, it, vi } from 'vitest'; +import { createAppStoreKiloPassPurchaseActions } from './use-store-kilo-pass-purchase'; +import { type AppStoreKiloPassProduct } from './store-products'; + +vi.mock('expo-iap', () => ({ + useIAP: () => ({ + finishTransaction: vi.fn(), + requestPurchase: vi.fn(), + }), +})); + +vi.mock('@tanstack/react-query', () => ({ + useMutation: () => ({ isPending: false, mutateAsync: vi.fn() }), + useQueryClient: () => ({ invalidateQueries: vi.fn() }), +})); + +vi.mock('sonner-native', () => ({ + toast: { error: vi.fn() }, +})); + +vi.mock('@/lib/trpc', () => ({ + useTRPC: () => ({ + kiloPass: { + completeAppStorePurchase: { mutationOptions: () => ({}) }, + getCreditHistory: { pathFilter: () => ({ queryKey: ['credit-history'] }) }, + getState: { pathFilter: () => ({ queryKey: ['state'] }) }, + }, + user: { + getContextBalance: { pathFilter: () => ({ queryKey: ['balance'] }) }, + getCreditBlocks: { pathFilter: () => ({ queryKey: ['credits'] }) }, + }, + }), +})); + +const product: AppStoreKiloPassProduct = { + appleProductId: 'kilopass.tier19.monthly.v1', + cadence: 'monthly', + description: 'Kilo Pass', + displayPrice: '$24.99', + googleBasePlanId: 'monthly-v1', + googleProductId: 'kilopass_tier19', + storeProduct: { + id: 'kilopass.tier19.monthly.v1', + displayPrice: '$24.99', + title: 'Kilo Pass', + description: 'Kilo Pass', + }, + suggestedStoreMonthlyPriceUsd: 24.7, + tier: 'tier_19', + title: 'Kilo Pass', + webMonthlyPriceUsd: 19, +}; + +describe('createAppStoreKiloPassPurchaseActions', () => { + it('requests an App Store subscription purchase', async () => { + const requestPurchase = vi.fn().mockResolvedValue(null); + const actions = createAppStoreKiloPassPurchaseActions({ + completeAppStorePurchase: vi.fn(), + finishTransaction: vi.fn(), + invalidateAfterCompletion: vi.fn(), + requestPurchase, + showError: () => undefined, + }); + + await actions.purchase(product); + + expect(requestPurchase).toHaveBeenCalledWith({ + request: { apple: { sku: product.appleProductId } }, + type: 'subs', + }); + }); + + it('does not finish the transaction when backend completion fails', async () => { + const finishTransaction = vi.fn(); + const actions = createAppStoreKiloPassPurchaseActions({ + completeAppStorePurchase: vi.fn().mockRejectedValue(new Error('backend failed')), + finishTransaction, + invalidateAfterCompletion: vi.fn(), + requestPurchase: vi.fn(), + showError: () => undefined, + }); + + await actions.handlePurchaseSuccess({ + id: 'purchase-1', + ids: null, + isAutoRenewing: true, + platform: 'ios', + productId: product.appleProductId, + purchaseState: 'purchased', + purchaseToken: 'signed-jws', + quantity: 1, + store: 'apple', + transactionDate: Date.now(), + transactionId: 'tx-1', + }); + + expect(finishTransaction).not.toHaveBeenCalled(); + }); + + it('finishes the transaction and invalidates Kilo Pass state after backend success', async () => { + const finishTransaction = vi.fn(); + const invalidateAfterCompletion = vi.fn(); + const purchase = { + id: 'purchase-1', + ids: null, + isAutoRenewing: true, + platform: 'ios', + productId: product.appleProductId, + purchaseState: 'purchased', + purchaseToken: 'signed-jws', + quantity: 1, + store: 'apple', + transactionDate: Date.now(), + transactionId: 'tx-1', + } satisfies Purchase; + const actions = createAppStoreKiloPassPurchaseActions({ + completeAppStorePurchase: vi.fn().mockResolvedValue({ alreadyProcessed: false }), + finishTransaction, + invalidateAfterCompletion, + requestPurchase: vi.fn(), + showError: () => undefined, + }); + + await actions.handlePurchaseSuccess(purchase); + + expect(invalidateAfterCompletion).toHaveBeenCalled(); + expect(finishTransaction).toHaveBeenCalledWith({ purchase, isConsumable: false }); + }); +}); diff --git a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts new file mode 100644 index 0000000000..a11ce6e4ae --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts @@ -0,0 +1,88 @@ +import { useCallback } from 'react'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { type Purchase, useIAP } from 'expo-iap'; +import { toast } from 'sonner-native'; + +import { useTRPC } from '@/lib/trpc'; +import { type AppStoreKiloPassProduct } from './store-products'; + +type AppStoreKiloPassPurchaseActionsDeps = { + requestPurchase: (params: { + request: { apple: { sku: string } }; + type: 'subs'; + }) => Promise; + completeAppStorePurchase: (input: { signedTransactionJws: string }) => Promise; + finishTransaction: (params: { purchase: Purchase; isConsumable: false }) => Promise; + invalidateAfterCompletion: () => Promise | void; + showError: (message: string) => void; +}; + +function getPurchaseToken(purchase: Purchase): string { + const token = purchase.purchaseToken; + if (!token) { + throw new Error('App Store purchase did not include a signed transaction JWS.'); + } + return token; +} + +export function createAppStoreKiloPassPurchaseActions(deps: AppStoreKiloPassPurchaseActionsDeps) { + return { + purchase: async (product: AppStoreKiloPassProduct) => { + await deps.requestPurchase({ + request: { apple: { sku: product.appleProductId } }, + type: 'subs', + }); + }, + handlePurchaseSuccess: async (purchase: Purchase) => { + try { + const signedTransactionJws = getPurchaseToken(purchase); + await deps.completeAppStorePurchase({ signedTransactionJws }); + await deps.invalidateAfterCompletion(); + await deps.finishTransaction({ purchase, isConsumable: false }); + } catch (error) { + deps.showError(error instanceof Error ? error.message : 'Failed to complete purchase.'); + } + }, + }; +} + +export function useStoreKiloPassPurchase() { + const trpc = useTRPC(); + const queryClient = useQueryClient(); + const completeAppStorePurchase = useMutation( + trpc.kiloPass.completeAppStorePurchase.mutationOptions() + ); + + const invalidateAfterCompletion = useCallback(async () => { + await Promise.all([ + queryClient.invalidateQueries(trpc.kiloPass.getState.pathFilter()), + queryClient.invalidateQueries(trpc.user.getContextBalance.pathFilter()), + queryClient.invalidateQueries(trpc.user.getCreditBlocks.pathFilter()), + queryClient.invalidateQueries(trpc.kiloPass.getCreditHistory.pathFilter()), + ]); + }, [queryClient, trpc]); + + const actionsRef = useIAP({ + onPurchaseError: error => { + toast.error(error.message); + }, + onPurchaseSuccess: purchase => { + void actions.handlePurchaseSuccess(purchase); + }, + }); + + const actions = createAppStoreKiloPassPurchaseActions({ + requestPurchase: actionsRef.requestPurchase, + completeAppStorePurchase: completeAppStorePurchase.mutateAsync, + finishTransaction: actionsRef.finishTransaction, + invalidateAfterCompletion, + showError: message => { + toast.error(message); + }, + }); + + return { + purchase: actions.purchase, + isPending: completeAppStorePurchase.isPending, + }; +} diff --git a/apps/mobile/vitest.config.ts b/apps/mobile/vitest.config.ts index f2b8c92fa1..4f0e22d42d 100644 --- a/apps/mobile/vitest.config.ts +++ b/apps/mobile/vitest.config.ts @@ -15,6 +15,8 @@ export default defineConfig({ 'src/lib/*.test.ts', 'src/lib/apple-iap/**/*.test.ts', 'src/lib/apple-iap/**/*.test.tsx', + 'src/lib/kilo-pass/**/*.test.ts', + 'src/lib/kilo-pass/**/*.test.tsx', 'src/lib/onboarding/**/*.test.ts', 'src/components/**/*.test.ts', ], diff --git a/apps/web/src/app/api/kilo-pass/apple/notifications/route.test.ts b/apps/web/src/app/api/kilo-pass/apple/notifications/route.test.ts new file mode 100644 index 0000000000..d895195228 --- /dev/null +++ b/apps/web/src/app/api/kilo-pass/apple/notifications/route.test.ts @@ -0,0 +1,57 @@ +import { captureException } from '@sentry/nextjs'; + +import { processAppStoreKiloPassNotification } from '@/lib/kilo-pass/apple-store-notifications'; +import { POST } from './route'; + +jest.mock('@sentry/nextjs', () => ({ + captureException: jest.fn(), +})); + +jest.mock('@/lib/kilo-pass/apple-store-notifications', () => ({ + processAppStoreKiloPassNotification: jest.fn(), +})); + +const mockProcess = jest.mocked(processAppStoreKiloPassNotification); + +function request(body: unknown) { + return new Request('https://app.example.com/api/kilo-pass/apple/notifications', { + method: 'POST', + body: JSON.stringify(body), + headers: { 'content-type': 'application/json' }, + }); +} + +describe('POST /api/kilo-pass/apple/notifications', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockProcess.mockResolvedValue({ processed: true }); + }); + + it('returns 400 when signedPayload is missing', async () => { + const response = await POST(request({})); + + expect(response.status).toBe(400); + expect(await response.json()).toEqual({ error: 'Missing signedPayload' }); + }); + + it('processes signed App Store notification payloads', async () => { + const response = await POST(request({ signedPayload: 'payload' })); + + expect(response.status).toBe(200); + expect(await response.json()).toEqual({ processed: true }); + expect(mockProcess).toHaveBeenCalledWith({ signedPayload: 'payload' }); + }); + + it('captures processing failures without exposing details', async () => { + const error = new Error('bad payload'); + mockProcess.mockRejectedValueOnce(error); + + const response = await POST(request({ signedPayload: 'payload' })); + + expect(response.status).toBe(500); + expect(await response.json()).toEqual({ error: 'Failed to process notification' }); + expect(captureException).toHaveBeenCalledWith(error, { + tags: { source: 'app_store_kilo_pass_notification' }, + }); + }); +}); diff --git a/apps/web/src/app/api/kilo-pass/apple/notifications/route.ts b/apps/web/src/app/api/kilo-pass/apple/notifications/route.ts new file mode 100644 index 0000000000..0b7c97ed27 --- /dev/null +++ b/apps/web/src/app/api/kilo-pass/apple/notifications/route.ts @@ -0,0 +1,25 @@ +import { captureException } from '@sentry/nextjs'; +import * as z from 'zod'; + +import { processAppStoreKiloPassNotification } from '@/lib/kilo-pass/apple-store-notifications'; + +const AppStoreNotificationBodySchema = z.object({ + signedPayload: z.string().min(1), +}); + +export async function POST(request: Request) { + try { + const body = AppStoreNotificationBodySchema.safeParse(await request.json()); + if (!body.success) { + return Response.json({ error: 'Missing signedPayload' }, { status: 400 }); + } + + const result = await processAppStoreKiloPassNotification({ + signedPayload: body.data.signedPayload, + }); + return Response.json(result); + } catch (error) { + captureException(error, { tags: { source: 'app_store_kilo_pass_notification' } }); + return Response.json({ error: 'Failed to process notification' }, { status: 500 }); + } +} diff --git a/apps/web/src/lib/kilo-pass/apple-store-notifications.test.ts b/apps/web/src/lib/kilo-pass/apple-store-notifications.test.ts new file mode 100644 index 0000000000..a5b24afbb1 --- /dev/null +++ b/apps/web/src/lib/kilo-pass/apple-store-notifications.test.ts @@ -0,0 +1,115 @@ +import { describe, expect, it } from '@jest/globals'; +import { eq } from 'drizzle-orm'; + +import { kilo_pass_store_events, kilo_pass_subscriptions } from '@kilocode/db/schema'; +import { db } from '@/lib/drizzle'; +import { insertTestUser } from '@/tests/helpers/user.helper'; +import { KiloPassPaymentProvider } from './enums'; +import { processAppStoreKiloPassNotification } from './apple-store-notifications'; +import type { AppleStoreDecodedNotification } from './apple-store-notifications'; +import type { AppleStoreDecodedTransaction } from './apple-store-verifier'; + +function notification( + overrides: Partial = {} +): AppleStoreDecodedNotification { + return { + notificationUUID: `note-${crypto.randomUUID()}`, + notificationType: 'DID_RENEW', + environment: 'Sandbox', + signedTransactionInfo: 'signed-transaction', + ...overrides, + }; +} + +function transaction( + overrides: Partial = {} +): AppleStoreDecodedTransaction { + return { + transactionId: `tx-${crypto.randomUUID()}`, + originalTransactionId: `orig-${crypto.randomUUID()}`, + bundleId: 'com.kilocode.kiloapp', + productId: 'kilopass.tier19.monthly.v1', + purchaseDate: 1_777_626_000_000, + environment: 'Sandbox', + rawPayload: { test: true }, + ...overrides, + }; +} + +describe('processAppStoreKiloPassNotification', () => { + it('records a renewal notification and completes the subscription once', async () => { + const user = await insertTestUser(); + const decodedNotification = notification(); + const decodedTransaction = transaction(); + + const result = await processAppStoreKiloPassNotification({ + signedPayload: 'payload', + userForRenewal: user, + decodeNotification: async () => decodedNotification, + decodeTransaction: async () => decodedTransaction, + }); + + expect(result).toEqual({ processed: true }); + + const events = await db + .select() + .from(kilo_pass_store_events) + .where(eq(kilo_pass_store_events.event_id, decodedNotification.notificationUUID)); + expect(events).toHaveLength(1); + expect(events[0]?.payment_provider).toBe(KiloPassPaymentProvider.AppStore); + + const subscriptions = await db + .select() + .from(kilo_pass_subscriptions) + .where(eq(kilo_pass_subscriptions.kilo_user_id, user.id)); + expect(subscriptions).toHaveLength(1); + }); + + it('deduplicates notification UUIDs', async () => { + const user = await insertTestUser(); + const decodedNotification = notification(); + const decodedTransaction = transaction(); + const params = { + signedPayload: 'payload', + userForRenewal: user, + decodeNotification: async () => decodedNotification, + decodeTransaction: async () => decodedTransaction, + }; + + await processAppStoreKiloPassNotification(params); + const replay = await processAppStoreKiloPassNotification(params); + + expect(replay).toEqual({ processed: false }); + }); + + it('marks a subscription ended for expiration notifications', async () => { + const user = await insertTestUser(); + const decodedTransaction = transaction(); + await processAppStoreKiloPassNotification({ + signedPayload: 'renewal', + userForRenewal: user, + decodeNotification: async () => notification({ notificationUUID: 'renewal' }), + decodeTransaction: async () => decodedTransaction, + }); + + await processAppStoreKiloPassNotification({ + signedPayload: 'expired', + decodeNotification: async () => + notification({ + notificationUUID: 'expired', + notificationType: 'EXPIRED', + signedTransactionInfo: 'expired-transaction', + }), + decodeTransaction: async () => decodedTransaction, + }); + + const subscription = await db.query.kilo_pass_subscriptions.findFirst({ + where: eq( + kilo_pass_subscriptions.provider_subscription_id, + decodedTransaction.originalTransactionId + ), + }); + expect(subscription?.status).toBe('canceled'); + expect(subscription?.ended_at).not.toBeNull(); + }); +}); diff --git a/apps/web/src/lib/kilo-pass/apple-store-notifications.ts b/apps/web/src/lib/kilo-pass/apple-store-notifications.ts new file mode 100644 index 0000000000..5f7304b180 --- /dev/null +++ b/apps/web/src/lib/kilo-pass/apple-store-notifications.ts @@ -0,0 +1,192 @@ +import { type ResponseBodyV2DecodedPayload } from '@apple/app-store-server-library'; +import { eq } from 'drizzle-orm'; +import * as z from 'zod'; + +import { + kilo_pass_store_events, + kilo_pass_subscriptions, + kilocode_users, + type User, +} from '@kilocode/db/schema'; +import { db } from '@/lib/drizzle'; +import { KiloPassAuditLogAction, KiloPassAuditLogResult, KiloPassPaymentProvider } from './enums'; +import { appendKiloPassAuditLog } from './issuance'; +import { + createAppleStoreSignedDataVerifier, + decodeAppleStoreTransactionJws, + mapAppleKiloPassTransaction, + type AppleStoreDecodedTransaction, + type AppleStoreEnvironment, +} from './apple-store-verifier'; +import { completeStoreKiloPassPurchase } from './store-subscription-completion'; + +export type AppleStoreDecodedNotification = { + notificationUUID: string; + notificationType: string; + subtype?: string; + environment: AppleStoreEnvironment; + signedTransactionInfo?: string; +}; + +type DecodeNotification = (signedPayload: string) => Promise; +type DecodeTransaction = (signedTransactionJws: string) => Promise; + +const RENEWAL_TYPES = new Set(['DID_RENEW', 'SUBSCRIBED']); +const EXPIRED_TYPES = new Set(['EXPIRED', 'DID_FAIL_TO_RENEW']); +const REFUND_TYPES = new Set(['REFUND', 'REVOKE', 'CONSUMPTION_REQUEST']); + +const AppleStoreNotificationPayloadSchema = z + .object({ + notificationUUID: z.string().min(1), + notificationType: z.string().min(1), + subtype: z.string().optional(), + data: z + .object({ + environment: z.string().optional(), + signedTransactionInfo: z.string().optional(), + }) + .optional(), + }) + .passthrough(); + +function normalizeEnvironment(environment: string | undefined): AppleStoreEnvironment { + if (environment === 'Production') return 'Production'; + return 'Sandbox'; +} + +export async function decodeAppleStoreNotificationJws( + signedPayload: string +): Promise { + const decoded = (await createAppleStoreSignedDataVerifier().verifyAndDecodeNotification( + signedPayload + )) as ResponseBodyV2DecodedPayload; + + const parsed = AppleStoreNotificationPayloadSchema.safeParse(decoded); + if (!parsed.success) { + throw new Error('Apple notification payload missing required identifiers'); + } + const payload = parsed.data; + + return { + notificationUUID: payload.notificationUUID, + notificationType: payload.notificationType, + subtype: payload.subtype, + environment: normalizeEnvironment(payload.data?.environment), + signedTransactionInfo: payload.data?.signedTransactionInfo, + }; +} + +async function markStoreSubscriptionEnded( + transaction: AppleStoreDecodedTransaction +): Promise { + await db + .update(kilo_pass_subscriptions) + .set({ + status: 'canceled', + cancel_at_period_end: false, + ended_at: new Date().toISOString(), + }) + .where(eq(kilo_pass_subscriptions.provider_subscription_id, transaction.originalTransactionId)); +} + +async function getUserForStoreRenewal( + providerSubscriptionId: string, + fallbackUser?: User +): Promise { + if (fallbackUser) return fallbackUser; + + const row = await db + .select({ user: kilocode_users }) + .from(kilo_pass_subscriptions) + .innerJoin(kilocode_users, eq(kilo_pass_subscriptions.kilo_user_id, kilocode_users.id)) + .where(eq(kilo_pass_subscriptions.provider_subscription_id, providerSubscriptionId)) + .limit(1); + + return row[0]?.user ?? null; +} + +export async function processAppStoreKiloPassNotification(params: { + signedPayload: string; + userForRenewal?: User; + decodeNotification?: DecodeNotification; + decodeTransaction?: DecodeTransaction; +}): Promise<{ processed: boolean }> { + const decodeNotification = params.decodeNotification ?? decodeAppleStoreNotificationJws; + const decodeTransaction = params.decodeTransaction ?? decodeAppleStoreTransactionJws; + const notification = await decodeNotification(params.signedPayload); + const transaction = notification.signedTransactionInfo + ? await decodeTransaction(notification.signedTransactionInfo) + : null; + const purchase = transaction ? mapAppleKiloPassTransaction(transaction) : null; + + const insertResult = await db + .insert(kilo_pass_store_events) + .values({ + payment_provider: KiloPassPaymentProvider.AppStore, + event_id: notification.notificationUUID, + provider_subscription_id: purchase?.providerSubscriptionId ?? null, + provider_transaction_id: purchase?.providerTransactionId ?? null, + product_id: purchase?.productId ?? 'unknown', + environment: notification.environment, + payload_json: { + notificationType: notification.notificationType, + subtype: notification.subtype ?? null, + }, + }) + .onConflictDoNothing(); + + if ((insertResult.rowCount ?? 0) === 0) { + return { processed: false }; + } + + if (purchase && RENEWAL_TYPES.has(notification.notificationType)) { + const user = await getUserForStoreRenewal( + purchase.providerSubscriptionId, + params.userForRenewal + ); + if (!user) { + throw new Error('App Store renewal notification cannot create a subscription without a user'); + } + await completeStoreKiloPassPurchase({ user, purchase }); + await appendKiloPassAuditLog(db, { + action: KiloPassAuditLogAction.StoreSubscriptionRenewed, + result: KiloPassAuditLogResult.Success, + kiloUserId: user.id, + payload: { + notificationUUID: notification.notificationUUID, + providerSubscriptionId: purchase.providerSubscriptionId, + }, + }); + } + + if (transaction && EXPIRED_TYPES.has(notification.notificationType)) { + await markStoreSubscriptionEnded(transaction); + await appendKiloPassAuditLog(db, { + action: KiloPassAuditLogAction.StoreSubscriptionExpired, + result: KiloPassAuditLogResult.Success, + payload: { + notificationUUID: notification.notificationUUID, + providerSubscriptionId: transaction.originalTransactionId, + }, + }); + } + + if (transaction && REFUND_TYPES.has(notification.notificationType)) { + await markStoreSubscriptionEnded(transaction); + await appendKiloPassAuditLog(db, { + action: KiloPassAuditLogAction.StoreSubscriptionRefunded, + result: KiloPassAuditLogResult.Success, + payload: { + notificationUUID: notification.notificationUUID, + providerSubscriptionId: transaction.originalTransactionId, + }, + }); + } + + await db + .update(kilo_pass_store_events) + .set({ processed_at: new Date().toISOString() }) + .where(eq(kilo_pass_store_events.event_id, notification.notificationUUID)); + + return { processed: true }; +} diff --git a/apps/web/src/lib/kilo-pass/apple-store-verifier.test.ts b/apps/web/src/lib/kilo-pass/apple-store-verifier.test.ts new file mode 100644 index 0000000000..dd0155a86c --- /dev/null +++ b/apps/web/src/lib/kilo-pass/apple-store-verifier.test.ts @@ -0,0 +1,59 @@ +import { describe, expect, it } from '@jest/globals'; + +import { KiloPassCadence, KiloPassPaymentProvider, KiloPassTier } from './enums'; +import { mapAppleKiloPassTransaction } from './apple-store-verifier'; +import type { AppleStoreDecodedTransaction } from './apple-store-verifier'; + +function transaction( + overrides: Partial = {} +): AppleStoreDecodedTransaction { + return { + transactionId: 'tx-1', + originalTransactionId: 'orig-1', + bundleId: 'com.kilocode.kiloapp', + productId: 'kilopass.tier19.yearly.v1', + purchaseDate: 1_777_626_000_000, + environment: 'Sandbox', + rawPayload: { transactionId: 'tx-1' }, + ...overrides, + }; +} + +describe('mapAppleKiloPassTransaction', () => { + it('maps a valid App Store transaction to a validated Kilo Pass purchase', () => { + expect(mapAppleKiloPassTransaction(transaction())).toMatchObject({ + paymentProvider: KiloPassPaymentProvider.AppStore, + productId: 'kilopass.tier19.yearly.v1', + providerTransactionId: 'tx-1', + providerSubscriptionId: 'orig-1', + providerOriginalTransactionId: 'orig-1', + environment: 'Sandbox', + tier: KiloPassTier.Tier19, + cadence: KiloPassCadence.Yearly, + }); + }); + + it('rejects the wrong bundle id', () => { + expect(() => mapAppleKiloPassTransaction(transaction({ bundleId: 'com.example.bad' }))).toThrow( + 'Apple transaction bundle mismatch' + ); + }); + + it('rejects revoked transactions', () => { + expect(() => mapAppleKiloPassTransaction(transaction({ revocationDate: 1 }))).toThrow( + 'Apple transaction has been revoked' + ); + }); + + it('rejects unknown products', () => { + expect(() => mapAppleKiloPassTransaction(transaction({ productId: 'unknown' }))).toThrow( + 'Apple Kilo Pass product is not enabled' + ); + }); + + it('requires original transaction id for subscription identity', () => { + expect(() => mapAppleKiloPassTransaction(transaction({ originalTransactionId: '' }))).toThrow( + 'Apple transaction payload missing required identifiers' + ); + }); +}); diff --git a/apps/web/src/lib/kilo-pass/apple-store-verifier.ts b/apps/web/src/lib/kilo-pass/apple-store-verifier.ts new file mode 100644 index 0000000000..f90093bf11 --- /dev/null +++ b/apps/web/src/lib/kilo-pass/apple-store-verifier.ts @@ -0,0 +1,152 @@ +import { + Environment, + SignedDataVerifier, + type JWSTransactionDecodedPayload, +} from '@apple/app-store-server-library'; +import * as z from 'zod'; + +import { getEnvVariable } from '@/lib/dotenvx'; +import type { ValidatedStoreKiloPassPurchase } from './store-subscription-completion'; +import { KiloPassPaymentProvider } from './enums'; +import { getMobileStoreKiloPassProductByAppleProductId } from './mobile-store-products'; + +const BUNDLE_ID = 'com.kilocode.kiloapp'; + +export type AppleStoreEnvironment = 'Sandbox' | 'Production'; + +export type AppleStoreDecodedTransaction = { + transactionId: string; + originalTransactionId: string; + bundleId: string; + productId: string; + purchaseDate: number; + revocationDate?: number; + environment: AppleStoreEnvironment; + rawPayload: Record; +}; + +const AppleStoreTransactionPayloadSchema = z + .object({ + transactionId: z.string().min(1), + originalTransactionId: z.string().min(1), + bundleId: z.string().min(1), + productId: z.string().min(1), + purchaseDate: z.number(), + revocationDate: z.number().optional(), + environment: z.string().optional(), + }) + .passthrough(); + +function requiredEnv(name: string): string { + const value = getEnvVariable(name); + if (!value) throw new Error(`${name} is not set`); + return value; +} + +function getAppleEnvironment(): Environment { + return requiredEnv('APPLE_IAP_ENVIRONMENT') === 'Production' + ? Environment.PRODUCTION + : Environment.SANDBOX; +} + +function getAppleAppAppleId(): number | undefined { + const value = getEnvVariable('APPLE_APP_APPLE_ID'); + return value ? Number(value) : undefined; +} + +function getAppleRootCertificates(): Buffer[] { + const pemBundle = requiredEnv('APPLE_ROOT_CERTIFICATES_PEM'); + return pemBundle + .split('-----END CERTIFICATE-----') + .map(part => part.trim()) + .filter(Boolean) + .map(part => Buffer.from(`${part}\n-----END CERTIFICATE-----\n`)); +} + +export function createAppleStoreSignedDataVerifier(): SignedDataVerifier { + return new SignedDataVerifier( + getAppleRootCertificates(), + true, + getAppleEnvironment(), + BUNDLE_ID, + getAppleAppAppleId() + ); +} + +function normalizeEnvironment(environment: string | undefined): AppleStoreEnvironment { + if (environment === 'Production') return 'Production'; + return 'Sandbox'; +} + +function decodeAppleStoreTransactionPayload( + decoded: JWSTransactionDecodedPayload +): AppleStoreDecodedTransaction { + const parsed = AppleStoreTransactionPayloadSchema.safeParse(decoded); + if (!parsed.success) { + throw new Error('Apple transaction payload missing required identifiers'); + } + const payload = parsed.data; + + return { + transactionId: payload.transactionId, + originalTransactionId: payload.originalTransactionId, + bundleId: payload.bundleId, + productId: payload.productId, + purchaseDate: payload.purchaseDate, + revocationDate: payload.revocationDate, + environment: normalizeEnvironment(payload.environment), + rawPayload: payload, + }; +} + +export async function decodeAppleStoreTransactionJws( + signedTransactionJws: string +): Promise { + const decoded = (await createAppleStoreSignedDataVerifier().verifyAndDecodeTransaction( + signedTransactionJws + )) as JWSTransactionDecodedPayload; + return decodeAppleStoreTransactionPayload(decoded); +} + +export function mapAppleKiloPassTransaction( + transaction: AppleStoreDecodedTransaction +): ValidatedStoreKiloPassPurchase { + if (!transaction.transactionId || !transaction.originalTransactionId || !transaction.bundleId) { + throw new Error('Apple transaction payload missing required identifiers'); + } + if (transaction.bundleId !== BUNDLE_ID) { + throw new Error('Apple transaction bundle mismatch'); + } + if (transaction.revocationDate) { + throw new Error('Apple transaction has been revoked'); + } + + const product = getMobileStoreKiloPassProductByAppleProductId(transaction.productId); + if (!product) { + throw new Error('Apple Kilo Pass product is not enabled'); + } + + return { + paymentProvider: KiloPassPaymentProvider.AppStore, + productId: transaction.productId, + providerTransactionId: transaction.transactionId, + providerOriginalTransactionId: transaction.originalTransactionId, + providerSubscriptionId: transaction.originalTransactionId, + purchaseToken: null, + environment: transaction.environment, + purchasedAtIso: new Date(transaction.purchaseDate).toISOString(), + tier: product.tier, + cadence: product.cadence, + rawPayload: transaction.rawPayload, + }; +} + +export async function verifyAppleKiloPassTransactionJws( + signedTransactionJws: string +): Promise { + const transaction = await decodeAppleStoreTransactionJws(signedTransactionJws); + return { + ...mapAppleKiloPassTransaction(transaction), + purchaseToken: signedTransactionJws, + }; +} diff --git a/apps/web/src/lib/kilo-pass/enums.ts b/apps/web/src/lib/kilo-pass/enums.ts index 4cb536fc50..417346b680 100644 --- a/apps/web/src/lib/kilo-pass/enums.ts +++ b/apps/web/src/lib/kilo-pass/enums.ts @@ -1,6 +1,7 @@ export { KiloPassTier, KiloPassCadence, + KiloPassPaymentProvider, KiloPassIssuanceSource, KiloPassIssuanceItemKind, KiloPassAuditLogAction, diff --git a/apps/web/src/lib/kilo-pass/issuance.ts b/apps/web/src/lib/kilo-pass/issuance.ts index 9eaecc60c2..93825dc423 100644 --- a/apps/web/src/lib/kilo-pass/issuance.ts +++ b/apps/web/src/lib/kilo-pass/issuance.ts @@ -314,12 +314,24 @@ export async function issueBaseCreditsForIssuance( * The Stripe Invoice ID here is used as the Stripe Payment ID for `processTopUp`. * Even though it isn't a payment ID, it's good enough because it's guaranteed to be unique. */ - stripeInvoiceId: string; + stripeInvoiceId?: string | null; + providerPaymentId?: string | null; description: string; } ): Promise { - const { issuanceId, subscriptionId, kiloUserId, amountUsd, stripeInvoiceId, description } = - params; + const { + issuanceId, + subscriptionId, + kiloUserId, + amountUsd, + stripeInvoiceId, + providerPaymentId, + description, + } = params; + const creditPaymentId = stripeInvoiceId ?? providerPaymentId; + if (!creditPaymentId) { + throw new Error('issueBaseCreditsForIssuance requires a payment id'); + } await lockIssuanceRow(tx, issuanceId); @@ -334,7 +346,7 @@ export async function issueBaseCreditsForIssuance( result: KiloPassAuditLogResult.SkippedIdempotent, kiloUserId, kiloPassSubscriptionId: subscriptionId, - stripeInvoiceId, + stripeInvoiceId: stripeInvoiceId ?? null, relatedCreditTransactionId: existing.creditTransactionId, relatedMonthlyIssuanceId: issuanceId, payload: { reason: 'issuance_item_already_exists', kind: KiloPassIssuanceItemKind.Base }, @@ -362,7 +374,7 @@ export async function issueBaseCreditsForIssuance( amountCents, { type: 'stripe', - stripe_payment_id: stripeInvoiceId, + stripe_payment_id: creditPaymentId, }, { dbOrTx: tx, @@ -378,13 +390,13 @@ export async function issueBaseCreditsForIssuance( await tx .select({ id: credit_transactions.id }) .from(credit_transactions) - .where(eq(credit_transactions.stripe_payment_id, stripeInvoiceId)) + .where(eq(credit_transactions.stripe_payment_id, creditPaymentId)) .limit(1) )[0]?.id; if (!creditTransactionId) { throw new Error( - `processTopUp returned ok=${topUpOk} but no credit_transactions row exists (stripe_payment_id=${stripeInvoiceId})` + `processTopUp returned ok=${topUpOk} but no credit_transactions row exists (stripe_payment_id=${creditPaymentId})` ); } @@ -409,13 +421,14 @@ export async function issueBaseCreditsForIssuance( result: topUpOk ? KiloPassAuditLogResult.Success : KiloPassAuditLogResult.SkippedIdempotent, kiloUserId, kiloPassSubscriptionId: subscriptionId, - stripeInvoiceId, + stripeInvoiceId: stripeInvoiceId ?? null, relatedCreditTransactionId: creditTransactionId, relatedMonthlyIssuanceId: issuanceId, payload: { kind: KiloPassIssuanceItemKind.Base, amountUsd: centsToUsd(amountCents), - stripeInvoiceId, + stripeInvoiceId: stripeInvoiceId ?? null, + providerPaymentId: providerPaymentId ?? null, originalBaselineMicrodollarsUsed, }, }); diff --git a/apps/web/src/lib/kilo-pass/mobile-store-products.ts b/apps/web/src/lib/kilo-pass/mobile-store-products.ts new file mode 100644 index 0000000000..410142479b --- /dev/null +++ b/apps/web/src/lib/kilo-pass/mobile-store-products.ts @@ -0,0 +1,98 @@ +import { getMonthlyPriceUsd } from './bonus'; +import { KiloPassCadence, KiloPassTier } from './enums'; + +export type MobileStoreKiloPassProduct = { + tier: KiloPassTier; + cadence: KiloPassCadence; + appleProductId: string; + googleProductId: string; + googleBasePlanId: string; + webMonthlyPriceUsd: number; + suggestedStoreMonthlyPriceUsd: number; +}; + +const PRODUCT_IDS = { + [KiloPassTier.Tier19]: { + [KiloPassCadence.Monthly]: { + appleProductId: 'kilopass.tier19.monthly.v1', + googleProductId: 'kilopass_tier19', + googleBasePlanId: 'monthly-v1', + }, + [KiloPassCadence.Yearly]: { + appleProductId: 'kilopass.tier19.yearly.v1', + googleProductId: 'kilopass_tier19', + googleBasePlanId: 'yearly-v1', + }, + }, + [KiloPassTier.Tier49]: { + [KiloPassCadence.Monthly]: { + appleProductId: 'kilopass.tier49.monthly.v1', + googleProductId: 'kilopass_tier49', + googleBasePlanId: 'monthly-v1', + }, + [KiloPassCadence.Yearly]: { + appleProductId: 'kilopass.tier49.yearly.v1', + googleProductId: 'kilopass_tier49', + googleBasePlanId: 'yearly-v1', + }, + }, + [KiloPassTier.Tier199]: { + [KiloPassCadence.Monthly]: { + appleProductId: 'kilopass.tier199.monthly.v1', + googleProductId: 'kilopass_tier199', + googleBasePlanId: 'monthly-v1', + }, + [KiloPassCadence.Yearly]: { + appleProductId: 'kilopass.tier199.yearly.v1', + googleProductId: 'kilopass_tier199', + googleBasePlanId: 'yearly-v1', + }, + }, +} satisfies Record< + KiloPassTier, + Record< + KiloPassCadence, + { + appleProductId: string; + googleProductId: string; + googleBasePlanId: string; + } + > +>; + +function roundStoreMonthlyPrice(webMonthlyPriceUsd: number): number { + const gross = webMonthlyPriceUsd * 1.3; + return Math.round(gross * 100) / 100; +} + +export function getMobileStoreKiloPassProduct(params: { + tier: KiloPassTier; + cadence: KiloPassCadence; +}): MobileStoreKiloPassProduct { + const webMonthlyPriceUsd = getMonthlyPriceUsd(params.tier); + const ids = PRODUCT_IDS[params.tier][params.cadence]; + + return { + tier: params.tier, + cadence: params.cadence, + ...ids, + webMonthlyPriceUsd, + suggestedStoreMonthlyPriceUsd: roundStoreMonthlyPrice(webMonthlyPriceUsd), + }; +} + +export function getAllMobileStoreKiloPassProducts(): MobileStoreKiloPassProduct[] { + return Object.values(KiloPassTier).flatMap(tier => + Object.values(KiloPassCadence).map(cadence => getMobileStoreKiloPassProduct({ tier, cadence })) + ); +} + +export function getMobileStoreKiloPassProductByAppleProductId( + appleProductId: string +): MobileStoreKiloPassProduct | null { + return ( + getAllMobileStoreKiloPassProducts().find( + product => product.appleProductId === appleProductId + ) ?? null + ); +} diff --git a/apps/web/src/lib/kilo-pass/state.ts b/apps/web/src/lib/kilo-pass/state.ts index 1a316279e9..f88d795c58 100644 --- a/apps/web/src/lib/kilo-pass/state.ts +++ b/apps/web/src/lib/kilo-pass/state.ts @@ -5,7 +5,11 @@ import { kilo_pass_subscriptions } from '@kilocode/db/schema'; import type { DrizzleTransaction, db as defaultDb } from '@/lib/drizzle'; import { eq } from 'drizzle-orm'; import type Stripe from 'stripe'; -import type { KiloPassCadence, KiloPassTier } from '@/lib/kilo-pass/enums'; +import { + type KiloPassPaymentProvider, + type KiloPassCadence, + type KiloPassTier, +} from '@/lib/kilo-pass/enums'; import { isStripeSubscriptionEnded } from '@/lib/kilo-pass/stripe-subscription-status'; import { dayjs } from '@/lib/kilo-pass/dayjs'; import { getOpenPauseEvent } from '@/lib/kilo-pass/pause-events'; @@ -16,6 +20,8 @@ type DbOrTx = Db | DrizzleTransaction; export type KiloPassSubscriptionState = { subscriptionId: string; stripeSubscriptionId: string; + paymentProvider: KiloPassPaymentProvider; + providerSubscriptionId: string | null; tier: KiloPassTier; cadence: KiloPassCadence; status: Stripe.Subscription.Status; @@ -28,7 +34,9 @@ export type KiloPassSubscriptionState = { type KiloPassSubscriptionRowForState = { subscriptionId: string; - stripeSubscriptionId: string; + stripeSubscriptionId: string | null; + paymentProvider: KiloPassPaymentProvider; + providerSubscriptionId: string | null; tier: KiloPassTier; cadence: KiloPassCadence; status: Stripe.Subscription.Status; @@ -109,6 +117,8 @@ export async function getKiloPassStateForUser( .select({ subscriptionId: kilo_pass_subscriptions.id, stripeSubscriptionId: kilo_pass_subscriptions.stripe_subscription_id, + paymentProvider: kilo_pass_subscriptions.payment_provider, + providerSubscriptionId: kilo_pass_subscriptions.provider_subscription_id, tier: kilo_pass_subscriptions.tier, cadence: kilo_pass_subscriptions.cadence, status: kilo_pass_subscriptions.status, @@ -136,7 +146,9 @@ export async function getKiloPassStateForUser( return { subscriptionId: selected.subscriptionId, - stripeSubscriptionId: selected.stripeSubscriptionId, + stripeSubscriptionId: selected.stripeSubscriptionId ?? selected.providerSubscriptionId ?? '', + paymentProvider: selected.paymentProvider, + providerSubscriptionId: selected.providerSubscriptionId, tier: selected.tier, cadence: selected.cadence, status: isPaused ? 'paused' : selected.status, diff --git a/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts b/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts new file mode 100644 index 0000000000..19754d59a3 --- /dev/null +++ b/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts @@ -0,0 +1,139 @@ +import { describe, expect, it } from '@jest/globals'; +import { and, eq } from 'drizzle-orm'; + +import { + credit_transactions, + kilo_pass_issuance_items, + kilo_pass_issuances, + kilo_pass_store_purchases, + kilo_pass_subscriptions, +} from '@kilocode/db/schema'; +import { db } from '@/lib/drizzle'; +import { insertTestUser } from '@/tests/helpers/user.helper'; +import { getMonthlyPriceUsd } from './bonus'; +import { KiloPassCadence, KiloPassIssuanceItemKind, KiloPassTier } from './enums'; +import { KiloPassIssuanceSource, KiloPassPaymentProvider } from './enums'; +import { + completeStoreKiloPassPurchase, + type ValidatedStoreKiloPassPurchase, +} from './store-subscription-completion'; + +function applePurchase( + overrides: Partial = {} +): ValidatedStoreKiloPassPurchase { + return { + paymentProvider: KiloPassPaymentProvider.AppStore, + productId: 'kilopass.tier49.monthly.v1', + providerTransactionId: `tx-${crypto.randomUUID()}`, + providerOriginalTransactionId: `orig-${crypto.randomUUID()}`, + providerSubscriptionId: `orig-${crypto.randomUUID()}`, + purchaseToken: `jws-${crypto.randomUUID()}`, + environment: 'Sandbox', + purchasedAtIso: '2026-05-01T12:00:00.000Z', + tier: KiloPassTier.Tier49, + cadence: KiloPassCadence.Monthly, + rawPayload: { source: 'test' }, + ...overrides, + }; +} + +describe('completeStoreKiloPassPurchase', () => { + it('creates an active app store subscription and issues base credits once', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0, microdollars_used: 0 }); + const purchase = applePurchase(); + + const result = await completeStoreKiloPassPurchase({ user, purchase }); + + expect(result).toEqual({ + subscriptionId: expect.any(String), + tier: KiloPassTier.Tier49, + cadence: KiloPassCadence.Monthly, + alreadyProcessed: false, + }); + + const subscriptions = await db + .select() + .from(kilo_pass_subscriptions) + .where(eq(kilo_pass_subscriptions.kilo_user_id, user.id)); + expect(subscriptions).toHaveLength(1); + expect(subscriptions[0]).toMatchObject({ + payment_provider: KiloPassPaymentProvider.AppStore, + provider_subscription_id: purchase.providerSubscriptionId, + stripe_subscription_id: null, + status: 'active', + tier: KiloPassTier.Tier49, + cadence: KiloPassCadence.Monthly, + }); + + const storePurchases = await db + .select() + .from(kilo_pass_store_purchases) + .where(eq(kilo_pass_store_purchases.kilo_user_id, user.id)); + expect(storePurchases).toHaveLength(1); + + const issuances = await db + .select() + .from(kilo_pass_issuances) + .where(eq(kilo_pass_issuances.kilo_pass_subscription_id, result.subscriptionId)); + expect(issuances).toHaveLength(1); + expect(issuances[0]?.source).toBe(KiloPassIssuanceSource.AppStoreTransaction); + + const items = await db + .select({ + amountUsd: kilo_pass_issuance_items.amount_usd, + creditTransactionId: kilo_pass_issuance_items.credit_transaction_id, + }) + .from(kilo_pass_issuance_items) + .where( + and( + eq(kilo_pass_issuance_items.kilo_pass_issuance_id, issuances[0]?.id ?? ''), + eq(kilo_pass_issuance_items.kind, KiloPassIssuanceItemKind.Base) + ) + ); + expect(items).toHaveLength(1); + expect(items[0]?.amountUsd).toBe(getMonthlyPriceUsd(KiloPassTier.Tier49)); + + const creditRows = await db + .select({ amountMicrodollars: credit_transactions.amount_microdollars }) + .from(credit_transactions) + .where(eq(credit_transactions.id, items[0]?.creditTransactionId ?? '')); + expect(creditRows[0]?.amountMicrodollars).toBe(49_000_000); + }); + + it('returns idempotently when the same provider transaction is replayed by the same user', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0, microdollars_used: 0 }); + const purchase = applePurchase(); + + const first = await completeStoreKiloPassPurchase({ user, purchase }); + const replay = await completeStoreKiloPassPurchase({ user, purchase }); + + expect(replay).toEqual({ ...first, alreadyProcessed: true }); + + const storePurchases = await db + .select() + .from(kilo_pass_store_purchases) + .where(eq(kilo_pass_store_purchases.provider_transaction_id, purchase.providerTransactionId)); + expect(storePurchases).toHaveLength(1); + }); + + it('rejects when the same provider transaction is replayed by another user', async () => { + const firstUser = await insertTestUser(); + const secondUser = await insertTestUser(); + const purchase = applePurchase(); + + await completeStoreKiloPassPurchase({ user: firstUser, purchase }); + + await expect(completeStoreKiloPassPurchase({ user: secondUser, purchase })).rejects.toThrow( + 'Store transaction already belongs to another user' + ); + }); + + it('rejects when the user already has an active non-ended Kilo Pass subscription', async () => { + const user = await insertTestUser(); + await completeStoreKiloPassPurchase({ user, purchase: applePurchase() }); + + await expect( + completeStoreKiloPassPurchase({ user, purchase: applePurchase() }) + ).rejects.toThrow('You already have an active Kilo Pass subscription'); + }); +}); diff --git a/apps/web/src/lib/kilo-pass/store-subscription-completion.ts b/apps/web/src/lib/kilo-pass/store-subscription-completion.ts new file mode 100644 index 0000000000..f08a9773bf --- /dev/null +++ b/apps/web/src/lib/kilo-pass/store-subscription-completion.ts @@ -0,0 +1,228 @@ +import { + kilo_pass_store_purchases, + kilo_pass_subscriptions, + kilocode_users, + type User, +} from '@kilocode/db/schema'; +import { and, eq, isNull, sql } from 'drizzle-orm'; + +import { db } from '@/lib/drizzle'; +import { toMicrodollars } from '@/lib/utils'; +import { getMonthlyPriceUsd } from './bonus'; +import { dayjs } from './dayjs'; +import { + KiloPassAuditLogAction, + KiloPassAuditLogResult, + KiloPassCadence, + KiloPassIssuanceSource, + KiloPassPaymentProvider, + type KiloPassTier, +} from './enums'; +import { + appendKiloPassAuditLog, + computeIssueMonth, + createOrGetIssuanceHeader, + issueBaseCreditsForIssuance, +} from './issuance'; +import { isStripeSubscriptionEnded } from './stripe-subscription-status'; + +export type ValidatedStoreKiloPassPurchase = { + paymentProvider: KiloPassPaymentProvider.AppStore | KiloPassPaymentProvider.GooglePlay; + productId: string; + providerTransactionId: string; + providerOriginalTransactionId: string | null; + providerSubscriptionId: string; + purchaseToken: string | null; + environment: string; + purchasedAtIso: string; + tier: KiloPassTier; + cadence: KiloPassCadence; + rawPayload: Record; +}; + +export type CompleteStoreKiloPassPurchaseResult = { + subscriptionId: string; + tier: KiloPassTier; + cadence: KiloPassCadence; + alreadyProcessed: boolean; +}; + +function getIssuanceSource( + paymentProvider: ValidatedStoreKiloPassPurchase['paymentProvider'] +): KiloPassIssuanceSource { + if (paymentProvider === KiloPassPaymentProvider.AppStore) { + return KiloPassIssuanceSource.AppStoreTransaction; + } + return KiloPassIssuanceSource.GooglePlayTransaction; +} + +function getNextYearlyIssueAt(params: { + cadence: KiloPassCadence; + purchasedAtIso: string; +}): string | null { + if (params.cadence !== KiloPassCadence.Yearly) return null; + return dayjs(params.purchasedAtIso).utc().add(1, 'month').toISOString(); +} + +function getProviderPaymentId(purchase: ValidatedStoreKiloPassPurchase): string { + return `kilo-pass:${purchase.paymentProvider}:${purchase.providerTransactionId}`; +} + +export async function completeStoreKiloPassPurchase(params: { + user: User; + purchase: ValidatedStoreKiloPassPurchase; +}): Promise { + const { user, purchase } = params; + + return db.transaction(async tx => { + const existingPurchase = await tx.query.kilo_pass_store_purchases.findFirst({ + where: and( + eq(kilo_pass_store_purchases.payment_provider, purchase.paymentProvider), + eq(kilo_pass_store_purchases.provider_transaction_id, purchase.providerTransactionId) + ), + }); + + if (existingPurchase) { + if (existingPurchase.kilo_user_id !== user.id) { + throw new Error('Store transaction already belongs to another user'); + } + + return { + subscriptionId: existingPurchase.kilo_pass_subscription_id, + tier: purchase.tier, + cadence: purchase.cadence, + alreadyProcessed: true, + }; + } + + const activeSubscription = await tx.query.kilo_pass_subscriptions.findFirst({ + where: and( + eq(kilo_pass_subscriptions.kilo_user_id, user.id), + isNull(kilo_pass_subscriptions.ended_at) + ), + }); + + if ( + activeSubscription && + !isStripeSubscriptionEnded(activeSubscription.status) && + activeSubscription.provider_subscription_id !== purchase.providerSubscriptionId + ) { + throw new Error('You already have an active Kilo Pass subscription'); + } + + const existingForProviderSubscription = await tx.query.kilo_pass_subscriptions.findFirst({ + where: and( + eq(kilo_pass_subscriptions.payment_provider, purchase.paymentProvider), + eq(kilo_pass_subscriptions.provider_subscription_id, purchase.providerSubscriptionId) + ), + }); + + const nextYearlyIssueAt = getNextYearlyIssueAt({ + cadence: purchase.cadence, + purchasedAtIso: purchase.purchasedAtIso, + }); + + const subscriptionRows = existingForProviderSubscription + ? await tx + .update(kilo_pass_subscriptions) + .set({ + kilo_user_id: user.id, + tier: purchase.tier, + cadence: purchase.cadence, + status: 'active', + cancel_at_period_end: false, + ended_at: null, + next_yearly_issue_at: nextYearlyIssueAt, + }) + .where(eq(kilo_pass_subscriptions.id, existingForProviderSubscription.id)) + .returning({ id: kilo_pass_subscriptions.id }) + : await tx + .insert(kilo_pass_subscriptions) + .values({ + kilo_user_id: user.id, + payment_provider: purchase.paymentProvider, + provider_subscription_id: purchase.providerSubscriptionId, + stripe_subscription_id: null, + tier: purchase.tier, + cadence: purchase.cadence, + status: 'active', + cancel_at_period_end: false, + started_at: purchase.purchasedAtIso, + ended_at: null, + current_streak_months: 1, + next_yearly_issue_at: nextYearlyIssueAt, + }) + .returning({ id: kilo_pass_subscriptions.id }); + + const subscriptionId = subscriptionRows[0]?.id; + if (!subscriptionId) { + throw new Error('Failed to persist store Kilo Pass subscription'); + } + + await tx.insert(kilo_pass_store_purchases).values({ + kilo_pass_subscription_id: subscriptionId, + kilo_user_id: user.id, + payment_provider: purchase.paymentProvider, + product_id: purchase.productId, + provider_subscription_id: purchase.providerSubscriptionId, + provider_transaction_id: purchase.providerTransactionId, + provider_original_transaction_id: purchase.providerOriginalTransactionId, + purchase_token: purchase.purchaseToken, + environment: purchase.environment, + purchased_at: purchase.purchasedAtIso, + raw_payload_json: purchase.rawPayload, + }); + + const issueMonth = computeIssueMonth(dayjs(purchase.purchasedAtIso)); + const issuanceHeader = await createOrGetIssuanceHeader(tx, { + subscriptionId, + issueMonth, + source: getIssuanceSource(purchase.paymentProvider), + }); + + const baseAmountUsd = getMonthlyPriceUsd(purchase.tier); + const baseCreditsResult = await issueBaseCreditsForIssuance(tx, { + issuanceId: issuanceHeader.issuanceId, + subscriptionId, + kiloUserId: user.id, + amountUsd: baseAmountUsd, + providerPaymentId: getProviderPaymentId(purchase), + description: `Kilo Pass base credits (${purchase.tier}, ${purchase.cadence})`, + }); + + if (baseCreditsResult.wasIssued) { + await tx + .update(kilocode_users) + .set({ + kilo_pass_threshold: sql`${kilocode_users.microdollars_used} + ${toMicrodollars( + baseAmountUsd + )}`, + }) + .where(eq(kilocode_users.id, user.id)); + } + + await appendKiloPassAuditLog(tx, { + action: KiloPassAuditLogAction.StorePurchaseCompleted, + result: KiloPassAuditLogResult.Success, + kiloUserId: user.id, + kiloPassSubscriptionId: subscriptionId, + relatedMonthlyIssuanceId: issuanceHeader.issuanceId, + payload: { + paymentProvider: purchase.paymentProvider, + productId: purchase.productId, + providerSubscriptionId: purchase.providerSubscriptionId, + providerTransactionId: purchase.providerTransactionId, + issueMonth, + issuanceHeaderWasCreated: issuanceHeader.wasCreated, + baseCreditsIssued: baseCreditsResult.wasIssued, + }, + }); + + return { + subscriptionId, + tier: purchase.tier, + cadence: purchase.cadence, + alreadyProcessed: false, + }; + }); +} diff --git a/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts b/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts new file mode 100644 index 0000000000..714ceb6dd2 --- /dev/null +++ b/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from '@jest/globals'; + +import { KiloPassCadence, KiloPassTier } from './enums'; +import { + getAllMobileStoreKiloPassProducts, + getMobileStoreKiloPassProduct, +} from './mobile-store-products'; + +describe('mobile Kilo Pass store products', () => { + it('maps every tier and cadence to Apple and Google product identifiers', () => { + const products = getAllMobileStoreKiloPassProducts(); + + expect(products).toHaveLength(6); + for (const tier of Object.values(KiloPassTier)) { + for (const cadence of Object.values(KiloPassCadence)) { + const product = getMobileStoreKiloPassProduct({ tier, cadence }); + expect(product).toMatchObject({ tier, cadence }); + expect(product.appleProductId).toMatch(/^kilopass\./); + expect(product.googleProductId).toMatch(/^kilopass_tier/); + expect(product.googleBasePlanId).toMatch(/^(monthly|yearly)-v1$/); + expect(product.webMonthlyPriceUsd).toBeGreaterThan(0); + expect(product.suggestedStoreMonthlyPriceUsd).toBeGreaterThan(product.webMonthlyPriceUsd); + } + } + }); +}); diff --git a/apps/web/src/lib/kilo-pass/stripe-handlers-invoice-paid.ts b/apps/web/src/lib/kilo-pass/stripe-handlers-invoice-paid.ts index e64c98047e..e2ccbc923f 100644 --- a/apps/web/src/lib/kilo-pass/stripe-handlers-invoice-paid.ts +++ b/apps/web/src/lib/kilo-pass/stripe-handlers-invoice-paid.ts @@ -40,6 +40,7 @@ import { KiloPassAuditLogResult, KiloPassCadence, KiloPassIssuanceSource, + KiloPassPaymentProvider, } from '@/lib/kilo-pass/enums'; import { isStripeSubscriptionEnded } from '@/lib/kilo-pass/stripe-subscription-status'; import { processTopUp } from '@/lib/credits'; @@ -303,6 +304,8 @@ export async function handleKiloPassInvoicePaid(params: { .insert(kilo_pass_subscriptions) .values({ kilo_user_id: kiloUserId, + payment_provider: KiloPassPaymentProvider.Stripe, + provider_subscription_id: subscription.id, stripe_subscription_id: subscription.id, tier, cadence, @@ -314,6 +317,8 @@ export async function handleKiloPassInvoicePaid(params: { target: kilo_pass_subscriptions.stripe_subscription_id, set: { kilo_user_id: kiloUserId, + payment_provider: KiloPassPaymentProvider.Stripe, + provider_subscription_id: subscription.id, tier, cadence, status: subscription.status, diff --git a/apps/web/src/lib/kilo-pass/stripe-handlers-subscription-events.ts b/apps/web/src/lib/kilo-pass/stripe-handlers-subscription-events.ts index a32b7b704d..4df8bdd9d0 100644 --- a/apps/web/src/lib/kilo-pass/stripe-handlers-subscription-events.ts +++ b/apps/web/src/lib/kilo-pass/stripe-handlers-subscription-events.ts @@ -12,7 +12,11 @@ import { getKiloPassSubscriptionMetadata } from '@/lib/kilo-pass/stripe-handlers import { getStripeEndedAtIso } from '@/lib/kilo-pass/stripe-handlers-utils'; import { client as stripe } from '@/lib/stripe-client'; import type Stripe from 'stripe'; -import { KiloPassAuditLogAction, KiloPassAuditLogResult } from '@/lib/kilo-pass/enums'; +import { + KiloPassAuditLogAction, + KiloPassAuditLogResult, + KiloPassPaymentProvider, +} from '@/lib/kilo-pass/enums'; import { isStripeSubscriptionEnded } from '@/lib/kilo-pass/stripe-subscription-status'; import { dayjs } from '@/lib/kilo-pass/dayjs'; @@ -76,6 +80,8 @@ export async function handleKiloPassSubscriptionEvent(params: { .insert(kilo_pass_subscriptions) .values({ ...baseValues, + payment_provider: KiloPassPaymentProvider.Stripe, + provider_subscription_id: subscription.id, stripe_subscription_id: subscription.id, started_at: dayjs.unix(subscription.start_date).utc().toISOString(), ended_at: endedAt, @@ -83,7 +89,11 @@ export async function handleKiloPassSubscriptionEvent(params: { }) .onConflictDoUpdate({ target: kilo_pass_subscriptions.stripe_subscription_id, - set: updateSet, + set: { + ...updateSet, + payment_provider: KiloPassPaymentProvider.Stripe, + provider_subscription_id: subscription.id, + }, }) .returning({ id: kilo_pass_subscriptions.id }); diff --git a/apps/web/src/routers/kilo-pass-router.ts b/apps/web/src/routers/kilo-pass-router.ts index 27e33d580d..0a6186fcda 100644 --- a/apps/web/src/routers/kilo-pass-router.ts +++ b/apps/web/src/routers/kilo-pass-router.ts @@ -19,6 +19,7 @@ import { KiloPassAuditLogResult, KiloPassScheduledChangeStatus, KiloPassTier, + KiloPassPaymentProvider, } from '@/lib/kilo-pass/enums'; import { KiloPassIssuanceItemKind } from '@/lib/kilo-pass/enums'; import { and, desc, eq, inArray, isNull, ne, sql, sum } from 'drizzle-orm'; @@ -47,6 +48,9 @@ import type Stripe from 'stripe'; import { dayjs } from '@/lib/kilo-pass/dayjs'; import { computeChurnkeyAuthHash } from '@/lib/churnkey/auth'; import { closePauseEvent } from '@/lib/kilo-pass/pause-events'; +import { getAllMobileStoreKiloPassProducts } from '@/lib/kilo-pass/mobile-store-products'; +import { verifyAppleKiloPassTransactionJws } from '@/lib/kilo-pass/apple-store-verifier'; +import { completeStoreKiloPassPurchase } from '@/lib/kilo-pass/store-subscription-completion'; const CursorInputSchema = z.object({ cursor: z.string().nullable().optional(), @@ -81,6 +85,7 @@ function parseOffsetCursor(cursor: string | null | undefined): number { const KiloPassTierSchema = z.enum(KiloPassTier); const KiloPassCadenceSchema = z.enum(KiloPassCadence); +const KiloPassPaymentProviderSchema = z.enum(KiloPassPaymentProvider); const KiloPassSubscriptionStatusSchema = z.union([ z.literal('active'), @@ -96,6 +101,8 @@ const KiloPassSubscriptionStatusSchema = z.union([ const KiloPassSubscriptionStateBaseSchema = z.object({ subscriptionId: z.string(), stripeSubscriptionId: z.string(), + paymentProvider: KiloPassPaymentProviderSchema, + providerSubscriptionId: z.string().nullable(), tier: KiloPassTierSchema, cadence: KiloPassCadenceSchema, status: KiloPassSubscriptionStatusSchema, @@ -131,6 +138,13 @@ const GetAverageMonthlyUsageLast3MonthsOutputSchema = z.object({ averageMonthlyUsageUsd: z.number(), }); +const CompleteStorePurchaseOutputSchema = z.object({ + subscriptionId: z.string(), + tier: KiloPassTierSchema, + cadence: KiloPassCadenceSchema, + alreadyProcessed: z.boolean(), +}); + function isTwoMonthPromoOfferActive(): boolean { return dayjs().utc().isBefore(KILO_PASS_MONTHLY_FIRST_2_MONTHS_PROMO_CUTOFF); } @@ -169,6 +183,35 @@ async function getIsFirstTimeSubscriberEver(params: { return otherSubscriptions.length === 0; } +async function getIsFirstTimeSubscriberEverBySubscriptionId(params: { + kiloUserId: string; + subscriptionId: string; +}): Promise { + const otherSubscriptions = await db + .select({ id: kilo_pass_subscriptions.id }) + .from(kilo_pass_subscriptions) + .where( + and( + eq(kilo_pass_subscriptions.kilo_user_id, params.kiloUserId), + ne(kilo_pass_subscriptions.id, params.subscriptionId) + ) + ) + .limit(1); + + return otherSubscriptions.length === 0; +} + +function assertStripeManagedSubscription(subscription: { + paymentProvider: KiloPassPaymentProvider; +}): void { + if (subscription.paymentProvider !== KiloPassPaymentProvider.Stripe) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'Manage this Kilo Pass subscription through the mobile app store.', + }); + } +} + async function getIsBonusUnlockedForSubscriptionId(subscriptionId: string): Promise { const lastIssuance = await db .select({ id: kilo_pass_issuances.id }) @@ -345,6 +388,18 @@ const GetScheduledChangeOutputSchema = z.object({ }); export const kiloPassRouter = createTRPCRouter({ + getMobileStoreProducts: baseProcedure.query(() => ({ + products: getAllMobileStoreKiloPassProducts(), + })), + + completeAppStorePurchase: baseProcedure + .input(z.object({ signedTransactionJws: z.string().min(1) })) + .output(CompleteStorePurchaseOutputSchema) + .mutation(async ({ ctx, input }) => { + const purchase = await verifyAppleKiloPassTransactionJws(input.signedTransactionJws); + return completeStoreKiloPassPurchase({ user: ctx.user, purchase }); + }), + getAverageMonthlyUsageLast3Months: baseProcedure .output(GetAverageMonthlyUsageLast3MonthsOutputSchema) .query(async ({ ctx }) => { @@ -387,6 +442,53 @@ export const kiloPassRouter = createTRPCRouter({ return { subscription: null, isEligibleForFirstMonthPromo: isTwoMonthPromoOfferActive() }; } + if (subscriptionBase.paymentProvider !== KiloPassPaymentProvider.Stripe) { + const isFirstTimeSubscriberEver = await getIsFirstTimeSubscriberEverBySubscriptionId({ + kiloUserId: ctx.user.id, + subscriptionId: subscriptionBase.subscriptionId, + }); + const baseAmountUsd = getMonthlyPriceUsd(subscriptionBase.tier); + const startedAtUtc = subscriptionBase.startedAt + ? dayjs(subscriptionBase.startedAt).utc() + : null; + const nextBillingAt = + startedAtUtc?.isValid() === true + ? startedAtUtc + .add(1, subscriptionBase.cadence === KiloPassCadence.Yearly ? 'year' : 'month') + .toISOString() + : null; + const isBonusUnlocked = await getIsBonusUnlockedForSubscriptionId( + subscriptionBase.subscriptionId + ); + + return { + subscription: { + ...subscriptionBase, + nextBonusCreditsUsd: + subscriptionBase.cadence === KiloPassCadence.Yearly + ? roundToCents(computeYearlyCadenceMonthlyBonusUsd(subscriptionBase.tier)) + : roundToCents( + baseAmountUsd * + computeMonthlyCadenceBonusPercent({ + tier: subscriptionBase.tier, + streakMonths: Math.max(1, subscriptionBase.currentStreakMonths + 1), + isFirstTimeSubscriberEver, + subscriptionStartedAtIso: subscriptionBase.startedAt, + }) + ), + nextBillingAt, + isFirstTimeSubscriberEver, + currentPeriodBaseCreditsUsd: baseAmountUsd, + currentPeriodUsageUsd: 0, + currentPeriodHostingCostUsd: 0, + currentPeriodBonusCreditsUsd: null, + isBonusUnlocked, + refillAt: subscriptionBase.nextYearlyIssueAt ?? nextBillingAt, + }, + isEligibleForFirstMonthPromo: false, + }; + } + const stripeCustomerId = ctx.user.stripe_customer_id; if (!stripeCustomerId) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'Missing Stripe customer for user.' }); @@ -631,6 +733,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'No Kilo Pass subscription found.' }); } + assertStripeManagedSubscription(subscription); // Can only cancel active subscriptions that aren't already pending cancellation if (subscription.status !== 'active' || subscription.cancelAtPeriodEnd) { @@ -695,6 +798,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'No Kilo Pass subscription found.' }); } + assertStripeManagedSubscription(subscription); if (!subscription.cancelAtPeriodEnd) { throw new TRPCError({ @@ -744,6 +848,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'No Kilo Pass subscription found.' }); } + assertStripeManagedSubscription(subscription); if (subscription.status !== 'paused') { throw new TRPCError({ @@ -775,6 +880,9 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { return { scheduledChange: null }; } + if (subscription.paymentProvider !== KiloPassPaymentProvider.Stripe) { + return { scheduledChange: null }; + } const scheduledChange = await db.query.kilo_pass_scheduled_changes.findFirst({ columns: { @@ -817,6 +925,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'No Kilo Pass subscription found.' }); } + assertStripeManagedSubscription(subscription); // Only allow scheduling changes for active subscriptions. if (subscription.status !== 'active') { @@ -1017,6 +1126,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'No Kilo Pass subscription found.' }); } + assertStripeManagedSubscription(subscription); const scheduledChange = await db.query.kilo_pass_scheduled_changes.findFirst({ columns: { id: true, stripe_schedule_id: true }, @@ -1054,6 +1164,7 @@ export const kiloPassRouter = createTRPCRouter({ if (!subscription) { return { entries: [], hasMore: false, cursor: null }; } + assertStripeManagedSubscription(subscription); const limit = input.limit ?? 10; const invoices = await stripe.invoices.list({ @@ -1179,7 +1290,12 @@ export const kiloPassRouter = createTRPCRouter({ getChurnkeyAuthHash: baseProcedure .output(z.object({ hash: z.string(), customerId: z.string() })) - .query(({ ctx }) => { + .query(async ({ ctx }) => { + const subscription = await getKiloPassStateForUser(db, ctx.user.id); + if (subscription) { + assertStripeManagedSubscription(subscription); + } + const stripeCustomerId = ctx.user.stripe_customer_id; if (!stripeCustomerId) { throw new TRPCError({ code: 'BAD_REQUEST', message: 'Missing Stripe customer for user.' }); diff --git a/packages/db/src/migrations/0115_productive_captain_cross.sql b/packages/db/src/migrations/0115_productive_captain_cross.sql new file mode 100644 index 0000000000..c120f17745 --- /dev/null +++ b/packages/db/src/migrations/0115_productive_captain_cross.sql @@ -0,0 +1,50 @@ +CREATE TABLE "kilo_pass_store_events" ( + "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, + "payment_provider" text NOT NULL, + "event_id" text NOT NULL, + "provider_subscription_id" text, + "provider_transaction_id" text, + "product_id" text NOT NULL, + "environment" text NOT NULL, + "payload_json" jsonb DEFAULT '{}'::jsonb NOT NULL, + "processed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "kilo_pass_store_events_payment_provider_check" CHECK ("kilo_pass_store_events"."payment_provider" IN ('stripe', 'app_store', 'google_play')) +); +--> statement-breakpoint +CREATE TABLE "kilo_pass_store_purchases" ( + "id" uuid PRIMARY KEY DEFAULT pg_catalog.gen_random_uuid() NOT NULL, + "kilo_pass_subscription_id" uuid NOT NULL, + "kilo_user_id" text NOT NULL, + "payment_provider" text NOT NULL, + "product_id" text NOT NULL, + "provider_subscription_id" text NOT NULL, + "provider_transaction_id" text NOT NULL, + "provider_original_transaction_id" text, + "purchase_token" text, + "environment" text NOT NULL, + "purchased_at" timestamp with time zone NOT NULL, + "raw_payload_json" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "kilo_pass_store_purchases_payment_provider_check" CHECK ("kilo_pass_store_purchases"."payment_provider" IN ('stripe', 'app_store', 'google_play')) +); +--> statement-breakpoint +ALTER TABLE "kilo_pass_audit_log" DROP CONSTRAINT "kilo_pass_audit_log_action_check";--> statement-breakpoint +ALTER TABLE "kilo_pass_issuances" DROP CONSTRAINT "kilo_pass_issuances_source_check";--> statement-breakpoint +ALTER TABLE "kilo_pass_subscriptions" ALTER COLUMN "stripe_subscription_id" DROP NOT NULL;--> statement-breakpoint +ALTER TABLE "kilo_pass_subscriptions" ADD COLUMN "payment_provider" text DEFAULT 'stripe' NOT NULL;--> statement-breakpoint +ALTER TABLE "kilo_pass_subscriptions" ADD COLUMN "provider_subscription_id" text;--> statement-breakpoint +ALTER TABLE "kilo_pass_store_purchases" ADD CONSTRAINT "kilo_pass_store_purchases_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk" FOREIGN KEY ("kilo_pass_subscription_id") REFERENCES "public"."kilo_pass_subscriptions"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +ALTER TABLE "kilo_pass_store_purchases" ADD CONSTRAINT "kilo_pass_store_purchases_kilo_user_id_kilocode_users_id_fk" FOREIGN KEY ("kilo_user_id") REFERENCES "public"."kilocode_users"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_kilo_pass_store_events_provider_event" ON "kilo_pass_store_events" USING btree ("payment_provider","event_id");--> statement-breakpoint +CREATE INDEX "IDX_kilo_pass_store_events_provider_subscription" ON "kilo_pass_store_events" USING btree ("payment_provider","provider_subscription_id");--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_kilo_pass_store_purchases_provider_transaction" ON "kilo_pass_store_purchases" USING btree ("payment_provider","provider_transaction_id");--> statement-breakpoint +CREATE INDEX "IDX_kilo_pass_store_purchases_subscription_id" ON "kilo_pass_store_purchases" USING btree ("kilo_pass_subscription_id");--> statement-breakpoint +CREATE INDEX "IDX_kilo_pass_store_purchases_user_id" ON "kilo_pass_store_purchases" USING btree ("kilo_user_id");--> statement-breakpoint +CREATE INDEX "IDX_kilo_pass_subscriptions_payment_provider" ON "kilo_pass_subscriptions" USING btree ("payment_provider");--> statement-breakpoint +CREATE UNIQUE INDEX "UQ_kilo_pass_subscriptions_provider_subscription" ON "kilo_pass_subscriptions" USING btree ("payment_provider","provider_subscription_id") WHERE "kilo_pass_subscriptions"."provider_subscription_id" IS NOT NULL;--> statement-breakpoint +ALTER TABLE "kilo_pass_audit_log" ADD CONSTRAINT "kilo_pass_audit_log_action_check" CHECK ("kilo_pass_audit_log"."action" IN ('stripe_webhook_received', 'kilo_pass_invoice_paid_handled', 'store_purchase_completed', 'store_notification_received', 'store_subscription_renewed', 'store_subscription_canceled', 'store_subscription_expired', 'store_subscription_refunded', 'base_credits_issued', 'bonus_credits_issued', 'bonus_credits_skipped_idempotent', 'first_month_50pct_promo_issued', 'yearly_monthly_base_cron_started', 'yearly_monthly_base_cron_completed', 'issue_yearly_remaining_credits', 'yearly_monthly_bonus_cron_started', 'yearly_monthly_bonus_cron_completed'));--> statement-breakpoint +ALTER TABLE "kilo_pass_issuances" ADD CONSTRAINT "kilo_pass_issuances_source_check" CHECK ("kilo_pass_issuances"."source" IN ('stripe_invoice', 'app_store_transaction', 'google_play_transaction', 'cron'));--> statement-breakpoint +ALTER TABLE "kilo_pass_subscriptions" ADD CONSTRAINT "kilo_pass_subscriptions_provider_subscription_required_check" CHECK ("kilo_pass_subscriptions"."provider_subscription_id" IS NOT NULL OR "kilo_pass_subscriptions"."payment_provider" = 'stripe');--> statement-breakpoint +ALTER TABLE "kilo_pass_subscriptions" ADD CONSTRAINT "kilo_pass_subscriptions_payment_provider_check" CHECK ("kilo_pass_subscriptions"."payment_provider" IN ('stripe', 'app_store', 'google_play')); \ No newline at end of file diff --git a/packages/db/src/migrations/meta/0115_snapshot.json b/packages/db/src/migrations/meta/0115_snapshot.json new file mode 100644 index 0000000000..fdc4a05ec7 --- /dev/null +++ b/packages/db/src/migrations/meta/0115_snapshot.json @@ -0,0 +1,19125 @@ +{ + "id": "42d6b3d5-b6dc-4fbb-b22f-3bccdd9178f7", + "prevId": "cd0d7b9b-c7a1-41d2-a29e-b62696cba715", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.agent_configs": { + "name": "agent_configs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agent_type": { + "name": "agent_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "runtime_state": { + "name": "runtime_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_configs_org_id": { + "name": "IDX_agent_configs_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_owned_by_user_id": { + "name": "IDX_agent_configs_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_agent_type": { + "name": "IDX_agent_configs_agent_type", + "columns": [ + { + "expression": "agent_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_configs_platform": { + "name": "IDX_agent_configs_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_configs_owned_by_organization_id_organizations_id_fk": { + "name": "agent_configs_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_configs", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_configs_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_configs_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_configs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_configs_org_agent_platform": { + "name": "UQ_agent_configs_org_agent_platform", + "nullsNotDistinct": false, + "columns": [ + "owned_by_organization_id", + "agent_type", + "platform" + ] + }, + "UQ_agent_configs_user_agent_platform": { + "name": "UQ_agent_configs_user_agent_platform", + "nullsNotDistinct": false, + "columns": [ + "owned_by_user_id", + "agent_type", + "platform" + ] + } + }, + "policies": {}, + "checkConstraints": { + "agent_configs_owner_check": { + "name": "agent_configs_owner_check", + "value": "(\n (\"agent_configs\".\"owned_by_user_id\" IS NOT NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_configs\".\"owned_by_user_id\" IS NULL AND \"agent_configs\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "agent_configs_agent_type_check": { + "name": "agent_configs_agent_type_check", + "value": "\"agent_configs\".\"agent_type\" IN ('code_review', 'auto_triage', 'auto_fix', 'security_scan')" + } + }, + "isRLSEnabled": false + }, + "public.agent_environment_profile_commands": { + "name": "agent_environment_profile_commands", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_env_profile_commands_profile_id": { + "name": "IDX_agent_env_profile_commands_profile_id", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_commands_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_commands", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_env_profile_commands_profile_sequence": { + "name": "UQ_agent_env_profile_commands_profile_sequence", + "nullsNotDistinct": false, + "columns": [ + "profile_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_environment_profile_repo_bindings": { + "name": "agent_environment_profile_repo_bindings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_agent_env_profile_repo_bindings_user": { + "name": "UQ_agent_env_profile_repo_bindings_user", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profile_repo_bindings_org": { + "name": "UQ_agent_env_profile_repo_bindings_org", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_repo_bindings_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk": { + "name": "agent_environment_profile_repo_bindings_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_environment_profile_repo_bindings_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_environment_profile_repo_bindings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "agent_env_profile_repo_bindings_owner_check": { + "name": "agent_env_profile_repo_bindings_owner_check", + "value": "(\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profile_repo_bindings\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profile_repo_bindings\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.agent_environment_profile_vars": { + "name": "agent_environment_profile_vars", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_secret": { + "name": "is_secret", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_agent_env_profile_vars_profile_id": { + "name": "IDX_agent_env_profile_vars_profile_id", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk": { + "name": "agent_environment_profile_vars_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "agent_environment_profile_vars", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_agent_env_profile_vars_profile_key": { + "name": "UQ_agent_env_profile_vars_profile_key", + "nullsNotDistinct": false, + "columns": [ + "profile_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.agent_environment_profiles": { + "name": "agent_environment_profiles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_agent_env_profiles_org_name": { + "name": "UQ_agent_env_profiles_org_name", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_user_name": { + "name": "UQ_agent_env_profiles_user_name", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_org_default": { + "name": "UQ_agent_env_profiles_org_default", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_agent_env_profiles_user_default": { + "name": "UQ_agent_env_profiles_user_default", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"agent_environment_profiles\".\"is_default\" = true AND \"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_env_profiles_org_id": { + "name": "IDX_agent_env_profiles_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_agent_env_profiles_user_id": { + "name": "IDX_agent_env_profiles_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "agent_environment_profiles_owned_by_organization_id_organizations_id_fk": { + "name": "agent_environment_profiles_owned_by_organization_id_organizations_id_fk", + "tableFrom": "agent_environment_profiles", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk": { + "name": "agent_environment_profiles_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "agent_environment_profiles", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "agent_env_profiles_owner_check": { + "name": "agent_env_profiles_owner_check", + "value": "(\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NOT NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NULL) OR\n (\"agent_environment_profiles\".\"owned_by_user_id\" IS NULL AND \"agent_environment_profiles\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.api_kind": { + "name": "api_kind", + "schema": "", + "columns": { + "api_kind_id": { + "name": "api_kind_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "api_kind": { + "name": "api_kind", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_api_kind": { + "name": "UQ_api_kind", + "columns": [ + { + "expression": "api_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.api_request_log": { + "name": "api_request_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "request": { + "name": "request", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "response": { + "name": "response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_api_request_log_created_at": { + "name": "idx_api_request_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_feedback": { + "name": "app_builder_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preview_status": { + "name": "preview_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_streaming": { + "name": "is_streaming", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recent_messages": { + "name": "recent_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_app_builder_feedback_created_at": { + "name": "IDX_app_builder_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_feedback_kilo_user_id": { + "name": "IDX_app_builder_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_feedback_project_id": { + "name": "IDX_app_builder_feedback_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "app_builder_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "app_builder_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "app_builder_feedback_project_id_app_builder_projects_id_fk": { + "name": "app_builder_feedback_project_id_app_builder_projects_id_fk", + "tableFrom": "app_builder_feedback", + "tableTo": "app_builder_projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_project_sessions": { + "name": "app_builder_project_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "worker_version": { + "name": "worker_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'v2'" + } + }, + "indexes": { + "IDX_app_builder_project_sessions_project_id": { + "name": "IDX_app_builder_project_sessions_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_project_sessions_project_id_app_builder_projects_id_fk": { + "name": "app_builder_project_sessions_project_id_app_builder_projects_id_fk", + "tableFrom": "app_builder_project_sessions", + "tableTo": "app_builder_projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_app_builder_project_sessions_cloud_agent_session_id": { + "name": "UQ_app_builder_project_sessions_cloud_agent_session_id", + "nullsNotDistinct": false, + "columns": [ + "cloud_agent_session_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_builder_projects": { + "name": "app_builder_projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template": { + "name": "template", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "git_repo_full_name": { + "name": "git_repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_platform_integration_id": { + "name": "git_platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "migrated_at": { + "name": "migrated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_app_builder_projects_created_by_user_id": { + "name": "IDX_app_builder_projects_created_by_user_id", + "columns": [ + { + "expression": "created_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_owned_by_user_id": { + "name": "IDX_app_builder_projects_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_owned_by_organization_id": { + "name": "IDX_app_builder_projects_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_created_at": { + "name": "IDX_app_builder_projects_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_app_builder_projects_last_message_at": { + "name": "IDX_app_builder_projects_last_message_at", + "columns": [ + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "app_builder_projects_owned_by_user_id_kilocode_users_id_fk": { + "name": "app_builder_projects_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "app_builder_projects_owned_by_organization_id_organizations_id_fk": { + "name": "app_builder_projects_owned_by_organization_id_organizations_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "app_builder_projects_deployment_id_deployments_id_fk": { + "name": "app_builder_projects_deployment_id_deployments_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk": { + "name": "app_builder_projects_git_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "app_builder_projects", + "tableTo": "platform_integrations", + "columnsFrom": [ + "git_platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "app_builder_projects_owner_check": { + "name": "app_builder_projects_owner_check", + "value": "(\n (\"app_builder_projects\".\"owned_by_user_id\" IS NOT NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NULL) OR\n (\"app_builder_projects\".\"owned_by_user_id\" IS NULL AND \"app_builder_projects\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.app_min_versions": { + "name": "app_min_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "ios_min_version": { + "name": "ios_min_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'1.0.0'" + }, + "android_min_version": { + "name": "android_min_version", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'1.0.0'" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app_reported_messages": { + "name": "app_reported_messages", + "schema": "", + "columns": { + "report_id": { + "name": "report_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "report_type": { + "name": "report_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signature": { + "name": "signature", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "app_reported_messages_cli_session_id_cli_sessions_session_id_fk": { + "name": "app_reported_messages_cli_session_id_cli_sessions_session_id_fk", + "tableFrom": "app_reported_messages", + "tableTo": "cli_sessions", + "columnsFrom": [ + "cli_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auto_fix_tickets": { + "name": "auto_fix_tickets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "triage_ticket_id": { + "name": "triage_ticket_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_number": { + "name": "issue_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "issue_url": { + "name": "issue_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_title": { + "name": "issue_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_body": { + "name": "issue_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issue_author": { + "name": "issue_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_labels": { + "name": "issue_labels", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "trigger_source": { + "name": "trigger_source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'label'" + }, + "review_comment_id": { + "name": "review_comment_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "review_comment_body": { + "name": "review_comment_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "line_number": { + "name": "line_number", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "diff_hunk": { + "name": "diff_hunk", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pr_head_ref": { + "name": "pr_head_ref", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "classification": { + "name": "classification", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confidence": { + "name": "confidence", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "intent_summary": { + "name": "intent_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_files": { + "name": "related_files", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "pr_number": { + "name": "pr_number", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "pr_url": { + "name": "pr_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pr_branch": { + "name": "pr_branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_fix_tickets_repo_issue": { + "name": "UQ_auto_fix_tickets_repo_issue", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "issue_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_fix_tickets\".\"trigger_source\" = 'label'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_auto_fix_tickets_repo_review_comment": { + "name": "UQ_auto_fix_tickets_repo_review_comment", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "review_comment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_fix_tickets\".\"review_comment_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_owned_by_org": { + "name": "IDX_auto_fix_tickets_owned_by_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_owned_by_user": { + "name": "IDX_auto_fix_tickets_owned_by_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_status": { + "name": "IDX_auto_fix_tickets_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_created_at": { + "name": "IDX_auto_fix_tickets_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_triage_ticket_id": { + "name": "IDX_auto_fix_tickets_triage_ticket_id", + "columns": [ + { + "expression": "triage_ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_fix_tickets_session_id": { + "name": "IDX_auto_fix_tickets_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_fix_tickets_owned_by_organization_id_organizations_id_fk": { + "name": "auto_fix_tickets_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_fix_tickets_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk": { + "name": "auto_fix_tickets_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk": { + "name": "auto_fix_tickets_triage_ticket_id_auto_triage_tickets_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "auto_triage_tickets", + "columnsFrom": [ + "triage_ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk": { + "name": "auto_fix_tickets_cli_session_id_cli_sessions_session_id_fk", + "tableFrom": "auto_fix_tickets", + "tableTo": "cli_sessions", + "columnsFrom": [ + "cli_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_fix_tickets_owner_check": { + "name": "auto_fix_tickets_owner_check", + "value": "(\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_fix_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_fix_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "auto_fix_tickets_status_check": { + "name": "auto_fix_tickets_status_check", + "value": "\"auto_fix_tickets\".\"status\" IN ('pending', 'running', 'completed', 'failed', 'cancelled')" + }, + "auto_fix_tickets_classification_check": { + "name": "auto_fix_tickets_classification_check", + "value": "\"auto_fix_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'unclear')" + }, + "auto_fix_tickets_confidence_check": { + "name": "auto_fix_tickets_confidence_check", + "value": "\"auto_fix_tickets\".\"confidence\" >= 0 AND \"auto_fix_tickets\".\"confidence\" <= 1" + }, + "auto_fix_tickets_trigger_source_check": { + "name": "auto_fix_tickets_trigger_source_check", + "value": "\"auto_fix_tickets\".\"trigger_source\" IN ('label', 'review_comment')" + } + }, + "isRLSEnabled": false + }, + "public.auto_model": { + "name": "auto_model", + "schema": "", + "columns": { + "auto_model_id": { + "name": "auto_model_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "auto_model": { + "name": "auto_model", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_auto_model": { + "name": "UQ_auto_model", + "columns": [ + { + "expression": "auto_model", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auto_top_up_configs": { + "name": "auto_top_up_configs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_payment_method_id": { + "name": "stripe_payment_method_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_cents": { + "name": "amount_cents", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5000 + }, + "last_auto_top_up_at": { + "name": "last_auto_top_up_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempt_started_at": { + "name": "attempt_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_top_up_configs_owned_by_user_id": { + "name": "UQ_auto_top_up_configs_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_auto_top_up_configs_owned_by_organization_id": { + "name": "UQ_auto_top_up_configs_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_top_up_configs_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_top_up_configs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "auto_top_up_configs_owned_by_organization_id_organizations_id_fk": { + "name": "auto_top_up_configs_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_top_up_configs", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_top_up_configs_exactly_one_owner": { + "name": "auto_top_up_configs_exactly_one_owner", + "value": "(\"auto_top_up_configs\".\"owned_by_user_id\" IS NOT NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NULL) OR (\"auto_top_up_configs\".\"owned_by_user_id\" IS NULL AND \"auto_top_up_configs\".\"owned_by_organization_id\" IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.auto_triage_tickets": { + "name": "auto_triage_tickets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_number": { + "name": "issue_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "issue_url": { + "name": "issue_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_title": { + "name": "issue_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_body": { + "name": "issue_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issue_author": { + "name": "issue_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_type": { + "name": "issue_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "issue_labels": { + "name": "issue_labels", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "classification": { + "name": "classification", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confidence": { + "name": "confidence", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "intent_summary": { + "name": "intent_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_files": { + "name": "related_files", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_duplicate": { + "name": "is_duplicate", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "duplicate_of_ticket_id": { + "name": "duplicate_of_ticket_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "similarity_score": { + "name": "similarity_score", + "type": "numeric(3, 2)", + "primaryKey": false, + "notNull": false + }, + "qdrant_point_id": { + "name": "qdrant_point_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "should_auto_fix": { + "name": "should_auto_fix", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "action_taken": { + "name": "action_taken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action_metadata": { + "name": "action_metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_auto_triage_tickets_repo_issue": { + "name": "UQ_auto_triage_tickets_repo_issue", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "issue_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owned_by_org": { + "name": "IDX_auto_triage_tickets_owned_by_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owned_by_user": { + "name": "IDX_auto_triage_tickets_owned_by_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_status": { + "name": "IDX_auto_triage_tickets_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_created_at": { + "name": "IDX_auto_triage_tickets_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_qdrant_point_id": { + "name": "IDX_auto_triage_tickets_qdrant_point_id", + "columns": [ + { + "expression": "qdrant_point_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_owner_status_created": { + "name": "IDX_auto_triage_tickets_owner_status_created", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_user_status_created": { + "name": "IDX_auto_triage_tickets_user_status_created", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_auto_triage_tickets_repo_classification": { + "name": "IDX_auto_triage_tickets_repo_classification", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "classification", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auto_triage_tickets_owned_by_organization_id_organizations_id_fk": { + "name": "auto_triage_tickets_owned_by_organization_id_organizations_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk": { + "name": "auto_triage_tickets_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk": { + "name": "auto_triage_tickets_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk": { + "name": "auto_triage_tickets_duplicate_of_ticket_id_auto_triage_tickets_id_fk", + "tableFrom": "auto_triage_tickets", + "tableTo": "auto_triage_tickets", + "columnsFrom": [ + "duplicate_of_ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "auto_triage_tickets_owner_check": { + "name": "auto_triage_tickets_owner_check", + "value": "(\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NOT NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NULL) OR\n (\"auto_triage_tickets\".\"owned_by_user_id\" IS NULL AND \"auto_triage_tickets\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "auto_triage_tickets_issue_type_check": { + "name": "auto_triage_tickets_issue_type_check", + "value": "\"auto_triage_tickets\".\"issue_type\" IN ('issue', 'pull_request')" + }, + "auto_triage_tickets_classification_check": { + "name": "auto_triage_tickets_classification_check", + "value": "\"auto_triage_tickets\".\"classification\" IN ('bug', 'feature', 'question', 'duplicate', 'unclear')" + }, + "auto_triage_tickets_confidence_check": { + "name": "auto_triage_tickets_confidence_check", + "value": "\"auto_triage_tickets\".\"confidence\" >= 0 AND \"auto_triage_tickets\".\"confidence\" <= 1" + }, + "auto_triage_tickets_similarity_score_check": { + "name": "auto_triage_tickets_similarity_score_check", + "value": "\"auto_triage_tickets\".\"similarity_score\" >= 0 AND \"auto_triage_tickets\".\"similarity_score\" <= 1" + }, + "auto_triage_tickets_status_check": { + "name": "auto_triage_tickets_status_check", + "value": "\"auto_triage_tickets\".\"status\" IN ('pending', 'analyzing', 'actioned', 'failed', 'skipped')" + }, + "auto_triage_tickets_action_taken_check": { + "name": "auto_triage_tickets_action_taken_check", + "value": "\"auto_triage_tickets\".\"action_taken\" IN ('pr_created', 'comment_posted', 'closed_duplicate', 'needs_clarification')" + } + }, + "isRLSEnabled": false + }, + "public.bot_request_cloud_agent_sessions": { + "name": "bot_request_cloud_agent_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "bot_request_id": { + "name": "bot_request_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "spawn_group_id": { + "name": "spawn_group_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_session_id": { + "name": "kilo_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "execution_id": { + "name": "execution_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'running'" + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_repo": { + "name": "github_repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlab_project": { + "name": "gitlab_project", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "callback_step": { + "name": "callback_step", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "final_message": { + "name": "final_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "final_message_fetched_at": { + "name": "final_message_fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "final_message_error": { + "name": "final_message_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_at": { + "name": "terminal_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "continuation_started_at": { + "name": "continuation_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_bot_request_cas_cloud_agent_session_id": { + "name": "UQ_bot_request_cas_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id": { + "name": "IDX_bot_request_cas_bot_request_id", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id_spawn_group_id": { + "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "spawn_group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_request_cas_bot_request_id_spawn_group_id_status": { + "name": "IDX_bot_request_cas_bot_request_id_spawn_group_id_status", + "columns": [ + { + "expression": "bot_request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "spawn_group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk": { + "name": "bot_request_cloud_agent_sessions_bot_request_id_bot_requests_id_fk", + "tableFrom": "bot_request_cloud_agent_sessions", + "tableTo": "bot_requests", + "columnsFrom": [ + "bot_request_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bot_requests": { + "name": "bot_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_thread_id": { + "name": "platform_thread_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_message_id": { + "name": "platform_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_message": { + "name": "user_message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_used": { + "name": "model_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "steps": { + "name": "steps", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_time_ms": { + "name": "response_time_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_bot_requests_created_at": { + "name": "IDX_bot_requests_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_created_by": { + "name": "IDX_bot_requests_created_by", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_organization_id": { + "name": "IDX_bot_requests_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_platform_integration_id": { + "name": "IDX_bot_requests_platform_integration_id", + "columns": [ + { + "expression": "platform_integration_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_bot_requests_status": { + "name": "IDX_bot_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "bot_requests_created_by_kilocode_users_id_fk": { + "name": "bot_requests_created_by_kilocode_users_id_fk", + "tableFrom": "bot_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bot_requests_organization_id_organizations_id_fk": { + "name": "bot_requests_organization_id_organizations_id_fk", + "tableFrom": "bot_requests", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bot_requests_platform_integration_id_platform_integrations_id_fk": { + "name": "bot_requests_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "bot_requests", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.byok_api_keys": { + "name": "byok_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_api_key": { + "name": "encrypted_api_key", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "IDX_byok_api_keys_organization_id": { + "name": "IDX_byok_api_keys_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_byok_api_keys_kilo_user_id": { + "name": "IDX_byok_api_keys_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_byok_api_keys_provider_id": { + "name": "IDX_byok_api_keys_provider_id", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "byok_api_keys_organization_id_organizations_id_fk": { + "name": "byok_api_keys_organization_id_organizations_id_fk", + "tableFrom": "byok_api_keys", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "byok_api_keys_kilo_user_id_kilocode_users_id_fk": { + "name": "byok_api_keys_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "byok_api_keys", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_byok_api_keys_org_provider": { + "name": "UQ_byok_api_keys_org_provider", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "provider_id" + ] + }, + "UQ_byok_api_keys_user_provider": { + "name": "UQ_byok_api_keys_user_provider", + "nullsNotDistinct": false, + "columns": [ + "kilo_user_id", + "provider_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "byok_api_keys_owner_check": { + "name": "byok_api_keys_owner_check", + "value": "(\n (\"byok_api_keys\".\"kilo_user_id\" IS NOT NULL AND \"byok_api_keys\".\"organization_id\" IS NULL) OR\n (\"byok_api_keys\".\"kilo_user_id\" IS NULL AND \"byok_api_keys\".\"organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.cli_sessions": { + "name": "cli_sessions", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_on_platform": { + "name": "created_on_platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "api_conversation_history_blob_url": { + "name": "api_conversation_history_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "task_metadata_blob_url": { + "name": "task_metadata_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ui_messages_blob_url": { + "name": "ui_messages_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_state_blob_url": { + "name": "git_state_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_url": { + "name": "git_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "forked_from": { + "name": "forked_from", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "parent_session_id": { + "name": "parent_session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "last_mode": { + "name": "last_mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_model": { + "name": "last_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cli_sessions_kilo_user_id": { + "name": "IDX_cli_sessions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_created_at": { + "name": "IDX_cli_sessions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_updated_at": { + "name": "IDX_cli_sessions_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_organization_id": { + "name": "IDX_cli_sessions_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_user_updated": { + "name": "IDX_cli_sessions_user_updated", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cli_sessions_kilo_user_id_kilocode_users_id_fk": { + "name": "cli_sessions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "cli_sessions_forked_from_cli_sessions_session_id_fk": { + "name": "cli_sessions_forked_from_cli_sessions_session_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "forked_from" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_parent_session_id_cli_sessions_session_id_fk": { + "name": "cli_sessions_parent_session_id_cli_sessions_session_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "parent_session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_organization_id_organizations_id_fk": { + "name": "cli_sessions_organization_id_organizations_id_fk", + "tableFrom": "cli_sessions", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "cli_sessions_cloud_agent_session_id_unique": { + "name": "cli_sessions_cloud_agent_session_id_unique", + "nullsNotDistinct": false, + "columns": [ + "cloud_agent_session_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cli_sessions_v2": { + "name": "cli_sessions_v2", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_id": { + "name": "public_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "parent_session_id": { + "name": "parent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_on_platform": { + "name": "created_on_platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "git_url": { + "name": "git_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_updated_at": { + "name": "status_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cli_sessions_v2_parent_session_id_kilo_user_id": { + "name": "IDX_cli_sessions_v2_parent_session_id_kilo_user_id", + "columns": [ + { + "expression": "parent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cli_sessions_v2_public_id": { + "name": "UQ_cli_sessions_v2_public_id", + "columns": [ + { + "expression": "public_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cli_sessions_v2\".\"public_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cli_sessions_v2_cloud_agent_session_id": { + "name": "UQ_cli_sessions_v2_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cli_sessions_v2\".\"cloud_agent_session_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_organization_id": { + "name": "IDX_cli_sessions_v2_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_kilo_user_id": { + "name": "IDX_cli_sessions_v2_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_created_at": { + "name": "IDX_cli_sessions_v2_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cli_sessions_v2_user_updated": { + "name": "IDX_cli_sessions_v2_user_updated", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk": { + "name": "cli_sessions_v2_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "cli_sessions_v2_organization_id_organizations_id_fk": { + "name": "cli_sessions_v2_organization_id_organizations_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "cli_sessions_v2_parent_session_id_kilo_user_id_fk": { + "name": "cli_sessions_v2_parent_session_id_kilo_user_id_fk", + "tableFrom": "cli_sessions_v2", + "tableTo": "cli_sessions_v2", + "columnsFrom": [ + "parent_session_id", + "kilo_user_id" + ], + "columnsTo": [ + "session_id", + "kilo_user_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "cli_sessions_v2_session_id_kilo_user_id_pk": { + "name": "cli_sessions_v2_session_id_kilo_user_id_pk", + "columns": [ + "session_id", + "kilo_user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cloud_agent_code_reviews": { + "name": "cloud_agent_code_reviews", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_number": { + "name": "pr_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pr_url": { + "name": "pr_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_title": { + "name": "pr_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_author": { + "name": "pr_author", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pr_author_github_id": { + "name": "pr_author_github_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "base_ref": { + "name": "base_ref", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "head_ref": { + "name": "head_ref", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "head_sha": { + "name": "head_sha", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "platform_project_id": { + "name": "platform_project_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terminal_reason": { + "name": "terminal_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "agent_version": { + "name": "agent_version", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'v1'" + }, + "check_run_id": { + "name": "check_run_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "total_tokens_in": { + "name": "total_tokens_in", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_tokens_out": { + "name": "total_tokens_out", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_cost_musd": { + "name": "total_cost_musd", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_cloud_agent_code_reviews_repo_pr_sha": { + "name": "UQ_cloud_agent_code_reviews_repo_pr_sha", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pr_number", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "head_sha", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_owned_by_org_id": { + "name": "idx_cloud_agent_code_reviews_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_owned_by_user_id": { + "name": "idx_cloud_agent_code_reviews_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_session_id": { + "name": "idx_cloud_agent_code_reviews_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_cli_session_id": { + "name": "idx_cloud_agent_code_reviews_cli_session_id", + "columns": [ + { + "expression": "cli_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_status": { + "name": "idx_cloud_agent_code_reviews_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_repo": { + "name": "idx_cloud_agent_code_reviews_repo", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_pr_number": { + "name": "idx_cloud_agent_code_reviews_pr_number", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pr_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_created_at": { + "name": "idx_cloud_agent_code_reviews_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cloud_agent_code_reviews_pr_author_github_id": { + "name": "idx_cloud_agent_code_reviews_pr_author_github_id", + "columns": [ + { + "expression": "pr_author_github_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk": { + "name": "cloud_agent_code_reviews_owned_by_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_code_reviews_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk": { + "name": "cloud_agent_code_reviews_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "cloud_agent_code_reviews", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "cloud_agent_code_reviews_owner_check": { + "name": "cloud_agent_code_reviews_owner_check", + "value": "(\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NOT NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NULL) OR\n (\"cloud_agent_code_reviews\".\"owned_by_user_id\" IS NULL AND \"cloud_agent_code_reviews\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.cloud_agent_feedback": { + "name": "cloud_agent_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_streaming": { + "name": "is_streaming", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recent_messages": { + "name": "recent_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_cloud_agent_feedback_created_at": { + "name": "IDX_cloud_agent_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_feedback_kilo_user_id": { + "name": "IDX_cloud_agent_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_feedback_cloud_agent_session_id": { + "name": "IDX_cloud_agent_feedback_cloud_agent_session_id", + "columns": [ + { + "expression": "cloud_agent_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "cloud_agent_feedback_organization_id_organizations_id_fk": { + "name": "cloud_agent_feedback_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_feedback", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cloud_agent_webhook_triggers": { + "name": "cloud_agent_webhook_triggers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "trigger_id": { + "name": "trigger_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'cloud_agent'" + }, + "kiloclaw_instance_id": { + "name": "kiloclaw_instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "activation_mode": { + "name": "activation_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'webhook'" + }, + "cron_expression": { + "name": "cron_expression", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cron_timezone": { + "name": "cron_timezone", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'UTC'" + }, + "github_repo": { + "name": "github_repo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_cloud_agent_webhook_triggers_user_trigger": { + "name": "UQ_cloud_agent_webhook_triggers_user_trigger", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trigger_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cloud_agent_webhook_triggers\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_cloud_agent_webhook_triggers_org_trigger": { + "name": "UQ_cloud_agent_webhook_triggers_org_trigger", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trigger_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"cloud_agent_webhook_triggers\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_user": { + "name": "IDX_cloud_agent_webhook_triggers_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_org": { + "name": "IDX_cloud_agent_webhook_triggers_org", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_active": { + "name": "IDX_cloud_agent_webhook_triggers_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_cloud_agent_webhook_triggers_profile": { + "name": "IDX_cloud_agent_webhook_triggers_profile", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk": { + "name": "cloud_agent_webhook_triggers_user_id_kilocode_users_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_organization_id_organizations_id_fk": { + "name": "cloud_agent_webhook_triggers_organization_id_organizations_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk": { + "name": "cloud_agent_webhook_triggers_kiloclaw_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "kiloclaw_instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk": { + "name": "cloud_agent_webhook_triggers_profile_id_agent_environment_profiles_id_fk", + "tableFrom": "cloud_agent_webhook_triggers", + "tableTo": "agent_environment_profiles", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "CHK_cloud_agent_webhook_triggers_owner": { + "name": "CHK_cloud_agent_webhook_triggers_owner", + "value": "(\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NULL) OR\n (\"cloud_agent_webhook_triggers\".\"user_id\" IS NULL AND \"cloud_agent_webhook_triggers\".\"organization_id\" IS NOT NULL)\n )" + }, + "CHK_cloud_agent_webhook_triggers_cloud_agent_fields": { + "name": "CHK_cloud_agent_webhook_triggers_cloud_agent_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'cloud_agent' OR\n (\"cloud_agent_webhook_triggers\".\"github_repo\" IS NOT NULL AND \"cloud_agent_webhook_triggers\".\"profile_id\" IS NOT NULL)\n )" + }, + "CHK_cloud_agent_webhook_triggers_kiloclaw_fields": { + "name": "CHK_cloud_agent_webhook_triggers_kiloclaw_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"target_type\" != 'kiloclaw_chat' OR\n \"cloud_agent_webhook_triggers\".\"kiloclaw_instance_id\" IS NOT NULL\n )" + }, + "CHK_cloud_agent_webhook_triggers_scheduled_fields": { + "name": "CHK_cloud_agent_webhook_triggers_scheduled_fields", + "value": "(\n \"cloud_agent_webhook_triggers\".\"activation_mode\" != 'scheduled' OR\n \"cloud_agent_webhook_triggers\".\"cron_expression\" IS NOT NULL\n )" + } + }, + "isRLSEnabled": false + }, + "public.code_indexing_manifest": { + "name": "code_indexing_manifest", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_hash": { + "name": "file_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chunk_count": { + "name": "chunk_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "total_lines": { + "name": "total_lines", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_ai_lines": { + "name": "total_ai_lines", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_code_indexing_manifest_organization_id": { + "name": "IDX_code_indexing_manifest_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_kilo_user_id": { + "name": "IDX_code_indexing_manifest_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_project_id": { + "name": "IDX_code_indexing_manifest_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_file_hash": { + "name": "IDX_code_indexing_manifest_file_hash", + "columns": [ + { + "expression": "file_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_git_branch": { + "name": "IDX_code_indexing_manifest_git_branch", + "columns": [ + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_manifest_created_at": { + "name": "IDX_code_indexing_manifest_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk": { + "name": "code_indexing_manifest_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "code_indexing_manifest", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_code_indexing_manifest_org_user_project_hash_branch": { + "name": "UQ_code_indexing_manifest_org_user_project_hash_branch", + "nullsNotDistinct": true, + "columns": [ + "organization_id", + "kilo_user_id", + "project_id", + "file_path", + "git_branch" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.code_indexing_search": { + "name": "code_indexing_search", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_code_indexing_search_organization_id": { + "name": "IDX_code_indexing_search_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_kilo_user_id": { + "name": "IDX_code_indexing_search_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_project_id": { + "name": "IDX_code_indexing_search_project_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_code_indexing_search_created_at": { + "name": "IDX_code_indexing_search_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "code_indexing_search_kilo_user_id_kilocode_users_id_fk": { + "name": "code_indexing_search_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "code_indexing_search", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_contributors": { + "name": "contributor_champion_contributors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "github_login": { + "name": "github_login", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_profile_url": { + "name": "github_profile_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_user_id": { + "name": "github_user_id", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "first_contribution_at": { + "name": "first_contribution_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_contribution_at": { + "name": "last_contribution_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "all_time_contributions": { + "name": "all_time_contributions", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "manual_email": { + "name": "manual_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_contributors_last_contribution_at": { + "name": "IDX_contributor_champion_contributors_last_contribution_at", + "columns": [ + { + "expression": "last_contribution_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_contributors_manual_email": { + "name": "IDX_contributor_champion_contributors_manual_email", + "columns": [ + { + "expression": "manual_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_contributors_github_login": { + "name": "UQ_contributor_champion_contributors_github_login", + "nullsNotDistinct": false, + "columns": [ + "github_login" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_events": { + "name": "contributor_champion_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "contributor_id": { + "name": "contributor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_pr_number": { + "name": "github_pr_number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "github_pr_url": { + "name": "github_pr_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_pr_title": { + "name": "github_pr_title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_author_login": { + "name": "github_author_login", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_author_email": { + "name": "github_author_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_events_contributor_id": { + "name": "IDX_contributor_champion_events_contributor_id", + "columns": [ + { + "expression": "contributor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_events_merged_at": { + "name": "IDX_contributor_champion_events_merged_at", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_events_author_email": { + "name": "IDX_contributor_champion_events_author_email", + "columns": [ + { + "expression": "github_author_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk": { + "name": "contributor_champion_events_contributor_id_contributor_champion_contributors_id_fk", + "tableFrom": "contributor_champion_events", + "tableTo": "contributor_champion_contributors", + "columnsFrom": [ + "contributor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_events_repo_pr": { + "name": "UQ_contributor_champion_events_repo_pr", + "nullsNotDistinct": false, + "columns": [ + "repo_full_name", + "github_pr_number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contributor_champion_memberships": { + "name": "contributor_champion_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "contributor_id": { + "name": "contributor_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "selected_tier": { + "name": "selected_tier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enrolled_tier": { + "name": "enrolled_tier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enrolled_at": { + "name": "enrolled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "credit_amount_microdollars": { + "name": "credit_amount_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "credits_last_granted_at": { + "name": "credits_last_granted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "linked_kilo_user_id": { + "name": "linked_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_contributor_champion_memberships_credits_due": { + "name": "IDX_contributor_champion_memberships_credits_due", + "columns": [ + { + "expression": "credits_last_granted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NOT NULL AND \"contributor_champion_memberships\".\"credit_amount_microdollars\" > 0", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_contributor_champion_memberships_linked_kilo_user_id": { + "name": "IDX_contributor_champion_memberships_linked_kilo_user_id", + "columns": [ + { + "expression": "linked_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk": { + "name": "contributor_champion_memberships_contributor_id_contributor_champion_contributors_id_fk", + "tableFrom": "contributor_champion_memberships", + "tableTo": "contributor_champion_contributors", + "columnsFrom": [ + "contributor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk": { + "name": "contributor_champion_memberships_linked_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "contributor_champion_memberships", + "tableTo": "kilocode_users", + "columnsFrom": [ + "linked_kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_contributor_champion_memberships_contributor_id": { + "name": "UQ_contributor_champion_memberships_contributor_id", + "nullsNotDistinct": false, + "columns": [ + "contributor_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "contributor_champion_memberships_selected_tier_check": { + "name": "contributor_champion_memberships_selected_tier_check", + "value": "\"contributor_champion_memberships\".\"selected_tier\" IS NULL OR \"contributor_champion_memberships\".\"selected_tier\" IN ('contributor', 'ambassador', 'champion')" + }, + "contributor_champion_memberships_enrolled_tier_check": { + "name": "contributor_champion_memberships_enrolled_tier_check", + "value": "\"contributor_champion_memberships\".\"enrolled_tier\" IS NULL OR \"contributor_champion_memberships\".\"enrolled_tier\" IN ('contributor', 'ambassador', 'champion')" + } + }, + "isRLSEnabled": false + }, + "public.contributor_champion_sync_state": { + "name": "contributor_champion_sync_state", + "schema": "", + "columns": { + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_merged_at": { + "name": "last_merged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.credit_campaigns": { + "name": "credit_campaigns", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credit_category": { + "name": "credit_category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_microdollars": { + "name": "amount_microdollars", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credit_expiry_hours": { + "name": "credit_expiry_hours", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_ends_at": { + "name": "campaign_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_redemptions_allowed": { + "name": "total_redemptions_allowed", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by_kilo_user_id": { + "name": "created_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_credit_campaigns_slug": { + "name": "UQ_credit_campaigns_slug", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_credit_campaigns_credit_category": { + "name": "UQ_credit_campaigns_credit_category", + "columns": [ + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "credit_campaigns_slug_format_check": { + "name": "credit_campaigns_slug_format_check", + "value": "\"credit_campaigns\".\"slug\" ~ '^[a-z0-9-]{5,40}$'" + }, + "credit_campaigns_amount_positive_check": { + "name": "credit_campaigns_amount_positive_check", + "value": "\"credit_campaigns\".\"amount_microdollars\" > 0" + }, + "credit_campaigns_credit_expiry_hours_positive_check": { + "name": "credit_campaigns_credit_expiry_hours_positive_check", + "value": "\"credit_campaigns\".\"credit_expiry_hours\" IS NULL OR \"credit_campaigns\".\"credit_expiry_hours\" > 0" + }, + "credit_campaigns_total_redemptions_allowed_positive_check": { + "name": "credit_campaigns_total_redemptions_allowed_positive_check", + "value": "\"credit_campaigns\".\"total_redemptions_allowed\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.credit_transactions": { + "name": "credit_transactions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_microdollars": { + "name": "amount_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "expiration_baseline_microdollars_used": { + "name": "expiration_baseline_microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "original_baseline_microdollars_used": { + "name": "original_baseline_microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "original_transaction_id": { + "name": "original_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "stripe_payment_id": { + "name": "stripe_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "coinbase_credit_block_id": { + "name": "coinbase_credit_block_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credit_category": { + "name": "credit_category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expiry_date": { + "name": "expiry_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "check_category_uniqueness": { + "name": "check_category_uniqueness", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "IDX_credit_transactions_created_at": { + "name": "IDX_credit_transactions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_is_free": { + "name": "IDX_credit_transactions_is_free", + "columns": [ + { + "expression": "is_free", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_kilo_user_id": { + "name": "IDX_credit_transactions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_credit_category": { + "name": "IDX_credit_transactions_credit_category", + "columns": [ + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_stripe_payment_id": { + "name": "IDX_credit_transactions_stripe_payment_id", + "columns": [ + { + "expression": "stripe_payment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_original_transaction_id": { + "name": "IDX_credit_transactions_original_transaction_id", + "columns": [ + { + "expression": "original_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_coinbase_credit_block_id": { + "name": "IDX_credit_transactions_coinbase_credit_block_id", + "columns": [ + { + "expression": "coinbase_credit_block_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_organization_id": { + "name": "IDX_credit_transactions_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_credit_transactions_unique_category": { + "name": "IDX_credit_transactions_unique_category", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "credit_category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"credit_transactions\".\"check_category_uniqueness\" = TRUE", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_llm2": { + "name": "custom_llm2", + "schema": "", + "columns": { + "public_id": { + "name": "public_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "definition": { + "name": "definition", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_builds": { + "name": "deployment_builds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_builds_deployment_id": { + "name": "idx_deployment_builds_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_builds_status": { + "name": "idx_deployment_builds_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_builds_deployment_id_deployments_id_fk": { + "name": "deployment_builds_deployment_id_deployments_id_fk", + "tableFrom": "deployment_builds", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_env_vars": { + "name": "deployment_env_vars", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_secret": { + "name": "is_secret", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_env_vars_deployment_id": { + "name": "idx_deployment_env_vars_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_env_vars_deployment_id_deployments_id_fk": { + "name": "deployment_env_vars_deployment_id_deployments_id_fk", + "tableFrom": "deployment_env_vars", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_deployment_env_vars_deployment_key": { + "name": "UQ_deployment_env_vars_deployment_key", + "nullsNotDistinct": false, + "columns": [ + "deployment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_events": { + "name": "deployment_events", + "schema": "", + "columns": { + "build_id": { + "name": "build_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'log'" + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_deployment_events_build_id": { + "name": "idx_deployment_events_build_id", + "columns": [ + { + "expression": "build_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_events_timestamp": { + "name": "idx_deployment_events_timestamp", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_events_type": { + "name": "idx_deployment_events_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_events_build_id_deployment_builds_id_fk": { + "name": "deployment_events_build_id_deployment_builds_id_fk", + "tableFrom": "deployment_events", + "tableTo": "deployment_builds", + "columnsFrom": [ + "build_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "deployment_events_build_id_event_id_pk": { + "name": "deployment_events_build_id_event_id_pk", + "columns": [ + "build_id", + "event_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment_threat_detections": { + "name": "deployment_threat_detections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "build_id": { + "name": "build_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "threat_type": { + "name": "threat_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_deployment_threat_detections_deployment_id": { + "name": "idx_deployment_threat_detections_deployment_id", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployment_threat_detections_created_at": { + "name": "idx_deployment_threat_detections_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_threat_detections_deployment_id_deployments_id_fk": { + "name": "deployment_threat_detections_deployment_id_deployments_id_fk", + "tableFrom": "deployment_threat_detections", + "tableTo": "deployments", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_threat_detections_build_id_deployment_builds_id_fk": { + "name": "deployment_threat_detections_build_id_deployment_builds_id_fk", + "tableFrom": "deployment_threat_detections", + "tableTo": "deployment_builds", + "columnsFrom": [ + "build_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployments": { + "name": "deployments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "deployment_slug": { + "name": "deployment_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "internal_worker_name": { + "name": "internal_worker_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repository_source": { + "name": "repository_source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deployment_url": { + "name": "deployment_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "git_auth_token": { + "name": "git_auth_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_deployed_at": { + "name": "last_deployed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_build_id": { + "name": "last_build_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "threat_status": { + "name": "threat_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_from": { + "name": "created_from", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_deployments_owned_by_user_id": { + "name": "idx_deployments_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_owned_by_organization_id": { + "name": "idx_deployments_owned_by_organization_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_platform_integration_id": { + "name": "idx_deployments_platform_integration_id", + "columns": [ + { + "expression": "platform_integration_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_repository_source_branch": { + "name": "idx_deployments_repository_source_branch", + "columns": [ + { + "expression": "repository_source", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_deployments_threat_status_pending": { + "name": "idx_deployments_threat_status_pending", + "columns": [ + { + "expression": "threat_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"deployments\".\"threat_status\" = 'pending_scan'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployments_owned_by_user_id_kilocode_users_id_fk": { + "name": "deployments_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "deployments", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployments_owned_by_organization_id_organizations_id_fk": { + "name": "deployments_owned_by_organization_id_organizations_id_fk", + "tableFrom": "deployments", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_deployments_deployment_slug": { + "name": "UQ_deployments_deployment_slug", + "nullsNotDistinct": false, + "columns": [ + "deployment_slug" + ] + } + }, + "policies": {}, + "checkConstraints": { + "deployments_owner_check": { + "name": "deployments_owner_check", + "value": "(\n (\"deployments\".\"owned_by_user_id\" IS NOT NULL AND \"deployments\".\"owned_by_organization_id\" IS NULL) OR\n (\"deployments\".\"owned_by_user_id\" IS NULL AND \"deployments\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "deployments_source_type_check": { + "name": "deployments_source_type_check", + "value": "\"deployments\".\"source_type\" IN ('github', 'git', 'app-builder')" + } + }, + "isRLSEnabled": false + }, + "public.device_auth_requests": { + "name": "device_auth_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_device_auth_requests_code": { + "name": "UQ_device_auth_requests_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_status": { + "name": "IDX_device_auth_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_expires_at": { + "name": "IDX_device_auth_requests_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_device_auth_requests_kilo_user_id": { + "name": "IDX_device_auth_requests_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "device_auth_requests_kilo_user_id_kilocode_users_id_fk": { + "name": "device_auth_requests_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "device_auth_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.discord_gateway_listener": { + "name": "discord_gateway_listener", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "default": 1 + }, + "listener_id": { + "name": "listener_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.editor_name": { + "name": "editor_name", + "schema": "", + "columns": { + "editor_name_id": { + "name": "editor_name_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "editor_name": { + "name": "editor_name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_editor_name": { + "name": "UQ_editor_name", + "columns": [ + { + "expression": "editor_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.enrichment_data": { + "name": "enrichment_data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "github_enrichment_data": { + "name": "github_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "linkedin_enrichment_data": { + "name": "linkedin_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "clay_enrichment_data": { + "name": "clay_enrichment_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_enrichment_data_user_id": { + "name": "IDX_enrichment_data_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "enrichment_data_user_id_kilocode_users_id_fk": { + "name": "enrichment_data_user_id_kilocode_users_id_fk", + "tableFrom": "enrichment_data", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_enrichment_data_user_id": { + "name": "UQ_enrichment_data_user_id", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exa_monthly_usage": { + "name": "exa_monthly_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "month": { + "name": "month", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "total_cost_microdollars": { + "name": "total_cost_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "total_charged_microdollars": { + "name": "total_charged_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "free_allowance_microdollars": { + "name": "free_allowance_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 10000000 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_exa_monthly_usage_personal": { + "name": "idx_exa_monthly_usage_personal", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"exa_monthly_usage\".\"organization_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_exa_monthly_usage_org": { + "name": "idx_exa_monthly_usage_org", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"exa_monthly_usage\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exa_usage_log": { + "name": "exa_usage_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost_microdollars": { + "name": "cost_microdollars", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "charged_to_balance": { + "name": "charged_to_balance", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_exa_usage_log_user_created": { + "name": "idx_exa_usage_log_user_created", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "exa_usage_log_id_created_at_pk": { + "name": "exa_usage_log_id_created_at_pk", + "columns": [ + "id", + "created_at" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.feature": { + "name": "feature", + "schema": "", + "columns": { + "feature_id": { + "name": "feature_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "feature": { + "name": "feature", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_feature": { + "name": "UQ_feature", + "columns": [ + { + "expression": "feature", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.finish_reason": { + "name": "finish_reason", + "schema": "", + "columns": { + "finish_reason_id": { + "name": "finish_reason_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "finish_reason": { + "name": "finish_reason", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_finish_reason": { + "name": "UQ_finish_reason", + "columns": [ + { + "expression": "finish_reason", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.free_model_usage": { + "name": "free_model_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_free_model_usage_ip_created_at": { + "name": "idx_free_model_usage_ip_created_at", + "columns": [ + { + "expression": "ip_address", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_free_model_usage_created_at": { + "name": "idx_free_model_usage_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_free_model_usage_user_created_at": { + "name": "idx_free_model_usage_user_created_at", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"free_model_usage\".\"kilo_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.http_ip": { + "name": "http_ip", + "schema": "", + "columns": { + "http_ip_id": { + "name": "http_ip_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "http_ip": { + "name": "http_ip", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_http_ip": { + "name": "UQ_http_ip", + "columns": [ + { + "expression": "http_ip", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.http_user_agent": { + "name": "http_user_agent", + "schema": "", + "columns": { + "http_user_agent_id": { + "name": "http_user_agent_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_http_user_agent": { + "name": "UQ_http_user_agent", + "columns": [ + { + "expression": "http_user_agent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ja4_digest": { + "name": "ja4_digest", + "schema": "", + "columns": { + "ja4_digest_id": { + "name": "ja4_digest_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "ja4_digest": { + "name": "ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_ja4_digest": { + "name": "UQ_ja4_digest", + "columns": [ + { + "expression": "ja4_digest", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kilo_pass_audit_log": { + "name": "kilo_pass_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_event_id": { + "name": "stripe_event_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "related_credit_transaction_id": { + "name": "related_credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "related_monthly_issuance_id": { + "name": "related_monthly_issuance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "payload_json": { + "name": "payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "IDX_kilo_pass_audit_log_created_at": { + "name": "IDX_kilo_pass_audit_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_kilo_user_id": { + "name": "IDX_kilo_pass_audit_log_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_kilo_pass_subscription_id": { + "name": "IDX_kilo_pass_audit_log_kilo_pass_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_action": { + "name": "IDX_kilo_pass_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_result": { + "name": "IDX_kilo_pass_audit_log_result", + "columns": [ + { + "expression": "result", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_idempotency_key": { + "name": "IDX_kilo_pass_audit_log_idempotency_key", + "columns": [ + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_event_id": { + "name": "IDX_kilo_pass_audit_log_stripe_event_id", + "columns": [ + { + "expression": "stripe_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_invoice_id": { + "name": "IDX_kilo_pass_audit_log_stripe_invoice_id", + "columns": [ + { + "expression": "stripe_invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_stripe_subscription_id": { + "name": "IDX_kilo_pass_audit_log_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_related_credit_transaction_id": { + "name": "IDX_kilo_pass_audit_log_related_credit_transaction_id", + "columns": [ + { + "expression": "related_credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_audit_log_related_monthly_issuance_id": { + "name": "IDX_kilo_pass_audit_log_related_monthly_issuance_id", + "columns": [ + { + "expression": "related_monthly_issuance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_audit_log_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_audit_log_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk": { + "name": "kilo_pass_audit_log_related_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "credit_transactions", + "columnsFrom": [ + "related_credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + }, + "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk": { + "name": "kilo_pass_audit_log_related_monthly_issuance_id_kilo_pass_issuances_id_fk", + "tableFrom": "kilo_pass_audit_log", + "tableTo": "kilo_pass_issuances", + "columnsFrom": [ + "related_monthly_issuance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_audit_log_action_check": { + "name": "kilo_pass_audit_log_action_check", + "value": "\"kilo_pass_audit_log\".\"action\" IN ('stripe_webhook_received', 'kilo_pass_invoice_paid_handled', 'store_purchase_completed', 'store_notification_received', 'store_subscription_renewed', 'store_subscription_canceled', 'store_subscription_expired', 'store_subscription_refunded', 'base_credits_issued', 'bonus_credits_issued', 'bonus_credits_skipped_idempotent', 'first_month_50pct_promo_issued', 'yearly_monthly_base_cron_started', 'yearly_monthly_base_cron_completed', 'issue_yearly_remaining_credits', 'yearly_monthly_bonus_cron_started', 'yearly_monthly_bonus_cron_completed')" + }, + "kilo_pass_audit_log_result_check": { + "name": "kilo_pass_audit_log_result_check", + "value": "\"kilo_pass_audit_log\".\"result\" IN ('success', 'skipped_idempotent', 'failed')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_issuance_items": { + "name": "kilo_pass_issuance_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_issuance_id": { + "name": "kilo_pass_issuance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credit_transaction_id": { + "name": "credit_transaction_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true + }, + "bonus_percent_applied": { + "name": "bonus_percent_applied", + "type": "numeric(6, 4)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_issuance_items_issuance_id": { + "name": "IDX_kilo_pass_issuance_items_issuance_id", + "columns": [ + { + "expression": "kilo_pass_issuance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuance_items_credit_transaction_id": { + "name": "IDX_kilo_pass_issuance_items_credit_transaction_id", + "columns": [ + { + "expression": "credit_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk": { + "name": "kilo_pass_issuance_items_kilo_pass_issuance_id_kilo_pass_issuances_id_fk", + "tableFrom": "kilo_pass_issuance_items", + "tableTo": "kilo_pass_issuances", + "columnsFrom": [ + "kilo_pass_issuance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk": { + "name": "kilo_pass_issuance_items_credit_transaction_id_credit_transactions_id_fk", + "tableFrom": "kilo_pass_issuance_items", + "tableTo": "credit_transactions", + "columnsFrom": [ + "credit_transaction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kilo_pass_issuance_items_credit_transaction_id_unique": { + "name": "kilo_pass_issuance_items_credit_transaction_id_unique", + "nullsNotDistinct": false, + "columns": [ + "credit_transaction_id" + ] + }, + "UQ_kilo_pass_issuance_items_issuance_kind": { + "name": "UQ_kilo_pass_issuance_items_issuance_kind", + "nullsNotDistinct": false, + "columns": [ + "kilo_pass_issuance_id", + "kind" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_issuance_items_bonus_percent_applied_range_check": { + "name": "kilo_pass_issuance_items_bonus_percent_applied_range_check", + "value": "\"kilo_pass_issuance_items\".\"bonus_percent_applied\" IS NULL OR (\"kilo_pass_issuance_items\".\"bonus_percent_applied\" >= 0 AND \"kilo_pass_issuance_items\".\"bonus_percent_applied\" <= 1)" + }, + "kilo_pass_issuance_items_amount_usd_non_negative_check": { + "name": "kilo_pass_issuance_items_amount_usd_non_negative_check", + "value": "\"kilo_pass_issuance_items\".\"amount_usd\" >= 0" + }, + "kilo_pass_issuance_items_kind_check": { + "name": "kilo_pass_issuance_items_kind_check", + "value": "\"kilo_pass_issuance_items\".\"kind\" IN ('base', 'bonus', 'promo_first_month_50pct')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_issuances": { + "name": "kilo_pass_issuances", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "issue_month": { + "name": "issue_month", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_invoice_id": { + "name": "stripe_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kilo_pass_issuances_stripe_invoice_id": { + "name": "UQ_kilo_pass_issuances_stripe_invoice_id", + "columns": [ + { + "expression": "stripe_invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_issuances\".\"stripe_invoice_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuances_subscription_id": { + "name": "IDX_kilo_pass_issuances_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_issuances_issue_month": { + "name": "IDX_kilo_pass_issuances_issue_month", + "columns": [ + { + "expression": "issue_month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_issuances_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_issuances", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_kilo_pass_issuances_subscription_issue_month": { + "name": "UQ_kilo_pass_issuances_subscription_issue_month", + "nullsNotDistinct": false, + "columns": [ + "kilo_pass_subscription_id", + "issue_month" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_issuances_issue_month_day_one_check": { + "name": "kilo_pass_issuances_issue_month_day_one_check", + "value": "EXTRACT(DAY FROM \"kilo_pass_issuances\".\"issue_month\") = 1" + }, + "kilo_pass_issuances_source_check": { + "name": "kilo_pass_issuances_source_check", + "value": "\"kilo_pass_issuances\".\"source\" IN ('stripe_invoice', 'app_store_transaction', 'google_play_transaction', 'cron')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_pause_events": { + "name": "kilo_pass_pause_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "paused_at": { + "name": "paused_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "resumes_at": { + "name": "resumes_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "resumed_at": { + "name": "resumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_pause_events_subscription_id": { + "name": "IDX_kilo_pass_pause_events_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilo_pass_pause_events_one_open_per_sub": { + "name": "UQ_kilo_pass_pause_events_one_open_per_sub", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_pause_events_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_pause_events", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_pause_events_resumed_at_after_paused_at_check": { + "name": "kilo_pass_pause_events_resumed_at_after_paused_at_check", + "value": "\"kilo_pass_pause_events\".\"resumed_at\" IS NULL OR \"kilo_pass_pause_events\".\"resumed_at\" >= \"kilo_pass_pause_events\".\"paused_at\"" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_scheduled_changes": { + "name": "kilo_pass_scheduled_changes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_tier": { + "name": "from_tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_cadence": { + "name": "from_cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_tier": { + "name": "to_tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_cadence": { + "name": "to_cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_schedule_id": { + "name": "stripe_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "effective_at": { + "name": "effective_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_scheduled_changes_kilo_user_id": { + "name": "IDX_kilo_pass_scheduled_changes_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_status": { + "name": "IDX_kilo_pass_scheduled_changes_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_stripe_subscription_id": { + "name": "IDX_kilo_pass_scheduled_changes_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id": { + "name": "UQ_kilo_pass_scheduled_changes_active_stripe_subscription_id", + "columns": [ + { + "expression": "stripe_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_scheduled_changes\".\"deleted_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_effective_at": { + "name": "IDX_kilo_pass_scheduled_changes_effective_at", + "columns": [ + { + "expression": "effective_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_scheduled_changes_deleted_at": { + "name": "IDX_kilo_pass_scheduled_changes_deleted_at", + "columns": [ + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_scheduled_changes_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_scheduled_changes", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk": { + "name": "kilo_pass_scheduled_changes_stripe_subscription_id_kilo_pass_subscriptions_stripe_subscription_id_fk", + "tableFrom": "kilo_pass_scheduled_changes", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "stripe_subscription_id" + ], + "columnsTo": [ + "stripe_subscription_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_scheduled_changes_from_tier_check": { + "name": "kilo_pass_scheduled_changes_from_tier_check", + "value": "\"kilo_pass_scheduled_changes\".\"from_tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_scheduled_changes_from_cadence_check": { + "name": "kilo_pass_scheduled_changes_from_cadence_check", + "value": "\"kilo_pass_scheduled_changes\".\"from_cadence\" IN ('monthly', 'yearly')" + }, + "kilo_pass_scheduled_changes_to_tier_check": { + "name": "kilo_pass_scheduled_changes_to_tier_check", + "value": "\"kilo_pass_scheduled_changes\".\"to_tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_scheduled_changes_to_cadence_check": { + "name": "kilo_pass_scheduled_changes_to_cadence_check", + "value": "\"kilo_pass_scheduled_changes\".\"to_cadence\" IN ('monthly', 'yearly')" + }, + "kilo_pass_scheduled_changes_status_check": { + "name": "kilo_pass_scheduled_changes_status_check", + "value": "\"kilo_pass_scheduled_changes\".\"status\" IN ('not_started', 'active', 'completed', 'released', 'canceled')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_store_events": { + "name": "kilo_pass_store_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "payment_provider": { + "name": "payment_provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_subscription_id": { + "name": "provider_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_transaction_id": { + "name": "provider_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "product_id": { + "name": "product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment": { + "name": "environment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload_json": { + "name": "payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kilo_pass_store_events_provider_event": { + "name": "UQ_kilo_pass_store_events_provider_event", + "columns": [ + { + "expression": "payment_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_store_events_provider_subscription": { + "name": "IDX_kilo_pass_store_events_provider_subscription", + "columns": [ + { + "expression": "payment_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_store_events_payment_provider_check": { + "name": "kilo_pass_store_events_payment_provider_check", + "value": "\"kilo_pass_store_events\".\"payment_provider\" IN ('stripe', 'app_store', 'google_play')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_store_purchases": { + "name": "kilo_pass_store_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_pass_subscription_id": { + "name": "kilo_pass_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payment_provider": { + "name": "payment_provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product_id": { + "name": "product_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_subscription_id": { + "name": "provider_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_transaction_id": { + "name": "provider_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_original_transaction_id": { + "name": "provider_original_transaction_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "purchase_token": { + "name": "purchase_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "environment": { + "name": "environment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "purchased_at": { + "name": "purchased_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "raw_payload_json": { + "name": "raw_payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kilo_pass_store_purchases_provider_transaction": { + "name": "UQ_kilo_pass_store_purchases_provider_transaction", + "columns": [ + { + "expression": "payment_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_transaction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_store_purchases_subscription_id": { + "name": "IDX_kilo_pass_store_purchases_subscription_id", + "columns": [ + { + "expression": "kilo_pass_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_store_purchases_user_id": { + "name": "IDX_kilo_pass_store_purchases_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_store_purchases_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk": { + "name": "kilo_pass_store_purchases_kilo_pass_subscription_id_kilo_pass_subscriptions_id_fk", + "tableFrom": "kilo_pass_store_purchases", + "tableTo": "kilo_pass_subscriptions", + "columnsFrom": [ + "kilo_pass_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "kilo_pass_store_purchases_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_store_purchases_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_store_purchases", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kilo_pass_store_purchases_payment_provider_check": { + "name": "kilo_pass_store_purchases_payment_provider_check", + "value": "\"kilo_pass_store_purchases\".\"payment_provider\" IN ('stripe', 'app_store', 'google_play')" + } + }, + "isRLSEnabled": false + }, + "public.kilo_pass_subscriptions": { + "name": "kilo_pass_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payment_provider": { + "name": "payment_provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'stripe'" + }, + "provider_subscription_id": { + "name": "provider_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tier": { + "name": "tier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cadence": { + "name": "cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_streak_months": { + "name": "current_streak_months", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_yearly_issue_at": { + "name": "next_yearly_issue_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kilo_pass_subscriptions_kilo_user_id": { + "name": "IDX_kilo_pass_subscriptions_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_subscriptions_payment_provider": { + "name": "IDX_kilo_pass_subscriptions_payment_provider", + "columns": [ + { + "expression": "payment_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_subscriptions_status": { + "name": "IDX_kilo_pass_subscriptions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilo_pass_subscriptions_cadence": { + "name": "IDX_kilo_pass_subscriptions_cadence", + "columns": [ + { + "expression": "cadence", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilo_pass_subscriptions_provider_subscription": { + "name": "UQ_kilo_pass_subscriptions_provider_subscription", + "columns": [ + { + "expression": "payment_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilo_pass_subscriptions\".\"provider_subscription_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk": { + "name": "kilo_pass_subscriptions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kilo_pass_subscriptions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kilo_pass_subscriptions_stripe_subscription_id_unique": { + "name": "kilo_pass_subscriptions_stripe_subscription_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_subscription_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kilo_pass_subscriptions_current_streak_months_non_negative_check": { + "name": "kilo_pass_subscriptions_current_streak_months_non_negative_check", + "value": "\"kilo_pass_subscriptions\".\"current_streak_months\" >= 0" + }, + "kilo_pass_subscriptions_provider_subscription_required_check": { + "name": "kilo_pass_subscriptions_provider_subscription_required_check", + "value": "\"kilo_pass_subscriptions\".\"provider_subscription_id\" IS NOT NULL OR \"kilo_pass_subscriptions\".\"payment_provider\" = 'stripe'" + }, + "kilo_pass_subscriptions_payment_provider_check": { + "name": "kilo_pass_subscriptions_payment_provider_check", + "value": "\"kilo_pass_subscriptions\".\"payment_provider\" IN ('stripe', 'app_store', 'google_play')" + }, + "kilo_pass_subscriptions_tier_check": { + "name": "kilo_pass_subscriptions_tier_check", + "value": "\"kilo_pass_subscriptions\".\"tier\" IN ('tier_19', 'tier_49', 'tier_199')" + }, + "kilo_pass_subscriptions_cadence_check": { + "name": "kilo_pass_subscriptions_cadence_check", + "value": "\"kilo_pass_subscriptions\".\"cadence\" IN ('monthly', 'yearly')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_access_codes": { + "name": "kiloclaw_access_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "redeemed_at": { + "name": "redeemed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_access_codes_code": { + "name": "UQ_kiloclaw_access_codes_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_access_codes_user_status": { + "name": "IDX_kiloclaw_access_codes_user_status", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_access_codes_one_active_per_user": { + "name": "UQ_kiloclaw_access_codes_one_active_per_user", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "status = 'active'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_access_codes_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_access_codes", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_admin_audit_logs": { + "name": "kiloclaw_admin_audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_user_id": { + "name": "target_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kiloclaw_admin_audit_logs_target_user_id": { + "name": "IDX_kiloclaw_admin_audit_logs_target_user_id", + "columns": [ + { + "expression": "target_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_admin_audit_logs_action": { + "name": "IDX_kiloclaw_admin_audit_logs_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_admin_audit_logs_created_at": { + "name": "IDX_kiloclaw_admin_audit_logs_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_cli_runs": { + "name": "kiloclaw_cli_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "initiated_by_admin_id": { + "name": "initiated_by_admin_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'running'" + }, + "exit_code": { + "name": "exit_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_cli_runs_user_id": { + "name": "IDX_kiloclaw_cli_runs_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_cli_runs_started_at": { + "name": "IDX_kiloclaw_cli_runs_started_at", + "columns": [ + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_cli_runs_instance_id": { + "name": "IDX_kiloclaw_cli_runs_instance_id", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_cli_runs_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_cli_runs_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_cli_runs_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk": { + "name": "kiloclaw_cli_runs_initiated_by_admin_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_cli_runs", + "tableTo": "kilocode_users", + "columnsFrom": [ + "initiated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_earlybird_purchases": { + "name": "kiloclaw_earlybird_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manual_payment_id": { + "name": "manual_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_earlybird_purchases_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_earlybird_purchases", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_earlybird_purchases_user_id_unique": { + "name": "kiloclaw_earlybird_purchases_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + }, + "kiloclaw_earlybird_purchases_stripe_charge_id_unique": { + "name": "kiloclaw_earlybird_purchases_stripe_charge_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_charge_id" + ] + }, + "kiloclaw_earlybird_purchases_manual_payment_id_unique": { + "name": "kiloclaw_earlybird_purchases_manual_payment_id_unique", + "nullsNotDistinct": false, + "columns": [ + "manual_payment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_email_log": { + "name": "kiloclaw_email_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "email_type": { + "name": "email_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "'epoch'" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_email_log_user_type_global": { + "name": "UQ_kiloclaw_email_log_user_type_global", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_email_log\".\"instance_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_email_log_user_instance_type_period": { + "name": "UQ_kiloclaw_email_log_user_instance_type_period", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_email_log_type_sent_instance": { + "name": "IDX_kiloclaw_email_log_type_sent_instance", + "columns": [ + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sent_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_email_log\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_email_log_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_email_log_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_email_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_email_log_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_email_log", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_google_oauth_connections": { + "name": "kiloclaw_google_oauth_connections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'google'" + }, + "account_email": { + "name": "account_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_subject": { + "name": "account_subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oauth_client_id": { + "name": "oauth_client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oauth_client_secret_encrypted": { + "name": "oauth_client_secret_encrypted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_profile": { + "name": "credential_profile", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'kilo_owned'" + }, + "refresh_token_encrypted": { + "name": "refresh_token_encrypted", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "grants_by_source": { + "name": "grants_by_source", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "capabilities": { + "name": "capabilities", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_at": { + "name": "last_error_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "connected_at": { + "name": "connected_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_kiloclaw_google_oauth_connections_instance": { + "name": "UQ_kiloclaw_google_oauth_connections_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_google_oauth_connections_status": { + "name": "IDX_kiloclaw_google_oauth_connections_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_google_oauth_connections_provider": { + "name": "IDX_kiloclaw_google_oauth_connections_provider", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_google_oauth_connections_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_google_oauth_connections", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kiloclaw_google_oauth_connections_status_check": { + "name": "kiloclaw_google_oauth_connections_status_check", + "value": "\"kiloclaw_google_oauth_connections\".\"status\" IN ('active', 'action_required', 'disconnected')" + }, + "kiloclaw_google_oauth_connections_credential_profile_check": { + "name": "kiloclaw_google_oauth_connections_credential_profile_check", + "value": "\"kiloclaw_google_oauth_connections\".\"credential_profile\" IN ('legacy', 'kilo_owned')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_image_catalog": { + "name": "kiloclaw_image_catalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "openclaw_version": { + "name": "openclaw_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "variant": { + "name": "variant", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + }, + "image_tag": { + "name": "image_tag", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image_digest": { + "name": "image_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'available'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_by": { + "name": "updated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "synced_at": { + "name": "synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "rollout_percent": { + "name": "rollout_percent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_latest": { + "name": "is_latest", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "IDX_kiloclaw_image_catalog_status": { + "name": "IDX_kiloclaw_image_catalog_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_image_catalog_variant": { + "name": "IDX_kiloclaw_image_catalog_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_image_catalog_one_latest_per_variant": { + "name": "UQ_kiloclaw_image_catalog_one_latest_per_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_image_catalog\".\"is_latest\" = true", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_image_catalog_one_candidate_per_variant": { + "name": "UQ_kiloclaw_image_catalog_one_candidate_per_variant", + "columns": [ + { + "expression": "variant", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_image_catalog\".\"is_latest\" = false AND \"kiloclaw_image_catalog\".\"rollout_percent\" > 0 AND \"kiloclaw_image_catalog\".\"status\" = 'available'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_image_catalog_image_tag_unique": { + "name": "kiloclaw_image_catalog_image_tag_unique", + "nullsNotDistinct": false, + "columns": [ + "image_tag" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_inbound_email_aliases": { + "name": "kiloclaw_inbound_email_aliases", + "schema": "", + "columns": { + "alias": { + "name": "alias", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "retired_at": { + "name": "retired_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_inbound_email_aliases_instance_id": { + "name": "IDX_kiloclaw_inbound_email_aliases_instance_id", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_inbound_email_aliases_active_instance": { + "name": "UQ_kiloclaw_inbound_email_aliases_active_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_inbound_email_aliases\".\"retired_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_inbound_email_aliases_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_inbound_email_aliases", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_inbound_email_reserved_aliases": { + "name": "kiloclaw_inbound_email_reserved_aliases", + "schema": "", + "columns": { + "alias": { + "name": "alias", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_instances": { + "name": "kiloclaw_instances", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sandbox_id": { + "name": "sandbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'fly'" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "inbound_email_enabled": { + "name": "inbound_email_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "inactive_trial_stopped_at": { + "name": "inactive_trial_stopped_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "destroyed_at": { + "name": "destroyed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tracked_image_tag": { + "name": "tracked_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_instances_active": { + "name": "UQ_kiloclaw_instances_active", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sandbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_active_personal_by_user": { + "name": "IDX_kiloclaw_instances_active_personal_by_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"organization_id\" IS NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_active_org_by_user_org": { + "name": "IDX_kiloclaw_instances_active_org_by_user_org", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"organization_id\" IS NOT NULL AND \"kiloclaw_instances\".\"destroyed_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_instances_tracked_image_tag": { + "name": "IDX_kiloclaw_instances_tracked_image_tag", + "columns": [ + { + "expression": "tracked_image_tag", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_instances\".\"destroyed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_instances_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_instances_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_instances", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_instances_organization_id_organizations_id_fk": { + "name": "kiloclaw_instances_organization_id_organizations_id_fk", + "tableFrom": "kiloclaw_instances", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_notifications": { + "name": "kiloclaw_scheduled_action_notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "target_id": { + "name": "target_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'notice'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel": { + "name": "UQ_kiloclaw_scheduled_action_notifications_target_kind_channel", + "columns": [ + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_notifications_pending": { + "name": "IDX_kiloclaw_scheduled_action_notifications_pending", + "columns": [ + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_notifications\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk": { + "name": "kiloclaw_scheduled_action_notifications_target_id_kiloclaw_scheduled_action_targets_id_fk", + "tableFrom": "kiloclaw_scheduled_action_notifications", + "tableTo": "kiloclaw_scheduled_action_targets", + "columnsFrom": [ + "target_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_stages": { + "name": "kiloclaw_scheduled_action_stages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scheduled_action_id": { + "name": "scheduled_action_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "stage_index": { + "name": "stage_index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "notice_sent_at": { + "name": "notice_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "applied_count": { + "name": "applied_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skipped_count": { + "name": "skipped_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed_count": { + "name": "failed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_stages_parent_index": { + "name": "UQ_kiloclaw_scheduled_action_stages_parent_index", + "columns": [ + { + "expression": "scheduled_action_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stage_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_stages_notice_due": { + "name": "IDX_kiloclaw_scheduled_action_stages_notice_due", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_stages\".\"notice_sent_at\" IS NULL AND \"kiloclaw_scheduled_action_stages\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { + "name": "kiloclaw_scheduled_action_stages_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", + "tableFrom": "kiloclaw_scheduled_action_stages", + "tableTo": "kiloclaw_scheduled_actions", + "columnsFrom": [ + "scheduled_action_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_action_targets": { + "name": "kiloclaw_scheduled_action_targets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "scheduled_action_id": { + "name": "scheduled_action_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "stage_id": { + "name": "stage_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source_image_tag": { + "name": "source_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_image_tag": { + "name": "target_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applied_at": { + "name": "applied_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "skip_reason": { + "name": "skip_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "UQ_kiloclaw_scheduled_action_targets_parent_instance": { + "name": "UQ_kiloclaw_scheduled_action_targets_parent_instance", + "columns": [ + { + "expression": "scheduled_action_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_targets_stage": { + "name": "IDX_kiloclaw_scheduled_action_targets_stage", + "columns": [ + { + "expression": "stage_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_action_targets_pending_by_instance": { + "name": "IDX_kiloclaw_scheduled_action_targets_pending_by_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_scheduled_action_targets\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk": { + "name": "kiloclaw_scheduled_action_targets_scheduled_action_id_kiloclaw_scheduled_actions_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_scheduled_actions", + "columnsFrom": [ + "scheduled_action_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk": { + "name": "kiloclaw_scheduled_action_targets_stage_id_kiloclaw_scheduled_action_stages_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_scheduled_action_stages", + "columnsFrom": [ + "stage_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_scheduled_action_targets_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_scheduled_action_targets_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_scheduled_action_targets", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_scheduled_actions": { + "name": "kiloclaw_scheduled_actions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action_type": { + "name": "action_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_image_tag": { + "name": "target_image_tag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "override_pins": { + "name": "override_pins", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notice_lead_hours": { + "name": "notice_lead_hours", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 24 + }, + "notice_subject": { + "name": "notice_subject", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "notice_body": { + "name": "notice_body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'scheduled'" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancelled_at": { + "name": "cancelled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_count": { + "name": "total_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "applied_count": { + "name": "applied_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skipped_count": { + "name": "skipped_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed_count": { + "name": "failed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "IDX_kiloclaw_scheduled_actions_status": { + "name": "IDX_kiloclaw_scheduled_actions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_actions_action_type": { + "name": "IDX_kiloclaw_scheduled_actions_action_type", + "columns": [ + { + "expression": "action_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_scheduled_actions_created_by": { + "name": "IDX_kiloclaw_scheduled_actions_created_by", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk": { + "name": "kiloclaw_scheduled_actions_target_image_tag_kiloclaw_image_catalog_image_tag_fk", + "tableFrom": "kiloclaw_scheduled_actions", + "tableTo": "kiloclaw_image_catalog", + "columnsFrom": [ + "target_image_tag" + ], + "columnsTo": [ + "image_tag" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk": { + "name": "kiloclaw_scheduled_actions_created_by_kilocode_users_id_fk", + "tableFrom": "kiloclaw_scheduled_actions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kiloclaw_subscription_change_log": { + "name": "kiloclaw_subscription_change_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "subscription_id": { + "name": "subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "actor_type": { + "name": "actor_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "before_state": { + "name": "before_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after_state": { + "name": "after_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kiloclaw_subscription_change_log_subscription_created_at": { + "name": "IDX_kiloclaw_subscription_change_log_subscription_created_at", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscription_change_log_created_at": { + "name": "IDX_kiloclaw_subscription_change_log_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk": { + "name": "kiloclaw_subscription_change_log_subscription_id_kiloclaw_subscriptions_id_fk", + "tableFrom": "kiloclaw_subscription_change_log", + "tableTo": "kiloclaw_subscriptions", + "columnsFrom": [ + "subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "kiloclaw_subscription_change_log_actor_type_check": { + "name": "kiloclaw_subscription_change_log_actor_type_check", + "value": "\"kiloclaw_subscription_change_log\".\"actor_type\" IN ('user', 'system')" + }, + "kiloclaw_subscription_change_log_action_check": { + "name": "kiloclaw_subscription_change_log_action_check", + "value": "\"kiloclaw_subscription_change_log\".\"action\" IN ('created', 'status_changed', 'plan_switched', 'period_advanced', 'canceled', 'reactivated', 'suspended', 'destruction_scheduled', 'reassigned', 'backfilled', 'payment_source_changed', 'schedule_changed', 'admin_override')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_subscriptions": { + "name": "kiloclaw_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_subscription_id": { + "name": "stripe_subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_schedule_id": { + "name": "stripe_schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "transferred_to_subscription_id": { + "name": "transferred_to_subscription_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "access_origin": { + "name": "access_origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_source": { + "name": "payment_source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scheduled_plan": { + "name": "scheduled_plan", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_by": { + "name": "scheduled_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "pending_conversion": { + "name": "pending_conversion", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "trial_started_at": { + "name": "trial_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "trial_ends_at": { + "name": "trial_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_period_start": { + "name": "current_period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "current_period_end": { + "name": "current_period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "credit_renewal_at": { + "name": "credit_renewal_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "commit_ends_at": { + "name": "commit_ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "past_due_since": { + "name": "past_due_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "suspended_at": { + "name": "suspended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "destruction_deadline": { + "name": "destruction_deadline", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_requested_at": { + "name": "auto_resume_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_retry_after": { + "name": "auto_resume_retry_after", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_resume_attempt_count": { + "name": "auto_resume_attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "auto_top_up_triggered_for_period": { + "name": "auto_top_up_triggered_for_period", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_kiloclaw_subscriptions_status": { + "name": "IDX_kiloclaw_subscriptions_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_user_id": { + "name": "IDX_kiloclaw_subscriptions_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_user_status": { + "name": "IDX_kiloclaw_subscriptions_user_status", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_transferred_to": { + "name": "IDX_kiloclaw_subscriptions_transferred_to", + "columns": [ + { + "expression": "transferred_to_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_stripe_schedule_id": { + "name": "IDX_kiloclaw_subscriptions_stripe_schedule_id", + "columns": [ + { + "expression": "stripe_schedule_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_auto_resume_retry_after": { + "name": "IDX_kiloclaw_subscriptions_auto_resume_retry_after", + "columns": [ + { + "expression": "auto_resume_retry_after", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_subscriptions_instance": { + "name": "UQ_kiloclaw_subscriptions_instance", + "columns": [ + { + "expression": "instance_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_subscriptions\".\"instance_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kiloclaw_subscriptions_transferred_to": { + "name": "UQ_kiloclaw_subscriptions_transferred_to", + "columns": [ + { + "expression": "transferred_to_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kiloclaw_subscriptions\".\"transferred_to_subscription_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kiloclaw_subscriptions_earlybird_origin": { + "name": "IDX_kiloclaw_subscriptions_earlybird_origin", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "access_origin", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"kiloclaw_subscriptions\".\"access_origin\" = 'earlybird'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "kiloclaw_subscriptions_user_id_kilocode_users_id_fk": { + "name": "kiloclaw_subscriptions_user_id_kilocode_users_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk": { + "name": "kiloclaw_subscriptions_transferred_to_subscription_id_kiloclaw_subscriptions_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kiloclaw_subscriptions", + "columnsFrom": [ + "transferred_to_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_subscriptions_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_subscriptions", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_subscriptions_stripe_subscription_id_unique": { + "name": "kiloclaw_subscriptions_stripe_subscription_id_unique", + "nullsNotDistinct": false, + "columns": [ + "stripe_subscription_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "kiloclaw_subscriptions_plan_check": { + "name": "kiloclaw_subscriptions_plan_check", + "value": "\"kiloclaw_subscriptions\".\"plan\" IN ('trial', 'commit', 'standard')" + }, + "kiloclaw_subscriptions_scheduled_plan_check": { + "name": "kiloclaw_subscriptions_scheduled_plan_check", + "value": "\"kiloclaw_subscriptions\".\"scheduled_plan\" IN ('commit', 'standard')" + }, + "kiloclaw_subscriptions_scheduled_by_check": { + "name": "kiloclaw_subscriptions_scheduled_by_check", + "value": "\"kiloclaw_subscriptions\".\"scheduled_by\" IN ('auto', 'user')" + }, + "kiloclaw_subscriptions_status_check": { + "name": "kiloclaw_subscriptions_status_check", + "value": "\"kiloclaw_subscriptions\".\"status\" IN ('trialing', 'active', 'past_due', 'canceled', 'unpaid')" + }, + "kiloclaw_subscriptions_access_origin_check": { + "name": "kiloclaw_subscriptions_access_origin_check", + "value": "\"kiloclaw_subscriptions\".\"access_origin\" IN ('earlybird')" + }, + "kiloclaw_subscriptions_payment_source_check": { + "name": "kiloclaw_subscriptions_payment_source_check", + "value": "\"kiloclaw_subscriptions\".\"payment_source\" IN ('stripe', 'credits')" + } + }, + "isRLSEnabled": false + }, + "public.kiloclaw_version_pins": { + "name": "kiloclaw_version_pins", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "instance_id": { + "name": "instance_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "image_tag": { + "name": "image_tag", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pinned_by": { + "name": "pinned_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk": { + "name": "kiloclaw_version_pins_instance_id_kiloclaw_instances_id_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kiloclaw_instances", + "columnsFrom": [ + "instance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk": { + "name": "kiloclaw_version_pins_image_tag_kiloclaw_image_catalog_image_tag_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kiloclaw_image_catalog", + "columnsFrom": [ + "image_tag" + ], + "columnsTo": [ + "image_tag" + ], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk": { + "name": "kiloclaw_version_pins_pinned_by_kilocode_users_id_fk", + "tableFrom": "kiloclaw_version_pins", + "tableTo": "kilocode_users", + "columnsFrom": [ + "pinned_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kiloclaw_version_pins_instance_id_unique": { + "name": "kiloclaw_version_pins_instance_id_unique", + "nullsNotDistinct": false, + "columns": [ + "instance_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.kilocode_users": { + "name": "kilocode_users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "google_user_email": { + "name": "google_user_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "google_user_name": { + "name": "google_user_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "google_user_image_url": { + "name": "google_user_image_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "hosted_domain": { + "name": "hosted_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "microdollars_used": { + "name": "microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "kilo_pass_threshold": { + "name": "kilo_pass_threshold", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_admin": { + "name": "is_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "total_microdollars_acquired": { + "name": "total_microdollars_acquired", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "next_credit_expiration_at": { + "name": "next_credit_expiration_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "has_validation_stytch": { + "name": "has_validation_stytch", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "has_validation_novel_card_with_hold": { + "name": "has_validation_novel_card_with_hold", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_by_kilo_user_id": { + "name": "blocked_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_token_pepper": { + "name": "api_token_pepper", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "web_session_pepper": { + "name": "web_session_pepper", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_top_up_enabled": { + "name": "auto_top_up_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_bot": { + "name": "is_bot", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "kiloclaw_early_access": { + "name": "kiloclaw_early_access", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "default_model": { + "name": "default_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cohorts": { + "name": "cohorts", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "completed_welcome_form": { + "name": "completed_welcome_form", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "linkedin_url": { + "name": "linkedin_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_url": { + "name": "github_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discord_server_membership_verified_at": { + "name": "discord_server_membership_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "openrouter_upstream_safety_identifier": { + "name": "openrouter_upstream_safety_identifier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vercel_downstream_safety_identifier": { + "name": "vercel_downstream_safety_identifier", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customer_source": { + "name": "customer_source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signup_ip": { + "name": "signup_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "account_deletion_requested_at": { + "name": "account_deletion_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "normalized_email": { + "name": "normalized_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_domain": { + "name": "email_domain", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_kilocode_users_signup_ip_created_at": { + "name": "IDX_kilocode_users_signup_ip_created_at", + "columns": [ + { + "expression": "signup_ip", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_blocked_at": { + "name": "IDX_kilocode_users_blocked_at", + "columns": [ + { + "expression": "blocked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_blocked_by_kilo_user_id": { + "name": "IDX_kilocode_users_blocked_by_kilo_user_id", + "columns": [ + { + "expression": "blocked_by_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilocode_users_openrouter_upstream_safety_identifier": { + "name": "UQ_kilocode_users_openrouter_upstream_safety_identifier", + "columns": [ + { + "expression": "openrouter_upstream_safety_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilocode_users\".\"openrouter_upstream_safety_identifier\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_kilocode_users_vercel_downstream_safety_identifier": { + "name": "UQ_kilocode_users_vercel_downstream_safety_identifier", + "columns": [ + { + "expression": "vercel_downstream_safety_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"kilocode_users\".\"vercel_downstream_safety_identifier\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_normalized_email": { + "name": "IDX_kilocode_users_normalized_email", + "columns": [ + { + "expression": "normalized_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_kilocode_users_email_domain": { + "name": "IDX_kilocode_users_email_domain", + "columns": [ + { + "expression": "email_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_b1afacbcf43f2c7c4cb9f7e7faa": { + "name": "UQ_b1afacbcf43f2c7c4cb9f7e7faa", + "nullsNotDistinct": false, + "columns": [ + "google_user_email" + ] + } + }, + "policies": {}, + "checkConstraints": { + "blocked_reason_not_empty": { + "name": "blocked_reason_not_empty", + "value": "length(blocked_reason) > 0" + } + }, + "isRLSEnabled": false + }, + "public.magic_link_tokens": { + "name": "magic_link_tokens", + "schema": "", + "columns": { + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_magic_link_tokens_email": { + "name": "idx_magic_link_tokens_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_magic_link_tokens_expires_at": { + "name": "idx_magic_link_tokens_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "check_expires_at_future": { + "name": "check_expires_at_future", + "value": "\"magic_link_tokens\".\"expires_at\" > \"magic_link_tokens\".\"created_at\"" + } + }, + "isRLSEnabled": false + }, + "public.microdollar_usage": { + "name": "microdollar_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost": { + "name": "cost", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "output_tokens": { + "name": "output_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_write_tokens": { + "name": "cache_write_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_hit_tokens": { + "name": "cache_hit_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_model": { + "name": "requested_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cache_discount": { + "name": "cache_discount", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_error": { + "name": "has_error", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "abuse_classification": { + "name": "abuse_classification", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "inference_provider": { + "name": "inference_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_created_at": { + "name": "idx_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_abuse_classification": { + "name": "idx_abuse_classification", + "columns": [ + { + "expression": "abuse_classification", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_kilo_user_id_created_at2": { + "name": "idx_kilo_user_id_created_at2", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_microdollar_usage_organization_id": { + "name": "idx_microdollar_usage_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"microdollar_usage\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.microdollar_usage_metadata": { + "name": "microdollar_usage_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "http_user_agent_id": { + "name": "http_user_agent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "http_ip_id": { + "name": "http_ip_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_city_id": { + "name": "vercel_ip_city_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_country_id": { + "name": "vercel_ip_country_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_latitude": { + "name": "vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "vercel_ip_longitude": { + "name": "vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "ja4_digest_id": { + "name": "ja4_digest_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "user_prompt_prefix": { + "name": "user_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_prefix_id": { + "name": "system_prompt_prefix_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "system_prompt_length": { + "name": "system_prompt_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_tokens": { + "name": "max_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_middle_out_transform": { + "name": "has_middle_out_transform", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "upstream_id": { + "name": "upstream_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finish_reason_id": { + "name": "finish_reason_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "latency": { + "name": "latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "moderation_latency": { + "name": "moderation_latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "generation_time": { + "name": "generation_time", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "is_byok": { + "name": "is_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_user_byok": { + "name": "is_user_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "streamed": { + "name": "streamed", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "cancelled": { + "name": "cancelled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "editor_name_id": { + "name": "editor_name_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "api_kind_id": { + "name": "api_kind_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "has_tools": { + "name": "has_tools", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "machine_id": { + "name": "machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature_id": { + "name": "feature_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mode_id": { + "name": "mode_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "auto_model_id": { + "name": "auto_model_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "market_cost": { + "name": "market_cost", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_microdollar_usage_metadata_created_at": { + "name": "idx_microdollar_usage_metadata_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk": { + "name": "microdollar_usage_metadata_http_user_agent_id_http_user_agent_http_user_agent_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "http_user_agent", + "columnsFrom": [ + "http_user_agent_id" + ], + "columnsTo": [ + "http_user_agent_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk": { + "name": "microdollar_usage_metadata_http_ip_id_http_ip_http_ip_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "http_ip", + "columnsFrom": [ + "http_ip_id" + ], + "columnsTo": [ + "http_ip_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk": { + "name": "microdollar_usage_metadata_vercel_ip_city_id_vercel_ip_city_vercel_ip_city_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "vercel_ip_city", + "columnsFrom": [ + "vercel_ip_city_id" + ], + "columnsTo": [ + "vercel_ip_city_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk": { + "name": "microdollar_usage_metadata_vercel_ip_country_id_vercel_ip_country_vercel_ip_country_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "vercel_ip_country", + "columnsFrom": [ + "vercel_ip_country_id" + ], + "columnsTo": [ + "vercel_ip_country_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk": { + "name": "microdollar_usage_metadata_ja4_digest_id_ja4_digest_ja4_digest_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "ja4_digest", + "columnsFrom": [ + "ja4_digest_id" + ], + "columnsTo": [ + "ja4_digest_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk": { + "name": "microdollar_usage_metadata_system_prompt_prefix_id_system_prompt_prefix_system_prompt_prefix_id_fk", + "tableFrom": "microdollar_usage_metadata", + "tableTo": "system_prompt_prefix", + "columnsFrom": [ + "system_prompt_prefix_id" + ], + "columnsTo": [ + "system_prompt_prefix_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mode": { + "name": "mode", + "schema": "", + "columns": { + "mode_id": { + "name": "mode_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_mode": { + "name": "UQ_mode", + "columns": [ + { + "expression": "mode", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.model_stats": { + "name": "model_stats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "is_featured": { + "name": "is_featured", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_stealth": { + "name": "is_stealth", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_recommended": { + "name": "is_recommended", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "openrouter_id": { + "name": "openrouter_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "aa_slug": { + "name": "aa_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_creator": { + "name": "model_creator", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "creator_slug": { + "name": "creator_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "release_date": { + "name": "release_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "price_input": { + "name": "price_input", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "price_output": { + "name": "price_output", + "type": "numeric(10, 6)", + "primaryKey": false, + "notNull": false + }, + "coding_index": { + "name": "coding_index", + "type": "numeric(5, 2)", + "primaryKey": false, + "notNull": false + }, + "speed_tokens_per_sec": { + "name": "speed_tokens_per_sec", + "type": "numeric(8, 2)", + "primaryKey": false, + "notNull": false + }, + "context_length": { + "name": "context_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_output_tokens": { + "name": "max_output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "input_modalities": { + "name": "input_modalities", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "openrouter_data": { + "name": "openrouter_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "benchmarks": { + "name": "benchmarks", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "chart_data": { + "name": "chart_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_model_stats_openrouter_id": { + "name": "IDX_model_stats_openrouter_id", + "columns": [ + { + "expression": "openrouter_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_slug": { + "name": "IDX_model_stats_slug", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_is_active": { + "name": "IDX_model_stats_is_active", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_creator_slug": { + "name": "IDX_model_stats_creator_slug", + "columns": [ + { + "expression": "creator_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_price_input": { + "name": "IDX_model_stats_price_input", + "columns": [ + { + "expression": "price_input", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_coding_index": { + "name": "IDX_model_stats_coding_index", + "columns": [ + { + "expression": "coding_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_model_stats_context_length": { + "name": "IDX_model_stats_context_length", + "columns": [ + { + "expression": "context_length", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "model_stats_openrouter_id_unique": { + "name": "model_stats_openrouter_id_unique", + "nullsNotDistinct": false, + "columns": [ + "openrouter_id" + ] + }, + "model_stats_slug_unique": { + "name": "model_stats_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.models_by_provider": { + "name": "models_by_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "openrouter": { + "name": "openrouter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "vercel": { + "name": "vercel", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_audit_logs": { + "name": "organization_audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_audit_logs_organization_id": { + "name": "IDX_organization_audit_logs_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_action": { + "name": "IDX_organization_audit_logs_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_actor_id": { + "name": "IDX_organization_audit_logs_actor_id", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_audit_logs_created_at": { + "name": "IDX_organization_audit_logs_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_invitations": { + "name": "organization_invitations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invited_by": { + "name": "invited_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_organization_invitations_token": { + "name": "UQ_organization_invitations_token", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_org_id": { + "name": "IDX_organization_invitations_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_email": { + "name": "IDX_organization_invitations_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_invitations_expires_at": { + "name": "IDX_organization_invitations_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_membership_removals": { + "name": "organization_membership_removals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "removed_at": { + "name": "removed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "removed_by": { + "name": "removed_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_role": { + "name": "previous_role", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "IDX_org_membership_removals_org_id": { + "name": "IDX_org_membership_removals_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_org_membership_removals_user_id": { + "name": "IDX_org_membership_removals_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_org_membership_removals_org_user": { + "name": "UQ_org_membership_removals_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_memberships": { + "name": "organization_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "invited_by": { + "name": "invited_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_memberships_org_id": { + "name": "IDX_organization_memberships_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_memberships_user_id": { + "name": "IDX_organization_memberships_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_memberships_org_user": { + "name": "UQ_organization_memberships_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_seats_purchases": { + "name": "organization_seats_purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "subscription_stripe_id": { + "name": "subscription_stripe_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "seat_count": { + "name": "seat_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "subscription_status": { + "name": "subscription_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "starts_at": { + "name": "starts_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "billing_cycle": { + "name": "billing_cycle", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'monthly'" + } + }, + "indexes": { + "IDX_organization_seats_org_id": { + "name": "IDX_organization_seats_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_expires_at": { + "name": "IDX_organization_seats_expires_at", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_created_at": { + "name": "IDX_organization_seats_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_updated_at": { + "name": "IDX_organization_seats_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_seats_starts_at": { + "name": "IDX_organization_seats_starts_at", + "columns": [ + { + "expression": "starts_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_seats_idempotency_key": { + "name": "UQ_organization_seats_idempotency_key", + "nullsNotDistinct": false, + "columns": [ + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_user_limits": { + "name": "organization_user_limits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit_type": { + "name": "limit_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "microdollar_limit": { + "name": "microdollar_limit", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_user_limits_org_id": { + "name": "IDX_organization_user_limits_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_user_limits_user_id": { + "name": "IDX_organization_user_limits_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_user_limits_org_user": { + "name": "UQ_organization_user_limits_org_user", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id", + "limit_type" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_user_usage": { + "name": "organization_user_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "usage_date": { + "name": "usage_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "limit_type": { + "name": "limit_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "microdollar_usage": { + "name": "microdollar_usage", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_organization_user_daily_usage_org_id": { + "name": "IDX_organization_user_daily_usage_org_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_organization_user_daily_usage_user_id": { + "name": "IDX_organization_user_daily_usage_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_user_daily_usage_org_user_date": { + "name": "UQ_organization_user_daily_usage_org_user_date", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "kilo_user_id", + "limit_type", + "usage_date" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organizations": { + "name": "organizations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "microdollars_used": { + "name": "microdollars_used", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "microdollars_balance": { + "name": "microdollars_balance", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "total_microdollars_acquired": { + "name": "total_microdollars_acquired", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "next_credit_expiration_at": { + "name": "next_credit_expiration_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_top_up_enabled": { + "name": "auto_top_up_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "seat_count": { + "name": "seat_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "require_seats": { + "name": "require_seats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by_kilo_user_id": { + "name": "created_by_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sso_domain": { + "name": "sso_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'teams'" + }, + "free_trial_end_at": { + "name": "free_trial_end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "company_domain": { + "name": "company_domain", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_organizations_sso_domain": { + "name": "IDX_organizations_sso_domain", + "columns": [ + { + "expression": "sso_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "organizations_name_not_empty_check": { + "name": "organizations_name_not_empty_check", + "value": "length(trim(\"organizations\".\"name\")) > 0" + } + }, + "isRLSEnabled": false + }, + "public.organization_modes": { + "name": "organization_modes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "IDX_organization_modes_organization_id": { + "name": "IDX_organization_modes_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_organization_modes_org_id_slug": { + "name": "UQ_organization_modes_org_id_slug", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payment_methods": { + "name": "payment_methods", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "stripe_fingerprint": { + "name": "stripe_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last4": { + "name": "last4", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand": { + "name": "brand", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line1": { + "name": "address_line1", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line2": { + "name": "address_line2", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_city": { + "name": "address_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_state": { + "name": "address_state", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_zip": { + "name": "address_zip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "three_d_secure_supported": { + "name": "three_d_secure_supported", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "funding": { + "name": "funding", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "regulated_status": { + "name": "regulated_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_line1_check_status": { + "name": "address_line1_check_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code_check_status": { + "name": "postal_code_check_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "eligible_for_free_credits": { + "name": "eligible_for_free_credits", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "stripe_data": { + "name": "stripe_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_d7d7fb15569674aaadcfbc0428": { + "name": "IDX_d7d7fb15569674aaadcfbc0428", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_e1feb919d0ab8a36381d5d5138": { + "name": "IDX_e1feb919d0ab8a36381d5d5138", + "columns": [ + { + "expression": "stripe_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_payment_methods_organization_id": { + "name": "IDX_payment_methods_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_29df1b0403df5792c96bbbfdbe6": { + "name": "UQ_29df1b0403df5792c96bbbfdbe6", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "stripe_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pending_impact_sale_reversals": { + "name": "pending_impact_sale_reversals", + "schema": "", + "columns": { + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "dispute_id": { + "name": "dispute_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_date": { + "name": "event_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_attempt_at": { + "name": "last_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "pending_impact_sale_reversals_attempt_count_non_negative_check": { + "name": "pending_impact_sale_reversals_attempt_count_non_negative_check", + "value": "\"pending_impact_sale_reversals\".\"attempt_count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.platform_integrations": { + "name": "platform_integrations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "integration_type": { + "name": "integration_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform_installation_id": { + "name": "platform_installation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_account_id": { + "name": "platform_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_account_login": { + "name": "platform_account_login", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permissions": { + "name": "permissions", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "repository_access": { + "name": "repository_access", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "repositories": { + "name": "repositories", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "repositories_synced_at": { + "name": "repositories_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "kilo_requester_user_id": { + "name": "kilo_requester_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_requester_account_id": { + "name": "platform_requester_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "integration_status": { + "name": "integration_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "suspended_at": { + "name": "suspended_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "suspended_by": { + "name": "suspended_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "github_app_type": { + "name": "github_app_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'standard'" + }, + "installed_at": { + "name": "installed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_platform_integrations_owned_by_org_platform_inst": { + "name": "UQ_platform_integrations_owned_by_org_platform_inst", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_platform_integrations_owned_by_user_platform_inst": { + "name": "UQ_platform_integrations_owned_by_user_platform_inst", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_platform_integrations_slack_platform_inst": { + "name": "UQ_platform_integrations_slack_platform_inst", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"platform_integrations\".\"platform\" = 'slack' AND \"platform_integrations\".\"platform_installation_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_org_id": { + "name": "IDX_platform_integrations_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_user_id": { + "name": "IDX_platform_integrations_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform_inst_id": { + "name": "IDX_platform_integrations_platform_inst_id", + "columns": [ + { + "expression": "platform_installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform": { + "name": "IDX_platform_integrations_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_org_platform": { + "name": "IDX_platform_integrations_owned_by_org_platform", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_owned_by_user_platform": { + "name": "IDX_platform_integrations_owned_by_user_platform", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_integration_status": { + "name": "IDX_platform_integrations_integration_status", + "columns": [ + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_kilo_requester": { + "name": "IDX_platform_integrations_kilo_requester", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kilo_requester_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_platform_integrations_platform_requester": { + "name": "IDX_platform_integrations_platform_requester", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "platform_requester_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "integration_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "platform_integrations_owned_by_organization_id_organizations_id_fk": { + "name": "platform_integrations_owned_by_organization_id_organizations_id_fk", + "tableFrom": "platform_integrations", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "platform_integrations_owned_by_user_id_kilocode_users_id_fk": { + "name": "platform_integrations_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "platform_integrations", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "platform_integrations_owner_check": { + "name": "platform_integrations_owner_check", + "value": "(\n (\"platform_integrations\".\"owned_by_user_id\" IS NOT NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NULL) OR\n (\"platform_integrations\".\"owned_by_user_id\" IS NULL AND \"platform_integrations\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.referral_code_usages": { + "name": "referral_code_usages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "referring_kilo_user_id": { + "name": "referring_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "redeeming_kilo_user_id": { + "name": "redeeming_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_usd": { + "name": "amount_usd", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "paid_at": { + "name": "paid_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_referral_code_usages_redeeming_kilo_user_id": { + "name": "IDX_referral_code_usages_redeeming_kilo_user_id", + "columns": [ + { + "expression": "redeeming_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_referral_code_usages_redeeming_user_id_code": { + "name": "UQ_referral_code_usages_redeeming_user_id_code", + "nullsNotDistinct": false, + "columns": [ + "redeeming_kilo_user_id", + "referring_kilo_user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.referral_codes": { + "name": "referral_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "max_redemptions": { + "name": "max_redemptions", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 10 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_referral_codes_kilo_user_id": { + "name": "UQ_referral_codes_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_referral_codes_code": { + "name": "IDX_referral_codes_code", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_check_catalog": { + "name": "security_advisor_check_catalog", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "check_id": { + "name": "check_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "explanation": { + "name": "explanation", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "risk": { + "name": "risk", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_check_catalog_check_id_unique": { + "name": "security_advisor_check_catalog_check_id_unique", + "nullsNotDistinct": false, + "columns": [ + "check_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "security_advisor_check_catalog_severity_check": { + "name": "security_advisor_check_catalog_severity_check", + "value": "\"security_advisor_check_catalog\".\"severity\" in ('critical', 'warn', 'info')" + } + }, + "isRLSEnabled": false + }, + "public.security_advisor_content": { + "name": "security_advisor_content", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_content_key_unique": { + "name": "security_advisor_content_key_unique", + "nullsNotDistinct": false, + "columns": [ + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_kiloclaw_coverage": { + "name": "security_advisor_kiloclaw_coverage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "area": { + "name": "area", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "match_check_ids": { + "name": "match_check_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_advisor_kiloclaw_coverage_area_unique": { + "name": "security_advisor_kiloclaw_coverage_area_unique", + "nullsNotDistinct": false, + "columns": [ + "area" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_advisor_scans": { + "name": "security_advisor_scans", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_platform": { + "name": "source_platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_method": { + "name": "source_method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "plugin_version": { + "name": "plugin_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "openclaw_version": { + "name": "openclaw_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_ip": { + "name": "public_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "findings_critical": { + "name": "findings_critical", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "findings_warn": { + "name": "findings_warn", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "findings_info": { + "name": "findings_info", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_security_advisor_scans_user_created_at": { + "name": "idx_security_advisor_scans_user_created_at", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_advisor_scans_created_at": { + "name": "idx_security_advisor_scans_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_advisor_scans_platform": { + "name": "idx_security_advisor_scans_platform", + "columns": [ + { + "expression": "source_platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security_analysis_owner_state": { + "name": "security_analysis_owner_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_analysis_enabled_at": { + "name": "auto_analysis_enabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_until": { + "name": "blocked_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "block_reason": { + "name": "block_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "consecutive_actor_resolution_failures": { + "name": "consecutive_actor_resolution_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_actor_resolution_failure_at": { + "name": "last_actor_resolution_failure_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_security_analysis_owner_state_org_owner": { + "name": "UQ_security_analysis_owner_state_org_owner", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"security_analysis_owner_state\".\"owned_by_organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_security_analysis_owner_state_user_owner": { + "name": "UQ_security_analysis_owner_state_user_owner", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"security_analysis_owner_state\".\"owned_by_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk": { + "name": "security_analysis_owner_state_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_analysis_owner_state", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_analysis_owner_state_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_analysis_owner_state", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_analysis_owner_state_owner_check": { + "name": "security_analysis_owner_state_owner_check", + "value": "(\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_owner_state\".\"owned_by_user_id\" IS NULL AND \"security_analysis_owner_state\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "security_analysis_owner_state_block_reason_check": { + "name": "security_analysis_owner_state_block_reason_check", + "value": "\"security_analysis_owner_state\".\"block_reason\" IS NULL OR \"security_analysis_owner_state\".\"block_reason\" IN ('INSUFFICIENT_CREDITS', 'ACTOR_RESOLUTION_FAILED', 'OPERATOR_PAUSE')" + } + }, + "isRLSEnabled": false + }, + "public.security_analysis_queue": { + "name": "security_analysis_queue", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "finding_id": { + "name": "finding_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "queue_status": { + "name": "queue_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity_rank": { + "name": "severity_rank", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "queued_at": { + "name": "queued_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_by_job_id": { + "name": "claimed_by_job_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "claim_token": { + "name": "claim_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reopen_requeue_count": { + "name": "reopen_requeue_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failure_code": { + "name": "failure_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_redacted": { + "name": "last_error_redacted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_security_analysis_queue_finding_id": { + "name": "UQ_security_analysis_queue_finding_id", + "columns": [ + { + "expression": "finding_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_claim_path_org": { + "name": "idx_security_analysis_queue_claim_path_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "severity_rank", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_claim_path_user": { + "name": "idx_security_analysis_queue_claim_path_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "severity_rank", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_in_flight_org": { + "name": "idx_security_analysis_queue_in_flight_org", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queue_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_in_flight_user": { + "name": "idx_security_analysis_queue_in_flight_user", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "queue_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_lag_dashboards": { + "name": "idx_security_analysis_queue_lag_dashboards", + "columns": [ + { + "expression": "queued_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_pending_reconciliation": { + "name": "idx_security_analysis_queue_pending_reconciliation", + "columns": [ + { + "expression": "claimed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_running_reconciliation": { + "name": "idx_security_analysis_queue_running_reconciliation", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"queue_status\" = 'running'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_analysis_queue_failure_trend": { + "name": "idx_security_analysis_queue_failure_trend", + "columns": [ + { + "expression": "failure_code", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_analysis_queue\".\"failure_code\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_analysis_queue_finding_id_security_findings_id_fk": { + "name": "security_analysis_queue_finding_id_security_findings_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "security_findings", + "columnsFrom": [ + "finding_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_queue_owned_by_organization_id_organizations_id_fk": { + "name": "security_analysis_queue_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_analysis_queue_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_analysis_queue", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_analysis_queue_owner_check": { + "name": "security_analysis_queue_owner_check", + "value": "(\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NOT NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_analysis_queue\".\"owned_by_user_id\" IS NULL AND \"security_analysis_queue\".\"owned_by_organization_id\" IS NOT NULL)\n )" + }, + "security_analysis_queue_status_check": { + "name": "security_analysis_queue_status_check", + "value": "\"security_analysis_queue\".\"queue_status\" IN ('queued', 'pending', 'running', 'failed', 'completed')" + }, + "security_analysis_queue_claim_token_required_check": { + "name": "security_analysis_queue_claim_token_required_check", + "value": "\"security_analysis_queue\".\"queue_status\" NOT IN ('pending', 'running') OR \"security_analysis_queue\".\"claim_token\" IS NOT NULL" + }, + "security_analysis_queue_attempt_count_non_negative_check": { + "name": "security_analysis_queue_attempt_count_non_negative_check", + "value": "\"security_analysis_queue\".\"attempt_count\" >= 0" + }, + "security_analysis_queue_reopen_requeue_count_non_negative_check": { + "name": "security_analysis_queue_reopen_requeue_count_non_negative_check", + "value": "\"security_analysis_queue\".\"reopen_requeue_count\" >= 0" + }, + "security_analysis_queue_severity_rank_check": { + "name": "security_analysis_queue_severity_rank_check", + "value": "\"security_analysis_queue\".\"severity_rank\" IN (0, 1, 2, 3)" + }, + "security_analysis_queue_failure_code_check": { + "name": "security_analysis_queue_failure_code_check", + "value": "\"security_analysis_queue\".\"failure_code\" IS NULL OR \"security_analysis_queue\".\"failure_code\" IN (\n 'NETWORK_TIMEOUT',\n 'UPSTREAM_5XX',\n 'TEMP_TOKEN_FAILURE',\n 'START_CALL_AMBIGUOUS',\n 'REQUEUE_TEMPORARY_PRECONDITION',\n 'ACTOR_RESOLUTION_FAILED',\n 'GITHUB_TOKEN_UNAVAILABLE',\n 'INVALID_CONFIG',\n 'MISSING_OWNERSHIP',\n 'PERMISSION_DENIED_PERMANENT',\n 'UNSUPPORTED_SEVERITY',\n 'INSUFFICIENT_CREDITS',\n 'STATE_GUARD_REJECTED',\n 'SKIPPED_ALREADY_IN_PROGRESS',\n 'SKIPPED_NO_LONGER_ELIGIBLE',\n 'REOPEN_LOOP_GUARD',\n 'RUN_LOST'\n )" + } + }, + "isRLSEnabled": false + }, + "public.security_audit_log": { + "name": "security_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_name": { + "name": "actor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "before_state": { + "name": "before_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "after_state": { + "name": "after_state", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_security_audit_log_org_created": { + "name": "IDX_security_audit_log_org_created", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_user_created": { + "name": "IDX_security_audit_log_user_created", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_resource": { + "name": "IDX_security_audit_log_resource", + "columns": [ + { + "expression": "resource_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_actor": { + "name": "IDX_security_audit_log_actor", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_security_audit_log_action": { + "name": "IDX_security_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_audit_log_owned_by_organization_id_organizations_id_fk": { + "name": "security_audit_log_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_audit_log", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_audit_log_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_audit_log_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_audit_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "security_audit_log_owner_check": { + "name": "security_audit_log_owner_check", + "value": "(\"security_audit_log\".\"owned_by_user_id\" IS NOT NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NULL) OR (\"security_audit_log\".\"owned_by_user_id\" IS NULL AND \"security_audit_log\".\"owned_by_organization_id\" IS NOT NULL)" + }, + "security_audit_log_action_check": { + "name": "security_audit_log_action_check", + "value": "\"security_audit_log\".\"action\" IN ('security.finding.created', 'security.finding.status_change', 'security.finding.dismissed', 'security.finding.auto_dismissed', 'security.finding.analysis_started', 'security.finding.analysis_completed', 'security.finding.deleted', 'security.config.enabled', 'security.config.disabled', 'security.config.updated', 'security.sync.triggered', 'security.sync.completed', 'security.audit_log.exported')" + } + }, + "isRLSEnabled": false + }, + "public.security_findings": { + "name": "security_findings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "repo_full_name": { + "name": "repo_full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ghsa_id": { + "name": "ghsa_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cve_id": { + "name": "cve_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "package_name": { + "name": "package_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "package_ecosystem": { + "name": "package_ecosystem", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "vulnerable_version_range": { + "name": "vulnerable_version_range", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "patched_version": { + "name": "patched_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "manifest_path": { + "name": "manifest_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "ignored_reason": { + "name": "ignored_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ignored_by": { + "name": "ignored_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fixed_at": { + "name": "fixed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sla_due_at": { + "name": "sla_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dependabot_html_url": { + "name": "dependabot_html_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cwe_ids": { + "name": "cwe_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "cvss_score": { + "name": "cvss_score", + "type": "numeric(3, 1)", + "primaryKey": false, + "notNull": false + }, + "dependency_scope": { + "name": "dependency_scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cli_session_id": { + "name": "cli_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis_status": { + "name": "analysis_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis_started_at": { + "name": "analysis_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "analysis_completed_at": { + "name": "analysis_completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "analysis_error": { + "name": "analysis_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "analysis": { + "name": "analysis", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "raw_data": { + "name": "raw_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "first_detected_at": { + "name": "first_detected_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_security_findings_org_id": { + "name": "idx_security_findings_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_user_id": { + "name": "idx_security_findings_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_repo": { + "name": "idx_security_findings_repo", + "columns": [ + { + "expression": "repo_full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_severity": { + "name": "idx_security_findings_severity", + "columns": [ + { + "expression": "severity", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_status": { + "name": "idx_security_findings_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_package": { + "name": "idx_security_findings_package", + "columns": [ + { + "expression": "package_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_sla_due_at": { + "name": "idx_security_findings_sla_due_at", + "columns": [ + { + "expression": "sla_due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_session_id": { + "name": "idx_security_findings_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_cli_session_id": { + "name": "idx_security_findings_cli_session_id", + "columns": [ + { + "expression": "cli_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_analysis_status": { + "name": "idx_security_findings_analysis_status", + "columns": [ + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_org_analysis_in_flight": { + "name": "idx_security_findings_org_analysis_in_flight", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_security_findings_user_analysis_in_flight": { + "name": "idx_security_findings_user_analysis_in_flight", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "analysis_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"security_findings\".\"analysis_status\" IN ('pending', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "security_findings_owned_by_organization_id_organizations_id_fk": { + "name": "security_findings_owned_by_organization_id_organizations_id_fk", + "tableFrom": "security_findings", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_findings_owned_by_user_id_kilocode_users_id_fk": { + "name": "security_findings_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "security_findings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "security_findings_platform_integration_id_platform_integrations_id_fk": { + "name": "security_findings_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "security_findings", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_security_findings_source": { + "name": "uq_security_findings_source", + "nullsNotDistinct": false, + "columns": [ + "repo_full_name", + "source", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "security_findings_owner_check": { + "name": "security_findings_owner_check", + "value": "(\n (\"security_findings\".\"owned_by_user_id\" IS NOT NULL AND \"security_findings\".\"owned_by_organization_id\" IS NULL) OR\n (\"security_findings\".\"owned_by_user_id\" IS NULL AND \"security_findings\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.shared_cli_sessions": { + "name": "shared_cli_sessions", + "schema": "", + "columns": { + "share_id": { + "name": "share_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shared_state": { + "name": "shared_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'public'" + }, + "api_conversation_history_blob_url": { + "name": "api_conversation_history_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "task_metadata_blob_url": { + "name": "task_metadata_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ui_messages_blob_url": { + "name": "ui_messages_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "git_state_blob_url": { + "name": "git_state_blob_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_shared_cli_sessions_session_id": { + "name": "IDX_shared_cli_sessions_session_id", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_shared_cli_sessions_created_at": { + "name": "IDX_shared_cli_sessions_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_cli_sessions_session_id_cli_sessions_session_id_fk": { + "name": "shared_cli_sessions_session_id_cli_sessions_session_id_fk", + "tableFrom": "shared_cli_sessions", + "tableTo": "cli_sessions", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "session_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk": { + "name": "shared_cli_sessions_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "shared_cli_sessions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "shared_cli_sessions_shared_state_check": { + "name": "shared_cli_sessions_shared_state_check", + "value": "\"shared_cli_sessions\".\"shared_state\" IN ('public', 'organization')" + } + }, + "isRLSEnabled": false + }, + "public.slack_bot_requests": { + "name": "slack_bot_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform_integration_id": { + "name": "platform_integration_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "slack_team_id": { + "name": "slack_team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_team_name": { + "name": "slack_team_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slack_channel_id": { + "name": "slack_channel_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_user_id": { + "name": "slack_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slack_thread_ts": { + "name": "slack_thread_ts", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_message": { + "name": "user_message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_message_truncated": { + "name": "user_message_truncated", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_time_ms": { + "name": "response_time_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "model_used": { + "name": "model_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tool_calls_made": { + "name": "tool_calls_made", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "cloud_agent_session_id": { + "name": "cloud_agent_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_slack_bot_requests_created_at": { + "name": "idx_slack_bot_requests_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_slack_team_id": { + "name": "idx_slack_bot_requests_slack_team_id", + "columns": [ + { + "expression": "slack_team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_owned_by_org_id": { + "name": "idx_slack_bot_requests_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_owned_by_user_id": { + "name": "idx_slack_bot_requests_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_status": { + "name": "idx_slack_bot_requests_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_event_type": { + "name": "idx_slack_bot_requests_event_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_slack_bot_requests_team_created": { + "name": "idx_slack_bot_requests_team_created", + "columns": [ + { + "expression": "slack_team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "slack_bot_requests_owned_by_organization_id_organizations_id_fk": { + "name": "slack_bot_requests_owned_by_organization_id_organizations_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk": { + "name": "slack_bot_requests_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "slack_bot_requests_platform_integration_id_platform_integrations_id_fk": { + "name": "slack_bot_requests_platform_integration_id_platform_integrations_id_fk", + "tableFrom": "slack_bot_requests", + "tableTo": "platform_integrations", + "columnsFrom": [ + "platform_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "slack_bot_requests_owner_check": { + "name": "slack_bot_requests_owner_check", + "value": "(\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NOT NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NOT NULL) OR\n (\"slack_bot_requests\".\"owned_by_user_id\" IS NULL AND \"slack_bot_requests\".\"owned_by_organization_id\" IS NULL)\n )" + } + }, + "isRLSEnabled": false + }, + "public.source_embeddings": { + "name": "source_embeddings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": true + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "file_hash": { + "name": "file_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_line": { + "name": "start_line", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "end_line": { + "name": "end_line", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "git_branch": { + "name": "git_branch", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'main'" + }, + "is_base_branch": { + "name": "is_base_branch", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_source_embeddings_organization_id": { + "name": "IDX_source_embeddings_organization_id", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_kilo_user_id": { + "name": "IDX_source_embeddings_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_project_id": { + "name": "IDX_source_embeddings_project_id", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_created_at": { + "name": "IDX_source_embeddings_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_updated_at": { + "name": "IDX_source_embeddings_updated_at", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_file_path_lower": { + "name": "IDX_source_embeddings_file_path_lower", + "columns": [ + { + "expression": "LOWER(\"file_path\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_git_branch": { + "name": "IDX_source_embeddings_git_branch", + "columns": [ + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_source_embeddings_org_project_branch": { + "name": "IDX_source_embeddings_org_project_branch", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "git_branch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "source_embeddings_organization_id_organizations_id_fk": { + "name": "source_embeddings_organization_id_organizations_id_fk", + "tableFrom": "source_embeddings", + "tableTo": "organizations", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "source_embeddings_kilo_user_id_kilocode_users_id_fk": { + "name": "source_embeddings_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "source_embeddings", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_source_embeddings_org_project_branch_file_lines": { + "name": "UQ_source_embeddings_org_project_branch_file_lines", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "project_id", + "git_branch", + "file_path", + "start_line", + "end_line" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.stytch_fingerprints": { + "name": "stytch_fingerprints", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visitor_fingerprint": { + "name": "visitor_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "browser_fingerprint": { + "name": "browser_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "browser_id": { + "name": "browser_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hardware_fingerprint": { + "name": "hardware_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "network_fingerprint": { + "name": "network_fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visitor_id": { + "name": "visitor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verdict_action": { + "name": "verdict_action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "detected_device_type": { + "name": "detected_device_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_authentic_device": { + "name": "is_authentic_device", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{\"\"}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "fingerprint_data": { + "name": "fingerprint_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "kilo_free_tier_allowed": { + "name": "kilo_free_tier_allowed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_fingerprint_data": { + "name": "idx_fingerprint_data", + "columns": [ + { + "expression": "fingerprint_data", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_hardware_fingerprint": { + "name": "idx_hardware_fingerprint", + "columns": [ + { + "expression": "hardware_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_kilo_user_id": { + "name": "idx_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reasons": { + "name": "idx_reasons", + "columns": [ + { + "expression": "reasons", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_verdict_action": { + "name": "idx_verdict_action", + "columns": [ + { + "expression": "verdict_action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_visitor_fingerprint": { + "name": "idx_visitor_fingerprint", + "columns": [ + { + "expression": "visitor_fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.system_prompt_prefix": { + "name": "system_prompt_prefix", + "schema": "", + "columns": { + "system_prompt_prefix_id": { + "name": "system_prompt_prefix_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "system_prompt_prefix": { + "name": "system_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_system_prompt_prefix": { + "name": "UQ_system_prompt_prefix", + "columns": [ + { + "expression": "system_prompt_prefix", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.transactional_email_log": { + "name": "transactional_email_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_type": { + "name": "email_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_transactional_email_log_type_idempotency_key": { + "name": "UQ_transactional_email_log_type_idempotency_key", + "columns": [ + { + "expression": "email_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_transactional_email_log_user_id": { + "name": "IDX_transactional_email_log_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "transactional_email_log_user_id_kilocode_users_id_fk": { + "name": "transactional_email_log_user_id_kilocode_users_id_fk", + "tableFrom": "transactional_email_log", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_admin_notes": { + "name": "user_admin_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "note_content": { + "name": "note_content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "admin_kilo_user_id": { + "name": "admin_kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_34517df0b385234babc38fe81b": { + "name": "IDX_34517df0b385234babc38fe81b", + "columns": [ + { + "expression": "admin_kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_ccbde98c4c14046daa5682ec4f": { + "name": "IDX_ccbde98c4c14046daa5682ec4f", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_d0270eb24ef6442d65a0b7853c": { + "name": "IDX_d0270eb24ef6442d65a0b7853c", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_affiliate_attributions": { + "name": "user_affiliate_attributions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tracking_id": { + "name": "tracking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_affiliate_attributions_user_id": { + "name": "IDX_user_affiliate_attributions_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_affiliate_attributions_user_id_kilocode_users_id_fk": { + "name": "user_affiliate_attributions_user_id_kilocode_users_id_fk", + "tableFrom": "user_affiliate_attributions", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_user_affiliate_attributions_user_provider": { + "name": "UQ_user_affiliate_attributions_user_provider", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "provider" + ] + } + }, + "policies": {}, + "checkConstraints": { + "user_affiliate_attributions_provider_check": { + "name": "user_affiliate_attributions_provider_check", + "value": "\"user_affiliate_attributions\".\"provider\" IN ('impact')" + } + }, + "isRLSEnabled": false + }, + "public.user_affiliate_events": { + "name": "user_affiliate_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parent_event_id": { + "name": "parent_event_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "delivery_state": { + "name": "delivery_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "payload_json": { + "name": "payload_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "stripe_charge_id": { + "name": "stripe_charge_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impact_action_id": { + "name": "impact_action_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impact_submission_uri": { + "name": "impact_submission_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_retry_at": { + "name": "next_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_affiliate_events_claim_path": { + "name": "IDX_user_affiliate_events_claim_path", + "columns": [ + { + "expression": "delivery_state", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"next_retry_at\", '-infinity'::timestamptz)", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_affiliate_events_parent_event_id": { + "name": "IDX_user_affiliate_events_parent_event_id", + "columns": [ + { + "expression": "parent_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_affiliate_events_provider_event_type_charge": { + "name": "IDX_user_affiliate_events_provider_event_type_charge", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "stripe_charge_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_affiliate_events_user_id_kilocode_users_id_fk": { + "name": "user_affiliate_events_user_id_kilocode_users_id_fk", + "tableFrom": "user_affiliate_events", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "user_affiliate_events_parent_event_id_fk": { + "name": "user_affiliate_events_parent_event_id_fk", + "tableFrom": "user_affiliate_events", + "tableTo": "user_affiliate_events", + "columnsFrom": [ + "parent_event_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_user_affiliate_events_dedupe_key": { + "name": "UQ_user_affiliate_events_dedupe_key", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "user_affiliate_events_provider_check": { + "name": "user_affiliate_events_provider_check", + "value": "\"user_affiliate_events\".\"provider\" IN ('impact')" + }, + "user_affiliate_events_event_type_check": { + "name": "user_affiliate_events_event_type_check", + "value": "\"user_affiliate_events\".\"event_type\" IN ('signup', 'trial_start', 'trial_end', 'sale', 'sale_reversal')" + }, + "user_affiliate_events_delivery_state_check": { + "name": "user_affiliate_events_delivery_state_check", + "value": "\"user_affiliate_events\".\"delivery_state\" IN ('queued', 'blocked', 'sending', 'delivered', 'failed')" + }, + "user_affiliate_events_attempt_count_non_negative_check": { + "name": "user_affiliate_events_attempt_count_non_negative_check", + "value": "\"user_affiliate_events\".\"attempt_count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.user_auth_provider": { + "name": "user_auth_provider", + "schema": "", + "columns": { + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hosted_domain": { + "name": "hosted_domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_auth_provider_kilo_user_id": { + "name": "IDX_user_auth_provider_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_auth_provider_hosted_domain": { + "name": "IDX_user_auth_provider_hosted_domain", + "columns": [ + { + "expression": "hosted_domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "user_auth_provider_provider_provider_account_id_pk": { + "name": "user_auth_provider_provider_provider_account_id_pk", + "columns": [ + "provider", + "provider_account_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_feedback": { + "name": "user_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feedback_text": { + "name": "feedback_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "feedback_for": { + "name": "feedback_for", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "feedback_batch": { + "name": "feedback_batch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "context_json": { + "name": "context_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_user_feedback_created_at": { + "name": "IDX_user_feedback_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_kilo_user_id": { + "name": "IDX_user_feedback_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_feedback_for": { + "name": "IDX_user_feedback_feedback_for", + "columns": [ + { + "expression": "feedback_for", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_feedback_batch": { + "name": "IDX_user_feedback_feedback_batch", + "columns": [ + { + "expression": "feedback_batch", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_feedback_source": { + "name": "IDX_user_feedback_source", + "columns": [ + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_feedback_kilo_user_id_kilocode_users_id_fk": { + "name": "user_feedback_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "user_feedback", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_period_cache": { + "name": "user_period_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cache_type": { + "name": "cache_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_type": { + "name": "period_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_key": { + "name": "period_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "computed_at": { + "name": "computed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "shared_url_token": { + "name": "shared_url_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shared_at": { + "name": "shared_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "IDX_user_period_cache_kilo_user_id": { + "name": "IDX_user_period_cache_kilo_user_id", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_user_period_cache": { + "name": "UQ_user_period_cache", + "columns": [ + { + "expression": "kilo_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "cache_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_period_cache_lookup": { + "name": "IDX_user_period_cache_lookup", + "columns": [ + { + "expression": "cache_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "UQ_user_period_cache_share_token": { + "name": "UQ_user_period_cache_share_token", + "columns": [ + { + "expression": "shared_url_token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"user_period_cache\".\"shared_url_token\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_period_cache_kilo_user_id_kilocode_users_id_fk": { + "name": "user_period_cache_kilo_user_id_kilocode_users_id_fk", + "tableFrom": "user_period_cache", + "tableTo": "kilocode_users", + "columnsFrom": [ + "kilo_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "user_period_cache_period_type_check": { + "name": "user_period_cache_period_type_check", + "value": "\"user_period_cache\".\"period_type\" IN ('year', 'quarter', 'month', 'week', 'custom')" + } + }, + "isRLSEnabled": false + }, + "public.user_push_tokens": { + "name": "user_push_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "UQ_user_push_tokens_token": { + "name": "UQ_user_push_tokens_token", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_user_push_tokens_user_id": { + "name": "IDX_user_push_tokens_user_id", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_push_tokens_user_id_kilocode_users_id_fk": { + "name": "user_push_tokens_user_id_kilocode_users_id_fk", + "tableFrom": "user_push_tokens", + "tableTo": "kilocode_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vercel_ip_city": { + "name": "vercel_ip_city", + "schema": "", + "columns": { + "vercel_ip_city_id": { + "name": "vercel_ip_city_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "vercel_ip_city": { + "name": "vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_vercel_ip_city": { + "name": "UQ_vercel_ip_city", + "columns": [ + { + "expression": "vercel_ip_city", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vercel_ip_country": { + "name": "vercel_ip_country", + "schema": "", + "columns": { + "vercel_ip_country_id": { + "name": "vercel_ip_country_id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "vercel_ip_country": { + "name": "vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "UQ_vercel_ip_country": { + "name": "UQ_vercel_ip_country", + "columns": [ + { + "expression": "vercel_ip_country", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_events": { + "name": "webhook_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "pg_catalog.gen_random_uuid()" + }, + "owned_by_organization_id": { + "name": "owned_by_organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owned_by_user_id": { + "name": "owned_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "platform": { + "name": "platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_action": { + "name": "event_action", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "processed": { + "name": "processed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "handlers_triggered": { + "name": "handlers_triggered", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "errors": { + "name": "errors", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "event_signature": { + "name": "event_signature", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "IDX_webhook_events_owned_by_org_id": { + "name": "IDX_webhook_events_owned_by_org_id", + "columns": [ + { + "expression": "owned_by_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_owned_by_user_id": { + "name": "IDX_webhook_events_owned_by_user_id", + "columns": [ + { + "expression": "owned_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_platform": { + "name": "IDX_webhook_events_platform", + "columns": [ + { + "expression": "platform", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_event_type": { + "name": "IDX_webhook_events_event_type", + "columns": [ + { + "expression": "event_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "IDX_webhook_events_created_at": { + "name": "IDX_webhook_events_created_at", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_events_owned_by_organization_id_organizations_id_fk": { + "name": "webhook_events_owned_by_organization_id_organizations_id_fk", + "tableFrom": "webhook_events", + "tableTo": "organizations", + "columnsFrom": [ + "owned_by_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_events_owned_by_user_id_kilocode_users_id_fk": { + "name": "webhook_events_owned_by_user_id_kilocode_users_id_fk", + "tableFrom": "webhook_events", + "tableTo": "kilocode_users", + "columnsFrom": [ + "owned_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "UQ_webhook_events_signature": { + "name": "UQ_webhook_events_signature", + "nullsNotDistinct": false, + "columns": [ + "event_signature" + ] + } + }, + "policies": {}, + "checkConstraints": { + "webhook_events_owner_check": { + "name": "webhook_events_owner_check", + "value": "(\n (\"webhook_events\".\"owned_by_user_id\" IS NOT NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NULL) OR\n (\"webhook_events\".\"owned_by_user_id\" IS NULL AND \"webhook_events\".\"owned_by_organization_id\" IS NOT NULL)\n )" + } + }, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "public.microdollar_usage_view": { + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kilo_user_id": { + "name": "kilo_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "output_tokens": { + "name": "output_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_write_tokens": { + "name": "cache_write_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "cache_hit_tokens": { + "name": "cache_hit_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "http_x_forwarded_for": { + "name": "http_x_forwarded_for", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_city": { + "name": "http_x_vercel_ip_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_country": { + "name": "http_x_vercel_ip_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_latitude": { + "name": "http_x_vercel_ip_latitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ip_longitude": { + "name": "http_x_vercel_ip_longitude", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "http_x_vercel_ja4_digest": { + "name": "http_x_vercel_ja4_digest", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_model": { + "name": "requested_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_prompt_prefix": { + "name": "user_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_prefix": { + "name": "system_prompt_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_prompt_length": { + "name": "system_prompt_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "http_user_agent": { + "name": "http_user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cache_discount": { + "name": "cache_discount", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "max_tokens": { + "name": "max_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "has_middle_out_transform": { + "name": "has_middle_out_transform", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "has_error": { + "name": "has_error", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "abuse_classification": { + "name": "abuse_classification", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "inference_provider": { + "name": "inference_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "upstream_id": { + "name": "upstream_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finish_reason": { + "name": "finish_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "latency": { + "name": "latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "moderation_latency": { + "name": "moderation_latency", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "generation_time": { + "name": "generation_time", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "is_byok": { + "name": "is_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_user_byok": { + "name": "is_user_byok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "streamed": { + "name": "streamed", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "cancelled": { + "name": "cancelled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "editor_name": { + "name": "editor_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_kind": { + "name": "api_kind", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "has_tools": { + "name": "has_tools", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "machine_id": { + "name": "machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature": { + "name": "feature", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_model": { + "name": "auto_model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "market_cost": { + "name": "market_cost", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "is_free": { + "name": "is_free", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "definition": "\n SELECT\n mu.id,\n mu.kilo_user_id,\n meta.message_id,\n mu.cost,\n mu.input_tokens,\n mu.output_tokens,\n mu.cache_write_tokens,\n mu.cache_hit_tokens,\n mu.created_at,\n ip.http_ip AS http_x_forwarded_for,\n city.vercel_ip_city AS http_x_vercel_ip_city,\n country.vercel_ip_country AS http_x_vercel_ip_country,\n meta.vercel_ip_latitude AS http_x_vercel_ip_latitude,\n meta.vercel_ip_longitude AS http_x_vercel_ip_longitude,\n ja4.ja4_digest AS http_x_vercel_ja4_digest,\n mu.provider,\n mu.model,\n mu.requested_model,\n meta.user_prompt_prefix,\n spp.system_prompt_prefix,\n meta.system_prompt_length,\n ua.http_user_agent,\n mu.cache_discount,\n meta.max_tokens,\n meta.has_middle_out_transform,\n mu.has_error,\n mu.abuse_classification,\n mu.organization_id,\n mu.inference_provider,\n mu.project_id,\n meta.status_code,\n meta.upstream_id,\n frfr.finish_reason,\n meta.latency,\n meta.moderation_latency,\n meta.generation_time,\n meta.is_byok,\n meta.is_user_byok,\n meta.streamed,\n meta.cancelled,\n edit.editor_name,\n ak.api_kind,\n meta.has_tools,\n meta.machine_id,\n feat.feature,\n meta.session_id,\n md.mode,\n am.auto_model,\n meta.market_cost,\n meta.is_free\n FROM \"microdollar_usage\" mu\n LEFT JOIN \"microdollar_usage_metadata\" meta ON mu.id = meta.id\n LEFT JOIN \"http_ip\" ip ON meta.http_ip_id = ip.http_ip_id\n LEFT JOIN \"vercel_ip_city\" city ON meta.vercel_ip_city_id = city.vercel_ip_city_id\n LEFT JOIN \"vercel_ip_country\" country ON meta.vercel_ip_country_id = country.vercel_ip_country_id\n LEFT JOIN \"ja4_digest\" ja4 ON meta.ja4_digest_id = ja4.ja4_digest_id\n LEFT JOIN \"system_prompt_prefix\" spp ON meta.system_prompt_prefix_id = spp.system_prompt_prefix_id\n LEFT JOIN \"http_user_agent\" ua ON meta.http_user_agent_id = ua.http_user_agent_id\n LEFT JOIN \"finish_reason\" frfr ON meta.finish_reason_id = frfr.finish_reason_id\n LEFT JOIN \"editor_name\" edit ON meta.editor_name_id = edit.editor_name_id\n LEFT JOIN \"api_kind\" ak ON meta.api_kind_id = ak.api_kind_id\n LEFT JOIN \"feature\" feat ON meta.feature_id = feat.feature_id\n LEFT JOIN \"mode\" md ON meta.mode_id = md.mode_id\n LEFT JOIN \"auto_model\" am ON meta.auto_model_id = am.auto_model_id\n", + "name": "microdollar_usage_view", + "schema": "public", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json index 9ffedee20e..e4e10991a4 100644 --- a/packages/db/src/migrations/meta/_journal.json +++ b/packages/db/src/migrations/meta/_journal.json @@ -806,6 +806,13 @@ "when": 1778050833487, "tag": "0114_steep_hercules", "breakpoints": true + }, + { + "idx": 115, + "version": "7", + "when": 1778088504613, + "tag": "0115_productive_captain_cross", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/packages/db/src/schema-types.ts b/packages/db/src/schema-types.ts index 0ceab425c6..1d8de36fcd 100644 --- a/packages/db/src/schema-types.ts +++ b/packages/db/src/schema-types.ts @@ -17,8 +17,16 @@ export enum KiloPassCadence { Yearly = 'yearly', } +export enum KiloPassPaymentProvider { + Stripe = 'stripe', + AppStore = 'app_store', + GooglePlay = 'google_play', +} + export enum KiloPassIssuanceSource { StripeInvoice = 'stripe_invoice', + AppStoreTransaction = 'app_store_transaction', + GooglePlayTransaction = 'google_play_transaction', Cron = 'cron', } @@ -31,6 +39,12 @@ export enum KiloPassIssuanceItemKind { export enum KiloPassAuditLogAction { StripeWebhookReceived = 'stripe_webhook_received', KiloPassInvoicePaidHandled = 'kilo_pass_invoice_paid_handled', + StorePurchaseCompleted = 'store_purchase_completed', + StoreNotificationReceived = 'store_notification_received', + StoreSubscriptionRenewed = 'store_subscription_renewed', + StoreSubscriptionCanceled = 'store_subscription_canceled', + StoreSubscriptionExpired = 'store_subscription_expired', + StoreSubscriptionRefunded = 'store_subscription_refunded', BaseCreditsIssued = 'base_credits_issued', BonusCreditsIssued = 'bonus_credits_issued', BonusCreditsSkippedIdempotent = 'bonus_credits_skipped_idempotent', diff --git a/packages/db/src/schema.test.ts b/packages/db/src/schema.test.ts index 860645307e..7593aef04f 100644 --- a/packages/db/src/schema.test.ts +++ b/packages/db/src/schema.test.ts @@ -65,11 +65,23 @@ describe('database schema', () => { const expectedEnumValues = { KiloPassTier: ['tier_19', 'tier_49', 'tier_199'], KiloPassCadence: ['monthly', 'yearly'], - KiloPassIssuanceSource: ['stripe_invoice', 'cron'], + KiloPassPaymentProvider: ['stripe', 'app_store', 'google_play'], + KiloPassIssuanceSource: [ + 'stripe_invoice', + 'app_store_transaction', + 'google_play_transaction', + 'cron', + ], KiloPassIssuanceItemKind: ['base', 'bonus', 'promo_first_month_50pct'], KiloPassAuditLogAction: [ 'stripe_webhook_received', 'kilo_pass_invoice_paid_handled', + 'store_purchase_completed', + 'store_notification_received', + 'store_subscription_renewed', + 'store_subscription_canceled', + 'store_subscription_expired', + 'store_subscription_refunded', 'base_credits_issued', 'bonus_credits_issued', 'bonus_credits_skipped_idempotent', @@ -169,4 +181,9 @@ describe('database schema', () => { } } }); + + it('exposes provider-aware Kilo Pass store tables', () => { + expect(Object.hasOwn(schema, 'kilo_pass_store_events')).toBe(true); + expect(Object.hasOwn(schema, 'kilo_pass_store_purchases')).toBe(true); + }); }); diff --git a/packages/db/src/schema.ts b/packages/db/src/schema.ts index d6bdfb58fb..fccc444f7a 100644 --- a/packages/db/src/schema.ts +++ b/packages/db/src/schema.ts @@ -28,6 +28,7 @@ import * as z from 'zod'; import { KiloPassTier, KiloPassCadence, + KiloPassPaymentProvider, KiloPassIssuanceSource, KiloPassIssuanceItemKind, KiloPassAuditLogAction, @@ -114,6 +115,7 @@ export function enumCheck>( export const SCHEMA_CHECK_ENUMS = { KiloPassTier, KiloPassCadence, + KiloPassPaymentProvider, KiloPassIssuanceSource, KiloPassIssuanceItemKind, KiloPassAuditLogAction, @@ -441,7 +443,12 @@ export const kilo_pass_subscriptions = pgTable( kilo_user_id: text() .notNull() .references(() => kilocode_users.id, { onDelete: 'cascade', onUpdate: 'cascade' }), - stripe_subscription_id: text().notNull().unique(), + payment_provider: text() + .notNull() + .$type() + .default(KiloPassPaymentProvider.Stripe), + provider_subscription_id: text(), + stripe_subscription_id: text().unique(), tier: text().notNull().$type(), cadence: text().notNull().$type(), status: text().notNull().$type(), @@ -468,12 +475,25 @@ export const kilo_pass_subscriptions = pgTable( }, table => [ index('IDX_kilo_pass_subscriptions_kilo_user_id').on(table.kilo_user_id), + index('IDX_kilo_pass_subscriptions_payment_provider').on(table.payment_provider), index('IDX_kilo_pass_subscriptions_status').on(table.status), index('IDX_kilo_pass_subscriptions_cadence').on(table.cadence), + uniqueIndex('UQ_kilo_pass_subscriptions_provider_subscription') + .on(table.payment_provider, table.provider_subscription_id) + .where(sql`${table.provider_subscription_id} IS NOT NULL`), check( 'kilo_pass_subscriptions_current_streak_months_non_negative_check', sql`${table.current_streak_months} >= 0` ), + check( + 'kilo_pass_subscriptions_provider_subscription_required_check', + sql`${table.provider_subscription_id} IS NOT NULL OR ${table.payment_provider} = 'stripe'` + ), + enumCheck( + 'kilo_pass_subscriptions_payment_provider_check', + table.payment_provider, + KiloPassPaymentProvider + ), enumCheck('kilo_pass_subscriptions_tier_check', table.tier, KiloPassTier), enumCheck('kilo_pass_subscriptions_cadence_check', table.cadence, KiloPassCadence), ] @@ -482,6 +502,89 @@ export const kilo_pass_subscriptions = pgTable( export type KiloPassSubscription = typeof kilo_pass_subscriptions.$inferSelect; export type NewKiloPassSubscription = typeof kilo_pass_subscriptions.$inferInsert; +export const kilo_pass_store_events = pgTable( + 'kilo_pass_store_events', + { + id: uuid() + .default(sql`pg_catalog.gen_random_uuid()`) + .primaryKey() + .notNull(), + payment_provider: text().notNull().$type(), + event_id: text().notNull(), + provider_subscription_id: text(), + provider_transaction_id: text(), + product_id: text().notNull(), + environment: text().notNull(), + payload_json: jsonb().$type>().notNull().default({}), + processed_at: timestamp({ withTimezone: true, mode: 'string' }), + created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), + }, + table => [ + uniqueIndex('UQ_kilo_pass_store_events_provider_event').on( + table.payment_provider, + table.event_id + ), + index('IDX_kilo_pass_store_events_provider_subscription').on( + table.payment_provider, + table.provider_subscription_id + ), + enumCheck( + 'kilo_pass_store_events_payment_provider_check', + table.payment_provider, + KiloPassPaymentProvider + ), + ] +); + +export type KiloPassStoreEvent = typeof kilo_pass_store_events.$inferSelect; +export type NewKiloPassStoreEvent = typeof kilo_pass_store_events.$inferInsert; + +export const kilo_pass_store_purchases = pgTable( + 'kilo_pass_store_purchases', + { + id: uuid() + .default(sql`pg_catalog.gen_random_uuid()`) + .primaryKey() + .notNull(), + kilo_pass_subscription_id: uuid() + .notNull() + .references(() => kilo_pass_subscriptions.id, { onDelete: 'cascade', onUpdate: 'cascade' }), + kilo_user_id: text() + .notNull() + .references(() => kilocode_users.id, { onDelete: 'cascade', onUpdate: 'cascade' }), + payment_provider: text().notNull().$type(), + product_id: text().notNull(), + provider_subscription_id: text().notNull(), + provider_transaction_id: text().notNull(), + provider_original_transaction_id: text(), + purchase_token: text(), + environment: text().notNull(), + purchased_at: timestamp({ withTimezone: true, mode: 'string' }).notNull(), + raw_payload_json: jsonb().$type>().notNull().default({}), + created_at: timestamp({ withTimezone: true, mode: 'string' }).defaultNow().notNull(), + updated_at: timestamp({ withTimezone: true, mode: 'string' }) + .defaultNow() + .notNull() + .$onUpdateFn(() => sql`now()`), + }, + table => [ + uniqueIndex('UQ_kilo_pass_store_purchases_provider_transaction').on( + table.payment_provider, + table.provider_transaction_id + ), + index('IDX_kilo_pass_store_purchases_subscription_id').on(table.kilo_pass_subscription_id), + index('IDX_kilo_pass_store_purchases_user_id').on(table.kilo_user_id), + enumCheck( + 'kilo_pass_store_purchases_payment_provider_check', + table.payment_provider, + KiloPassPaymentProvider + ), + ] +); + +export type KiloPassStorePurchase = typeof kilo_pass_store_purchases.$inferSelect; +export type NewKiloPassStorePurchase = typeof kilo_pass_store_purchases.$inferInsert; + export const kilo_pass_issuances = pgTable( 'kilo_pass_issuances', { From 8d3fa34d8841a99c259950f98be8f3ea2e614313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:02:55 +0200 Subject: [PATCH 22/34] fix(kilo-pass): order app store subscriptions --- apps/web/src/lib/kilo-pass/mobile-store-products.ts | 13 +++++++++++-- .../kilo-pass/store-subscription-products.test.ts | 8 ++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/web/src/lib/kilo-pass/mobile-store-products.ts b/apps/web/src/lib/kilo-pass/mobile-store-products.ts index 410142479b..d31c8323de 100644 --- a/apps/web/src/lib/kilo-pass/mobile-store-products.ts +++ b/apps/web/src/lib/kilo-pass/mobile-store-products.ts @@ -60,6 +60,15 @@ const PRODUCT_IDS = { > >; +const STORE_PRODUCT_ORDER = [ + { tier: KiloPassTier.Tier199, cadence: KiloPassCadence.Yearly }, + { tier: KiloPassTier.Tier199, cadence: KiloPassCadence.Monthly }, + { tier: KiloPassTier.Tier49, cadence: KiloPassCadence.Yearly }, + { tier: KiloPassTier.Tier49, cadence: KiloPassCadence.Monthly }, + { tier: KiloPassTier.Tier19, cadence: KiloPassCadence.Yearly }, + { tier: KiloPassTier.Tier19, cadence: KiloPassCadence.Monthly }, +] satisfies { tier: KiloPassTier; cadence: KiloPassCadence }[]; + function roundStoreMonthlyPrice(webMonthlyPriceUsd: number): number { const gross = webMonthlyPriceUsd * 1.3; return Math.round(gross * 100) / 100; @@ -82,8 +91,8 @@ export function getMobileStoreKiloPassProduct(params: { } export function getAllMobileStoreKiloPassProducts(): MobileStoreKiloPassProduct[] { - return Object.values(KiloPassTier).flatMap(tier => - Object.values(KiloPassCadence).map(cadence => getMobileStoreKiloPassProduct({ tier, cadence })) + return STORE_PRODUCT_ORDER.map(product => + getMobileStoreKiloPassProduct({ tier: product.tier, cadence: product.cadence }) ); } diff --git a/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts b/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts index 714ceb6dd2..19928c5476 100644 --- a/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts +++ b/apps/web/src/lib/kilo-pass/store-subscription-products.test.ts @@ -11,6 +11,14 @@ describe('mobile Kilo Pass store products', () => { const products = getAllMobileStoreKiloPassProducts(); expect(products).toHaveLength(6); + expect(products.map(product => product.appleProductId)).toEqual([ + 'kilopass.tier199.yearly.v1', + 'kilopass.tier199.monthly.v1', + 'kilopass.tier49.yearly.v1', + 'kilopass.tier49.monthly.v1', + 'kilopass.tier19.yearly.v1', + 'kilopass.tier19.monthly.v1', + ]); for (const tier of Object.values(KiloPassTier)) { for (const cadence of Object.values(KiloPassCadence)) { const product = getMobileStoreKiloPassProduct({ tier, cadence }); From 33f1fa5f65dbf34e3da8368a086866fe2f4daa68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:03:38 +0200 Subject: [PATCH 23/34] fix(mobile): make Kilo Pass purchase sheet native --- .../kilo-pass-subscription-sheet.tsx | 139 ++++++++++++------ 1 file changed, 95 insertions(+), 44 deletions(-) diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx index 9d52723ce4..a9d322a4df 100644 --- a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx @@ -1,5 +1,7 @@ +import { Portal } from '@rn-primitives/portal'; import { Check, X } from 'lucide-react-native'; -import { ActivityIndicator, Modal, Pressable, View } from 'react-native'; +import { useEffect, useMemo, useState } from 'react'; +import { ActivityIndicator, Pressable, ScrollView, View } from 'react-native'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; @@ -33,80 +35,129 @@ export function KiloPassSubscriptionSheet({ onPurchase, }: Readonly) { const colors = useThemeColors(); + const [selectedProductId, setSelectedProductId] = useState(null); + const selectedProduct = useMemo( + () => products.find(product => product.appleProductId === selectedProductId) ?? products[0], + [products, selectedProductId] + ); + + useEffect(() => { + if (selectedProductId === null && products[0]) { + setSelectedProductId(products[0].appleProductId); + } + }, [products, selectedProductId]); + + if (!visible) { + return null; + } return ( - - - - - - - Kilo Pass + + + + + + + + + + + Kilo Pass App Store subscription - + - + {isLoading && [0, 1, 2].map(index => ( - + ))} {!isLoading && - products.map(product => ( - { - onPurchase(product); - }} - > - - - - {formatTier(product)} · {formatCadence(product)} - + products.map(product => { + const selected = product.appleProductId === selectedProduct?.appleProductId; + + return ( + { + setSelectedProductId(product.appleProductId); + }} + > + + + + {formatTier(product)} · {formatCadence(product)} + + + Same Kilo Pass credits and bonus progress as web. + + + + + {product.displayPrice} + + + {selected && } + + + + + - Same Kilo Pass credits and bonus progress as web. + Credits are added after store validation. - {product.displayPrice} - - - - - Credits are added after store validation. - - - - ))} - + + ); + })} + - + ); } From b77479afe2da5bab1254053ec53ec6148fb80ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:03:59 +0200 Subject: [PATCH 24/34] fix(mobile): remove web parity Kilo Pass copy --- .../src/components/kilo-pass/kilo-pass-subscription-sheet.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx index a9d322a4df..0d2d66d4c2 100644 --- a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx @@ -112,7 +112,7 @@ export function KiloPassSubscriptionSheet({ {formatTier(product)} · {formatCadence(product)} - Same Kilo Pass credits and bonus progress as web. + Base credits plus monthly bonus progress. From a3438c4a8adb4400c8b9f7bfe84c850e00d6aaad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:04:26 +0200 Subject: [PATCH 25/34] fix(mobile): add Kilo Pass explainer link --- .../kilo-pass/kilo-pass-subscription-sheet.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx index 0d2d66d4c2..2900680c5b 100644 --- a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-sheet.tsx @@ -1,7 +1,7 @@ import { Portal } from '@rn-primitives/portal'; import { Check, X } from 'lucide-react-native'; import { useEffect, useMemo, useState } from 'react'; -import { ActivityIndicator, Pressable, ScrollView, View } from 'react-native'; +import { ActivityIndicator, Linking, Pressable, ScrollView, View } from 'react-native'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; @@ -9,6 +9,8 @@ import { Text } from '@/components/ui/text'; import { useThemeColors } from '@/lib/hooks/use-theme-colors'; import { type AppStoreKiloPassProduct } from '@/lib/kilo-pass/store-products'; +const KILO_PASS_INFO_URL = 'https://kilo.ai/features/kilo-pass'; + type KiloPassSubscriptionSheetProps = { visible: boolean; products: AppStoreKiloPassProduct[]; @@ -67,6 +69,16 @@ export function KiloPassSubscriptionSheet({ Kilo Pass + { + void Linking.openURL(KILO_PASS_INFO_URL); + }} + > + How Kilo Pass works + App Store subscription Date: Wed, 6 May 2026 20:04:46 +0200 Subject: [PATCH 26/34] fix(mobile): update Kilo Pass teaser copy --- .../src/components/kilo-pass/kilo-pass-subscription-card.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx index eae8a0c343..79e6d67535 100644 --- a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx @@ -26,7 +26,7 @@ export function KiloPassSubscriptionCard() { const title = subscription ? 'Kilo Pass active' : 'Kilo Pass'; const description = subscription ? `$${subscription.currentPeriodBaseCreditsUsd.toFixed(0)} monthly credits` - : 'Subscribe with your App Store account'; + : 'Monthly credits with bonus progress'; return ( <> From 5b2a06381ded6efaf430d11396e8fbb9c3e7b19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:05:46 +0200 Subject: [PATCH 27/34] fix(mobile): route web Kilo Pass management --- .../kilo-pass/kilo-pass-subscription-card.tsx | 23 ++++++----- .../kilo-pass/subscription-card-state.test.ts | 28 +++++++++++++ .../lib/kilo-pass/subscription-card-state.ts | 41 +++++++++++++++++++ 3 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 apps/mobile/src/lib/kilo-pass/subscription-card-state.test.ts create mode 100644 apps/mobile/src/lib/kilo-pass/subscription-card-state.ts diff --git a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx index 79e6d67535..0e1171a167 100644 --- a/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx +++ b/apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx @@ -1,15 +1,19 @@ import { useState } from 'react'; -import { Platform, Pressable, View } from 'react-native'; +import { Linking, Platform, Pressable, View } from 'react-native'; import { ShieldCheck } from 'lucide-react-native'; import { useQuery } from '@tanstack/react-query'; import { Text } from '@/components/ui/text'; import { KiloPassSubscriptionSheet } from '@/components/kilo-pass/kilo-pass-subscription-sheet'; import { useThemeColors } from '@/lib/hooks/use-theme-colors'; +import { WEB_BASE_URL } from '@/lib/config'; import { useTRPC } from '@/lib/trpc'; +import { getKiloPassSubscriptionCardState } from '@/lib/kilo-pass/subscription-card-state'; import { useStoreKiloPassProducts } from '@/lib/kilo-pass/use-store-kilo-pass-products'; import { useStoreKiloPassPurchase } from '@/lib/kilo-pass/use-store-kilo-pass-purchase'; +const KILO_PASS_MANAGE_URL = `${WEB_BASE_URL}/subscriptions/kilo-pass`; + export function KiloPassSubscriptionCard() { const [sheetVisible, setSheetVisible] = useState(false); const colors = useThemeColors(); @@ -23,16 +27,17 @@ export function KiloPassSubscriptionCard() { } const subscription = stateQuery.data?.subscription; - const title = subscription ? 'Kilo Pass active' : 'Kilo Pass'; - const description = subscription - ? `$${subscription.currentPeriodBaseCreditsUsd.toFixed(0)} monthly credits` - : 'Monthly credits with bonus progress'; + const cardState = getKiloPassSubscriptionCardState(subscription); return ( <> { + if (cardState.action === 'open-web-management') { + void Linking.openURL(KILO_PASS_MANAGE_URL); + return; + } setSheetVisible(true); }} > @@ -41,12 +46,10 @@ export function KiloPassSubscriptionCard() { - {title} - {description} + {cardState.title} + {cardState.description} - - {subscription ? 'Manage' : 'Subscribe'} - + {cardState.actionLabel} diff --git a/apps/mobile/src/lib/kilo-pass/subscription-card-state.test.ts b/apps/mobile/src/lib/kilo-pass/subscription-card-state.test.ts new file mode 100644 index 0000000000..aeb4fab7f2 --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/subscription-card-state.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from 'vitest'; + +import { getKiloPassSubscriptionCardState } from './subscription-card-state'; + +describe('getKiloPassSubscriptionCardState', () => { + it('sends Stripe-managed Kilo Pass users to web management', () => { + expect( + getKiloPassSubscriptionCardState({ + currentPeriodBaseCreditsUsd: 49, + paymentProvider: 'stripe', + }) + ).toEqual({ + action: 'open-web-management', + actionLabel: 'Manage on web', + description: '$49 monthly credits · Managed on web', + title: 'Kilo Pass active', + }); + }); + + it('keeps unsubscribed users on the App Store purchase path', () => { + expect(getKiloPassSubscriptionCardState(null)).toEqual({ + action: 'open-store-sheet', + actionLabel: 'Subscribe', + description: 'Monthly credits with bonus progress', + title: 'Kilo Pass', + }); + }); +}); diff --git a/apps/mobile/src/lib/kilo-pass/subscription-card-state.ts b/apps/mobile/src/lib/kilo-pass/subscription-card-state.ts new file mode 100644 index 0000000000..e8af39eb94 --- /dev/null +++ b/apps/mobile/src/lib/kilo-pass/subscription-card-state.ts @@ -0,0 +1,41 @@ +type KiloPassSubscriptionCardSubscription = { + currentPeriodBaseCreditsUsd: number; + paymentProvider: 'stripe' | 'app_store' | 'google_play'; +}; + +type KiloPassSubscriptionCardState = { + action: 'open-store-sheet' | 'open-web-management'; + actionLabel: string; + description: string; + title: string; +}; + +export function getKiloPassSubscriptionCardState( + subscription: KiloPassSubscriptionCardSubscription | null | undefined +): KiloPassSubscriptionCardState { + if (!subscription) { + return { + action: 'open-store-sheet', + actionLabel: 'Subscribe', + description: 'Monthly credits with bonus progress', + title: 'Kilo Pass', + }; + } + + const credits = `$${subscription.currentPeriodBaseCreditsUsd.toFixed(0)} monthly credits`; + if (subscription.paymentProvider === 'stripe') { + return { + action: 'open-web-management', + actionLabel: 'Manage on web', + description: `${credits} · Managed on web`, + title: 'Kilo Pass active', + }; + } + + return { + action: 'open-store-sheet', + actionLabel: 'Manage', + description: credits, + title: 'Kilo Pass active', + }; +} From 39a64b319013945151dce269bf92691aea1fffd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:08:24 +0200 Subject: [PATCH 28/34] fix(mobile): recover Kilo Pass store purchases --- .../use-store-kilo-pass-purchase.test.tsx | 52 +++++++++ .../kilo-pass/use-store-kilo-pass-purchase.ts | 104 ++++++++++++++---- 2 files changed, 137 insertions(+), 19 deletions(-) diff --git a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx index 3277841705..9beb451b74 100644 --- a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx +++ b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx @@ -5,11 +5,18 @@ import { type AppStoreKiloPassProduct } from './store-products'; vi.mock('expo-iap', () => ({ useIAP: () => ({ + availablePurchases: [], + connected: false, finishTransaction: vi.fn(), + getAvailablePurchases: vi.fn(), requestPurchase: vi.fn(), }), })); +vi.mock('react-native', () => ({ + Platform: { OS: 'ios' }, +})); + vi.mock('@tanstack/react-query', () => ({ useMutation: () => ({ isPending: false, mutateAsync: vi.fn() }), useQueryClient: () => ({ invalidateQueries: vi.fn() }), @@ -127,4 +134,49 @@ describe('createAppStoreKiloPassPurchaseActions', () => { expect(invalidateAfterCompletion).toHaveBeenCalled(); expect(finishTransaction).toHaveBeenCalledWith({ purchase, isConsumable: false }); }); + + it('recovers unfinished Kilo Pass App Store purchases', async () => { + const finishTransaction = vi.fn(); + const completeAppStorePurchase = vi.fn().mockResolvedValue({ alreadyProcessed: false }); + const purchase = { + id: 'purchase-1', + ids: null, + isAutoRenewing: true, + platform: 'ios', + productId: product.appleProductId, + purchaseState: 'purchased', + purchaseToken: 'signed-jws', + quantity: 1, + store: 'apple', + transactionDate: Date.now(), + transactionId: 'tx-1', + } satisfies Purchase; + const actions = createAppStoreKiloPassPurchaseActions({ + completeAppStorePurchase, + finishTransaction, + invalidateAfterCompletion: vi.fn(), + requestPurchase: vi.fn(), + showError: () => undefined, + }); + + await actions.recoverPurchases([ + purchase, + { + ...purchase, + id: 'other-purchase', + productId: 'not-kilopass', + transactionId: 'other-tx', + }, + { + ...purchase, + id: 'pending-purchase', + purchaseState: 'pending', + transactionId: 'pending-tx', + }, + ]); + + expect(completeAppStorePurchase).toHaveBeenCalledTimes(1); + expect(completeAppStorePurchase).toHaveBeenCalledWith({ signedTransactionJws: 'signed-jws' }); + expect(finishTransaction).toHaveBeenCalledWith({ purchase, isConsumable: false }); + }); }); diff --git a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts index a11ce6e4ae..ab03754021 100644 --- a/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts +++ b/apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts @@ -1,6 +1,7 @@ -import { useCallback } from 'react'; +import { useCallback, useEffect, useMemo, useRef } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { type Purchase, useIAP } from 'expo-iap'; +import { Platform } from 'react-native'; import { toast } from 'sonner-native'; import { useTRPC } from '@/lib/trpc'; @@ -17,6 +18,16 @@ type AppStoreKiloPassPurchaseActionsDeps = { showError: (message: string) => void; }; +function isRecoverableKiloPassPurchase(purchase: Purchase): boolean { + if (purchase.purchaseState === 'pending') { + return false; + } + if (purchase.store !== 'apple') { + return false; + } + return purchase.productId.startsWith('kilopass.'); +} + function getPurchaseToken(purchase: Purchase): string { const token = purchase.purchaseToken; if (!token) { @@ -26,6 +37,17 @@ function getPurchaseToken(purchase: Purchase): string { } export function createAppStoreKiloPassPurchaseActions(deps: AppStoreKiloPassPurchaseActionsDeps) { + async function handlePurchaseSuccess(purchase: Purchase) { + try { + const signedTransactionJws = getPurchaseToken(purchase); + await deps.completeAppStorePurchase({ signedTransactionJws }); + await deps.invalidateAfterCompletion(); + await deps.finishTransaction({ purchase, isConsumable: false }); + } catch (error) { + deps.showError(error instanceof Error ? error.message : 'Failed to complete purchase.'); + } + } + return { purchase: async (product: AppStoreKiloPassProduct) => { await deps.requestPurchase({ @@ -33,15 +55,15 @@ export function createAppStoreKiloPassPurchaseActions(deps: AppStoreKiloPassPurc type: 'subs', }); }, - handlePurchaseSuccess: async (purchase: Purchase) => { - try { - const signedTransactionJws = getPurchaseToken(purchase); - await deps.completeAppStorePurchase({ signedTransactionJws }); - await deps.invalidateAfterCompletion(); - await deps.finishTransaction({ purchase, isConsumable: false }); - } catch (error) { - deps.showError(error instanceof Error ? error.message : 'Failed to complete purchase.'); - } + handlePurchaseSuccess, + recoverPurchases: async (purchases: Purchase[]) => { + await Promise.all( + purchases + .filter(purchase => isRecoverableKiloPassPurchase(purchase)) + .map(async purchase => { + await handlePurchaseSuccess(purchase); + }) + ); }, }; } @@ -49,6 +71,7 @@ export function createAppStoreKiloPassPurchaseActions(deps: AppStoreKiloPassPurc export function useStoreKiloPassPurchase() { const trpc = useTRPC(); const queryClient = useQueryClient(); + const recoveredPurchaseIdsRef = useRef(new Set()); const completeAppStorePurchase = useMutation( trpc.kiloPass.completeAppStorePurchase.mutationOptions() ); @@ -70,16 +93,59 @@ export function useStoreKiloPassPurchase() { void actions.handlePurchaseSuccess(purchase); }, }); + const { + availablePurchases, + connected, + finishTransaction, + getAvailablePurchases, + requestPurchase, + } = actionsRef; - const actions = createAppStoreKiloPassPurchaseActions({ - requestPurchase: actionsRef.requestPurchase, - completeAppStorePurchase: completeAppStorePurchase.mutateAsync, - finishTransaction: actionsRef.finishTransaction, - invalidateAfterCompletion, - showError: message => { - toast.error(message); - }, - }); + const actions = useMemo( + () => + createAppStoreKiloPassPurchaseActions({ + requestPurchase, + completeAppStorePurchase: completeAppStorePurchase.mutateAsync, + finishTransaction, + invalidateAfterCompletion, + showError: message => { + toast.error(message); + }, + }), + [ + completeAppStorePurchase.mutateAsync, + finishTransaction, + invalidateAfterCompletion, + requestPurchase, + ] + ); + + useEffect(() => { + if (Platform.OS !== 'ios' || !connected) { + return; + } + + void getAvailablePurchases(); + }, [connected, getAvailablePurchases]); + + useEffect(() => { + if (Platform.OS !== 'ios' || availablePurchases.length === 0) { + return; + } + + const unrecoveredPurchases = availablePurchases.filter(purchase => { + const id = purchase.transactionId ?? purchase.id; + if (recoveredPurchaseIdsRef.current.has(id)) { + return false; + } + recoveredPurchaseIdsRef.current.add(id); + return true; + }); + + if (unrecoveredPurchases.length > 0) { + void actions.recoverPurchases(unrecoveredPurchases); + } + }, [actions, availablePurchases]); return { purchase: actions.purchase, From 88d0a49d17a48d06ae245269f3aa19baf453994b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:21:06 +0200 Subject: [PATCH 29/34] fix(mobile): sign out on unauthorized tRPC queries --- apps/mobile/package.json | 3 +- apps/mobile/src/lib/auth/auth-context.tsx | 3 ++ apps/mobile/src/lib/auth/trpc-unauthorized.ts | 54 +++++++++++++++++++ apps/mobile/src/lib/query-client.ts | 12 ++++- apps/mobile/src/lib/trpc-unauthorized.test.ts | 35 ++++++++++++ pnpm-lock.yaml | 3 ++ 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 apps/mobile/src/lib/auth/trpc-unauthorized.ts create mode 100644 apps/mobile/src/lib/trpc-unauthorized.test.ts diff --git a/apps/mobile/package.json b/apps/mobile/package.json index fd1e6abc62..4b8ea18fd3 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -85,7 +85,8 @@ "sonner-native": "^0.23.1", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.2", - "ulid": "3.0.1" + "ulid": "3.0.1", + "zod": "catalog:" }, "devDependencies": { "@sentry/cli": "catalog:", diff --git a/apps/mobile/src/lib/auth/auth-context.tsx b/apps/mobile/src/lib/auth/auth-context.tsx index 5c19c1a13e..d3c3fab21b 100644 --- a/apps/mobile/src/lib/auth/auth-context.tsx +++ b/apps/mobile/src/lib/auth/auth-context.tsx @@ -11,6 +11,7 @@ import { import { trackEvent } from '@/lib/appsflyer'; import { queryClient } from '@/lib/query-client'; +import { setTrpcUnauthorizedHandler } from '@/lib/auth/trpc-unauthorized'; import { AUTH_TOKEN_KEY, NOTIFICATION_PROMPT_SEEN_KEY, @@ -62,6 +63,8 @@ export function AuthProvider({ children }: { readonly children: ReactNode }) { setToken(undefined); }, []); + useEffect(() => setTrpcUnauthorizedHandler(signOut), [signOut]); + const value = useMemo( () => ({ token, isLoading, signIn, signOut }), [token, isLoading, signIn, signOut] diff --git a/apps/mobile/src/lib/auth/trpc-unauthorized.ts b/apps/mobile/src/lib/auth/trpc-unauthorized.ts new file mode 100644 index 0000000000..3d07a988d1 --- /dev/null +++ b/apps/mobile/src/lib/auth/trpc-unauthorized.ts @@ -0,0 +1,54 @@ +import { z } from 'zod'; + +type TrpcUnauthorizedHandler = () => Promise | void; + +const DirectUnauthorizedErrorSchema = z.looseObject({ + data: z.looseObject({ httpStatus: z.literal(401) }), +}); + +const ShapedUnauthorizedErrorSchema = z.looseObject({ + shape: z.looseObject({ + data: z.looseObject({ httpStatus: z.literal(401) }), + }), +}); + +let unauthorizedHandler: TrpcUnauthorizedHandler | null = null; +let isHandlingUnauthorized = false; + +export function isUnauthorizedTrpcError(error: unknown): boolean { + const direct = DirectUnauthorizedErrorSchema.safeParse(error); + if (direct.success) { + return true; + } + + return ShapedUnauthorizedErrorSchema.safeParse(error).success; +} + +export function setTrpcUnauthorizedHandler(handler: TrpcUnauthorizedHandler): () => void { + unauthorizedHandler = handler; + return () => { + if (unauthorizedHandler === handler) { + unauthorizedHandler = null; + } + }; +} + +export function handleTrpcQueryError(error: unknown): void { + if (!isUnauthorizedTrpcError(error) || !unauthorizedHandler || isHandlingUnauthorized) { + return; + } + + const handler = unauthorizedHandler; + void runUnauthorizedHandler(handler); +} + +async function runUnauthorizedHandler(handler: TrpcUnauthorizedHandler): Promise { + isHandlingUnauthorized = true; + try { + await handler(); + } catch { + // A failed sign-out should not make every later 401 permanently ignored. + } finally { + isHandlingUnauthorized = false; + } +} diff --git a/apps/mobile/src/lib/query-client.ts b/apps/mobile/src/lib/query-client.ts index 6d46de5917..164676f7de 100644 --- a/apps/mobile/src/lib/query-client.ts +++ b/apps/mobile/src/lib/query-client.ts @@ -1,3 +1,11 @@ -import { QueryClient } from '@tanstack/react-query'; +import { QueryCache, QueryClient } from '@tanstack/react-query'; -export const queryClient = new QueryClient(); +import { handleTrpcQueryError } from '@/lib/auth/trpc-unauthorized'; + +export const queryClient = new QueryClient({ + queryCache: new QueryCache({ + onError: error => { + handleTrpcQueryError(error); + }, + }), +}); diff --git a/apps/mobile/src/lib/trpc-unauthorized.test.ts b/apps/mobile/src/lib/trpc-unauthorized.test.ts new file mode 100644 index 0000000000..69a94c66cb --- /dev/null +++ b/apps/mobile/src/lib/trpc-unauthorized.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { + handleTrpcQueryError, + isUnauthorizedTrpcError, + setTrpcUnauthorizedHandler, +} from './auth/trpc-unauthorized'; + +describe('tRPC unauthorized handling', () => { + it('recognizes tRPC query errors with HTTP 401 status', () => { + expect(isUnauthorizedTrpcError({ data: { httpStatus: 401 } })).toBe(true); + expect(isUnauthorizedTrpcError({ shape: { data: { httpStatus: 401 } } })).toBe(true); + expect(isUnauthorizedTrpcError({ data: { httpStatus: 403 } })).toBe(false); + }); + + it('runs the registered sign-out handler for a 401 query error', () => { + const signOut = vi.fn(); + const clear = setTrpcUnauthorizedHandler(signOut); + + handleTrpcQueryError({ data: { httpStatus: 401 } }); + + expect(signOut).toHaveBeenCalledTimes(1); + clear(); + }); + + it('does not run the handler for non-401 query errors', () => { + const signOut = vi.fn(); + const clear = setTrpcUnauthorizedHandler(signOut); + + handleTrpcQueryError({ data: { httpStatus: 500 } }); + + expect(signOut).not.toHaveBeenCalled(); + clear(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 56fb9dde39..a060eed032 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -327,6 +327,9 @@ importers: ulid: specifier: 3.0.1 version: 3.0.1 + zod: + specifier: 'catalog:' + version: 4.3.6 dependenciesMeta: '@kilocode/kilo-chat-hooks': injected: true From 0c5228a148c3a7595e21414f56c40861ce396bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:22:26 +0200 Subject: [PATCH 30/34] fix(mobile): move KiloClaw skeleton to top --- apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx b/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx index ee36b6f1ab..2dcb309e1d 100644 --- a/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx +++ b/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx @@ -94,15 +94,18 @@ export default function KiloClawTab() { className="px-[22px]" headerRight={} /> - + {showInstanceSkeleton ? ( - + ) : ( - + Date: Wed, 6 May 2026 20:33:36 +0200 Subject: [PATCH 31/34] fix(mobile): add agent empty state CTA --- .../app/(app)/(tabs)/(1_kiloclaw)/index.tsx | 9 ++++- apps/mobile/src/app/(app)/(tabs)/_layout.tsx | 4 +- .../agents/session-list-content.tsx | 38 ++++++++++++++++--- .../components/agents/session-list-routes.ts | 5 +++ .../agents/session-list-screen.test.ts | 13 +++++++ .../components/agents/session-list-screen.tsx | 9 +++-- apps/mobile/src/lib/tab-bar-layout.test.ts | 17 +++++++++ apps/mobile/src/lib/tab-bar-layout.ts | 12 ++++++ 8 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 apps/mobile/src/components/agents/session-list-routes.ts create mode 100644 apps/mobile/src/components/agents/session-list-screen.test.ts create mode 100644 apps/mobile/src/lib/tab-bar-layout.test.ts create mode 100644 apps/mobile/src/lib/tab-bar-layout.ts diff --git a/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx b/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx index 2dcb309e1d..5806fd9dba 100644 --- a/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx +++ b/apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/index.tsx @@ -1,7 +1,8 @@ import { type Href, useRouter } from 'expo-router'; import { useCallback, useState } from 'react'; -import { View } from 'react-native'; +import { Platform, View } from 'react-native'; import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { EmptyStateContent } from '@/components/kiloclaw/empty-state-content'; import { getKiloClawEntryDecision } from '@/components/kiloclaw/instance-entry-state'; @@ -16,10 +17,12 @@ import { useKiloClawMobileOnboardingState } from '@/lib/hooks/use-kiloclaw-queri import { useThemeColors } from '@/lib/hooks/use-theme-colors'; import { useUnreadCounts } from '@/lib/hooks/use-unread-counts'; import { chatSandboxPath } from '@/lib/kilo-chat-routes'; +import { getTabBarOverlayHeight } from '@/lib/tab-bar-layout'; export default function KiloClawTab() { const router = useRouter(); const colors = useThemeColors(); + const { bottom } = useSafeAreaInsets(); const [manualRefreshing, setManualRefreshing] = useState(false); const instancesQuery = useAllKiloClawInstances(); const { data: instances } = instancesQuery; @@ -30,6 +33,9 @@ export default function KiloClawTab() { useForegroundInvalidateKiloclawState(); const showInstanceSkeleton = entryDecision.kind === 'loading' || onboardingQuery.isPending; + const emptyStateContainerStyle = { + paddingBottom: getTabBarOverlayHeight(bottom, Platform.OS), + }; const handleRefresh = useCallback(() => { void (async () => { @@ -105,6 +111,7 @@ export default function KiloClawTab() { Promise; onSessionPress: (sessionId: string, organizationId?: string | null) => void; onSearchChange: (text: string) => void; + onCreateSession: () => void; }; export function AgentSessionListContent({ @@ -37,9 +41,15 @@ export function AgentSessionListContent({ refetch, onSessionPress, onSearchChange, + onCreateSession, }: Readonly) { const colors = useThemeColors(); + const { bottom } = useSafeAreaInsets(); const { deleteSession, renameSession } = useSessionMutations(); + const emptyStateContainerStyle = useMemo( + () => ({ paddingBottom: getTabBarOverlayHeight(bottom, Platform.OS) }), + [bottom] + ); const listHeader = useMemo( () => ( @@ -59,17 +69,28 @@ export function AgentSessionListContent({ [colors.mutedForeground, onSearchChange] ); + const emptyStateAction = useMemo( + () => ( + + ), + [colors.foreground, onCreateSession] + ); + const listEmptyComponent = useMemo( () => ( ), - [] + [emptyStateAction] ); const organizationIdBySessionId = useMemo( @@ -154,11 +175,16 @@ export function AgentSessionListContent({ // list with only a ListEmptyComponent would leave the search bar fully visible. if (!hasAnySessions) { return ( - + ); diff --git a/apps/mobile/src/components/agents/session-list-routes.ts b/apps/mobile/src/components/agents/session-list-routes.ts new file mode 100644 index 0000000000..952caeba8e --- /dev/null +++ b/apps/mobile/src/components/agents/session-list-routes.ts @@ -0,0 +1,5 @@ +export function getNewAgentSessionPath(organizationId: string | null): string { + return organizationId + ? `/(app)/agent-chat/new?organizationId=${organizationId}` + : '/(app)/agent-chat/new'; +} diff --git a/apps/mobile/src/components/agents/session-list-screen.test.ts b/apps/mobile/src/components/agents/session-list-screen.test.ts new file mode 100644 index 0000000000..04d8287861 --- /dev/null +++ b/apps/mobile/src/components/agents/session-list-screen.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from 'vitest'; + +import { getNewAgentSessionPath } from '@/components/agents/session-list-routes'; + +describe('getNewAgentSessionPath', () => { + it('routes personal sessions to the new agent screen', () => { + expect(getNewAgentSessionPath(null)).toBe('/(app)/agent-chat/new'); + }); + + it('preserves the organization context', () => { + expect(getNewAgentSessionPath('org_123')).toBe('/(app)/agent-chat/new?organizationId=org_123'); + }); +}); diff --git a/apps/mobile/src/components/agents/session-list-screen.tsx b/apps/mobile/src/components/agents/session-list-screen.tsx index 513cd65e15..eddcf9d88d 100644 --- a/apps/mobile/src/components/agents/session-list-screen.tsx +++ b/apps/mobile/src/components/agents/session-list-screen.tsx @@ -3,6 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Pressable, View } from 'react-native'; import Animated, { LinearTransition } from 'react-native-reanimated'; +import { getNewAgentSessionPath } from '@/components/agents/session-list-routes'; import { AgentSessionListContent } from '@/components/agents/session-list-content'; import { type ProjectFilterOption, @@ -202,10 +203,7 @@ export function AgentSessionListScreen() { { - const path = organizationId - ? `/(app)/agent-chat/new?organizationId=${organizationId}` - : '/(app)/agent-chat/new'; - router.push(path as Href); + router.push(getNewAgentSessionPath(organizationId) as Href); }} hitSlop={8} accessibilityLabel="New session" @@ -251,6 +249,9 @@ export function AgentSessionListScreen() { refetch={refetch} onSessionPress={navigateToSession} onSearchChange={handleSearchChange} + onCreateSession={() => { + router.push(getNewAgentSessionPath(organizationId) as Href); + }} /> {showFilterModal && ( diff --git a/apps/mobile/src/lib/tab-bar-layout.test.ts b/apps/mobile/src/lib/tab-bar-layout.test.ts new file mode 100644 index 0000000000..fc14ab31c2 --- /dev/null +++ b/apps/mobile/src/lib/tab-bar-layout.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; + +import { getTabBarOverlayHeight } from '@/lib/tab-bar-layout'; + +describe('getTabBarOverlayHeight', () => { + it('includes the bottom safe area on iOS', () => { + expect(getTabBarOverlayHeight(34, 'ios')).toBe(84); + }); + + it('includes the Android extra padding used by the tab bar', () => { + expect(getTabBarOverlayHeight(16, 'android')).toBe(70); + }); + + it('ignores negative insets', () => { + expect(getTabBarOverlayHeight(-1, 'ios')).toBe(50); + }); +}); diff --git a/apps/mobile/src/lib/tab-bar-layout.ts b/apps/mobile/src/lib/tab-bar-layout.ts new file mode 100644 index 0000000000..d4b670cea6 --- /dev/null +++ b/apps/mobile/src/lib/tab-bar-layout.ts @@ -0,0 +1,12 @@ +export const TAB_BAR_BASE_HEIGHT = 50; +export const ANDROID_TAB_BAR_EXTRA_PADDING = 4; + +export type TabBarPlatform = 'android' | 'ios' | 'macos' | 'windows' | 'web'; + +export function getTabBarOverlayHeight(bottomInset: number, platform: TabBarPlatform): number { + return ( + TAB_BAR_BASE_HEIGHT + + Math.max(bottomInset, 0) + + (platform === 'android' ? ANDROID_TAB_BAR_EXTRA_PADDING : 0) + ); +} From 5dafc8bfe332e6de5321ffb0e19a894b589f997b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:40:53 +0200 Subject: [PATCH 32/34] fix(kilo-pass): make store completion idempotent --- .../store-subscription-completion.test.ts | 47 ++++++ .../store-subscription-completion.ts | 146 +++++++++++------- 2 files changed, 136 insertions(+), 57 deletions(-) diff --git a/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts b/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts index 19754d59a3..fac1c848fa 100644 --- a/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts +++ b/apps/web/src/lib/kilo-pass/store-subscription-completion.test.ts @@ -116,6 +116,53 @@ describe('completeStoreKiloPassPurchase', () => { expect(storePurchases).toHaveLength(1); }); + it('returns idempotently when the same provider transaction is completed concurrently', async () => { + const user = await insertTestUser({ total_microdollars_acquired: 0, microdollars_used: 0 }); + const purchase = applePurchase(); + + const results = await Promise.all( + Array.from({ length: 4 }, () => completeStoreKiloPassPurchase({ user, purchase })) + ); + + const subscriptionIds = new Set(results.map(result => result.subscriptionId)); + expect(subscriptionIds.size).toBe(1); + expect(results.filter(result => result.alreadyProcessed)).toHaveLength(3); + + const subscriptions = await db + .select() + .from(kilo_pass_subscriptions) + .where( + and( + eq(kilo_pass_subscriptions.payment_provider, purchase.paymentProvider), + eq(kilo_pass_subscriptions.provider_subscription_id, purchase.providerSubscriptionId) + ) + ); + expect(subscriptions).toHaveLength(1); + + const storePurchases = await db + .select() + .from(kilo_pass_store_purchases) + .where( + and( + eq(kilo_pass_store_purchases.payment_provider, purchase.paymentProvider), + eq(kilo_pass_store_purchases.provider_transaction_id, purchase.providerTransactionId) + ) + ); + expect(storePurchases).toHaveLength(1); + + const issuances = await db + .select() + .from(kilo_pass_issuances) + .where(eq(kilo_pass_issuances.kilo_pass_subscription_id, results[0]?.subscriptionId ?? '')); + expect(issuances).toHaveLength(1); + + const items = await db + .select() + .from(kilo_pass_issuance_items) + .where(eq(kilo_pass_issuance_items.kilo_pass_issuance_id, issuances[0]?.id ?? '')); + expect(items).toHaveLength(1); + }); + it('rejects when the same provider transaction is replayed by another user', async () => { const firstUser = await insertTestUser(); const secondUser = await insertTestUser(); diff --git a/apps/web/src/lib/kilo-pass/store-subscription-completion.ts b/apps/web/src/lib/kilo-pass/store-subscription-completion.ts index f08a9773bf..47ae7e0d3d 100644 --- a/apps/web/src/lib/kilo-pass/store-subscription-completion.ts +++ b/apps/web/src/lib/kilo-pass/store-subscription-completion.ts @@ -68,6 +68,18 @@ function getProviderPaymentId(purchase: ValidatedStoreKiloPassPurchase): string return `kilo-pass:${purchase.paymentProvider}:${purchase.providerTransactionId}`; } +function findStorePurchaseByProviderTransaction( + tx: Parameters[0]>[0], + purchase: ValidatedStoreKiloPassPurchase +) { + return tx.query.kilo_pass_store_purchases.findFirst({ + where: and( + eq(kilo_pass_store_purchases.payment_provider, purchase.paymentProvider), + eq(kilo_pass_store_purchases.provider_transaction_id, purchase.providerTransactionId) + ), + }); +} + export async function completeStoreKiloPassPurchase(params: { user: User; purchase: ValidatedStoreKiloPassPurchase; @@ -75,12 +87,7 @@ export async function completeStoreKiloPassPurchase(params: { const { user, purchase } = params; return db.transaction(async tx => { - const existingPurchase = await tx.query.kilo_pass_store_purchases.findFirst({ - where: and( - eq(kilo_pass_store_purchases.payment_provider, purchase.paymentProvider), - eq(kilo_pass_store_purchases.provider_transaction_id, purchase.providerTransactionId) - ), - }); + const existingPurchase = await findStorePurchaseByProviderTransaction(tx, purchase); if (existingPurchase) { if (existingPurchase.kilo_user_id !== user.id) { @@ -110,68 +117,93 @@ export async function completeStoreKiloPassPurchase(params: { throw new Error('You already have an active Kilo Pass subscription'); } - const existingForProviderSubscription = await tx.query.kilo_pass_subscriptions.findFirst({ - where: and( - eq(kilo_pass_subscriptions.payment_provider, purchase.paymentProvider), - eq(kilo_pass_subscriptions.provider_subscription_id, purchase.providerSubscriptionId) - ), - }); - const nextYearlyIssueAt = getNextYearlyIssueAt({ cadence: purchase.cadence, purchasedAtIso: purchase.purchasedAtIso, }); - const subscriptionRows = existingForProviderSubscription - ? await tx - .update(kilo_pass_subscriptions) - .set({ - kilo_user_id: user.id, - tier: purchase.tier, - cadence: purchase.cadence, - status: 'active', - cancel_at_period_end: false, - ended_at: null, - next_yearly_issue_at: nextYearlyIssueAt, - }) - .where(eq(kilo_pass_subscriptions.id, existingForProviderSubscription.id)) - .returning({ id: kilo_pass_subscriptions.id }) - : await tx - .insert(kilo_pass_subscriptions) - .values({ - kilo_user_id: user.id, - payment_provider: purchase.paymentProvider, - provider_subscription_id: purchase.providerSubscriptionId, - stripe_subscription_id: null, - tier: purchase.tier, - cadence: purchase.cadence, - status: 'active', - cancel_at_period_end: false, - started_at: purchase.purchasedAtIso, - ended_at: null, - current_streak_months: 1, - next_yearly_issue_at: nextYearlyIssueAt, - }) - .returning({ id: kilo_pass_subscriptions.id }); + const subscriptionRows = await tx + .insert(kilo_pass_subscriptions) + .values({ + kilo_user_id: user.id, + payment_provider: purchase.paymentProvider, + provider_subscription_id: purchase.providerSubscriptionId, + stripe_subscription_id: null, + tier: purchase.tier, + cadence: purchase.cadence, + status: 'active', + cancel_at_period_end: false, + started_at: purchase.purchasedAtIso, + ended_at: null, + current_streak_months: 1, + next_yearly_issue_at: nextYearlyIssueAt, + }) + .onConflictDoUpdate({ + target: [ + kilo_pass_subscriptions.payment_provider, + kilo_pass_subscriptions.provider_subscription_id, + ], + targetWhere: sql`${kilo_pass_subscriptions.provider_subscription_id} IS NOT NULL`, + set: { + kilo_user_id: user.id, + tier: purchase.tier, + cadence: purchase.cadence, + status: 'active', + cancel_at_period_end: false, + ended_at: null, + next_yearly_issue_at: nextYearlyIssueAt, + }, + }) + .returning({ id: kilo_pass_subscriptions.id }); const subscriptionId = subscriptionRows[0]?.id; if (!subscriptionId) { throw new Error('Failed to persist store Kilo Pass subscription'); } - await tx.insert(kilo_pass_store_purchases).values({ - kilo_pass_subscription_id: subscriptionId, - kilo_user_id: user.id, - payment_provider: purchase.paymentProvider, - product_id: purchase.productId, - provider_subscription_id: purchase.providerSubscriptionId, - provider_transaction_id: purchase.providerTransactionId, - provider_original_transaction_id: purchase.providerOriginalTransactionId, - purchase_token: purchase.purchaseToken, - environment: purchase.environment, - purchased_at: purchase.purchasedAtIso, - raw_payload_json: purchase.rawPayload, - }); + const purchaseRows = await tx + .insert(kilo_pass_store_purchases) + .values({ + kilo_pass_subscription_id: subscriptionId, + kilo_user_id: user.id, + payment_provider: purchase.paymentProvider, + product_id: purchase.productId, + provider_subscription_id: purchase.providerSubscriptionId, + provider_transaction_id: purchase.providerTransactionId, + provider_original_transaction_id: purchase.providerOriginalTransactionId, + purchase_token: purchase.purchaseToken, + environment: purchase.environment, + purchased_at: purchase.purchasedAtIso, + raw_payload_json: purchase.rawPayload, + }) + .onConflictDoNothing({ + target: [ + kilo_pass_store_purchases.payment_provider, + kilo_pass_store_purchases.provider_transaction_id, + ], + }) + .returning({ + id: kilo_pass_store_purchases.id, + }); + + if (!purchaseRows[0]) { + const replayedPurchase = await findStorePurchaseByProviderTransaction(tx, purchase); + + if (!replayedPurchase) { + throw new Error('Failed to persist store Kilo Pass purchase'); + } + + if (replayedPurchase.kilo_user_id !== user.id) { + throw new Error('Store transaction already belongs to another user'); + } + + return { + subscriptionId: replayedPurchase.kilo_pass_subscription_id, + tier: purchase.tier, + cadence: purchase.cadence, + alreadyProcessed: true, + }; + } const issueMonth = computeIssueMonth(dayjs(purchase.purchasedAtIso)); const issuanceHeader = await createOrGetIssuanceHeader(tx, { From 96cd281f5fb551cb49d4cce6c6b2078cdcaf37da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:44:16 +0200 Subject: [PATCH 33/34] fix(web): show account on device authorization --- .../src/app/device-auth/DeviceAuthClient.tsx | 83 +++++++++++++++++-- apps/web/src/app/device-auth/page.tsx | 25 +++++- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/apps/web/src/app/device-auth/DeviceAuthClient.tsx b/apps/web/src/app/device-auth/DeviceAuthClient.tsx index 9c68a10606..86e15ff96f 100644 --- a/apps/web/src/app/device-auth/DeviceAuthClient.tsx +++ b/apps/web/src/app/device-auth/DeviceAuthClient.tsx @@ -1,18 +1,61 @@ 'use client'; import { useState } from 'react'; +import { signOut } from 'next-auth/react'; +import { z } from 'zod'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Alert, AlertDescription } from '@/components/ui/alert'; -import { CheckCircle2, XCircle, Loader2, Shield } from 'lucide-react'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; +import { CheckCircle2, XCircle, Loader2, Shield, LogOut } from 'lucide-react'; type DeviceAuthClientProps = { code: string; + user: { + name: string; + email: string; + imageUrl: string; + }; }; -export function DeviceAuthClient({ code }: DeviceAuthClientProps) { +const apiErrorSchema = z.object({ + error: z.string().optional(), +}); + +async function getApiErrorMessage(response: Response, fallback: string): Promise { + const data: unknown = await response.json().catch(() => null); + const parsed = apiErrorSchema.safeParse(data); + return parsed.success ? (parsed.data.error ?? fallback) : fallback; +} + +function getUserInitials(name: string): string { + const parts = name.trim().split(/\s+/).filter(Boolean); + if (parts.length >= 2) { + const first = parts[0]?.[0] ?? ''; + const last = parts.at(-1)?.[0] ?? ''; + return `${first}${last}`.toUpperCase(); + } + return name.slice(0, 2).toUpperCase(); +} + +export function DeviceAuthClient({ code, user }: DeviceAuthClientProps) { const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'denied' | 'error'>('idle'); const [errorMessage, setErrorMessage] = useState(''); + const [isSigningOut, setIsSigningOut] = useState(false); + + const displayName = user.name.trim() || user.email; + + const handleSignOut = async () => { + setIsSigningOut(true); + const callbackPath = `/device-auth?${new URLSearchParams({ code }).toString()}`; + const callbackUrl = `/users/sign_in?${new URLSearchParams({ callbackPath }).toString()}`; + + try { + await fetch('/api/auth/revoke-web-session', { method: 'POST' }); + } finally { + await signOut({ callbackUrl }); + } + }; const handleAuthorize = async (approved: boolean) => { setStatus('loading'); @@ -29,9 +72,8 @@ export function DeviceAuthClient({ code }: DeviceAuthClientProps) { }); if (!response.ok) { - const data = await response.json(); setStatus('error'); - setErrorMessage(data.error || 'Failed to authorize device'); + setErrorMessage(await getApiErrorMessage(response, 'Failed to authorize device')); return; } } else { @@ -41,9 +83,8 @@ export function DeviceAuthClient({ code }: DeviceAuthClientProps) { }); if (!response.ok) { - const data = await response.json(); setStatus('error'); - setErrorMessage(data.error || 'Failed to deny device'); + setErrorMessage(await getApiErrorMessage(response, 'Failed to deny device')); return; } setStatus('denied'); @@ -120,6 +161,36 @@ export function DeviceAuthClient({ code }: DeviceAuthClientProps) { +
+
+ + + {getUserInitials(displayName)} + +
+

Signed in as

+

{displayName}

+ {user.email !== displayName ? ( +

{user.email}

+ ) : null} +
+
+ +
+

This will allow the device to:

    diff --git a/apps/web/src/app/device-auth/page.tsx b/apps/web/src/app/device-auth/page.tsx index be03de42e3..89b072be9d 100644 --- a/apps/web/src/app/device-auth/page.tsx +++ b/apps/web/src/app/device-auth/page.tsx @@ -1,18 +1,26 @@ import { redirect } from 'next/navigation'; +import { z } from 'zod'; import { getUserFromAuthOrRedirect } from '@/lib/user.server'; import { DeviceAuthClient } from './DeviceAuthClient'; type PageProps = { - searchParams: Promise<{ code?: string }>; + searchParams: Promise>; }; +const deviceAuthSearchParamsSchema = z.object({ + code: z.preprocess( + value => (Array.isArray(value) ? value[0] : value), + z.string().min(1).optional() + ), +}); + export default async function DeviceAuthPage({ searchParams }: PageProps) { - const params = await searchParams; + const params = deviceAuthSearchParamsSchema.parse(await searchParams); const code = params.code; // Redirect to login if not authenticated, with callback to return here const callbackPath = `/device-auth${code ? `?code=${encodeURIComponent(code)}` : ''}`; - await getUserFromAuthOrRedirect( + const user = await getUserFromAuthOrRedirect( `/users/sign_in?callbackPath=${encodeURIComponent(callbackPath)}` ); @@ -20,5 +28,14 @@ export default async function DeviceAuthPage({ searchParams }: PageProps) { redirect('/'); } - return ; + return ( + + ); } From 9c418fa0b073a189e6275bf08ff830f3dd463aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Wed, 6 May 2026 20:52:20 +0200 Subject: [PATCH 34/34] docs: revert KiloClaw billing spec change --- .specs/kiloclaw-billing.md | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/.specs/kiloclaw-billing.md b/.specs/kiloclaw-billing.md index dd19abffca..400338a073 100644 --- a/.specs/kiloclaw-billing.md +++ b/.specs/kiloclaw-billing.md @@ -424,35 +424,6 @@ rules resolve conflicts. date six calendar months from enrollment, consistent with Commit Plan Lifecycle rule 2. -### Apple In-App Credit Purchases - -1. The system MAY allow iOS users to purchase personal credits through - Apple in-app purchases. Apple in-app purchases are a credit - acquisition mechanism only; they MUST NOT create Apple-funded - KiloClaw subscription rows. -2. Apple in-app credit purchases MUST be personal-only. They MUST NOT - credit an organization balance. -3. Apple in-app credit products MUST be server-allowlisted by product - ID. The backend MUST determine the credited amount from server - configuration, not from client-provided price or product data. -4. The backend MUST verify Apple-signed transaction data before - granting credits. A transaction with the wrong bundle ID, - environment, product ID, owning account, or revocation state MUST - NOT grant credits. -5. Each Apple transaction MUST grant credits at most once. Replays of - an already-granted transaction MUST return an idempotent success - for the owning user and MUST NOT create duplicate credit - transactions. -6. Apple refund or revocation events MUST append a negative paid credit - transaction for the full credited amount and decrement acquired - credits by the same amount. The user's computed balance MAY become - negative. -7. Apple-purchased credits MUST NOT receive first-top-up or - promotional bonus grants in the initial Apple IAP implementation. -8. User-facing purchase UI MUST describe the credits granted and MUST - NOT describe store commission, provider deductions, or internal - pricing math. - ### Kilo Pass Upsell Checkout Kilo Pass is the RECOMMENDED checkout path for KiloClaw hosting. The