# Double-Opt-In in MR9

## Zweck
Diese Anleitung beschreibt, wie Double-Opt-In in MR9 fachlich und technisch arbeitet. Sie ist als ausfuehrliche Referenz fuer Verwaltung, Support und spaetere Wartung gedacht.

Wichtig ist vor allem ein Grundsatz:

- Double-Opt-In ist in MR9 immer listenbezogen.
- Eine bestaetigte Einwilligung gilt nie global fuer alle Listen.
- Ein Empfaenger kann fuer mehrere Listen jeweils einen eigenen DOI-Nachweis haben.

## Grundprinzip
MR9 trennt Empfaenger, Listen-Zuordnung und DOI-Nachweis bewusst voneinander.

- `recipients`
  - enthaelt den Empfaenger als Person bzw. Kontakt
- `recipient_lists`
  - enthaelt die Zuordnung eines Empfaengers zu einer Liste
- `recipient_list_optin`
  - enthaelt den DOI-Nachweis fuer genau diesen Empfaenger in genau dieser Liste

Der DOI-Nachweis ist damit immer an die Kombination aus Empfaenger und Liste gebunden. Ein Listenwechsel erzeugt deshalb nicht automatisch eine neue Einwilligung.

## Ablauf im System

### 1. Liste vorbereiten
Die Grundlage wird in der Listenverwaltung gelegt.

- In [listen_create.php](/C:/xampp/htdocs/mr/admin/listen_create.php) und [listen_edit.php](/C:/xampp/htdocs/mr/admin/listen_edit.php) wird pro Liste festgelegt, ob `Double-Opt-In erforderlich` ist.
- Jede Liste braucht einen aktiven Absender.
- Beim Anlegen einer Liste werden Standard-Templates erzeugt:
  - optional ein DOI-Template
  - ein Welcome-Template
- Die Liste speichert dazu:
  - `requires_doi`
  - `doi_template_id`
  - `welcome_template_id`
  - `from_identity_id`

### 2. Formular-Anmeldung
Der Einstieg erfolgt ueber [formular_submit.php](/C:/xampp/htdocs/mr/formular_submit.php).

Beim Absenden eines echten Formulars passiert:

1. Formular und Liste werden geladen.
2. Der Empfaenger wird gesucht oder neu angelegt.
3. Die Zuordnung zur Liste wird hergestellt.
4. Ein DOI-Datensatz in `recipient_list_optin` wird angelegt oder aktualisiert.
5. Je nach Liste wird eine DOI-Mail oder direkt eine Welcome-Mail in die Queue eingeplant.
6. Systemmails mit Prioritaet `1` werden direkt ueber `send_queue_worker_s.php` angestossen.

Wichtige Fachregel:

- Hat die Liste `requires_doi = 1` und ein DOI-Template, wird zuerst die DOI-Mail eingeplant.
- Hat die Liste kein DOI, kann direkt die Welcome-Mail eingeplant werden.

### 3. DOI-Datensatz bei Anmeldung
Bei der Formular-Anmeldung schreibt MR9 einen Datensatz in `recipient_list_optin`.

Dabei werden unter anderem gespeichert:

- `recipient_id`
- `list_id`
- `doi_token`
- `doi_confirmed = 0`
- `doi_requested_at`
- `formular_id`
- `doi_ip_signup_enc`
- `doi_ip_signup_hash`
- `doi_user_agent`
- `doi_referrer`

Wenn derselbe Empfaenger dieselbe Liste erneut ueber dasselbe oder ein anderes Formular anstoesst, wird der vorhandene DOI-Datensatz aktualisiert:

- neues Token
- neuer Anfragezeitpunkt
- neue Anmelde-IP
- neuer Kontext
- `doi_confirmed` wird wieder auf `0` gesetzt

Das ist wichtig, weil dadurch immer der aktuelle DOI-Vorgang fuer diese Listen-Zuordnung abgebildet wird.

### 4. DOI-Mail
Wenn DOI aktiv ist, wird das DOI-Template der Liste in die Queue geschrieben.

