CLI-Skripte: DATABASE_URL wieder aufbaubar machen

Die drei neuen Wartungsskripte bauten sich einen eigenen PrismaClient und
gingen damit an src/lib/prisma.ts vorbei. Dort wird DATABASE_URL aus den
DB_*-Teilen zusammengesetzt, falls sie fehlt - und genau das ist bei
`docker compose exec <dienst> npx tsx prisma/<skript>.ts` der Fall: Der
Entrypoint exportiert sie nur in den Serverprozess, eine neue Shell erbt
sie nicht. Ergebnis war "Environment variable not found: DATABASE_URL".

Der Kommentar in src/lib/prisma.ts beschreibt genau diesen Fall; die
Loesung war da, ich habe sie nur umgangen.

Betroffen war auch rolle-zuweisen.ts. Das ist der Weg, den die Startwache
im Klartext nennt, wenn kein Konto mehr die Pflichtrechte haelt - er
haette in dem Moment versagt, fuer den er gebaut ist.

Geprueft mit entzogener DATABASE_URL und nur DB_*-Teilen in der
Umgebung: rechte-report, rolle-zuweisen --liste und sync-roles laufen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-08 14:23:58 +02:00
co-authored by Claude Opus 5
parent 77aeb69aeb
commit 9f879759d8
4 changed files with 29 additions and 6 deletions
+7 -2
View File
@@ -12,10 +12,15 @@
* etwas Lesbares ausgibt. * etwas Lesbares ausgibt.
*/ */
import { PrismaClient } from '@prisma/client'; // Ueber src/lib/prisma.js, NICHT ueber einen eigenen PrismaClient: Dort wird
// DATABASE_URL aus den DB_*-Teilen zusammengesetzt, falls sie fehlt. Bei
// `docker compose exec <dienst> npx tsx prisma/<skript>.ts` ist genau das der
// Fall - der Entrypoint exportiert sie nur in den Serverprozess, eine neue
// Shell erbt sie nicht. Ein eigener Client scheitert dort mit
// "Environment variable not found: DATABASE_URL".
import prisma from '../src/lib/prisma.js';
import { ALLE_RECHTE, SYSTEMROLLEN_NAMEN } from '../src/config/rechte-katalog.js'; import { ALLE_RECHTE, SYSTEMROLLEN_NAMEN } from '../src/config/rechte-katalog.js';
const prisma = new PrismaClient();
/** /**
* Liest isSystem/isHidden, sofern die Spalten existieren. * Liest isSystem/isHidden, sofern die Spalten existieren.
+7 -2
View File
@@ -25,10 +25,15 @@
* Aenderung sofort wirkt und nicht spurlos bleibt. * Aenderung sofort wirkt und nicht spurlos bleibt.
*/ */
import { PrismaClient } from '@prisma/client'; // Ueber src/lib/prisma.js, NICHT ueber einen eigenen PrismaClient: Dort wird
// DATABASE_URL aus den DB_*-Teilen zusammengesetzt, falls sie fehlt. Bei
// `docker compose exec <dienst> npx tsx prisma/<skript>.ts` ist genau das der
// Fall - der Entrypoint exportiert sie nur in den Serverprozess, eine neue
// Shell erbt sie nicht. Ein eigener Client scheitert dort mit
// "Environment variable not found: DATABASE_URL".
import prisma from '../src/lib/prisma.js';
import { createAuditLog } from '../src/services/audit.service.js'; import { createAuditLog } from '../src/services/audit.service.js';
const prisma = new PrismaClient();
async function main(): Promise<void> { async function main(): Promise<void> {
const args = process.argv.slice(2); const args = process.argv.slice(2);
+7 -2
View File
@@ -14,10 +14,15 @@
* Produktionsdatenbanken sicher. * Produktionsdatenbanken sicher.
*/ */
import { PrismaClient } from '@prisma/client'; // Ueber src/lib/prisma.js, NICHT ueber einen eigenen PrismaClient: Dort wird
// DATABASE_URL aus den DB_*-Teilen zusammengesetzt, falls sie fehlt. Bei
// `docker compose exec <dienst> npx tsx prisma/<skript>.ts` ist genau das der
// Fall - der Entrypoint exportiert sie nur in den Serverprozess, eine neue
// Shell erbt sie nicht. Ein eigener Client scheitert dort mit
// "Environment variable not found: DATABASE_URL".
import prisma from '../src/lib/prisma.js';
import { synchronisiereRechteUndRollen } from '../src/services/rollen-sync.service.js'; import { synchronisiereRechteUndRollen } from '../src/services/rollen-sync.service.js';
const prisma = new PrismaClient();
synchronisiereRechteUndRollen(prisma) synchronisiereRechteUndRollen(prisma)
.catch((e) => { .catch((e) => {
+8
View File
@@ -165,6 +165,14 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
noch in der Datenbank und bewachen nichts. Nicht gelöscht, sondern am noch in der Datenbank und bewachen nichts. Nicht gelöscht, sondern am
Lesezugriff gefiltert ein Filter ist die kleinere Behauptung als ein Lesezugriff gefiltert ein Filter ist die kleinere Behauptung als ein
DELETE. DELETE.
- **Nachtrag (Staging-Deploy)**: Die drei CLI-Skripte bauten sich einen
eigenen `PrismaClient` und gingen damit an `src/lib/prisma.ts` vorbei dort
wird `DATABASE_URL` aus den `DB_*`-Teilen zusammengesetzt, wenn sie fehlt.
Genau das ist bei `docker compose exec` der Fall: Der Entrypoint exportiert
sie nur in den Serverprozess. Folge: „Environment variable not found".
Betroffen war auch `rolle-zuweisen.ts` der Aussperr-Ausweg hätte in dem
Moment versagt, für den er gebaut ist. Jetzt nutzen alle drei den
gemeinsamen Client.
- **Beim Deploy**: Die Migration beendet alle Sitzungen einmalig - **Beim Deploy**: Die Migration beendet alle Sitzungen einmalig
(`tokenInvalidatedAt`). Nötig, weil die Rechte im Token stehen sonst (`tokenInvalidatedAt`). Nötig, weil die Rechte im Token stehen sonst
liefen bis zu 15 Minuten 403er. Alle müssen sich einmal neu anmelden. liefen bis zu 15 Minuten 403er. Alle müssen sich einmal neu anmelden.