# 🎯 Wdrażanie Endpoint'u Ustawień Dyscyplin

## 📋 Szybki Start

Wszystkie pliki zostały już stworzone. Aby wdrożyć system:

### 1. Pliki do wdrażania
```
✅ private_html/api/DisciplineSettingsModel.php
✅ private_html/api/DisciplineSettingsService.php  
✅ private_html/api/discipline-settings.php
✅ private_html/administration/disciplines/ping-pong/settings/index.php
✅ private_html/administration/disciplines/rock-paper-scissors/settings/index.php
✅ private_html/administration/disciplines/table-football/settings/index.php
✅ private_html/administration/disciplines/ping-pong/index.php (zaktualizowany panel)
✅ private_html/tests/discipline_settings_test.php
```

### 2. Baza danych
Tabela `settings_disciplines` jest **automatycznie tworzona** na pierwszy GET request.

Jeśli chcesz ją ręcznie stworzyć:

```sql
CREATE TABLE IF NOT EXISTS settings_disciplines (
    id INT AUTO_INCREMENT PRIMARY KEY,
    discipline VARCHAR(50) NOT NULL UNIQUE,
    
    -- Reguły gry (logika)
    pointsToWin INT NOT NULL DEFAULT 10,
    setsToWin INT NOT NULL DEFAULT 2,
    serveRotation INT NOT NULL DEFAULT 2,
    specialRules TEXT,
    
    -- Personalizacja UI (nie wpływa na logiką gry)
    customization JSON,
    
    -- Versioning ustawień
    settingsVersion INT NOT NULL DEFAULT 1,
    
    -- Metadane
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    updated_by INT,
    
    INDEX idx_discipline (discipline),
    INDEX idx_version (settingsVersion)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

---

## 🧪 Testowanie

### Test 1: Uruchom test jednostkowy
```bash
cd private_html/tests/
php discipline_settings_test.php
```

Oczekiwana odpowiedź: 10 testów PASS ✅

### Test 2: Pobierz ustawienia (cURL)
```bash
# Zaloguj się jako admin
curl -c cookies.txt -X POST \
  "http://localhost/login/login.php" \
  -d "email=admin@example.com&password=hasło"

# Pobierz ustawienia
curl -b cookies.txt \
  "http://localhost/administration/disciplines/ping-pong/settings"
```

Oczekiwana odpowiedź:
```json
{
  "success": true,
  "data": {
    "discipline": "ping-pong",
    "settingsVersion": 1,
    "rules": { ... },
    "customization": { ... }
  }
}
```

### Test 3: Pobierz snapshot (bez admin)
```bash
curl "http://localhost/api/discipline-settings.php?discipline=ping-pong&snapshot=true"
```

### Test 4: Panel administracyjny
Otwórz w przeglądarce:
```
http://localhost/administration/disciplines/ping-pong/
```

---

## 🚀 Użycie w Grze

### JavaScript - pobierz ustawienia na start meczu:
```javascript
async function loadGameSettings() {
  const response = await fetch(
    '/api/discipline-settings.php?discipline=ping-pong&snapshot=true'
  );
  const result = await response.json();
  
  if (result.success) {
    const snapshot = result.snapshot;
    
    // Uruchom grę z ustawieniami
    const game = new PingPongGame({
      pointsToWin: snapshot.rules.pointsToWin,
      setsToWin: snapshot.rules.setsToWin,
      serveRotation: snapshot.rules.serveRotation,
      settingsVersion: snapshot.settingsVersion
    });
    
    // Stosuj customization
    document.body.style.backgroundColor = snapshot.customization.tableColor;
  }
}
```

### PHP - zapisz snapshot w meczu:
```php
$model = new DisciplineSettingsModel($pdo);
$snapshot = $model->getSnapshot('ping-pong');