Zusatzlich speichert MR9 fuer Nachweiszwecke:

- `doi_mail_sent_at`
- `doi_mail_hash`
- `doi_mail_body_b64`

Damit laesst sich spaeter nachvollziehen, welcher DOI-Mail-Inhalt konkret verwendet wurde.

Der Platzhalter fuer den Bestaetigungslink ist:

- `[confirm_url]`

Im Versand wird daraus ein Link auf [confirm.php](/C:/xampp/htdocs/mr/confirm.php) mit Token.

### 5. Bestaetigung durch Klick
Die DOI-Bestaetigung laeuft ueber [confirm.php](/C:/xampp/htdocs/mr/confirm.php).

Wenn ein gueltiger noch nicht bestaetigter Token aufgerufen wird:

1. Der DOI-Datensatz wird geladen.
2. Die Klick-IP wird verschluesselt und gehasht vorbereitet.
3. Der DOI-Datensatz wird aktualisiert:
   - `doi_confirmed = 1`
   - `doi_confirmed_at = NOW()`
   - `doi_ip_confirm_enc`
   - `doi_ip_confirm_hash`
   - `doi_user_agent` falls noch leer
   - `doi_referrer` falls noch leer
4. Falls die Liste ein Welcome-Template hat, wird die Welcome-Mail mit Prioritaet `1` eingeplant.
5. Die Prioritaet-1-Mail wird direkt angestossen.

Ein Token kann also nicht beliebig oft zur Erstbestaetigung verwendet werden. Ein bereits bestaetigter oder ungueltiger Token wird abgewiesen.

## Was der DOI-Nachweis speichert
MR9 speichert nicht nur den Status, sondern den Nachweiskontext.

Typische Nachweisdaten sind:

- Anfragezeitpunkt
- Bestaetigungszeitpunkt
- Anmelde-IP verschluesselt
- Anmelde-IP gehasht
- Klick-IP verschluesselt
- Klick-IP gehasht
- User-Agent
- Referrer
- DOI-Token
- Hash des DOI-Mail-Inhalts
- DOI-Mail-Inhalt als Base64
- optional Policy-Hash, falls dieser im Datensatz vorhanden ist

Die Opt-In-Detailansicht in [optin_view.php](/C:/xampp/htdocs/mr/admin/tools/optin_view.php) zeigt diese Daten zur Pruefung an.

## Listenbezogenheit und ihre Folgen
Der wichtigste fachliche Punkt ist:

- DOI gilt immer nur fuer die Liste, fuer die der Nachweis entstanden ist.

Daraus folgen mehrere Regeln:

### Empfaenger in neue Liste aufnehmen
- Es entsteht nicht automatisch ein DOI fuer die neue Liste.
- Ein bestaetigter DOI aus Liste A darf nicht still in Liste B uebernommen werden.

### Empfaenger aus Liste entfernen
- Die Zuordnung kann enden.
- Der historische DOI-Nachweis der alten Liste bleibt fachlich trotzdem ein Nachweis fuer den damaligen Vorgang.

### Empfaenger komplett loeschen
- Dann werden auch personenbezogene DOI-Daten geloescht.
- In [empfaenger_delete.php](/C:/xampp/htdocs/mr/admin/empfaenger/empfaenger_delete.php) wird `recipient_list_optin` mit entfernt.

## Kampagnen und DOI
DOI spielt nicht nur im Formularfluss eine Rolle, sondern auch im Kampagnenversand.

In [campaign_create.php](/C:/xampp/htdocs/mr/admin/emails/campaign_create.php) und [campaign_edit.php](/C:/xampp/htdocs/mr/admin/emails/campaign_edit.php) gibt es:

- `Nur bestaetigte (Double Opt-In) Empfaenger`

Diese Option ist absichtlich listenabhaengig.

Das bedeutet:

- Ohne ausgewaehlte Liste ist `use_doi_only` fachlich nicht zulaessig.
- Eine DOI-Pruefung ohne Listenbezug waere in MR9 falsch, weil der DOI nie global gespeichert wird.

