feat(03-cookie-consent): integrate CookieNoticePro with Google Consent Mode v2
Phase 3 complete: - Copy CookieNoticePro library to libraries/CookieNoticePro/ - Fix bug: analytics_storage sent 'granted' instead of 'denied' on rejection - Add Consent Mode v2 default-denied init before GTM snippet in layout-logged.php - Fix plugin init: cookieNoticePro.init() per library docs - Fix duplicate button label (CSS display:none for acceptBtnSettingsLabel) - Add Bootstrap 5 compatibility reset for banner buttons - Set regulamin link to https://bilety.brzezovka.pl/tickets/regulamin/ v0.2 Analytics & Privacy milestone complete. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
227
.paul/phases/03-cookie-consent/03-01-PLAN.md
Normal file
227
.paul/phases/03-cookie-consent/03-01-PLAN.md
Normal file
@@ -0,0 +1,227 @@
|
||||
---
|
||||
phase: 03-cookie-consent
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- libraries/CookieNoticePro/cookienoticepro.script.js
|
||||
- libraries/CookieNoticePro/cookienoticepro.style.css
|
||||
- templates/site/layout-logged.php
|
||||
autonomous: false
|
||||
delegation: off
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Wdrożyć baner zgody na cookies (CookieNoticePro) z Google Consent Mode v2, naprawić błąd `analytics_storage: 'granted'` w bibliotece oraz dodać domyślną inicjalizację consent mode przed snippetem GTM.
|
||||
|
||||
## Purpose
|
||||
Wymaganie RODO — serwis musi uzyskać zgodę użytkownika przed uruchomieniem trackerów analitycznych i marketingowych. Google Consent Mode v2 zapewnia zgodność z wymaganiami Google (od marca 2024) i zachowanie modelowanych danych konwersji nawet przy braku zgody.
|
||||
|
||||
## Output
|
||||
- `libraries/CookieNoticePro/cookienoticepro.script.js` — zkopiony z pomysloweprezenty.pl i naprawiony (linia ~351: `'granted'` → `'denied'`)
|
||||
- `libraries/CookieNoticePro/cookienoticepro.style.css` — zkopiony z pomysloweprezenty.pl
|
||||
- `templates/site/layout-logged.php` — consent mode v2 default init przed GTM, załadowane CSS/JS banera, wywołanie `$.cookieNoticePro()`
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
|
||||
## Source Files
|
||||
@templates/site/layout-logged.php
|
||||
|
||||
## Biblioteka źródłowa (pomysloweprezenty.pl)
|
||||
Pliki do skopiowania:
|
||||
- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.script.js`
|
||||
- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.style.css`
|
||||
</context>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Consent Mode v2 default init przed GTM
|
||||
```gherkin
|
||||
Given layout-logged.php jest renderowany w przeglądarce
|
||||
When strona się ładuje
|
||||
Then w <head>, PRZED snippetem GTM, znajduje się blok gtag('consent','default',{...}) ustawiający wszystkie storage na 'denied'
|
||||
```
|
||||
|
||||
## AC-2: Baner cookies wyświetla się przy pierwszej wizycie
|
||||
```gherkin
|
||||
Given użytkownik odwiedza serwis po raz pierwszy (brak cookie COOKIE_CONSENT)
|
||||
When strona się załaduje
|
||||
Then pojawia się baner CookieNoticePro z przyciskami akceptacji/odrzucenia/dostosowania
|
||||
```
|
||||
|
||||
## AC-3: Naprawa błędu analytics_storage denied
|
||||
```gherkin
|
||||
Given użytkownik odwiedza serwis i wybiera "Odrzuć" lub wyłącza analytics w ustawieniach
|
||||
When biblioteka wywołuje googleConsentModeHandler()
|
||||
Then gtag('consent','update') wysyła {'analytics_storage': 'denied'} (nie 'granted')
|
||||
```
|
||||
|
||||
## AC-4: Akceptacja cookies uruchamia gtag update z 'granted'
|
||||
```gherkin
|
||||
Given użytkownik wybrał akceptację wszystkich cookies
|
||||
When biblioteka wywołuje googleConsentModeHandler()
|
||||
Then gtag('consent','update') wysyła {'analytics_storage': 'granted'} i {'ad_storage': 'granted', ...}
|
||||
```
|
||||
|
||||
## AC-5: Pliki biblioteki obecne w projekcie
|
||||
```gherkin
|
||||
Given wdrożenie jest kompletne
|
||||
When sprawdzamy strukturę projektu
|
||||
Then istnieją pliki libraries/CookieNoticePro/cookienoticepro.script.js i cookienoticepro.style.css
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Skopiuj pliki CookieNoticePro i napraw błąd analytics_storage</name>
|
||||
<files>libraries/CookieNoticePro/cookienoticepro.script.js, libraries/CookieNoticePro/cookienoticepro.style.css</files>
|
||||
<action>
|
||||
1. Skopiuj oba pliki z `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\` do `libraries/CookieNoticePro\` w tym projekcie.
|
||||
|
||||
2. W `cookienoticepro.script.js`, napraw błąd w funkcji `googleConsentModeHandler` (~linia 351):
|
||||
- Znajdź blok `else` po `if(preferences.indexOf("analytics") > -1)` — ten blok obsługuje sytuację gdy analytics NIE jest zaakceptowane
|
||||
- W tym bloku `else`, zmień:
|
||||
```js
|
||||
gtag('consent', 'update', {
|
||||
'analytics_storage': 'granted'
|
||||
});
|
||||
```
|
||||
na:
|
||||
```js
|
||||
gtag('consent', 'update', {
|
||||
'analytics_storage': 'denied'
|
||||
});
|
||||
```
|
||||
- Blok `if` (analytics zaakceptowane, ~linia 341-343) musi pozostać z `'granted'` — nie ruszaj go.
|
||||
|
||||
Unikaj: modyfikowania innych fragmentów pliku; zmiany konfiguracji `config {}` (kolory, tekst) — to ustawi się w layout.
|
||||
</action>
|
||||
<verify>
|
||||
Grep w skopiowanym pliku:
|
||||
- Potwierdź że istnieje dokładnie JEDNO wywołanie `'analytics_storage': 'denied'` w bloku else
|
||||
- Potwierdź że `'analytics_storage': 'granted'` nadal istnieje w bloku if (analytics accepted)
|
||||
Komenda: grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js
|
||||
</verify>
|
||||
<done>AC-3, AC-4, AC-5 satisfied: plik skopiowany, błąd naprawiony, 'denied' w else, 'granted' w if</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Dodaj Consent Mode v2 default init i integruj baner w layout-logged.php</name>
|
||||
<files>templates/site/layout-logged.php</files>
|
||||
<action>
|
||||
W `templates/site/layout-logged.php`:
|
||||
|
||||
1. **Consent Mode v2 default — PRZED snippetem GTM** (wstaw przed komentarzem `<!-- Google Tag Manager -->`):
|
||||
```html
|
||||
<!-- Google Consent Mode v2 - default -->
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('consent', 'default', {
|
||||
'analytics_storage': 'denied',
|
||||
'ad_storage': 'denied',
|
||||
'ad_user_data': 'denied',
|
||||
'ad_personalization': 'denied',
|
||||
'wait_for_update': 500
|
||||
});
|
||||
</script>
|
||||
<!-- End Google Consent Mode v2 - default -->
|
||||
```
|
||||
|
||||
2. **CSS banera** — dodaj do sekcji `<head>` po istniejących linkach CSS (przed zamknięciem `</head>`):
|
||||
```html
|
||||
<link rel="stylesheet" type="text/css" href="/libraries/CookieNoticePro/cookienoticepro.style.css">
|
||||
```
|
||||
|
||||
3. **JS banera + inicjalizacja** — dodaj przed zamknięciem `</body>`, po istniejącym bloku `<script>` z hamburger menu:
|
||||
```html
|
||||
<script type="text/javascript" src="/libraries/CookieNoticePro/cookienoticepro.script.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$.cookieNoticePro();
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
Kolejność w `<head>` po zmianie (od góry):
|
||||
1. Meta tagi
|
||||
2. Linki CSS (istniejące + nowy CSS banera)
|
||||
3. jQuery i inne JS
|
||||
4. **Consent Mode v2 default** ← NOWE (musi być przed GTM)
|
||||
5. **GTM snippet** ← istniejący (bez zmian)
|
||||
|
||||
Unikaj: modyfikowania snippetu GTM; zmiany kolejności istniejących skryptów; dodawania atrybutu `async` lub `defer` do skryptu banera.
|
||||
</action>
|
||||
<verify>
|
||||
Sprawdź w pliku layout-logged.php:
|
||||
- Blok consent default pojawia się PRZED `<!-- Google Tag Manager -->`
|
||||
- `cookienoticepro.style.css` jest linkowany w `<head>`
|
||||
- `cookienoticepro.script.js` i wywołanie `$.cookieNoticePro()` są przed `</body>`
|
||||
Komenda: grep -n "Consent Mode\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php
|
||||
</verify>
|
||||
<done>AC-1, AC-2 satisfied: consent default init przed GTM, CSS i JS banera załadowane</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<what-built>Baner CookieNoticePro z Consent Mode v2 zintegrowany w layout-logged.php. Pliki biblioteki w libraries/CookieNoticePro/. Błąd analytics_storage naprawiony.</what-built>
|
||||
<how-to-verify>
|
||||
1. Wyślij pliki na serwer przez FTP (Ctrl+Shift+P → "FTP-kr: Upload")
|
||||
2. Otwórz https://bilety.brzezovka.pl w trybie incognito (brak cookies)
|
||||
3. Sprawdź czy pojawia się baner zgody na cookies
|
||||
4. Otwórz DevTools → Console — sprawdź czy NIE ma błędów JS
|
||||
5. Otwórz DevTools → Network → filtruj "gtm" — sprawdź czy GTM się ładuje
|
||||
6. W Console wpisz: `document.cookie` — nie powinno być COOKIE_CONSENT (przed akceptacją)
|
||||
7. Kliknij "Odrzuć wszystkie" → w DevTools → Application → Cookies sprawdź czy GOOGLE_CONSENT_MODE_ANALYTICS_STORAGE ma wartość false/brak
|
||||
8. Odśwież stronę — baner NIE powinien się pojawić ponownie (cookie zapamiętane)
|
||||
9. Kliknij ikonę ciasteczka (minimize) → wybierz "Akceptuj wszystkie" → sprawdź że gtag update wysyła 'granted' (DevTools → Console → wpisz: `dataLayer` i poszukaj consent update)
|
||||
</how-to-verify>
|
||||
<resume-signal>Wpisz "approved" jeśli baner działa poprawnie, lub opisz problemy do naprawienia</resume-signal>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- `templates/tickets/przelewy24.php` — purchase event (Phase 2, nie ruszać)
|
||||
- `templates/tickets/order-confirm.php` — po czyszczeniu Phase 2
|
||||
- Snippet GTM w layout-logged.php — tylko kolejność, nie treść
|
||||
- `config.php` — konfiguracja poza zakresem
|
||||
|
||||
## SCOPE LIMITS
|
||||
- Nie konfiguruj cookienoticepro dla innych layoutów (layout-unlogged.php nie jest używany)
|
||||
- Nie zmieniaj kolorów/tekstu/języka banera — domyślna konfiguracja z biblioteki jest wystarczająca na start
|
||||
- Nie dodawaj nowych zależności JS poza biblioteką CookieNoticePro
|
||||
- Nie wdrażaj server-side consent storage — tylko frontend cookies
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Przed ogłoszeniem planu za kompletny:
|
||||
- [ ] `grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js` → pokazuje 'denied' w else i 'granted' w if
|
||||
- [ ] `grep -n "consent.*default\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php` → consent default PRZED GTM
|
||||
- [ ] Baner pojawia się na stronie przy pierwszej wizycie (weryfikacja manualna — checkpoint)
|
||||
- [ ] Brak błędów JS w konsoli
|
||||
- [ ] Odrzucenie cookies → analytics_storage pozostaje denied (nie grantowane)
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Pliki CookieNoticePro obecne w libraries/CookieNoticePro/
|
||||
- Błąd analytics_storage naprawiony (denied zamiast granted w bloku else)
|
||||
- Consent Mode v2 default init znajduje się przed GTM snippetem w layout-logged.php
|
||||
- Baner wyświetla się przy pierwszej wizycie i zapamiętuje wybór
|
||||
- Serwis spełnia wymaganie RODO z PROJECT.md (Must Have: Zgodność z RODO)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Po zakończeniu utwórz `.paul/phases/03-cookie-consent/03-01-SUMMARY.md`
|
||||
</output>
|
||||
134
.paul/phases/03-cookie-consent/03-01-SUMMARY.md
Normal file
134
.paul/phases/03-cookie-consent/03-01-SUMMARY.md
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
phase: 03-cookie-consent
|
||||
plan: 01
|
||||
subsystem: ui
|
||||
tags: [cookies, gdpr, consent-mode-v2, gtm, cookienoticepro]
|
||||
|
||||
requires:
|
||||
- phase: 02-purchase-event-prepayment
|
||||
provides: GTM już wdrożony w layout-logged.php
|
||||
|
||||
provides:
|
||||
- Baner zgody na cookies (CookieNoticePro) zintegrowany z serwisem
|
||||
- Google Consent Mode v2 z domyślnymi denied przed GTM
|
||||
- Naprawiony błąd analytics_storage w bibliotece CookieNoticePro
|
||||
affects: []
|
||||
|
||||
tech-stack:
|
||||
added: [CookieNoticePro jQuery plugin]
|
||||
patterns: [Consent Mode v2 default-denied init before GTM snippet]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- libraries/CookieNoticePro/cookienoticepro.script.js
|
||||
- libraries/CookieNoticePro/cookienoticepro.style.css
|
||||
modified:
|
||||
- templates/site/layout-logged.php
|
||||
|
||||
key-decisions:
|
||||
- "Inicjalizacja: cookieNoticePro.init() zamiast $.fn.cookieNoticePro() — zgodnie z dokumentacją biblioteki"
|
||||
- "acceptBtnSettingsLabel ukryty przez CSS (display:none) — JS nie ustawiał stanu początkowego"
|
||||
|
||||
patterns-established:
|
||||
- "Consent Mode v2 default init zawsze przed snippetem GTM w <head>"
|
||||
|
||||
duration: ~45min
|
||||
started: 2026-04-26T00:00:00Z
|
||||
completed: 2026-04-26T00:00:00Z
|
||||
---
|
||||
|
||||
# Phase 3 Plan 01: Cookie Consent Banner Summary
|
||||
|
||||
**CookieNoticePro z Google Consent Mode v2 wdrożony — serwis spełnia wymogi RODO, analytics_storage poprawnie ustawiane na denied przy odmowie zgody.**
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Duration | ~45 min |
|
||||
| Tasks | 2 auto + 1 checkpoint |
|
||||
| Files modified | 3 |
|
||||
|
||||
## Acceptance Criteria Results
|
||||
|
||||
| Criterion | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| AC-1: Consent Mode v2 default przed GTM | Pass | Blok w `<head>` przed `<!-- Google Tag Manager -->` |
|
||||
| AC-2: Baner przy pierwszej wizycie | Pass | Zweryfikowane manualnie |
|
||||
| AC-3: Naprawa analytics_storage denied | Pass | Linia ~351: `'granted'` → `'denied'` w bloku else |
|
||||
| AC-4: Akceptacja → granted | Pass | Blok if (analytics accepted) bez zmian |
|
||||
| AC-5: Pliki biblioteki obecne | Pass | `libraries/CookieNoticePro/` skonfigurowany |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Skopiowano i zintegrowano bibliotekę CookieNoticePro z istniejącym projektem
|
||||
- Naprawiono błąd biblioteki: `analytics_storage: 'granted'` → `'denied'` w bloku odrzucenia analytics
|
||||
- Consent Mode v2 inicjalizowany z defaultami `denied` przed snippetem GTM — wymaganie Google od marca 2024
|
||||
- Baner wyświetla się przy pierwszej wizycie, zapamiętuje wybór przez 365 dni
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Change | Purpose |
|
||||
|------|--------|---------|
|
||||
| `libraries/CookieNoticePro/cookienoticepro.script.js` | Created | Biblioteka banera — zkopiona + naprawiony błąd analytics_storage + link regulaminu |
|
||||
| `libraries/CookieNoticePro/cookienoticepro.style.css` | Created | Style banera — zkopione + Bootstrap 5 compat reset + initial state fix |
|
||||
| `templates/site/layout-logged.php` | Modified | Consent Mode v2 default przed GTM, CSS/JS banera, inicjalizacja `cookieNoticePro.init()` |
|
||||
|
||||
## Decisions Made
|
||||
|
||||
| Decision | Rationale | Impact |
|
||||
|----------|-----------|--------|
|
||||
| `cookieNoticePro.init()` zamiast `$.fn.cookieNoticePro()` | Demo `index.html` z biblioteki pokazuje właściwy sposób inicjalizacji | Poprawne uruchomienie banera |
|
||||
| CSS `display:none` na `.acceptBtnSettingsLabel` | JS przełącza etykiety tylko na click — nie ustawia stanu początkowego | Brak duplikatu tekstu w przycisku "Akceptuj/Zatwierdź" |
|
||||
| Bootstrap 5 compat reset w CSS | Bootstrap nadpisuje `line-height`, `font-size` przycisków | Poprawny wygląd przycisków banera |
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Summary
|
||||
|
||||
| Type | Count | Impact |
|
||||
|------|-------|--------|
|
||||
| Auto-fixed | 3 | Niezbędne poprawki, brak scope creep |
|
||||
| Scope additions | 1 | Drobna zmiana na prośbę użytkownika |
|
||||
|
||||
**Total impact:** Drobne poprawki wynikające z integracji z Bootstrap 5 i specyfiki biblioteki
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. Inicjalizacja pluginu**
|
||||
- **Found during:** Checkpoint (błąd konsoli)
|
||||
- **Issue:** `$.cookieNoticePro is not a function` — plugin rejestruje się jako `$.fn`, nie `$`
|
||||
- **Fix:** `$.cookieNoticePro()` → `$.fn.cookieNoticePro()` → `cookieNoticePro.init()`
|
||||
- **Files:** `templates/site/layout-logged.php`
|
||||
|
||||
**2. Duplikat tekstu w przycisku akceptacji**
|
||||
- **Found during:** Checkpoint (feedback użytkownika)
|
||||
- **Issue:** `.acceptBtnSettingsLabel` ("Zatwierdź") widoczny razem z `.acceptBtnLabel` ("Akceptuj") — brak initial hide w JS
|
||||
- **Fix:** Dodano `display: none` w CSS dla `.acceptBtnSettingsLabel`
|
||||
- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
|
||||
|
||||
**3. Bootstrap 5 button override**
|
||||
- **Found during:** Checkpoint (button layout)
|
||||
- **Issue:** Bootstrap nadpisuje `line-height` i `font-size` przycisków banera
|
||||
- **Fix:** CSS reset z `!important`-safe specificity dla `.btn-wrap button`
|
||||
- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
|
||||
|
||||
### Scope Additions
|
||||
|
||||
- Link regulaminu zmieniony na `https://bilety.brzezovka.pl/tickets/regulamin/` (prośba użytkownika podczas weryfikacji)
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
**Ready:**
|
||||
- v0.2 Analytics & Privacy — wszystkie 3 fazy kompletne
|
||||
- Tracking ecommerce (Phase 1+2) + RODO (Phase 3) wdrożone
|
||||
|
||||
**Concerns:**
|
||||
- Brak — integracja stabilna
|
||||
|
||||
**Blockers:**
|
||||
- None
|
||||
|
||||
---
|
||||
*Phase: 03-cookie-consent, Plan: 01*
|
||||
*Completed: 2026-04-26*
|
||||
Reference in New Issue
Block a user