This commit is contained in:
2026-05-06 23:16:47 +02:00
parent ea77c8ea35
commit c4a485e530
23 changed files with 2141 additions and 1772 deletions

View File

@@ -0,0 +1,184 @@
---
phase: 09-finalizacja
plan: 03
subsystem: cleanup
tags: [cleanup, oauth-removal, ical-consolidation, migration]
requires:
- phase: 09-finalizacja/09-02
provides: globalna iCal sync (export feed + import + alias) — staje się jedynym mechanizmem po usunięciu konkurencji
provides:
- Plugin z jednym mechanizmem GCal sync (globalny iCal)
- Cleanup migration "po cichu" (Installer::migrate, idempotent, version-aware)
- Czysta baza po upgrade (4 stale meta keys + 6 stale options + per-yacht ical_import bookings + 5 cron hooków usuniętych)
- Skrócony codebase (~700 linii martwego kodu usuniętych, 3 pliki OAuth znikają)
affects:
- 09-04 Security audit — mniej powierzchni do auditu
- 09-05 Testy + i18n + dokumentacja — mniej do udokumentowania
- przyszłe milestone'y v1.x — czysty fundament bez OAuth dependencies
tech-stack:
added: []
patterns:
- "Idempotent version-gated migration: Installer::migrate() porównuje get_option('yacht_booking_version') z YACHT_BOOKING_VERSION i wykonuje cleanup tylko przy upgrade"
- "Cleanup po cichu — bez admin notice, klient nie musi wykonywać żadnych akcji ręcznych"
key-files:
created: []
modified:
- wp-content/plugins/yacht-booking-system/yacht-booking-system.php
- wp-content/plugins/yacht-booking-system/includes/class-yacht-booking.php
- wp-content/plugins/yacht-booking-system/includes/class-yacht.php
- wp-content/plugins/yacht-booking-system/includes/class-installer.php
- wp-content/plugins/yacht-booking-system/admin/class-admin.php
- wp-content/plugins/yacht-booking-system/admin/views/yacht-edit.php
- wp-content/plugins/yacht-booking-system/admin/class-yacht-list-table.php
- wp-content/plugins/yacht-booking-system/integrations/ical/class-ical-import.php
- wp-content/plugins/yacht-booking-system/integrations/ical/class-ical-feed.php
- wp-content/plugins/yacht-booking-system/uninstall.php
deleted:
- wp-content/plugins/yacht-booking-system/integrations/google-calendar/class-sync-controller.php
- wp-content/plugins/yacht-booking-system/integrations/google-calendar/class-gcal-service.php
- wp-content/plugins/yacht-booking-system/integrations/google-calendar/class-oauth-handler.php
key-decisions:
- "Per-yacht bookings z source 'ical_import' — usuwamy w migration (klient ponownie zaimportuje przez globalny mechanizm), zamiast migrować je do source 'ical_import_global'"
- "Migration idempotentna przez version_compare — kolejna aktywacja nie powtarza cleanup"
- "Bez admin notice po migration — klient wybrał 'po cichu'"
- "Per-yacht feedy iCal usunięte całkowicie (nie zostawione jako fallback) — model mentalny: jeden mechanizm"
patterns-established:
- "Wersja-aware cleanup w Installer::install() — pattern do reuse w przyszłych planach refaktorujących/usuwających legacy"
- "FQN namespace + lazy require_once dla klas używanych w activation hook (przed ładowaniem bootstrap)"
duration: ~30min
started: 2026-05-06T11:30:00Z
completed: 2026-05-06T12:00:00Z
---
# Phase 9 Plan 03: Cleanup OAuth + per-yacht iCal Summary
**Wycofanie OAuth (3 pliki + cała sekcja UI), per-yacht iCal feed/import (pole "Google Calendar ID", "iCal Import URL", kolumna w yacht-list, cron) z bezgłośną migracją bazy — plugin sprowadzony do jednego mechanizmu sync (globalny iCal z 09-02).**
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~30min |
| Tasks | 3 auto + 1 human-verify (wszystkie zaakceptowane) |
| Files modified | 10 |
| Files deleted | 3 |
| Lines removed | ~700+ (3 OAuth files + per-yacht iCal + UI + handlers) |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Pliki OAuth usunięte i nie ładowane | Pass | 3 pliki + katalog `integrations/google-calendar/` usunięte. Bootstrap (`yacht-booking-system.php`, `class-yacht-booking.php`) bez require/wiring. PHP lint OK. |
| AC-2: Sekcja OAuth zniknęła z Settings | Pass | `render_google_calendar_settings()` zawiera tylko nagłówek + sekcję "Globalna synchronizacja iCal". Usunięte: handle_oauth_callback, save_gcal_credentials, callback/disconnect/credentials w process_settings_save, notice connected/disconnected. |
| AC-3: Pola per-jacht zniknęły z yacht-edit i yacht-list | Pass | yacht-edit nie ma "Google Calendar ID", "iCal Import URL", "iCal Feed URL". Ma tylko Alias. Lista jachtów bez kolumny "Google Calendar". |
| AC-4: Per-jacht iCal cron i feed wyłączone | Pass | Cron `yacht_booking_ical_import` nie rejestrowany. Rewrite rule `^yacht-ical/(\d+)/...` usunięta — URL per-yacht zwróci 404. Globalny `^yacht-ical-global/...` aktywny. |
| AC-5: Cleanup migration | Pass | `Installer::migrate()` — version-gated. Kasuje 4 meta keys (delete_post_meta_by_key), 6 opcji OAuth, bookings z source 'ical_import' (Availability::clear_booking_availability + wp_delete_post), 5 cron hooków. |
| AC-6: Globalna iCal sync bez regresji | Pass | Boundary chronił z 09-02 — wszystkie globalne metody/UI/cron nietknięte, alias zachowany. |
| AC-7: uninstall.php zaktualizowany | Pass | Dodane delete_option dla `yacht_booking_global_ical_*`, `yacht_booking_enabled`. Defensywne delete_option dla legacy gcal_* keys. |
## Accomplishments
- Plugin ma JEDEN spójny mechanizm sync z GCal (globalny iCal), zamiast 4 (OAuth push, OAuth pull, per-yacht iCal feed, per-yacht iCal import) — drastyczne zmniejszenie powierzchni mentalnej i bug surface
- Czysta baza po automatycznej migracji — klient nie wykonuje żadnych akcji ręcznych, niepotrzebne meta i opcje znikają przy następnej aktywacji pluginu
- Codebase odchudzony o ~700+ linii martwego kodu (3 pliki OAuth/Sync + UI/CRUD per-yacht iCal)
- Zero regresji w globalnej iCal sync ani frontendzie (kalendarz widget, REST API, CPT, availability) — boundaries respektowane
- Plugin gotowy produkcyjnie w warstwie integracji GCal — pozostają tylko 09-04 (security audit) i 09-05 (testy + i18n + docs) do zamknięcia milestone v1.0
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `integrations/google-calendar/class-sync-controller.php` | **Deleted** | OAuth orchestrator usunięty całkowicie |
| `integrations/google-calendar/class-gcal-service.php` | **Deleted** | Google Calendar API calls usunięte |
| `integrations/google-calendar/class-oauth-handler.php` | **Deleted** | OAuth tokens + credentials usunięte |
| `yacht-booking-system.php` | Modified | Wycięte require + setup_cron + clear_cron Sync_Controller w activate/deactivate hooks |
| `includes/class-yacht-booking.php` | Modified | Wycięte 3 require_once + Sync_Controller::get_instance/register_cron_actions w `load_dependencies()` |
| `includes/class-yacht.php` | Modified | Usunięte `get_gcal_id()`, `update_gcal_id()` |
| `includes/class-installer.php` | Modified | Dodana `migrate()` (version-gated, idempotent), usunięty `yacht_booking_gcal_sync_enabled` z create_options |
| `admin/class-admin.php` | Modified | Wycięte: handle_oauth_callback, save_gcal_credentials, OAuth bloki w process_settings_save i display_admin_notices, cała sekcja OAuth w render_google_calendar_settings, save_yacht zapisuje tylko alias |
| `admin/views/yacht-edit.php` | Modified | Usunięte 3 wiersze tabeli (Google Calendar ID, iCal Import URL, iCal Feed URL) + 4 zmienne PHP. Pozostaje Alias. |
| `admin/class-yacht-list-table.php` | Modified | Usunięta kolumna `gcal` z get_columns + metoda column_gcal |
| `integrations/ical/class-ical-import.php` | Modified | Usunięte: const IMPORT_SOURCE, run_import, get_import_url, set_import_url, import_for_yacht, get_existing_import_map, upsert_booking, get_last_import_time. Cron 'yacht_booking_ical_import' nie rejestrowany. |
| `integrations/ical/class-ical-feed.php` | Modified | Usunięte: rewrite rule per-yacht, query var yacht_ical_id, branch per-yacht w handle_feed_request, output_ics, get_feed_token, regenerate_token, get_feed_url. Pozostaje globalna ścieżka. |
| `uninstall.php` | Modified | Dodane: yacht_booking_global_ical_*, yacht_booking_enabled. Defensywne legacy gcal_* delete_option. |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Usunięcie per-yacht bookings 'ical_import' w migration | Bez per-yacht importu nie będą odświeżane — lepsze UX usunąć i pozwolić ponowny globalny import niż zostawić "skamieniałe" blokady | Klient po deploy uruchamia "Importuj teraz" raz i ma świeże dane |
| Migration version-gated z version_compare | Idempotencja — kolejna aktywacja po pierwszej nie powtarza cleanup, bezpieczne dla repeated activate/deactivate | Zero ryzyka przy ręcznych re-aktywacjach lub WP auto-update |
| FQN dla `\YachtBooking\Availability` w migrate() | Activation hook ładuje Installer ręcznie przed bootstrap — autoloader może być nieaktywny | Lazy require_once jako fallback wewnątrz pętli `if (!class_exists)` |
| Defensywne delete_option dla legacy gcal_* w uninstall.php | Migration usuwa je przy upgrade, ale uninstall.php może być uruchomiony bezpośrednio na starszej wersji bez upgrade | Wszystkie ścieżki sprzątają legacy keys |
| Brak admin notice po migration | Klient w fazie planowania wybrał "po cichu" — żeby nie zaprzątać uwagi | Płynne UX, klient zauważy tylko że stare pola znikły |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 1 | Drobny |
| Scope additions | 0 | — |
| Deferred | 0 | — |
**Total impact:** Plan wykonany w pełni, jeden drobny auto-fix dla bezpieczeństwa.
### Auto-fixed Issues
**1. [Migration safety] Availability class loading w activation hook**
- **Found during:** Task 3 (Installer::migrate)
- **Issue:** Migration wywołuje `\YachtBooking\Availability::clear_booking_availability()`, ale Installer jest ładowany przez activation hook PRZED `plugins_loaded` (gdzie autoloader spl_autoload_register() jest rejestrowany). Pierwotna implementacja zakładała że Availability jest dostępne automatycznie.
- **Fix:** Dodany guard `if ( ! class_exists( '\YachtBooking\Availability' ) ) { require_once YACHT_BOOKING_PLUGIN_DIR . 'includes/class-availability.php'; }` przed pętlą usuwającą stale bookings. Dodatkowo otoczone `if (!empty($stale_bookings))` żeby nie ładować pliku gdy nie ma nic do usunięcia.
- **Files:** includes/class-installer.php
- **Verification:** PHP lint OK; logika idempotentna; w testach klient potwierdził że upgrade nie powoduje fatal error.
### Deferred Items
Brak.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| Brak konkretnych fatal errors lub regresji | — |
## Reproduction Path (do testów regresyjnych)
1. Po deploy FTP — aktywuj plugin (lub deactivate→activate na produkcji). Wyzwoli `Installer::install()``migrate()`.
2. Sprawdź WP Admin → Settings → Google Calendar: tylko sekcja "Globalna synchronizacja iCal" (z 09-02).
3. Sprawdź edycję jachtu: brak "Google Calendar ID"/"iCal Import URL"/"iCal Feed URL". Jest tylko "Alias dla Google Calendar".
4. Lista jachtów: brak kolumny "Google Calendar".
5. URL `/yacht-ical/X/token.ics` → 404. URL `/yacht-ical-global/{token}.ics` → poprawny .ics.
6. phpMyAdmin: brak meta `_yacht_gcal_id`/`_yacht_ical_*`, brak opcji `yacht_booking_gcal_*` (poza globalnymi `*_global_ical_*`), brak bookingów z source `ical_import`.
7. Druga aktywacja → migrate() nie powtarza cleanup (version match).
## Next Phase Readiness
**Ready:**
- Codebase czysty, 1 mechanizm GCal sync
- Migration mechanizm gotowy do reuse w przyszłych planach refaktorujących
- Plugin z punktu widzenia integracji GCal jest produkcyjnie skończony
**Concerns:**
- Klient po deploy musi pamiętać o uruchomieniu globalnego "Importuj teraz" w Settings, żeby ponownie zaimportować eventy z Google Calendar (stare per-yacht zostały skasowane). Mitigacja: zostało udokumentowane w checkpoint verify steps.
- `yacht_booking_capabilities_added` flag jest sprawdzany raz w `Yacht_Booking::add_custom_capabilities()` — zachowany w uninstall.php. Nie ruszamy go.
**Blockers:** None
## Otwarte kwestie milestone v1.0
- 09-04: Security audit (nonce, escaping, SQL prepare, capabilities)
- 09-05: Testy + tłumaczenia .pot/.po/.mo + dokumentacja użytkownika i dewelopera
---
*Phase: 09-finalizacja, Plan: 03*
*Completed: 2026-05-06*