Fix: Add unique constraint for policy_settings upsert
All checks were successful
Trigger Cloudarix Deploy / call-webhook (push) Successful in 1s

This commit is contained in:
Ahmed Darrazi 2025-12-06 23:33:43 +01:00
parent bd7758191e
commit 8b36902767
5 changed files with 506 additions and 2 deletions

43
fix-constraint.ts Normal file
View File

@ -0,0 +1,43 @@
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import { sql } from 'drizzle-orm';
async function fixConstraint() {
const dbUrl = process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/tenantpilot';
console.log('🔌 Connecting to:', dbUrl.replace(/:[^:@]+@/, ':****@'));
const pool = new Pool({ connectionString: dbUrl });
const db = drizzle(pool);
try {
console.log('⏳ Removing duplicate rows...');
await db.execute(sql`
DELETE FROM policy_settings a
USING policy_settings b
WHERE a.id > b.id
AND a.tenant_id = b.tenant_id
AND a.graph_policy_id = b.graph_policy_id
AND a.setting_name = b.setting_name
`);
console.log('⏳ Dropping old index...');
await db.execute(sql`DROP INDEX IF EXISTS policy_settings_upsert_idx`);
console.log('⏳ Adding unique constraint...');
await db.execute(sql`
ALTER TABLE policy_settings
ADD CONSTRAINT policy_settings_upsert_unique
UNIQUE(tenant_id, graph_policy_id, setting_name)
`);
console.log('✅ Constraint added successfully!');
await pool.end();
process.exit(0);
} catch (error) {
console.error('❌ Failed:', error);
await pool.end();
process.exit(1);
}
}
fixConstraint();

View File

@ -0,0 +1,3 @@
DROP INDEX "policy_settings_upsert_idx";--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "tenant_id" text;--> statement-breakpoint
ALTER TABLE "policy_settings" ADD CONSTRAINT "policy_settings_upsert_unique" UNIQUE("tenant_id","graph_policy_id","setting_name");

View File

@ -0,0 +1,450 @@
{
"id": "65f6746a-011c-4712-97db-c41f4b3e6547",
"prevId": "7bea20d0-987b-4a12-8446-a5966f2eb3e8",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.account": {
"name": "account",
"schema": "",
"columns": {
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"provider": {
"name": "provider",
"type": "text",
"primaryKey": false,
"notNull": true
},
"providerAccountId": {
"name": "providerAccountId",
"type": "text",
"primaryKey": false,
"notNull": true
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"token_type": {
"name": "token_type",
"type": "text",
"primaryKey": false,
"notNull": false
},
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
"notNull": false
},
"id_token": {
"name": "id_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"session_state": {
"name": "session_state",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"account_userId_user_id_fk": {
"name": "account_userId_user_id_fk",
"tableFrom": "account",
"tableTo": "user",
"columnsFrom": [
"userId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"account_provider_providerAccountId_pk": {
"name": "account_provider_providerAccountId_pk",
"columns": [
"provider",
"providerAccountId"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.session": {
"name": "session",
"schema": "",
"columns": {
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires": {
"name": "expires",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"session_userId_user_id_fk": {
"name": "session_userId_user_id_fk",
"tableFrom": "session",
"tableTo": "user",
"columnsFrom": [
"userId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"emailVerified": {
"name": "emailVerified",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"image": {
"name": "image",
"type": "text",
"primaryKey": false,
"notNull": false
},
"tenant_id": {
"name": "tenant_id",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.verificationToken": {
"name": "verificationToken",
"schema": "",
"columns": {
"identifier": {
"name": "identifier",
"type": "text",
"primaryKey": false,
"notNull": true
},
"token": {
"name": "token",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires": {
"name": "expires",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"verificationToken_identifier_token_pk": {
"name": "verificationToken_identifier_token_pk",
"columns": [
"identifier",
"token"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.policy_settings": {
"name": "policy_settings",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"tenant_id": {
"name": "tenant_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"policy_name": {
"name": "policy_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"policy_type": {
"name": "policy_type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"setting_name": {
"name": "setting_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"setting_value": {
"name": "setting_value",
"type": "text",
"primaryKey": false,
"notNull": true
},
"graph_policy_id": {
"name": "graph_policy_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"last_synced_at": {
"name": "last_synced_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"policy_settings_tenant_id_idx": {
"name": "policy_settings_tenant_id_idx",
"columns": [
{
"expression": "tenant_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"policy_settings_setting_name_idx": {
"name": "policy_settings_setting_name_idx",
"columns": [
{
"expression": "setting_name",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"policy_settings_upsert_unique": {
"name": "policy_settings_upsert_unique",
"nullsNotDistinct": false,
"columns": [
"tenant_id",
"graph_policy_id",
"setting_name"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.subscriptions": {
"name": "subscriptions",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"stripe_customer_id": {
"name": "stripe_customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"stripe_subscription_id": {
"name": "stripe_subscription_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"stripe_price_id": {
"name": "stripe_price_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"stripe_current_period_end": {
"name": "stripe_current_period_end",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"subscriptions_user_id_user_id_fk": {
"name": "subscriptions_user_id_user_id_fk",
"tableFrom": "subscriptions",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"subscriptions_user_id_stripe_customer_id_pk": {
"name": "subscriptions_user_id_stripe_customer_id_pk",
"columns": [
"user_id",
"stripe_customer_id"
]
}
},
"uniqueConstraints": {
"subscriptions_user_id_unique": {
"name": "subscriptions_user_id_unique",
"nullsNotDistinct": false,
"columns": [
"user_id"
]
},
"subscriptions_stripe_customer_id_unique": {
"name": "subscriptions_stripe_customer_id_unique",
"nullsNotDistinct": false,
"columns": [
"stripe_customer_id"
]
},
"subscriptions_stripe_subscription_id_unique": {
"name": "subscriptions_stripe_subscription_id_unique",
"nullsNotDistinct": false,
"columns": [
"stripe_subscription_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@ -8,6 +8,13 @@
"when": 1764967548076,
"tag": "0000_tiny_skin",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1765060303141,
"tag": "0001_reflective_dormammu",
"breakpoints": true
}
]
}

View File

@ -1,4 +1,4 @@
import { pgTable, text, timestamp, index } from 'drizzle-orm/pg-core';
import { pgTable, text, timestamp, index, unique } from 'drizzle-orm/pg-core';
import { createId } from '@paralleldrive/cuid2';
export const POLICY_TYPES = [
@ -43,7 +43,8 @@ export const policySettings = pgTable(
settingNameIdx: index('policy_settings_setting_name_idx').on(
table.settingName
),
upsertIdx: index('policy_settings_upsert_idx').on(
// Unique constraint for ON CONFLICT upsert
upsertUnique: unique('policy_settings_upsert_unique').on(
table.tenantId,
table.graphPolicyId,
table.settingName