9.1 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, started, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | duration | started | completed | |||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 09-finalizacja | 05 | ui, api |
|
|
|
|
|
|
|
|
~75min | 2026-05-07T22:30:00Z | 2026-05-07T23:50:00Z |
Phase 09 Plan 05: UX rezerwacja — tytuły GCal + per-day segmenty
Kalendarz zbiorczy [yacht_calendar_all] na /rezerwacja/ pokazuje tytuły rezerwacji (raw SUMMARY z Google Calendar bez prefiksu "GCal:") na osobnych paskach per dzień, z half-day visual na pierwszym i ostatnim dniu rezerwacji oraz native tooltip na hover.
Performance
| Metric | Value |
|---|---|
| Duration | ~75min (z 1 iteracją UX po pierwszym deploy) |
| Started | 2026-05-07T22:30:00Z |
| Completed | 2026-05-07T23:50:00Z |
| Tasks | 4 auto + 1 checkpoint + 1 iteracja UX (allDay fix) + 1 mini-fix (tooltip) |
| Files modified | 4 |
Acceptance Criteria Results
| Criterion | Status | Notes |
|---|---|---|
| AC-1: Tytuł rezerwacji z iCal w REST | Pass | _booking_notes zwracane jako title, prefiks "GCal:" zniknął |
| AC-2: Tytuł rezerwacji frontowej | Pass | Booking::get_customer_name() jako fallback |
| AC-3: Tytuł renderowany w pasku eventu | Pass | .yc-event-title z ellipsis; weryfikacja Playwright (events: "Kubuś - Julia R") |
| AC-4: Per-day segmenty z gap | Pass | Po fix do allDay — każda doba w osobnej komórce, margin 2px daje gap |
| AC-5: Half-day visual zachowany | Pass | extendedProps.is_first / is_last_night sterują gradientem |
| AC-6: Privacy — brak email/phone | Pass | Payload REST nie zawiera customer_email ani customer_phone |
Accomplishments
- Tytuły rezerwacji widoczne — klient może wzrokowo identyfikować rezerwacje na publicznym kalendarzu (np. "Kubuś - Julia R", "Maja - Kowalscy 5 osób") bez prefiksu "GCal:".
- Per-day allDay events — każda doba rezerwacji to osobny pasek w pojedynczej komórce dnia (1.06, 2.06, 3.06...) z 2px gapem między nimi. Rezerwacja 5-dniowa = 5 osobnych prostokątów zamiast jednej ciągłej belki.
- Half-day visual zachowany — pierwszy dzień rezerwacji (yacht odbierany w południe) ma lewą połowę transparentną, ostatni dzień (zwrot w południe) prawą połowę transparentną. Środkowe dni — pełny kolor.
- Native tooltip na hover —
titleattribute z formatem "{tytuł} ({YYYY-MM-DD})" — zero zależności, działa accessibility-friendly.
Files Created/Modified
| File | Change | Purpose |
|---|---|---|
api/class-rest-controller.php |
Modified | get_all_availability(): title z _booking_notes/customer_name, split per-day allDay events z extendedProps (is_first / is_last_night) |
frontend/assets/js/calendar-all.js |
Modified | eventContent renderuje .yc-event-title (escaped przez .text()); eventDidMount ustawia native title tooltip; applyHalfDayGradient czyta flagi z extendedProps |
frontend/assets/css/calendar-all.css |
Modified | Usunięte display:none z .fc-event-title; nowy .yc-event-title (ellipsis); margin: 1px 2px na .fc-daygrid-event (gap między paskami); mobile font-size |
yacht-booking-system.php |
Modified | Bump wersji 1.1.0 → 1.2.0 (cache busting) |
Decisions Made
| Decision | Rationale | Impact |
|---|---|---|
| Per-day allDay events zamiast timed 12:00→12:00 | Pierwsza próba z timed eventami crossowała północ → FC dayGrid renderował każdą dobę jako pasek na granicy dwóch komórek (efekt "schodków") | Każda doba zamknięta w jednej komórce, czysty layout |
Iteracja start_date <= end_date (INCLUSIVE) |
Yacht obecny od noon dnia start do noon dnia end → wszystkie dni tego zakresu są "occupied" | Rezerwacja 1.06 → 5.06 emituje 5 eventów (1, 2, 3, 4, 5) zamiast 4 nocy |
| Cofnięcie privacy z 09-04 | Klient zmienił zdanie — chce wzrokowo identyfikować rezerwacje | Tytuły widoczne publicznie. customer_email/customer_phone nadal NIE wychodzą przez REST. Security audit (09-06) musi to uwzględnić |
Tooltip = native title attribute |
Klient prosił o "jakiś label na hover" — najprostsze, bez nowych zależności | Hover po ~1s pokazuje "Kubuś - Julia R (2026-06-04)" |
Deviations from Plan
Summary
| Type | Count | Impact |
|---|---|---|
| Auto-fixed | 1 | Krytyczny: pierwsza wersja (timed events 12:00→12:00) renderowała "schodki" — zmiana na allDay events naprawiła layout |
| Scope additions | 1 | Native tooltip na hover (poza pierwotnym PLAN.md, prośba klienta po weryfikacji) |
| Deferred | 0 | — |
Total impact: Pierwsza implementacja per-PLAN była technicznie poprawna (timed events 12:00→12:00 = 1 doba), ale FC dayGrid renderuje takie eventy jako rozciągnięte przez granicę dwóch komórek (każda doba pojawiała się na pograniczu dnia N i N+1). Fix do allDay events rozwiązał to zachowując semantykę (start/end INCLUSIVE).
Auto-fixed Issues
1. Timed events 12:00→12:00 renderowały "schodki" w FC dayGrid
- Found during: Checkpoint human-verify (klient zgłosił "paski jakoś dziwnie wyszły")
- Issue: Każdy event był 24h cross-midnight (start dzień N 12:00 → dzień N+1 12:00). FC dayGrid pokazywał każdą dobę jako fragment na granicy dwóch komórek, eventy nakładały się wizualnie tworząc efekt schodków
- Fix: Zmiana na
allDay: truezstart = day(bez end). Iteracja od start_date do end_date INCLUSIVE. Każdy event w jednej komórce - Files:
api/class-rest-controller.php(pętla while) - Verification: Playwright snapshot po deploy — paski wyrównane do komórek dni, brak nakładek
- Commit: część zmiany w Task 1 (przed checkpointem) + redeploy po fix
Scope Additions
1. Native tooltip na hover
- Origin: Po zatwierdzeniu allDay fix klient poprosił o "jakiś label na hover"
- Implementation:
info.el.setAttribute('title', info.event.title + ' (' + dayStr + ')')weventDidMount - Verification: klient potwierdził OK
- Files:
frontend/assets/js/calendar-all.js
Deferred Items
None.
Issues Encountered
| Issue | Resolution |
|---|---|
| Timed events crossowały północ → "schodki" w grid | Zmiana modelu na allDay events INCLUSIVE start↔end |
Skill Audit
.paul/SPECIAL-FLOWS.md nie istnieje — skill audit pominięty.
Next Phase Readiness
Ready:
- Widget zbiorczy
[yacht_calendar_all]w pełni funkcjonalny — UX zatwierdzony przez klienta - Plugin v1.2.0 deployed
- Privacy w REST świadomie zarządzona — security audit (09-06) ma jasny precedens do oceny
Concerns:
- Privacy regression vs 09-04 —
_booking_notes(raw iCal SUMMARY) icustomer_namesą teraz publicznie wystawiane na/availability/all. Klient zaakceptował biznesowo. Security audit (09-06) powinien:- Potwierdzić że
customer_email/customer_phonenadal NIE wyciekają (są zablokowane na poziomie REST shape). - Rozważyć czy tytuły rezerwacji (zawierające imiona/nazwiska klientów) wymagają dodatkowych zabezpieczeń (np. throttling, robots noindex na endpoincie REST).
- Potwierdzić że
- Brak automatycznych testów regresji — przy kolejnych zmianach w
get_all_availability()regresja może umknąć
Blockers:
- None
Phase: 09-finalizacja, Plan: 05 Completed: 2026-05-07