# Plan implementacji zgodności RODO — Forno rezerwacje
Stan: 2026-09-02. Aplikacja rezerwacji działa na Render, ale wymaga naprawy
zgodności z RODO przed udostępnieniem klientom. Priorytety oznaczone 🔴 są
krytyczne i muszą być gotowe przed startem.
---
## Kontekst — co zbiera aplikacja
Formularz `views/forno-rezerwacja.ejs` zbiera:
- imię i nazwisko (dane osobowe, RODO art. 4 pkt 1)
- numer telefonu (dane osobowe — identyfikator)
- liczbę osób (nie jest daną osobową)
- uwagi (opcjonalnie — mogą zawierać dane osobowe)
Dane zapisywane w `reservations.json` i commitowane do GitHub przez
`github-sync.js`. SMS przypomnienie wysyłany przez `forno-notify.js`
(6 h przed terminem opłaty, tylko do statusu `pending`).
---
## Zadanie 0 — Repo prywatne (ręcznie, poza kodem) 🔴 KRYTYCZNE
**Problem:** `reservations.json` z imionami i telefonami klientów jest
commitowany do publicznego repo `github.com/DamianMalenta/trzciamajka`.
Każdy może pobrać plik i mieć bazę danych osobowych.
**Akcja (wykonuje Damian ręcznie na GitHub):**
1. `github.com/DamianMalenta/trzciamajka` → Settings → *Change repository
visibility* → **Private**
2. Render i GitHub Actions nadal działają (PAT ma uprawnienia do prywatnego repo)
3. Cron na GitHub Actions: prywatne repo ma 2000 min/mc darmowych — wystarczy
**Weryfikacja:** otwórz `github.com/DamianMalenta/trzciamajka` w oknie
prywatnym — powinien pokazać 404. Zalogowany nadal widzi repo.
**Nie dotyka kodu** — to czysta akcja na GitHub UI.
---
## Zadanie 1 — Checkbox zgody + klauzula informacyjna 🔴 KRYTYCZNE
**Plik:** `views/forno-rezerwacja.ejs`
### 1.1 Checkbox zgody (wymagany, przed przyciskiem submit)
Dodać pole checkbox **wymagane** w formularzu, przed przyciskiem
„Rezerwuję stolik":
```html
<% if (errors.consent) { %>
<%= errors.consent %>
<% } %>
```
**Wymagania:**
- checkbox `required` — nie zaznaczony = formularz nie przejdzie walidacji HTML5
- walidacja serwerowa też (Zadanie 2) — bo HTML5 można obejść
- tekst zgody konkretny: kto (venue_name), co (dane), po co (rezerwacja + SMS)
- zgoda **nie jest warunkiem** samej rezerwacji — to jest zgoda na przetwarzanie
danych niezbędnych do umowy (art. 6 ust. 1 lit. b) + zgoda na SMS (art. 6
ust. 1 lit. a — komunikacja elektroniczna)
### 1.2 Krótka klauzula informacyjna pod formularzem
Dodać pod formularzem (lub pod checkboxem) krótki blok informacyjny:
```html
🔒 Twoje dane
Administratorem Twoich danych jest <%= settings.venue_name %><% if
(settings.address) { %> (<%= settings.address %>)<% } %>. Dane przetwarzamy
w celu realizacji rezerwacji i obsługi płatności. Przechowujemy je do końca
wydarzenia, a następnie przez 30 dni w celach rozliczeniowych. Masz prawo
dostępu do swoich danych, ich sprostowania, usunięcia i ograniczenia
przetwarzania. Szczegóły: polityka prywatności.
```
### 1.3 CSS dla checkboxa i klauzuli
**Plik:** `public/forno.css`
Dodać style dla `.field--consent`, `.consent` (checkbox + tekst obok),
zgodnie z istniejącą szatą graficzną (kolory z zmiennych CSS, czytelne na
mobile).
---
## Zadanie 2 — Walidacja zgody po stronie serwera 🔴 KRYTYCZNE
**Plik:** `forno-data.js` — funkcja `validateReservationInput`
### 2.1 Dodać pole `consent` do walidacji
W `validateReservationInput` dodać sprawdzanie zgody:
```js
const consent = String(src.consent || '').trim();
if (consent !== '1' && consent !== 'true' && consent !== 'on') {
errors.consent = 'Musisz wyrazić zgodę na przetwarzanie danych, aby zarezerwować stolik.';
}
```
### 2.2 Dodać `consent` do zwracanego `value`
W obiekcie `value` zwracanym przez `validateReservationInput` dodać:
`consent: consent === '1' || consent === 'true' || consent === 'on'`
### 2.3 Zapisać zgodę w rezerwacji
W `createReservation` dodać pole `consent: true` i `consent_at: createdAt.toISOString()`
— dowód, że klient zaznaczył zgodę i kiedy (ważne dla audytu RODO).
### 2.4 Testy
**Plik:** `test/forno-data.test.js` (lub nowy `test/forno-consent.test.js`)
Dodać testy:
- `validateReservationInput` bez `consent` → `errors.consent` ustawione, `ok: false`
- `validateReservationInput` z `consent: '1'` → brak błędu zgody
- `createReservation` → rezerwacja ma `consent: true` i `consent_at`
- `POST /rezerwacja` bez zaznaczonego checkboxa → 400 + komunikat błędu
---
## Zadanie 3 — Podstrona polityki prywatności 🔴 KRYTYCZNE
**Pliki:** `views/forno-prywatnosc.ejs` + routing w `forno-server.js`
### 3.1 Nowy widok `views/forno-prywatnosc.ejs`
Pełna klauzula informacyjna RODO art. 13/14. Struktura:
1. **Administrator danych** — nazwa lokalu, adres, telefon kontaktowy
(z `settings.address`, `settings.contact_phone`)
2. **Cele przetwarzania** — realizacja rezerwacji, obsługa płatności,
przypomnienia SMS
3. **Podstawa prawna** — art. 6 ust. 1 lit. b (umowa) + lit. a (zgoda na SMS)
4. **Odbiorcy danych** — pracownicy lokalu (obsługa rezerwacji),
dostawca SMS Gateway (sms-gate.app — procesor), hosting (Render — procesor)
5. **Okres przechowywania** — do końca wydarzenia + 30 dni (rozliczenia),
potem usunięcie
6. **Prawa użytkownika** — dostęp, sprostowanie, usunięcie, ograniczenie,
przenoszenie, sprzeciw, wycofanie zgody, skarga do UODO
(Urząd Ochrony Danych Osobowych, ul. Postępu 2, 02-676 Warszawa)
7. **Wymóg podania danych** — dobrowolne, ale niezbędne do rezerwacji
8. **Automatyczne podejmowanie decyzji** — brak (profilowanie nie występuje)
9. **Transfer danych poza EOG** — Render (USA), sms-gate.app (UE) —
Render jako procesor z umową DPA (Data Processing Agreement)
**Szablon:** zgodny z `forno-rezerwacja.ejs` (hero, card, footer, CSS z
`forno.css`), link powrotu do `/`.
### 3.2 Routing w `forno-server.js`
Dodać route **przed** handlerem 404:
```js
app.get('/prywatnosc', (req, res) => {
res.render('forno-prywatnosc', { settings: data.loadSettings() });
});
```
### 3.3 Link w stopce
**Plik:** `views/partials/forno-footer.ejs`
Dodać link do polityki prywatności w stopce:
```html