// Zapisz w bazie
$stmt = $pdo->prepare(
  "UPDATE matches SET settingsSnapshot = ? WHERE id = ?"
);
$stmt->execute([json_encode($snapshot), $matchId]);
```

---

## 📊 Struktura Odpowiedzi API

### GET /administration/disciplines/ping-pong/settings
```json
{
  "success": true,
  "data": {
    "discipline": "ping-pong",
    "settingsVersion": 1,
    "rules": {
      "pointsToWin": 11,
      "setsToWin": 3,
      "serveRotation": 2,
      "specialRules": "Deuce at 10-10..."
    },
    "customization": {
      "tableColor": "#2d5016",
      "ballColor": "#ff6600",
      "paddleColor": "#000000",
      "uiTheme": "dark"
    },
    "metadata": {
      "created_at": "2026-01-28 12:30:45",
      "updated_at": "2026-01-28 12:30:45",
      "updated_by": 1
    },
    "status": "custom"
  }
}
```

### POST /administration/disciplines/ping-pong/settings
```json
{
  "success": true,
  "message": "Settings for ping-pong have been updated successfully",
  "data": { ... }
}
```

### GET /api/discipline-settings.php?snapshot=true
```json
{
  "success": true,
  "snapshot": {
    "discipline": "ping-pong",
    "settingsVersion": 1,
    "rules": {
      "pointsToWin": 11,
      "setsToWin": 3,
      "serveRotation": 2,
      "specialRules": "..."
    },
    "snapshotTimestamp": "2026-01-28 12:35:10"
  }
}
```

---

## 🔐 Bezpieczeństwo

### Panel administracyjny (`/administration/disciplines/*/settings`)
- ✅ Wymaga zalogowania
- ✅ Wymaga roli `admin`
- ✅ POST zawsze wymaga admin role
- ✅ GET wymaga admin role

### API publiczny (`/api/discipline-settings.php`)
- ✅ Nie wymaga logowania
- ✅ Tylko GET
- ✅ Brak zmian
- ✅ Ratelimiting (opcjonalnie): można dodać w przyszłości

---

## 💡 Najlepsze Praktyki

### 1. Snapshot dla startu meczu
```php
// ❌ ŹLE - ustawienia mogą się zmienić w trakcie meczu
$settings = $model->getSettings('ping-pong');

// ✅ DOBRZE - snapshot z momentu startu
$snapshot = $model->getSnapshot('ping-pong');
saveMatchSnapshot($matchId, $snapshot);
```

### 2. Versioning
```php
// Każda zmiana automatycznie zwiększa wersję
// Wersja 1 → 2 → 3 → ...
$updated = $service->validateAndUpdate('ping-pong', $input, $userId);
echo $updated['settingsVersion']; // 2
```

### 3. Walidacja
```php
// ✅ Walidacja zawsze w serwisie
try {
    $result = $service->validateAndUpdate('ping-pong', $input, $userId);
} catch (InvalidArgumentException $e) {
    // Błędy walidacji
    echo "Błąd: " . $e->getMessage();
}
```

---

## 🔧 Integracja z Istniejącymi Systemami

### 1. Z tabelą matches
Dodaj kolumnę do `matches`:
```sql
ALTER TABLE matches ADD COLUMN settingsSnapshot JSON AFTER Score;
```

### 2. Z systemem meczy
```php
// Przy starcie meczu pobierz snapshot
$snapshot = $model->getSnapshot($discipline);
$match = createMatch([
    'team1_id' => $team1,
    'team2_id' => $team2,
    'settingsSnapshot' => json_encode($snapshot)
]);
```

### 3. Z systemem auditowania
```php
// Log zmian
$before = $service->getSettingsForAPI('ping-pong');
$service->validateAndUpdate('ping-pong', $input, $adminId);
$after = $service->getSettingsForAPI('ping-pong');
$changes = $service->compareVersions($before, $after);
logAuditEvent('settings_updated', [
    'discipline' => 'ping-pong',
    'changes' => $changes,
    'admin_id' => $adminId
]);
```

---

## 📈 Rozszerzenia w Przyszłości

### Historia zmian
```sql
CREATE TABLE settings_disciplines_history (
    id INT AUTO_INCREMENT PRIMARY KEY,
    discipline VARCHAR(50),
    version INT,
    settings JSON,
    changed_by INT,
    changed_at DATETIME,
    PRIMARY KEY (discipline, version)
);
```

### Scheduled changes
```php
// Zmiana ustawień w określonym czasie
INSERT INTO settings_scheduled_changes (
    discipline, 
    settings_json, 
    scheduled_at
) VALUES ('ping-pong', '...', '2026-02-01 00:00:00');
```

### A/B testing
```php
// Różne ustawienia dla różnych grup graczy
INSERT INTO settings_ab_tests (
    discipline,
    variant_a, 
    variant_b,
    split_percentage
) VALUES ('ping-pong', '...', '...', 50);
```

---

## ⚠️ Troubleshooting

### Problem: "Table not found"
**Rozwiązanie:** Tabela tworzy się automatycznie na pierwszy GET. Jeśli nie działa:
```php
$model = new DisciplineSettingsModel($pdo);
$model->ensureTableExists(); // Ręczne wywołanie
```

### Problem: "Invalid JSON"
**Rozwiązanie:** Sprawdź czy customization jest poprawnym JSON:
```php
json_validate($input['customization']); // PHP 8.3+
// lub
json_last_error() === JSON_ERROR_NONE
```

### Problem: "Validation failed - odd numbers"
**Rozwiązanie:** pointsToWin i setsToWin muszą być nieparzyste:
- ✅ Poprawne: 11, 21, 3, 5
- ❌ Błędne: 10, 20, 2, 4

---

## 📞 Wsparcie

Jeśli masz problemy:

1. Sprawdź logi: `error_log` w PHP
2. Uruchom testy: `php discipline_settings_test.php`
3. Sprawdź logowanie: czy jesteś zalogowany jako admin?
4. Walidacja: czy dane spełniają wymagania?

