---
phase: 51-email-html-layout
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - database/migrations/20260328_000001_add_html_layout_to_email_mailboxes.sql
  - src/Modules/Settings/EmailMailboxController.php
  - src/Modules/Settings/EmailMailboxRepository.php
  - resources/views/settings/email-mailboxes.php
  - src/Modules/Email/EmailSendingService.php
autonomous: true
---

<objective>
## Goal
Rozbudowa modulu e-mail o HTML layout: header i footer konfigurowane na poziomie skrzynki pocztowej, content z szablonu. Finalna wiadomosc = header + content + footer. Edytor ograniczony do email-safe HTML.

## Purpose
Umozliwienie uzytkownikowi stworzenia spojnego brandingu e-mail (naglowek z logo/nazwa firmy, stopka z danymi kontaktowymi) bez powielania tresci w kazdym szablonie.

## Output
- Migracja DB: kolumny `header_html`, `footer_html` w `email_mailboxes`
- UI skrzynek: dwa edytory Quill (header/footer) z toolbar email-safe
- Kompozycja e-mail: header + body + footer w EmailSendingService i preview
</objective>

<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md

## Source Files
@src/Modules/Settings/EmailMailboxController.php
@src/Modules/Settings/EmailMailboxRepository.php
@resources/views/settings/email-mailboxes.php
@src/Modules/Email/EmailSendingService.php
@resources/views/settings/email-templates.php (reference — Quill config)
</context>

<skills>
## Required Skills (from SPECIAL-FLOWS.md)

No specialized flows configured as required for this work type.
</skills>

<acceptance_criteria>

## AC-1: Kolumny DB header_html i footer_html
```gherkin
Given tabela email_mailboxes istnieje
When migracja zostanie wykonana
Then tabela zawiera kolumny header_html TEXT NULL i footer_html TEXT NULL
And istniejace rekordy maja NULL w obu kolumnach (brak breaking change)
```

## AC-2: Edycja header/footer w formularzu skrzynki
```gherkin
Given uzytkownik otwiera formularz edycji skrzynki pocztowej
When widzi sekcje "Szablon wiadomosci" pod ustawieniami SMTP
Then sa dwa edytory Quill: "Naglowek (header)" i "Stopka (footer)"
And toolbar kazdego edytora ogranicza sie do: bold, italic, underline, link, kolor tekstu, kolor tla, wyrownanie, listy, naglowki (h1-h3), obraz (inline base64)
And tresc edytorow jest zapisywana do DB przy submit formularza
```

## AC-3: Kompozycja e-mail header + content + footer
```gherkin
Given skrzynka ma ustawiony header_html i footer_html
And szablon ma body_html
When e-mail jest wysylany lub podgladany (preview)
Then tresc wiadomosci = header_html + body_html (resolved) + footer_html
And header i footer rowniez przechodza przez variable resolver
```

