Analyse: Zielgruppen-Bestätigung in Historie, Rücknahme bei Fehler nach Dokument-Update, handelnde Person mit Name und E-Mail
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d05472b25
commit
f401dc14d7
7 files changed
+108
-56
No files matched your search
+46
-30
@@ -102,6 +102,9 @@ export async function controllerView(customerId) {
|
||||
return { company, address, email, ok, missing }
|
||||
}
|
||||
|
||||
/** "Name <E-Mail>" (oder was davon da ist), max. 100 Zeichen */
|
||||
const personLabel = (p) => (p?.name && p?.email ? `${p.name} <${p.email}>` : p?.name || p?.email || '').slice(0, 100)
|
||||
|
||||
const berlinToday = (now) => new Intl.DateTimeFormat('sv-SE', { timeZone: 'Europe/Berlin' }).format(now)
|
||||
|
||||
/**
|
||||
@@ -168,7 +171,7 @@ function privacyTicket(customerId, project, siteKey) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function activateAnalyse({ customerId, projectId, accentColor, consent, by = 'customer', actor, textform, now = new Date() }) {
|
||||
export async function activateAnalyse({ customerId, projectId, accentColor, consent, by = 'customer', actor, textform, audienceConfirmed, now = new Date() }) {
|
||||
const viaCustomer = by === 'customer'
|
||||
let accepted
|
||||
let proof = { date: '', channel: '' }
|
||||
@@ -176,9 +179,11 @@ export async function activateAnalyse({ customerId, projectId, accentColor, cons
|
||||
if (!consent || consent.accepted !== true || consent.avvVersion !== config.analyse.avvVersion) {
|
||||
throw httpError(400, 'Bitte den Auftragsverarbeitungsvertrag bestätigen')
|
||||
}
|
||||
accepted = String(actor?.name || actor?.email || '').slice(0, 100)
|
||||
// Name und E-Mail der handelnden Person (bei Admin-Sitzung der Admin, siehe Route)
|
||||
accepted = personLabel(actor)
|
||||
if (!accepted) throw httpError(400, 'Bitte melde Dich neu an')
|
||||
} else {
|
||||
if (audienceConfirmed !== true) throw httpError(400, 'Bitte bestätigen, dass die Website sich nicht gezielt an Kinder unter 16 Jahren richtet')
|
||||
const t = validateTextform(textform, { today: berlinToday(now) })
|
||||
proof = { date: t.date, channel: t.channel }
|
||||
accepted = String(by).slice(0, 100)
|
||||
@@ -206,42 +211,53 @@ export async function activateAnalyse({ customerId, projectId, accentColor, cons
|
||||
// Erst beim Sammeldienst anmelden: schlaegt das fehl, bleibt das Dokument unveraendert (erneut versuchbar)
|
||||
await analyseDeps.client.putSite(siteKey, { projectId, domains: analyseDomains(project), active: true })
|
||||
const at = now.toISOString()
|
||||
const entry = {
|
||||
customerId,
|
||||
projectId,
|
||||
siteKey,
|
||||
event: 'on',
|
||||
avvVersion: config.analyse.avvVersion,
|
||||
via: viaCustomer ? 'portal' : 'woms',
|
||||
acceptedAt: at,
|
||||
acceptedBy: accepted,
|
||||
textformDate: proof.date,
|
||||
textformChannel: proof.channel,
|
||||
audienceConfirmed: true, // Kunden-Haken enthaelt die Zielgruppen-Aussage; Mitarbeiter bestaetigen sie getrennt
|
||||
audienceTextVersion: config.analyse.avvVersion,
|
||||
}
|
||||
let updated = false
|
||||
try {
|
||||
await analyseDeps.recordConsent({
|
||||
customerId,
|
||||
projectId,
|
||||
doc = await updateDocument(config.collections.portalFeatures, existing.$id, {
|
||||
...stateFields('active'),
|
||||
siteKey,
|
||||
event: 'on',
|
||||
avvVersion: config.analyse.avvVersion,
|
||||
via: viaCustomer ? 'portal' : 'woms',
|
||||
acceptedAt: at,
|
||||
acceptedBy: accepted,
|
||||
textformDate: proof.date,
|
||||
textformChannel: proof.channel,
|
||||
accentColor: color,
|
||||
avvVersion: entry.avvVersion,
|
||||
avvAcceptedAt: at,
|
||||
avvAcceptedBy: accepted,
|
||||
avvConsentDate: proof.date,
|
||||
avvConsentChannel: proof.channel,
|
||||
audienceConfirmed: true,
|
||||
audienceTextVersion: entry.audienceTextVersion,
|
||||
activatedAt: at,
|
||||
offSince: '',
|
||||
activatedMailAt: '', // jede neue Aktivierung bekommt ihre K18
|
||||
privacyTicketId: '', // und ihre Tickets
|
||||
removalTicketId: '',
|
||||
publishTicketId: '',
|
||||
})
|
||||
updated = true
|
||||
// Nachweis erst nach dem Dokument: scheitert er, wird alles zurueckgenommen (kein "on" ohne aktives Dokument)
|
||||
await analyseDeps.recordConsent(entry)
|
||||
} catch (err) {
|
||||
// Ohne Nachweis keine Aktivierung: Messdienst zuruecknehmen
|
||||
await analyseDeps.client
|
||||
.putSite(siteKey, { projectId, domains: analyseDomains(project), active: false })
|
||||
.catch((e) => console.warn(`[analyse] Rücknahme für Projekt ${projectId} fehlgeschlagen:`, e.message))
|
||||
if (updated) {
|
||||
await updateDocument(config.collections.portalFeatures, existing.$id, { ...stateFields(existing.state || 'off'), offSince: existing.offSince || '' })
|
||||
.catch((e) => console.warn(`[analyse] Zurücksetzen für Projekt ${projectId} fehlgeschlagen:`, e.message))
|
||||
}
|
||||
throw err
|
||||
}
|
||||
doc = await updateDocument(config.collections.portalFeatures, existing.$id, {
|
||||
...stateFields('active'),
|
||||
siteKey,
|
||||
accentColor: color,
|
||||
avvVersion: config.analyse.avvVersion,
|
||||
avvAcceptedAt: at,
|
||||
avvAcceptedBy: accepted,
|
||||
avvConsentDate: proof.date,
|
||||
avvConsentChannel: proof.channel,
|
||||
activatedAt: at,
|
||||
offSince: '',
|
||||
activatedMailAt: '', // jede neue Aktivierung bekommt ihre K18
|
||||
privacyTicketId: '', // und ihre Tickets
|
||||
removalTicketId: '',
|
||||
publishTicketId: '',
|
||||
})
|
||||
changed = true
|
||||
} else if (existing.accentColor !== color) {
|
||||
doc = await updateDocument(config.collections.portalFeatures, existing.$id, { accentColor: color })
|
||||
@@ -288,7 +304,7 @@ export async function deactivateAnalyse({ customerId, projectId, now = new Date(
|
||||
avvVersion: config.analyse.avvVersion,
|
||||
via: by === 'customer' || by === 'system' ? 'portal' : 'woms',
|
||||
acceptedAt: now.toISOString(),
|
||||
acceptedBy: String((by === 'customer' && (actor?.name || actor?.email)) || by).slice(0, 100),
|
||||
acceptedBy: (by === 'customer' && personLabel(actor)) || String(by).slice(0, 100),
|
||||
textformDate: '',
|
||||
textformChannel: '',
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user