pnpm-Workspace mit web/, worker/, pdf/ und packages/db. Das Datenbankpaket ist eigenständig, weil Web-App und Worker denselben Prisma-Client brauchen. Schema nach docs/04-datenmodell.md, mit drei Abweichungen, die dort begründet sind: CaseParticipant bekommt einen eigenen Schlüssel statt eines zusammengesetzten mit NULL-Spalten, die Aktenzeichen laufen über CaseCounter statt über eine Sequenz pro Jahr, und ServiceHeartbeat kommt dazu, damit /api/health den Gateway-Zustand kennt, ohne Discord zu fragen. Die zweite Migration enthält, was Prisma nicht ausdrücken kann: - kein DELETE auf CaseEntry, CaseEntryVersion und AuditLog - authorId, createdAt, caseId und type eines Eintrags sind unveränderlich - an einer Eintragsversion darf nur minClearance angehoben werden - Volltextsuche mit deutscher Konfiguration; geschwärzte Bereiche werden vor dem Indizieren entfernt, sonst verrät ein Treffer den Inhalt - pg_notify bei Rollen- und Mapping-Änderungen Acht Tests prüfen diese Regeln gegen eine echte Postgres-Instanz, nicht gegen die Anwendungslogik.
70 lines
2.5 KiB
TypeScript
70 lines
2.5 KiB
TypeScript
import { createPrismaClient } from '../src/index.js'
|
|
|
|
/**
|
|
* Grundzustand der Anwendung. Alles hier ist Konfiguration, ohne die die App
|
|
* nicht sinnvoll läuft, kein Testinhalt.
|
|
*
|
|
* Die vier Startvorlagen (Korruptionsverdacht, Dienstvergehen,
|
|
* Sicherheitsvorfall, Routineprüfung) kommen in Phase 3 dazu, zusammen mit dem
|
|
* Vorlagen-Editor. Siehe TASKS.md.
|
|
*/
|
|
const db = createPrismaClient()
|
|
|
|
/**
|
|
* Auslieferungszustand nach docs/01-produkt.md. Ab Stufe 3 ist die Existenz
|
|
* einer Akte für niedrigere Stufen verborgen, darunter nur der Inhalt gesperrt.
|
|
* Der Leiter kann das im Adminbereich ändern.
|
|
*/
|
|
const CLEARANCE_LEVELS = [
|
|
{ level: 0, name: 'Offen', hiddenBelow: false, colorToken: 'stamp-0' },
|
|
{ level: 1, name: 'Intern', hiddenBelow: false, colorToken: 'stamp-1' },
|
|
{ level: 2, name: 'Vertraulich', hiddenBelow: false, colorToken: 'stamp-2' },
|
|
{ level: 3, name: 'Geheim', hiddenBelow: true, colorToken: 'stamp-3' },
|
|
{ level: 4, name: 'Streng geheim', hiddenBelow: true, colorToken: 'stamp-4' },
|
|
{ level: 5, name: 'Leitungssache', hiddenBelow: true, colorToken: 'stamp-5' },
|
|
]
|
|
|
|
async function main(): Promise<void> {
|
|
for (const config of CLEARANCE_LEVELS) {
|
|
await db.clearanceLevelConfig.upsert({
|
|
where: { level: config.level },
|
|
create: config,
|
|
update: { name: config.name, colorToken: config.colorToken },
|
|
})
|
|
}
|
|
console.log(`[seed] ${CLEARANCE_LEVELS.length} Freigabestufen`)
|
|
|
|
// Änderungsrichtlinie im Auslieferungszustand: eigene Einträge sind 15 Minuten
|
|
// frei änderbar, danach nur mit Recht. Eine Änderung in dieser Karenzzeit wird
|
|
// versioniert und protokolliert, aber nicht sichtbar markiert.
|
|
// Siehe docs/05-akten-und-vorlagen.md.
|
|
await db.appSetting.upsert({
|
|
where: { id: 1 },
|
|
create: { id: 1 },
|
|
update: {},
|
|
})
|
|
console.log('[seed] Änderungsrichtlinie GRACE_WINDOW, 15 Minuten')
|
|
|
|
const year = new Date().getFullYear()
|
|
await db.caseCounter.upsert({
|
|
where: { year },
|
|
create: { year, lastNumber: 0 },
|
|
update: {},
|
|
})
|
|
console.log(`[seed] Aktenzeichen-Zähler für ${year}`)
|
|
|
|
// entry.edit_own, entry.edit_any und entry.retract sind bewusst keiner Rolle
|
|
// zugeordnet. Der Leiter schaltet sie frei, wenn er sie will.
|
|
// Siehe docs/03-auth-und-rechte.md.
|
|
const mappings = await db.roleMapping.count()
|
|
console.log(`[seed] ${mappings} Rollen-Zuordnungen vorhanden, keine angelegt`)
|
|
}
|
|
|
|
main()
|
|
.then(() => db.$disconnect())
|
|
.catch(async (error: unknown) => {
|
|
console.error('[seed] fehlgeschlagen', error)
|
|
await db.$disconnect()
|
|
process.exit(1)
|
|
})
|