## AC-4: E-mail bez header/footer
```gherkin
Given skrzynka ma puste (NULL) header_html i/lub footer_html
When e-mail jest wysylany
Then tresc wiadomosci zawiera tylko body_html (bez pustych sekcji)
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Migracja DB + Repository + Controller</name>
  <files>
    database/migrations/20260328_000001_add_html_layout_to_email_mailboxes.sql,
    src/Modules/Settings/EmailMailboxRepository.php,
    src/Modules/Settings/EmailMailboxController.php
  </files>
  <action>
    1. Utworzyc migracje SQL:
       ```sql
       ALTER TABLE email_mailboxes
         ADD COLUMN header_html TEXT NULL AFTER sender_name,
         ADD COLUMN footer_html TEXT NULL AFTER header_html;
       ```

    2. EmailMailboxRepository:
       - `save()`: dodac `header_html` i `footer_html` do INSERT/UPDATE
       - `findById()`: upewnic sie ze zwraca te kolumny (juz zwraca SELECT * wiec OK)
       - `listAll()`: bez zmian (nie potrzebuje HTML w liscie)

    3. EmailMailboxController:
       - `save()`: pobrac `header_html` i `footer_html` z POST body
       - Nie escapowac HTML (to jest tresc edytora WYSIWYG, jak body_html w szablonach)
       - Przekazac do repozytorium w tablicy save data
  </action>
  <verify>
    - Migracja wykonuje sie bez bledow
    - DESCRIBE email_mailboxes pokazuje header_html i footer_html jako TEXT NULL
    - Zapis i odczyt skrzynki z header/footer dziala poprawnie
  </verify>
  <done>AC-1 satisfied: kolumny istnieja i sa zapisywane/odczytywane</done>
</task>

<task type="auto">
  <name>Task 2: UI edytorow header/footer w formularzu skrzynki</name>
  <files>resources/views/settings/email-mailboxes.php</files>
  <action>
    1. Po sekcji "Ustawienia SMTP" dodac nowa sekcje "Szablon wiadomosci" z dwoma edytorami Quill

    2. Kazdy edytor (header, footer):
       - Label: "Naglowek (header)" / "Stopka (footer)"
       - Div z id `js-header-editor` / `js-footer-editor` (kontener Quill)
       - Hidden input `header_html` / `footer_html` (sync przy submit)
       - Podpowiedz: "Opcjonalnie. Bedzie dolaczany do kazdego e-maila wysylanego z tej skrzynki."

    3. Toolbar edytora — TYLKO email-safe opcje:
       ```javascript
       [
         [{ header: [1, 2, 3, false] }],
         ['bold', 'italic', 'underline'],
         [{ color: [] }, { background: [] }],
         [{ align: [] }],
         [{ list: 'ordered' }, { list: 'bullet' }],
         ['link', 'image'],
         ['clean']
       ]
       ```
       - Image: Quill domyslnie wstawia jako base64 inline — to jest email-safe
       - Brak: strike, blockquote, code-block, video, indent (slabo obslugiwane w klientach pocztowych)

    4. Zaladowac Quill CSS/JS z CDN (ten sam co w email-templates: 2.0.3)

    5. Na submit formularza: sync innerHTML z edytorow do hidden inputs

    6. Przy edycji istniejacego rekordu: zaladowac HTML do edytorow przez `quill.root.innerHTML = ...`

    7. Edytory powinny miec mniejsza domyslna wysokosc niz edytor szablonu (np. min-height: 80px)
  </action>
  <verify>
    - Otworz /settings/email-mailboxes — formularz pokazuje dwa edytory
    - Wpisz tresc w header/footer, zapisz — dane sa w DB
    - Edytuj skrzynke — header/footer sa zaladowane do edytorow
    - Toolbar nie zawiera opcji niebezpiecznych dla e-mail (video, code-block)
  </verify>
  <done>AC-2 satisfied: edytory sa dostepne, ograniczone do email-safe, i zapisuja dane</done>
</task>

<task type="auto">
  <name>Task 3: Kompozycja e-mail w EmailSendingService</name>
  <files>src/Modules/Email/EmailSendingService.php</files>
  <action>
    1. W metodzie `send()` po rozwiazaniu zmiennych w body:
       - Pobrac header_html i footer_html z resolved mailbox
       - Przepuscic je przez variableResolver.resolve() (aby zmienne dzialaly tez w header/footer)
       - Zlozyc finalBody: header_html + resolvedBody + footer_html
       - Jezeli header_html lub footer_html sa NULL/puste — pominac (bez pustych divow)
       - Uzyc finalBody zamiast resolvedBody w sendViaSMTP i logEmail

    2. W metodzie `preview()`:
       - Analogicznie: pobrac mailbox dla szablonu, zlozyc header + body + footer
       - Aby preview dzialal, potrzebujemy mailbox — uzyc resolveMailbox() (juz istnieje)
       - Jezeli mailbox nie znaleziony — pokazac sam body (bez header/footer)

    3. Metoda `resolveMailbox()` jest private — juz zwraca pelne dane z findById() wlacznie z header_html/footer_html

    4. Nowa prywatna metoda `composeBody(string $resolvedBody, ?array $mailbox, array $variableMap): string`:
       - Wydzielic logike kompozycji do reusable metody
       - Uzyc w send() i preview()
  </action>
  <verify>
    - Wyslij e-mail ze skrzynka z ustawionym header/footer — e-mail zawiera header + body + footer
    - Wyslij e-mail ze skrzynka BEZ header/footer — e-mail zawiera tylko body
    - Preview pokazuje zlozony wynik header + body + footer
    - Zmienne w header/footer sa rozwiazywane (np. {{firma.nazwa}})
  </verify>
  <done>AC-3 i AC-4 satisfied: kompozycja dziala z i bez header/footer</done>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- resources/views/settings/email-templates.php (edytor szablonow — bez zmian)
- src/Modules/Email/VariableResolver.php (resolver zmiennych — bez zmian)
- src/Modules/Email/AttachmentGenerator.php
- database/migrations/ (istniejace migracje)
- Struktura tabeli email_templates (body_html pozostaje jak jest)

## SCOPE LIMITS
- Brak edytora MJML / dedykowanego email buildera — Quill z ograniczonym toolbar wystarcza
- Brak podgladu header/footer w formularzu skrzynki (preview jest w szablonach)
- Brak importu gotowych szablonow HTML
- Zmienne w header/footer dzialaja, ale panel zmiennych NIE jest dodawany do formularza skrzynki (header/footer to zwykle statyczny branding)

</boundaries>

<verification>
Before declaring plan complete:
- [ ] Migracja wykonana, kolumny widoczne w DESCRIBE
- [ ] Formularz skrzynki: dwa edytory Quill z email-safe toolbar
- [ ] Zapis i odczyt header/footer dziala
- [ ] E-mail wysylany ze skrzynka z header/footer zawiera zlozony layout
- [ ] E-mail wysylany ze skrzynka BEZ header/footer zawiera tylko body
- [ ] Preview pokazuje zlozony wynik
- [ ] Zmienne w header/footer sa rozwiazywane
- [ ] Brak bledow PHP/JS w konsoli
</verification>

<success_criteria>
- Wszystkie 3 taski zakonczone
- Wszystkie 4 acceptance criteria spelnione
- Wszystkie verification checks przeszly
- Brak regresji w istniejacym wysylaniu e-mail
</success_criteria>

<output>
After completion, create `.paul/phases/51-email-html-layout/51-01-SUMMARY.md`
</output>
