Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/scripts/dev-provision-rls-roles.mjs
T

49 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
// Local-only convenience wrapper around scripts/provision-rls-roles.mjs.
//
// The app-wide RLS cutover migration GRANTs to hivegrid_app / hivegrid_worker /
// hivegrid_rls_definer, so those roles must exist before `prisma migrate deploy`
// touches an empty database — otherwise migration 20260713190000 fails halfway
// and leaves the database in a failed-migration state (P3009).
//
// The managed role passwords are external deployment secrets and therefore have
// no place in .env.example or the config catalog. Locally they are irrelevant:
// dev runs with RLS_RUNTIME_MODE=off and the app connects as the DATABASE_URL
// owner, never as one of these roles. So we mint throwaway random passwords here
// instead of committing any value. Staging and production keep using
// `pnpm run db:roles:provision` with real, externally managed secrets.
import { randomBytes } from "node:crypto";
import { provisionRlsRoles, ROLE_PASSWORD_ENV } from "./provision-rls-roles.mjs";
if (process.env.NODE_ENV === "production") {
process.stderr.write("FAIL dev:db:roles is a local helper; use db:roles:provision with managed secrets instead\n");
process.exit(1);
}
const connectionString = process.env.HIVEGRID_RLS_PROVISION_DATABASE_URL ?? process.env.DIRECT_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
process.stderr.write("FAIL no DATABASE_URL (or DIRECT_URL) found — copy .env.example to .env first\n");
process.exit(1);
}
const env = {
...process.env,
HIVEGRID_RLS_PROVISION_DATABASE_URL: connectionString,
};
for (const passwordEnvName of Object.values(ROLE_PASSWORD_ENV)) {
// 48 hex chars, comfortably above the provisioner's 32-character floor and
// distinct per role (it rejects duplicates).
env[passwordEnvName] = randomBytes(24).toString("hex");
}
try {
await provisionRlsRoles({ env });
process.stdout.write("PASS local RLS roles provisioned (throwaway passwords, not persisted)\n");
} catch (error) {
const message = error instanceof Error ? error.message : "role provisioning failed";
process.stderr.write(`FAIL ${message}\n`);
process.exit(1);
}