feat: Werkzeugkatalog nennt tatsächliche Verarbeitungsländer statt EU/USA/gemischt-Eimer, plus DPF-Feld
Die USA sind DSGVO-rechtlich bereits ein Drittland wie jedes andere - der alte verarbeitungsort-Wertebereich (EU/USA/gemischt/on-prem) verschleierte das. Ersetzt durch verarbeitungslaender TEXT[] mit echter Weltländerliste im Formular (Mehrfachauswahl, kein JS nötig). Der harte Filter eu_verarbeitung verlangt jetzt, dass ALLE genannten Länder EU/EWR sind. Neues Feld dpf_zertifiziert macht die EU-US Data Privacy Framework-Zertifizierung strukturiert statt nur Fließtext. Öffnet nebenbei den Weg für Katalogeinträge außerhalb EU/USA (z. B. DeepSeek), die vorher am alten Wertebereich scheiterten. Zusätzlich Typografie-Nachbesserung nach Nutzer-Feedback: Formular- Abschnittsüberschriften (<legend>) saßen zu dicht am Kartenrand, weil <legend> das Padding des umschließenden <fieldset> ignoriert - jetzt mit eigenem Padding und größerer Schrift, h2/h3 einheitlich gesetzt.
This commit is contained in:
@@ -16,15 +16,27 @@ import (
|
||||
// LetztePruefung und Quelle sind Pflicht — jede Zusicherung im Katalog
|
||||
// muss belegbar sein.
|
||||
type Werkzeug struct {
|
||||
ID string
|
||||
AccountID *string
|
||||
Name string
|
||||
Anbieter string
|
||||
Verarbeitungsort string
|
||||
AVVVerfuegbar bool
|
||||
AVVURL string
|
||||
TrainingOptOut bool
|
||||
TrainingStandard bool
|
||||
ID string
|
||||
AccountID *string
|
||||
Name string
|
||||
Anbieter string
|
||||
// Verarbeitungslaender nennt die tatsächlichen Länder (oder, wenn
|
||||
// der Anbieter selbst keinen einzelnen Staat zusichert, eine Region
|
||||
// wie "EU-Region") statt eines groben EU/USA/gemischt-Eimers — die
|
||||
// USA sind DSGVO-rechtlich bereits ein Drittland wie jedes andere,
|
||||
// "gemischt" verschleierte, welche Länder konkret beteiligt sind.
|
||||
Verarbeitungslaender []string
|
||||
AVVVerfuegbar bool
|
||||
AVVURL string
|
||||
TrainingOptOut bool
|
||||
TrainingStandard bool
|
||||
// DPFZertifiziert: EU-US Data Privacy Framework — schmalere,
|
||||
// gerichtlich schon zweimal gekippte Rechtsgrundlage (Safe Harbor,
|
||||
// Privacy Shield) für Transfers in die USA, gilt nur für zertifizierte
|
||||
// Unternehmen. false bedeutet nicht "nicht zertifiziert" im Sinne von
|
||||
// widerlegt, sondern "nicht als Zusicherung belegt" — wie bei den
|
||||
// übrigen Booleans hier.
|
||||
DPFZertifiziert bool
|
||||
AufbewahrungTage *int // nil = vom Anbieter nicht beziffert, NICHT gleichbedeutend mit 0 Tagen
|
||||
Zertifizierungen []string
|
||||
Subprozessoren []string
|
||||
@@ -40,25 +52,26 @@ type Werkzeug struct {
|
||||
// Create/Update — bei 15 Feldern lesbarer als eine positionale
|
||||
// Parameterliste.
|
||||
type WerkzeugInput struct {
|
||||
AccountID *string
|
||||
Name string
|
||||
Anbieter string
|
||||
Verarbeitungsort string
|
||||
AVVVerfuegbar bool
|
||||
AVVURL string
|
||||
TrainingOptOut bool
|
||||
TrainingStandard bool
|
||||
AufbewahrungTage *int
|
||||
Zertifizierungen []string
|
||||
Subprozessoren []string
|
||||
GeeigneteZwecke []string
|
||||
Einschraenkungen []string
|
||||
LetztePruefung time.Time
|
||||
Quelle string
|
||||
AccountID *string
|
||||
Name string
|
||||
Anbieter string
|
||||
Verarbeitungslaender []string
|
||||
AVVVerfuegbar bool
|
||||
AVVURL string
|
||||
TrainingOptOut bool
|
||||
TrainingStandard bool
|
||||
DPFZertifiziert bool
|
||||
AufbewahrungTage *int
|
||||
Zertifizierungen []string
|
||||
Subprozessoren []string
|
||||
GeeigneteZwecke []string
|
||||
Einschraenkungen []string
|
||||
LetztePruefung time.Time
|
||||
Quelle string
|
||||
}
|
||||
|
||||
const werkzeugColumns = `id, account_id, name, anbieter, verarbeitungsort, avv_verfuegbar, avv_url,
|
||||
training_opt_out, training_standard, aufbewahrung_tage, zertifizierungen, subprozessoren,
|
||||
const werkzeugColumns = `id, account_id, name, anbieter, verarbeitungslaender, avv_verfuegbar, avv_url,
|
||||
training_opt_out, training_standard, dpf_zertifiziert, aufbewahrung_tage, zertifizierungen, subprozessoren,
|
||||
geeignete_zwecke, einschraenkungen, letzte_pruefung, quelle, created_at, updated_at`
|
||||
|
||||
func scanWerkzeug(row interface {
|
||||
@@ -66,8 +79,8 @@ func scanWerkzeug(row interface {
|
||||
}) (Werkzeug, error) {
|
||||
var w Werkzeug
|
||||
err := row.Scan(
|
||||
&w.ID, &w.AccountID, &w.Name, &w.Anbieter, &w.Verarbeitungsort, &w.AVVVerfuegbar, &w.AVVURL,
|
||||
&w.TrainingOptOut, &w.TrainingStandard, &w.AufbewahrungTage, &w.Zertifizierungen, &w.Subprozessoren,
|
||||
&w.ID, &w.AccountID, &w.Name, &w.Anbieter, &w.Verarbeitungslaender, &w.AVVVerfuegbar, &w.AVVURL,
|
||||
&w.TrainingOptOut, &w.TrainingStandard, &w.DPFZertifiziert, &w.AufbewahrungTage, &w.Zertifizierungen, &w.Subprozessoren,
|
||||
&w.GeeigneteZwecke, &w.Einschraenkungen, &w.LetztePruefung, &w.Quelle, &w.CreatedAt, &w.UpdatedAt,
|
||||
)
|
||||
return w, err
|
||||
@@ -79,6 +92,9 @@ func scanWerkzeug(row interface {
|
||||
// einer wenig hilfreichen Constraint-Fehlermeldung abgelehnt (derselbe
|
||||
// Fall wie früher bei finding.sources).
|
||||
func normalizeWerkzeugSlices(in *WerkzeugInput) {
|
||||
if in.Verarbeitungslaender == nil {
|
||||
in.Verarbeitungslaender = []string{}
|
||||
}
|
||||
if in.Zertifizierungen == nil {
|
||||
in.Zertifizierungen = []string{}
|
||||
}
|
||||
@@ -98,13 +114,13 @@ func (s *Store) CreateWerkzeug(ctx context.Context, in WerkzeugInput) (Werkzeug,
|
||||
normalizeWerkzeugSlices(&in)
|
||||
row := s.Pool.QueryRow(ctx, `
|
||||
INSERT INTO werkzeug (
|
||||
account_id, name, anbieter, verarbeitungsort, avv_verfuegbar, avv_url,
|
||||
training_opt_out, training_standard, aufbewahrung_tage, zertifizierungen, subprozessoren,
|
||||
account_id, name, anbieter, verarbeitungslaender, avv_verfuegbar, avv_url,
|
||||
training_opt_out, training_standard, dpf_zertifiziert, aufbewahrung_tage, zertifizierungen, subprozessoren,
|
||||
geeignete_zwecke, einschraenkungen, letzte_pruefung, quelle
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING `+werkzeugColumns,
|
||||
in.AccountID, in.Name, in.Anbieter, in.Verarbeitungsort, in.AVVVerfuegbar, in.AVVURL,
|
||||
in.TrainingOptOut, in.TrainingStandard, in.AufbewahrungTage, in.Zertifizierungen, in.Subprozessoren,
|
||||
in.AccountID, in.Name, in.Anbieter, in.Verarbeitungslaender, in.AVVVerfuegbar, in.AVVURL,
|
||||
in.TrainingOptOut, in.TrainingStandard, in.DPFZertifiziert, in.AufbewahrungTage, in.Zertifizierungen, in.Subprozessoren,
|
||||
in.GeeigneteZwecke, in.Einschraenkungen, in.LetztePruefung, in.Quelle,
|
||||
)
|
||||
w, err := scanWerkzeug(row)
|
||||
@@ -123,14 +139,14 @@ func (s *Store) UpdateWerkzeug(ctx context.Context, id string, in WerkzeugInput)
|
||||
normalizeWerkzeugSlices(&in)
|
||||
row := s.Pool.QueryRow(ctx, `
|
||||
UPDATE werkzeug SET
|
||||
name = $2, anbieter = $3, verarbeitungsort = $4, avv_verfuegbar = $5, avv_url = $6,
|
||||
training_opt_out = $7, training_standard = $8, aufbewahrung_tage = $9,
|
||||
zertifizierungen = $10, subprozessoren = $11, geeignete_zwecke = $12, einschraenkungen = $13,
|
||||
letzte_pruefung = $14, quelle = $15, updated_at = now()
|
||||
name = $2, anbieter = $3, verarbeitungslaender = $4, avv_verfuegbar = $5, avv_url = $6,
|
||||
training_opt_out = $7, training_standard = $8, dpf_zertifiziert = $9, aufbewahrung_tage = $10,
|
||||
zertifizierungen = $11, subprozessoren = $12, geeignete_zwecke = $13, einschraenkungen = $14,
|
||||
letzte_pruefung = $15, quelle = $16, updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING `+werkzeugColumns,
|
||||
id, in.Name, in.Anbieter, in.Verarbeitungsort, in.AVVVerfuegbar, in.AVVURL,
|
||||
in.TrainingOptOut, in.TrainingStandard, in.AufbewahrungTage, in.Zertifizierungen, in.Subprozessoren,
|
||||
id, in.Name, in.Anbieter, in.Verarbeitungslaender, in.AVVVerfuegbar, in.AVVURL,
|
||||
in.TrainingOptOut, in.TrainingStandard, in.DPFZertifiziert, in.AufbewahrungTage, in.Zertifizierungen, in.Subprozessoren,
|
||||
in.GeeigneteZwecke, in.Einschraenkungen, in.LetztePruefung, in.Quelle,
|
||||
)
|
||||
w, err := scanWerkzeug(row)
|
||||
|
||||
Reference in New Issue
Block a user