Deshalb validiert das System:

- `use_doi_only` ist nur erlaubt, wenn eine Liste ausgewaehlt ist

## Priority 1 und Systemmails
DOI- und Welcome-Mails haben im System eine Sonderrolle.

- Sie werden mit Prioritaet `1` eingeplant.
- Der normale Worker verarbeitet nur Queue-Eintraege mit Prioritaet groesser `1`.
- Systemmails mit Prioritaet `1` werden direkt ueber `send_queue_worker_s.php` angestossen.

Das sorgt dafuer, dass DOI- und Welcome-Mails sofort laufen und nicht hinter normalen Kampagnen warten.

## Typische Missverstaendnisse

### "Der Empfaenger ist doch schon bestaetigt."
Ja, aber nur fuer die Liste, fuer die dieser DOI entstanden ist.

### "Wir verschieben einfach in eine andere Liste."
Das aendert nicht den DOI-Status der Ziel-Liste. Dort ist ggf. ein neuer DOI noetig.

### "Wir koennen den DOI aus der alten Software ueberall verwenden."
Nur wenn fachlich und rechtlich wirklich dieselbe Einwilligung fuer dieselbe Liste bzw. denselben Zweck nachweisbar ist. Ein pauschales Uebertragen auf neue Listen ist nicht sauber.

### "DOI ist nur ein Checkbox-Thema."
Nein. In MR9 betrifft DOI:

- Listenlogik
- Formularfluss
- Template-Verwendung
- Queue-Prioritaet
- Bestaetigungslink
- Nachweisdaten
- kampagnenbezogene Versandregeln

## Empfohlene Arbeitsweise

### Fuer neue Listen
- Liste mit passendem Absender anlegen
- entscheiden, ob DOI Pflicht ist
- DOI- und Welcome-Template pruefen
- Formular mit dieser Liste verbinden
- kompletten DOI-Test einmal durchlaufen

### Fuer laufende Systeme
- bei Problemen immer zuerst Liste, Template und Formular-Zuordnung pruefen
- `optin_view.php` fuer konkrete Nachweise nutzen
- DOI nicht still durch Datenkorrekturen oder Massenimporte "erfinden"

### Bei Listenwechseln
- immer fachlich pruefen, ob eine neue Einwilligung benoetigt wird
- DOI niemals automatisch zwischen Listen kopieren

## Pruefpunkte bei Fehlern
Wenn DOI nicht sauber funktioniert, sind die haeufigsten Punkte:

1. Die Liste hat `requires_doi`, aber kein brauchbares `doi_template_id`.
2. `base_url` ist falsch, dadurch zeigt `[confirm_url]` auf den falschen Link.
3. Das Formular ist der falschen Liste zugeordnet.
4. Der Empfaenger wurde zwar angelegt, aber der DOI-Datensatz wurde nicht korrekt geschrieben.
5. Die Prioritaet-1-Mail konnte nicht direkt versendet werden.
6. Welcome-Template oder DOI-Template der Liste fehlen oder sind inhaltlich unbrauchbar.

Erste technische Stellen dafuer sind:

- [formular_submit.php](/C:/xampp/htdocs/mr/formular_submit.php)
- [confirm.php](/C:/xampp/htdocs/mr/confirm.php)
- [optin_view.php](/C:/xampp/htdocs/mr/admin/tools/optin_view.php)
- [troubleshooting.md](/C:/xampp/htdocs/mr/docs/troubleshooting.md)

## Kurzfassung fuer Entscheidungen
- DOI ist in MR9 immer listenbezogen.
- Eine Einwilligung ist kein globales Empfaenger-Merkmal.
- Listenwechsel erzeugt keinen automatischen DOI.
- DOI- und Welcome-Mails laufen als Systemmails mit Prioritaet `1`.
- Kampagnen mit `use_doi_only` brauchen einen klaren Listenbezug.
- DOI-Nachweise duerfen nicht still erweitert, kopiert oder frei umgedeutet werden.
