Files
2026-05-08 00:12:37 +02:00

6.5 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 06 ui, api
fullcalendar
validRange
rest
ux
phase provides
09-finalizacja widget zbiorczy `[yacht_calendar_all]` + REST `/availability/all` (09-04, 09-05)
REST endpoint `/availability/bounds` (publiczny, max booking date)
JS bootstrap fetch bounds przed init FullCalendar
validRange w FullCalendar (prev disabled na bieżącym miesiącu, next disabled po miesiącu max booking)
security audit (09-07) — kolejny publiczny endpoint do oceny
added patterns
bootstrap fetch w JS (osobny request przed instancjacją FC) + graceful degradation w fail callback
publiczny REST endpoint zwracający tylko zagregowaną datę (brak ujawnienia rezerwacji)
validRange jako kontrakt server↔client dla nawigacji
created modified
wp-content/plugins/yacht-booking-system/api/class-rest-controller.php
wp-content/plugins/yacht-booking-system/frontend/assets/js/calendar-all.js
wp-content/plugins/yacht-booking-system/yacht-booking-system.php
Endpoint publiczny (`__return_true`) — frontend renderuje widget dla anonimowych userów
Filtr `_booking_end_date >= dziś` — historyczne rezerwacje nie rozszerzają zakresu w przyszłość
Graceful degradation: fail bounds → kalendarz bez validRange (lepsze niż brak kalendarza)
validRange.end exclusive (pierwszy dzień miesiąca PO maxDate) — daje cały miesiąc maxDate dostępny
Boundary endpoints: lekkie REST endpointy zwracające metadane (max date, count) zamiast zagregowanych danych — minimalizuje payload + privacy
Fetch-before-init pattern w FullCalendar: jeden bootstrap call, potem instancjacja z opcjami zależnymi od odpowiedzi
~25min 2026-05-08T00:00:00Z 2026-05-08T00:25:00Z

Phase 09 Plan 06: Blokada nawigacji kalendarza

Kalendarz zbiorczy [yacht_calendar_all] na /rezerwacja/ blokuje nawigację: prev disabled na bieżącym miesiącu, next disabled po miesiącu zawierającym ostatnią rezerwację confirmed/pending — bazując na nowym publicznym REST endpoint /availability/bounds.

Performance

Metric Value
Duration ~25min
Started 2026-05-08T00:00:00Z
Completed 2026-05-08T00:25:00Z
Tasks 3 auto + 1 checkpoint
Files modified 3

Acceptance Criteria Results

Criterion Status Notes
AC-1: REST zwraca max booking date Pass get_availability_bounds() filtruje confirmed/pending + end >= dziś, sortuje DESC po _booking_end_date
AC-2: Brak rezerwacji → null Pass max_booking_date: null gdy get_posts pusty
AC-3: Prev disabled w bieżącym miesiącu Pass validRange.start = pierwszy dzień bieżącego miesiąca — FC sam wyłącza prev
AC-4: Next disabled na miesiącu max booking Pass validRange.end = pierwszy dzień miesiąca PO maxDate (exclusive)
AC-5: Next disabled gdy brak rezerwacji Pass rangeEnd = nextMonthFirst(today) gdy maxDate null lub w przeszłości
AC-6: Nawigacja w obrębie zakresu Pass Klient zatwierdził w checkpoincie

Accomplishments

  • REST /availability/bounds — lekki publiczny endpoint zwracający tylko { max_booking_date }, z filtrem statusu (confirmed/pending) i end_date >= dziś.
  • Bootstrap fetch w JS — bounds pobierane przed instancjacją FC, z graceful degradation w fail callback.
  • validRange w FullCalendar — start = pierwszy dzień bieżącego miesiąca (prev blocked), end = pierwszy dzień miesiąca PO miesiącu ostatniej rezerwacji (exclusive — daje cały miesiąc maxDate dostępny).
  • Plugin v1.2.1 — cache busting po deploy.

Files Created/Modified

File Change Purpose
api/class-rest-controller.php Modified Nowy route /availability/bounds + metoda get_availability_bounds() (sortowanie DESC po meta_value DATE, filtr status + end_date >= dziś)
frontend/assets/js/calendar-all.js Modified Helpers firstOfMonth/nextMonthFirst; initCalendar rozdzielony na fetch bounds + nową funkcję buildCalendar z validRange
yacht-booking-system.php Modified Bump 1.2.0 → 1.2.1

Decisions Made

Decision Rationale Impact
Endpoint publiczny Frontend renderuje widget dla anonimowych userów; brak nonce wymaga __return_true Każdy odwiedzający może zobaczyć datę ostatniej rezerwacji (security audit do oceny)
Filtr end_date >= dziś w SQL Historyczne rezerwacje nie powinny rozszerzać zakresu w przyszłość Próba np. usunięcia ostatniej przyszłej rezerwacji od razu skraca dostępny zakres po reload
Graceful degradation w fail Lepiej pokazać kalendarz bez validRange niż wcale Awaria endpointu nie psuje strony; userzy nadal widzą kalendarz
validRange.end exclusive FC tak interpretuje validRange — exclusive end nextMonthFirst(maxDate) daje cały miesiąc maxDate dostępny

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 0
Scope additions 0
Deferred 0

Total impact: Plan wykonany dokładnie jak zaplanowany. Brak iteracji UX po checkpoincie.

Deferred Items

None.

Issues Encountered

Issue Resolution
Edit z literówką new_str ng zamiast new_string Powtórzony Edit z prawidłowym kluczem

Skill Audit

.paul/SPECIAL-FLOWS.md nie istnieje — skill audit pominięty.

Next Phase Readiness

Ready:

  • Widget zbiorczy /rezerwacja/ w pełni funkcjonalny i ograniczony do sensownego zakresu dat
  • Kolejny publiczny endpoint /availability/bounds do uwzględnienia w security audit (09-07)
  • Plugin v1.2.1 deployed

Concerns:

  • Trzy publiczne endpointy w REST API (/availability/{yacht_id}, /availability/all, /availability/bounds) — security audit (09-07) powinien przeanalizować łącznie:
    1. Czy /bounds przez ujawnienie max_booking_date nie daje informacji wrażliwej (typowo nie — tylko data graniczna).
    2. Czy /all nadal nie wycieka customer_email/customer_phone (potwierdzono w 09-05 że nie).
    3. Throttling/rate-limiting publicznych endpointów.
  • Brak automatycznych testów — regresje w validRange mogą umknąć przy kolejnych zmianach JS

Blockers:

  • None

Phase: 09-finalizacja, Plan: 06 Completed: 2026-05-08