Files
FEDEO/backend/scripts/dedupe-auth-tenant-users.ts
flfeders 37d08ee984
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 37s
Build and Push Docker Images / build-frontend (push) Successful in 1m18s
Build and Push Docker Images / build-website (push) Successful in 17s
Build and Push Docker Images / build-docs (push) Successful in 16s
Prevent duplicate tenant memberships on import
2026-07-20 19:06:01 +02:00

68 lines
1.9 KiB
TypeScript

import "dotenv/config"
import { drizzle } from "drizzle-orm/node-postgres"
import { sql } from "drizzle-orm"
import { Pool } from "pg"
import { loadSecrets, secrets } from "../src/utils/secrets"
async function run() {
let connectionString = process.env.DATABASE_URL
if (!connectionString) {
await loadSecrets()
connectionString = secrets.DATABASE_URL
}
if (!connectionString) {
throw new Error("DATABASE_URL not configured")
}
const pool = new Pool({
connectionString,
max: 1,
connectionTimeoutMillis: 10000,
})
try {
const db = drizzle(pool)
const duplicates = await db.execute(sql`
SELECT tenant_id, user_id, count(*)::int AS count
FROM auth_tenant_users
GROUP BY tenant_id, user_id
HAVING count(*) > 1
ORDER BY count(*) DESC;
`)
console.log(`Gefundene doppelte Tenant-Zuordnungen: ${duplicates.rows.length}`)
for (const row of duplicates.rows as Record<string, any>[]) {
console.log(JSON.stringify(row))
}
const deleted = await db.execute(sql`
DELETE FROM auth_tenant_users duplicate
USING auth_tenant_users keep
WHERE duplicate.tenant_id = keep.tenant_id
AND duplicate.user_id = keep.user_id
AND duplicate.ctid > keep.ctid;
`)
console.log(`Entfernte doppelte Zeilen: ${deleted.rowCount || 0}`)
await db.execute(sql`
CREATE UNIQUE INDEX IF NOT EXISTS auth_tenant_users_tenant_user_unique
ON auth_tenant_users (tenant_id, user_id);
`)
console.log("Unique Index auth_tenant_users_tenant_user_unique ist vorhanden")
} finally {
await pool.end()
}
}
run().catch((err) => {
console.error("Dedupe auth_tenant_users failed")
console.error(err)
process.exit(1)
})