---
phase: 07-pre-expansion-fixes
plan: 02
subsystem: security, infra
tags: [ssl, curl, cron-throttle, migration-dedup, app-settings]

requires:
  - phase: 06-sonarqube-quality
    provides: ApiClient classes refactored
provides:
  - SSL verification in all 4 ApiClient classes
  - DB-backed cron web throttle (no more $_SESSION dependency)
  - Deduplicated migration sequence (000014b)
affects: [07-03, 07-04, 07-05]

tech-stack:
  added: []
  patterns: [getCaBundlePath-per-client, app-settings-as-kv-store]

key-files:
  created:
    - database/migrations/20260314_000049_add_cron_last_run_at_setting.sql
  modified:
    - src/Modules/Settings/AllegroApiClient.php
    - src/Modules/Settings/AllegroOAuthClient.php
    - src/Modules/Settings/ShopproApiClient.php
    - src/Modules/Settings/ApaczkaApiClient.php
    - src/Core/Application.php
    - .env.example
    - database/migrations/20260301_000014b_add_products_sku_format_setting.sql (renamed)

key-decisions:
  - "getCaBundlePath() per class — no shared trait, acceptable duplication for 4 classes"
  - "ON DUPLICATE KEY UPDATE with named params :ts/:ts2 (PDO limitation — no repeated named params)"

patterns-established:
  - "SSL: CURLOPT_SSL_VERIFYPEER=true + CURLOPT_SSL_VERIFYHOST=2 + CURLOPT_CAINFO in every curl call"
  - "app_settings as key-value store for cross-session state"

duration: ~10min
started: 2026-03-14
completed: 2026-03-14
---

# Phase 7 Plan 02: SSL + Cron Throttle + Migration Dedup Summary

**SSL verification w 4 ApiClient klasach, cron throttle przeniesiony z $_SESSION do app_settings DB, deduplikacja migracji 000014**

## Performance

| Metric | Value |
|--------|-------|
| Duration | ~10min |
| Started | 2026-03-14 |
| Completed | 2026-03-14 |
| Tasks | 3 completed |
| Files modified | 8 (6 modified, 1 created, 1 renamed) |

## Acceptance Criteria Results

| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: SSL weryfikowany w każdym cURL wywołaniu | Pass | 6 curl_setopt_array blocks w 4 plikach mają CURLOPT_SSL_VERIFYPEER=true + VERIFYHOST=2 + CAINFO |
| AC-2: Web cron throttle oparty na DB | Pass | $_SESSION['cron_web_last_run_at'] usunięty; getWebCronLastRunAt()/setWebCronLastRunAt() czytają/piszą app_settings |
| AC-3: Migracja 000014 zdeduplikowana | Pass | git mv → 000014b; INSERT ON DUPLICATE KEY UPDATE (idempotentna) |

## Accomplishments

- 4 klasy ApiClient (6 miejsc cURL) zabezpieczone SSL verification z fallback chain: ENV → XAMPP → system
- Cron web throttle nie zależy od sesji — działa poprawnie przy wielu aktywnych sesjach
- Sekwencja migracji czysta — brak duplikatów numerów

## Files Created/Modified

| File | Change | Purpose |
|------|--------|---------|
| `src/Modules/Settings/AllegroApiClient.php` | Modified | SSL opts w postJson(), postBinary(), requestJson() + getCaBundlePath() |
| `src/Modules/Settings/AllegroOAuthClient.php` | Modified | SSL opts w requestToken() + getCaBundlePath() |
| `src/Modules/Settings/ShopproApiClient.php` | Modified | SSL opts w requestJson() + getCaBundlePath() |
| `src/Modules/Settings/ApaczkaApiClient.php` | Modified | SSL opts w executeRequest() + getCaBundlePath() |
| `src/Core/Application.php` | Modified | isWebCronThrottled() → app_settings; +getWebCronLastRunAt(), +setWebCronLastRunAt() |
| `.env.example` | Modified | Dodano CURL_CA_BUNDLE_PATH |
| `database/migrations/20260314_000049_add_cron_last_run_at_setting.sql` | Created | Seed cron_web_last_run_at w app_settings |
| `database/migrations/20260301_000014b_...` | Renamed | git mv z 000014 na 000014b |

## Decisions Made

| Decision | Rationale | Impact |
|----------|-----------|--------|
| getCaBundlePath() w każdej klasie osobno | Brak wspólnego traita/klasy bazowej; 4 kopie to akceptowalna duplikacja vs. przedwczesna abstrakcja | Przyszła refaktoryzacja może wydzielić trait |
| PDO named params :ts/:ts2 w ON DUPLICATE KEY | PDO nie pozwala na powtórzenie tego samego named param; użyto dwóch nazw | Standardowy workaround |

## Deviations from Plan

### Summary

| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed | 1 | Minimal |
| Scope additions | 0 | - |
| Deferred | 0 | - |

**Total impact:** Minimalna odchyłka — data pliku migracji zmieniona z 20260313 na 20260314.

### Auto-fixed Issues

**1. Data migracji**
- **Found during:** Task 2
- **Issue:** Plan proponował `20260313_000049`, ale wykonanie było 2026-03-14
- **Fix:** Użyto `20260314_000049` zgodnie z datą wykonania
- **Verification:** Plik istnieje, spójna konwencja nazewnicza

## Issues Encountered

None

## Next Phase Readiness

**Ready:**
- Wszystkie ApiClienty bezpieczne pod SSL — nowe integracje mogą kopiować wzorzec
- Cron throttle stabilny dla wielu sesji
- Plan 07-03 (UX fixes) niezależny, może być wykonany natychmiast

**Concerns:**
- Migracja 000049 wymaga uruchomienia na środowisku docelowym

**Blockers:**
- None

---
*Phase: 07-pre-expansion-fixes, Plan: 02*
*Completed: 2026-03-14*
