Vertrag: „Portaldaten nicht möglich / nicht benötigt"-Opt-out
Dritter Radio-Button in der Zugangsdaten-Card des Vertragsformulars. Wenn gesetzt, unterdrückt das Cockpit die Warnung „Portal-Zugangs- daten fehlen" für diesen Vertrag – für Anbieter ohne Portal oder Kunden, die bewusst keine Zugangsdaten pflegen. Verstopft das Cockpit sonst dauerhaft. Neues Feld Contract.portalCredentialsNotRequired (Boolean, default false) + idempotente Migration (ADD COLUMN IF NOT EXISTS). Bestand bleibt auf false, Warnung greift wie bisher. Beim Umschalten auf Opt-out werden portalUsername, portalPasswordEncrypted und stressfreiEmailId server-seitig explizit auf NULL gesetzt – Datenhygiene, damit keine verwaisten Anmeldedaten in der DB stehen bleiben. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
-- Vertrag: „Portaldaten nicht möglich / nicht benötigt"-Marker.
|
||||
-- Wenn gesetzt, unterdrückt das Cockpit die Warnung „Portal-Zugangsdaten
|
||||
-- fehlen" für diesen Vertrag (Anbieter ohne Portal / Kunde bekommt keine
|
||||
-- Zugangsdaten). Bestehende Verträge bleiben auf FALSE, damit die
|
||||
-- Warnung wie bisher greift.
|
||||
|
||||
ALTER TABLE `Contract`
|
||||
ADD COLUMN IF NOT EXISTS `portalCredentialsNotRequired` BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
@@ -765,6 +765,11 @@ model Contract {
|
||||
stressfreiEmailId Int?
|
||||
stressfreiEmail StressfreiEmail? @relation(fields: [stressfreiEmailId], references: [id])
|
||||
|
||||
// Portaldaten bewusst nicht hinterlegt (Anbieter hat kein Portal oder
|
||||
// Kunde bekommt keine Zugangsdaten). Wenn true, unterdrückt das Cockpit
|
||||
// die „Portal-Zugangsdaten fehlen"-Warnung für diesen Vertrag.
|
||||
portalCredentialsNotRequired Boolean @default(false)
|
||||
|
||||
// Snooze: Vertrag zurückstellen bis Datum (für Cockpit)
|
||||
nextReviewDate DateTime? // Erneute Prüfung am
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@ interface ContractCreateData {
|
||||
portalUsername?: string;
|
||||
portalPassword?: string;
|
||||
stressfreiEmailId?: number;
|
||||
portalCredentialsNotRequired?: boolean;
|
||||
notes?: string;
|
||||
// Kündigungsdaten
|
||||
cancellationConfirmationDate?: Date;
|
||||
@@ -461,12 +462,26 @@ export async function updateContract(
|
||||
? encrypt(portalPassword)
|
||||
: undefined;
|
||||
|
||||
// Opt-out „Portaldaten nicht benötigt": Alte Anmeldedaten explizit
|
||||
// wegräumen, damit nach dem Umschalten kein verwaister verschlüsselter
|
||||
// Blob + Username in der DB stehen bleibt. Nur greifen, wenn das Flag
|
||||
// in diesem Update wirklich auf true gesetzt wird (nicht bei jedem PUT).
|
||||
const clearCredentials = contractData.portalCredentialsNotRequired === true;
|
||||
|
||||
// Update main contract
|
||||
await prisma.contract.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...contractData,
|
||||
...(portalPasswordEncrypted ? { portalPasswordEncrypted } : {}),
|
||||
...(clearCredentials
|
||||
? {
|
||||
portalUsername: null,
|
||||
portalPasswordEncrypted: null,
|
||||
stressfreiEmailId: null,
|
||||
}
|
||||
: portalPasswordEncrypted
|
||||
? { portalPasswordEncrypted }
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -443,18 +443,24 @@ export async function getCockpitData(opts?: { customerIds?: number[] }): Promise
|
||||
}
|
||||
|
||||
// 3. FEHLENDE PORTAL-ZUGANGSDATEN
|
||||
// Benutzername kann entweder manuell (portalUsername) oder via Stressfrei-Wechseln E-Mail (stressfreiEmailId) gesetzt sein
|
||||
const hasUsername = contract.portalUsername || contract.stressfreiEmailId;
|
||||
const hasPassword = contract.portalPasswordEncrypted;
|
||||
// Benutzername kann entweder manuell (portalUsername) oder via Stressfrei-Wechseln E-Mail (stressfreiEmailId) gesetzt sein.
|
||||
// Vertragsseitiges Opt-out: wenn der Anbieter kein Portal hat oder der
|
||||
// Kunde bewusst keine Zugangsdaten pflegt, unterdrückt
|
||||
// `portalCredentialsNotRequired` die Warnung. So verstopft die Zeile
|
||||
// nicht dauerhaft das Cockpit.
|
||||
if (!contract.portalCredentialsNotRequired) {
|
||||
const hasUsername = contract.portalUsername || contract.stressfreiEmailId;
|
||||
const hasPassword = contract.portalPasswordEncrypted;
|
||||
|
||||
if (!hasUsername || !hasPassword) {
|
||||
issues.push({
|
||||
type: 'missing_portal_credentials',
|
||||
label: 'Portal-Zugangsdaten fehlen',
|
||||
urgency: 'warning',
|
||||
details: 'Benutzername oder Passwort für das Anbieter-Portal fehlt',
|
||||
});
|
||||
summary.byCategory.missingCredentials++;
|
||||
if (!hasUsername || !hasPassword) {
|
||||
issues.push({
|
||||
type: 'missing_portal_credentials',
|
||||
label: 'Portal-Zugangsdaten fehlen',
|
||||
urgency: 'warning',
|
||||
details: 'Benutzername oder Passwort für das Anbieter-Portal fehlt',
|
||||
});
|
||||
summary.byCategory.missingCredentials++;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. KEINE KUNDENNUMMER BEIM ANBIETER
|
||||
|
||||
Reference in New Issue
Block a user