# ROADMAP ROZWOJU - IPTV Panel
## Szczegółowa analiza kodu i propozycje zmian

**Data analizy:** 23.12.2025  
**Wersja:** 1.0  
**Łączna ilość kodu:** ~17,000 linii (PHP + Smarty)

---

# 📊 STATYSTYKI PROJEKTU

| Kategoria | Ilość |
|-----------|-------|
| Pliki PHP | 28 |
| Szablony .tpl | 35+ |
| Kontrolery | 16 |
| Klasy modeli | 12 |
| Zapytania SQL | ~283 |
| Endpointy routingu | 80+ |

---

# 🔴 KATEGORIA A: BŁĘDY I PROBLEMY DO NAPRAWY

## A1. Walidacja formularzy
**Problem:** Niespójne walidacje HTML5 vs PHP
**Lokalizacja:** templates/users/form.tpl, templates/devices/form.tpl
**Opis:** 
- Atrybuty `required`, `minlength`, `pattern` na ukrytych/disabled polach powodują błędy
- Walidacja JS nie zawsze zsynchronizowana z PHP

**Rozwiązanie:**
```php
// Dodać klasę Validator
class Validator {
    public static function rules(): array;
    public static function validate(array $data, array $rules): array;
    public static function toHtmlAttributes(array $rules): string;
}
```

## A2. Obsługa błędów SQL
**Problem:** Nie wszystkie zapytania mają try-catch
**Lokalizacja:** classes/*.php
**Opis:** 36 bloków try-catch na 283 zapytania = ~13% pokrycia

**Rozwiązanie:**
- Wrapper w Database class dla wszystkich operacji
- Centralne logowanie błędów SQL
- Graceful degradation

## A3. Memory leaks przy dużych zbiorach
**Problem:** Brak paginacji w niektórych metodach
**Lokalizacja:** 
- `User::getVisibleUserIds()` - ładuje wszystkich
- `Reports::getUserActivityReport()` - brak limitu

**Rozwiązanie:**
- Dodać generators (yield) dla dużych zbiorów
- Streaming dla exportu CSV
- Lazy loading w raportach

## A4. N+1 Query Problem
**Problem:** Subqueries w pętlach
**Lokalizacja:** classes/Device.php, classes/Playlist.php
**Opis:** 
```sql
-- Każde urządzenie = dodatkowe query dla notes_count
(SELECT COUNT(*) FROM entity_notes WHERE entity_id = d.id)
```

**Rozwiązanie:**
- JOIN zamiast subquery
- Eager loading w jednym zapytaniu
- Cache dla często używanych counts

## A5. Brak transakcji
**Problem:** Operacje wielokrokowe bez transakcji
**Lokalizacja:** 
- DeviceController::clone() - kopiuje urządzenie + playlisty
- UserController::delete() - kaskadowe usuwanie

**Rozwiązanie:**
```php
$db->beginTransaction();
try {
    // operacje
    $db->commit();
} catch (Exception $e) {
    $db->rollback();
}
```

## A6. Race conditions
**Problem:** Brak blokad przy update'ach
**Lokalizacja:** Auth::createSession(), User::update()
**Opis:** Możliwe nadpisanie danych przy równoczesnym dostępie

**Rozwiązanie:**
- SELECT FOR UPDATE
- Optimistic locking (version column)
- Mutex dla krytycznych sekcji

## A7. Inconsistent error messages
**Problem:** Różne formaty błędów w różnych miejscach
**Opis:**
- `['success' => false, 'error' => '...']`
- `['success' => false, 'message' => '...']`
- Czasem `throw new Exception`

**Rozwiązanie:**
- Ustandaryzować Response class
- Jednolite kody błędów
- I18n dla komunikatów

---

# 🟠 KATEGORIA B: BEZPIECZEŃSTWO

## B1. Rate Limiting API
**Problem:** Brak throttlingu na /api/playlist.php
**Ryzyko:** DDoS, brute force

**Rozwiązanie:**
```php
class ApiRateLimiter {
    public function check(string $ip, string $mac): bool;
    public function increment(string $ip, string $mac): void;
    // Redis/APCu backend
}
```

**Konfiguracja:**
- 100 req/min per IP
- 60 req/min per MAC
- Exponential backoff przy przekroczeniu

## B2. Słabe szyfrowanie API
**Problem:** XOR encryption jest trywialne do złamania
**Lokalizacja:** api/playlist.php

**Rozwiązanie:**
- AES-256-GCM encryption
- HMAC dla integrity
- Key rotation
- Opcjonalnie: JWT tokens

```php
class ApiEncryption {
    public static function encrypt(array $data, string $key): string;
    public static function decrypt(string $data, string $key): ?array;
}
```

## B3. Session fixation
**Problem:** Token nie jest regenerowany po login
**Lokalizacja:** Auth::login()

**Rozwiązanie:**
- Regeneruj token po każdym login
- Bind session do IP + User-Agent
- Sliding expiration

## B4. Missing security headers
**Problem:** Brak CSP, X-Frame-Options, etc.
**Lokalizacja:** index.php, api/playlist.php

**Rozwiązanie:**
```php
// middleware/SecurityHeaders.php
header('Content-Security-Policy: default-src \'self\'');
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: geolocation=(), microphone=()');
```

## B5. SQL Injection vectors
**Problem:** Dynamiczne ORDER BY, LIMIT
**Lokalizacja:** Device::getAll(), Playlist::getAll()

**Rozwiązanie:**
- Whitelist dla kolumn sortowania
- Walidacja parametrów paginacji
```php
$allowedColumns = ['created_at', 'name', 'mac'];
if (!in_array($orderBy, $allowedColumns)) {
    $orderBy = 'created_at';
}
```

## B6. Sensitive data exposure
**Problem:** Hasła playlist (Xtream) w logach
**Lokalizacja:** AuditLog

**Rozwiązanie:**
- Maskowanie w UI (opcjonalne pokazywanie)
- Szyfrowanie w bazie (at rest)
- Audit log: hash zamiast plain text

## B7. CSRF na API
**Problem:** API nie wymaga CSRF
**Lokalizacja:** api/playlist.php

**Rozwiązanie:**
- API key authentication
- Request signing (HMAC)
- Timestamp validation (replay attack prevention)

## B8. Brak 2FA
**Problem:** Single factor authentication

**Rozwiązanie:**
```php
class TwoFactorAuth {
    public function generateSecret(): string;
    public function getQRCode(string $secret, string $username): string;
    public function verify(string $secret, string $code): bool;
}
// Biblioteka: pragmarx/google2fa
```

## B9. Password policy
**Problem:** Tylko minlength=6, brak wymogów złożoności

**Rozwiązanie:**
- Konfigurowalne reguły w settings
- Minimum: długość, wielkie/małe, cyfry, znaki specjalne
- Blacklist popularnych haseł
- Have I Been Pwned API integration

## B10. Audit log retention
**Problem:** Brak automatycznego czyszczenia audit logów
**Ryzyko:** Nieograniczony wzrost bazy

**Rozwiązanie:**
- CRON job do archiwizacji
- Kompresja starych logów
- Konfigurowalna retencja per log type

---

# 🟡 KATEGORIA C: ARCHITEKTURA I KOD

## C1. Dependency Injection
**Problem:** Hardcoded `new Class()` wszędzie
**Lokalizacja:** Wszystkie kontrolery i klasy

**Obecny stan:**
```php
public function __construct() {
    $this->db = Database::getInstance();
    $this->logger = new Logger();
}
```

**Rozwiązanie:**
```php
// Container
class Container {
    public function get(string $class): object;
    public function bind(string $interface, string $implementation): void;
}

// Użycie
public function __construct(Database $db, Logger $logger) {
    $this->db = $db;
    $this->logger = $logger;
}
```

## C2. Service Layer
**Problem:** Logika biznesowa w kontrolerach
**Lokalizacja:** PlaylistController (814 linii), AdminController (1120 linii)

**Rozwiązanie:**
```
controllers/          -> tylko routing, walidacja, response
services/
  ├── UserService.php
  ├── DeviceService.php
  ├── PlaylistService.php
  └── ReportService.php
repositories/         -> tylko dostęp do danych
```

## C3. Repository Pattern
**Problem:** SQL queries rozproszone w klasach
**Korzyści:** Testowalność, zamienność backend (SQLite→MySQL)

**Rozwiązanie:**
```php
interface UserRepositoryInterface {
    public function findById(int $id): ?User;
    public function findByUsername(string $username): ?User;
    public function save(User $user): void;
}

class SQLiteUserRepository implements UserRepositoryInterface {}
class MySQLUserRepository implements UserRepositoryInterface {}
```

## C4. Event System
**Problem:** Brak hooków dla rozszerzeń
**Korzyści:** Pluginy, async processing, audit

**Rozwiązanie:**
```php
class EventDispatcher {
    public function dispatch(string $event, array $payload): void;
    public function listen(string $event, callable $handler): void;
}

// Użycie
$dispatcher->dispatch('user.created', ['user' => $user]);
$dispatcher->dispatch('playlist.updated', ['old' => $old, 'new' => $new]);
```

## C5. DTO (Data Transfer Objects)
**Problem:** Arraye wszędzie, brak type safety
**Lokalizacja:** Wszystkie klasy

**Obecny stan:**
```php
public function create(array $data): array
```

**Rozwiązanie:**
```php
class CreatePlaylistDTO {
    public string $name;
    public string $type;
    public int $deviceId;
    public array $config;
    
    public static function fromRequest(Request $request): self;
}

class PlaylistEntity {
    public int $id;
    public string $name;
    // ...
}
```

## C6. Caching Layer
**Problem:** Brak cache, każdy request = query do DB
**Lokalizacja:** Settings, User permissions, często używane dane

**Rozwiązanie:**
```php
interface CacheInterface {
    public function get(string $key): mixed;
    public function set(string $key, mixed $value, int $ttl = 3600): void;
    public function delete(string $key): void;
    public function tags(array $tags): self;
}

// Implementacje
class FileCache implements CacheInterface {}
class RedisCache implements CacheInterface {}
class APCuCache implements CacheInterface {}
```

**Zastosowanie:**
- Settings: cache forever, invalidate on save
- User permissions: 5 min TTL
- Dashboard stats: 1 min TTL
- API responses: per MAC, 30 sec TTL

## C7. Queue System
**Problem:** Wszystko synchronicznie (maile, heavy operations)

**Rozwiązanie:**
```php
interface QueueInterface {
    public function push(Job $job): void;
    public function pop(): ?Job;
    public function process(): void;
}

class SendEmailJob extends Job {
    public function handle(): void;
}

// Worker (cron)
$queue->process();
```

## C8. Middleware Pattern
**Problem:** Powtarzający się kod w kontrolerach (auth, csrf, logging)

**Rozwiązanie:**
```php
// Middleware pipeline
$app->middleware([
    AuthMiddleware::class,
    CsrfMiddleware::class,
    RateLimitMiddleware::class,
    LoggingMiddleware::class,
]);

class AuthMiddleware {
    public function handle(Request $request, callable $next): Response;
}
```

## C9. Config Management
**Problem:** Mieszanie config z różnych źródeł (PHP, JSON, DB)

**Rozwiązanie:**
```php
class Config {
    private static array $config = [];
    
    public static function load(): void;
    public static function get(string $key, mixed $default = null): mixed;
    public static function set(string $key, mixed $value): void;
    
    // Źródła: config.php → settings.json → .env → database
}
```

## C10. Error Handling
**Problem:** Niespójne handlery błędów

**Rozwiązanie:**
```php
class ErrorHandler {
    public function register(): void;
    public function handleException(Throwable $e): void;
    public function handleError(int $errno, string $errstr): void;
    public function handleShutdown(): void;
}

// Custom exceptions
class ValidationException extends Exception {}
class AuthorizationException extends Exception {}
class NotFoundException extends Exception {}
```

---

# 🔵 KATEGORIA D: NOWE FUNKCJONALNOŚCI

## D1. System wygasania
**Opis:** Daty ważności dla urządzeń, playlist, użytkowników

**Implementacja:**
```sql
ALTER TABLE devices ADD expires_at DATETIME NULL;
ALTER TABLE playlists ADD expires_at DATETIME NULL;
ALTER TABLE users ADD expires_at DATETIME NULL;
```

**Funkcje:**
- Automatyczna dezaktywacja (CRON)
- Grace period (dni karencji)
- Powiadomienia email (7d, 3d, 1d przed)
- Dashboard widget: "Wygasające wkrótce"
- Bulk przedłużanie

## D2. Pakiety / Szablony playlist
**Opis:** Predefiniowane zestawy playlist do szybkiego przypisania

**Tabele:**
```sql
CREATE TABLE playlist_packages (
    id INTEGER PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    created_by INTEGER,
    created_at DATETIME
);

CREATE TABLE playlist_package_items (
    id INTEGER PRIMARY KEY,
    package_id INTEGER,
    playlist_template JSON  -- konfiguracja playlisty
);
```

**UI:**
- Tworzenie pakietów przez admina
- Przypisywanie pakietu do urządzenia (bulk create)
- Import/export pakietów

## D3. Monitoring playlist (Health Check)
**Opis:** Automatyczne sprawdzanie działania playlist

**Implementacja:**
```php
class PlaylistHealthChecker {
    public function checkXtream(array $config): HealthResult;
    public function checkM3U(string $url): HealthResult;
    public function checkStalker(array $config): HealthResult;
}

class HealthResult {
    public bool $success;
    public int $responseTime;
    public ?string $error;
    public int $channelsCount;
}
```

**CRON:** Co godzinę sprawdzaj losowe 10% playlist
**Alerty:** Email gdy playlista nie działa > 1h

## D4. Import/Export zaawansowany
**Formaty:**
- CSV (users, devices, playlists)
- JSON (full backup)
- M3U (import playlist z URL)
- XML (XMLTV dla EPG)

**Implementacja:**
```php
interface ImporterInterface {
    public function validate(string $content): ValidationResult;
    public function import(string $content): ImportResult;
}

class CsvPlaylistImporter implements ImporterInterface {}
class M3UPlaylistImporter implements ImporterInterface {}
class JsonBackupImporter implements ImporterInterface {}
```

## D5. Dashboard customizable
**Opis:** Drag & drop widgety, zapisywanie per user

**Widgety dostępne:**
- Stats (users, devices, playlists)
- Recent activity
- API calls chart
- Expiring soon
- Top users
- System health
- Quick actions
- Notes

**Tabela:**
```sql
CREATE TABLE dashboard_layouts (
    user_id INTEGER PRIMARY KEY,
    layout JSON,  -- pozycje i widoczność widgetów
    updated_at DATETIME
);
```

## D6. Powiadomienia
**Kanały:**
- Email (SMTP już jest)
- Push (browser notifications)
- Telegram bot
- Discord webhook

**Typy:**
- Login z nowego IP
- Zmiana hasła
- Wygasające subskrypcje
- Niedziałające playlisty
- Przekroczenie limitów (reseller)

**Implementacja:**
```php
interface NotificationChannel {
    public function send(Notification $notification): void;
}

class EmailChannel implements NotificationChannel {}
class TelegramChannel implements NotificationChannel {}
class PushChannel implements NotificationChannel {}

class NotificationManager {
    public function notify(User $user, Notification $notification): void;
}
```

## D7. API v2 (REST)
**Endpoints:**
```
GET    /api/v2/devices
POST   /api/v2/devices
GET    /api/v2/devices/{id}
PUT    /api/v2/devices/{id}
DELETE /api/v2/devices/{id}

GET    /api/v2/devices/{id}/playlists
POST   /api/v2/playlists
...

GET    /api/v2/users (admin/reseller)
POST   /api/v2/users
...
```

**Autentykacja:**
- API Key (header: X-API-Key)
- JWT tokens
- OAuth2 (opcjonalnie)

**Dokumentacja:**
- OpenAPI 3.0 spec
- Swagger UI

## D8. Webhooks
**Events:**
- device.created, device.updated, device.deleted
- playlist.created, playlist.updated, playlist.deleted
- user.created, user.login
- subscription.expiring, subscription.expired

**Implementacja:**
```sql
CREATE TABLE webhooks (
    id INTEGER PRIMARY KEY,
    user_id INTEGER,
    url VARCHAR(500),
    events JSON,  -- ["device.created", "playlist.*"]
    secret VARCHAR(64),
    is_active INTEGER DEFAULT 1,
    created_at DATETIME
);

CREATE TABLE webhook_logs (
    id INTEGER PRIMARY KEY,
    webhook_id INTEGER,
    event VARCHAR(100),
    payload JSON,
    response_code INTEGER,
    response_body TEXT,
    created_at DATETIME
);
```

## D9. Multi-language (i18n)
**Implementacja:**
```php
class Translator {
    private string $locale;
    private array $translations = [];
    
    public function setLocale(string $locale): void;
    public function get(string $key, array $params = []): string;
}

// Użycie w Smarty
{t key="users.create.title"}
{t key="errors.validation" params=['field' => 'email']}
```

**Pliki:**
```
lang/
  ├── pl.json
  ├── en.json
  ├── de.json
  └── ru.json
```

## D10. Reseller Portal
**Osobna subdomena:** reseller.panel.com

**Funkcje:**
- Dashboard z własnymi statystykami
- Zarządzanie użytkownikami
- Custom branding (logo, kolory)
- Własne szablony email
- Billing overview
- API access

## D11. End-User Portal
**Opis:** Self-service dla końcowych użytkowników

**Funkcje:**
- Podgląd swoich urządzeń
- Dodawanie urządzeń (jeśli w limicie)
- Przedłużanie subskrypcji
- Historia płatności
- Tickety support
- Zmiana hasła

## D12. Ticketing System
**Tabele:**
```sql
CREATE TABLE tickets (
    id INTEGER PRIMARY KEY,
    user_id INTEGER,
    assigned_to INTEGER,
    subject VARCHAR(200),
    status ENUM('open', 'in_progress', 'waiting', 'resolved', 'closed'),
    priority ENUM('low', 'medium', 'high', 'urgent'),
    created_at DATETIME,
    updated_at DATETIME
);

CREATE TABLE ticket_messages (
    id INTEGER PRIMARY KEY,
    ticket_id INTEGER,
    user_id INTEGER,
    message TEXT,
    attachments JSON,
    created_at DATETIME
);
```

---

# 🛠️ KATEGORIA E: TECHNICZNE / DEVOPS

## E1. Docker Support
```dockerfile
# Dockerfile
FROM php:8.2-apache
RUN docker-php-ext-install pdo pdo_sqlite
COPY . /var/www/html
RUN chown -R www-data:www-data /var/www/html

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:80"
    volumes:
      - ./data:/var/www/html/panel/db
      - ./logs:/var/www/html/logs
      - ./backups:/var/www/html/backups
```

## E2. CI/CD Pipeline
```yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - name: Install dependencies
        run: composer install
      - name: Run tests
        run: vendor/bin/phpunit
      - name: Static analysis
        run: vendor/bin/phpstan analyse
```

## E3. Automated Testing
**Struktura:**
```
tests/
  ├── Unit/
  │   ├── UserTest.php
  │   ├── PlaylistTest.php
  │   └── AuthTest.php
  ├── Integration/
  │   ├── ApiTest.php
  │   └── DatabaseTest.php
  └── E2E/
      └── LoginTest.php
```

**Narzędzia:**
- PHPUnit (unit tests)
- Pest (alternatywa)
- Cypress (E2E)

## E4. Database Migrations
```php
// migrations/001_create_users_table.php
class CreateUsersTable extends Migration {
    public function up(): void {
        $this->execute("CREATE TABLE users ...");
    }
    
    public function down(): void {
        $this->execute("DROP TABLE users");
    }
}

// CLI
php migrate.php migrate
php migrate.php rollback
php migrate.php status
```

## E5. CLI Commands
```php
// bin/console
Commands:
  user:create      Create a new user
  user:password    Reset user password
  cache:clear      Clear all caches
  db:backup        Create database backup
  db:migrate       Run migrations
  cron:run         Run scheduled tasks
  queue:work       Process queue jobs
  health:check     Check system health
```

## E6. Monitoring & Metrics
**Prometheus metrics:**
```php
// /metrics endpoint
app_requests_total{method="GET",path="/api/playlist"} 12345
app_request_duration_seconds{path="/api/playlist"} 0.05
app_active_sessions 150
app_database_size_bytes 52428800
app_cache_hits_total 9999
app_cache_misses_total 100
```

**Grafana dashboards:**
- Request rate
- Error rate
- Response time
- Active users
- System resources

## E7. Logging Enhancement
```php
// Monolog integration
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler;

$logger = new Logger('app');
$logger->pushHandler(new RotatingFileHandler('logs/app.log', 30));
$logger->pushHandler(new StreamHandler('php://stderr', Logger::ERROR));

// Structured logging
$logger->info('User login', [
    'user_id' => $user->id,
    'ip' => $request->ip(),
    'user_agent' => $request->userAgent()
]);
```

## E8. Performance Optimization
**Query optimization:**
- Analyze slow queries
- Add missing indexes
- Optimize N+1 queries
- Use EXPLAIN

**Caching:**
- OPcache enabled
- Query cache
- Template cache (Smarty)
- Asset cache (CSS/JS)

**Frontend:**
- Minify CSS/JS
- Lazy loading images
- HTTP/2 push
- Gzip compression

## E9. Backup System Enhancement
**Automated backups:**
- Daily: database + config
- Weekly: full backup (including uploads)
- Monthly: archive to cloud (S3, GCS)

**Retention:**
- Daily: 7 days
- Weekly: 4 weeks
- Monthly: 12 months

**Recovery testing:**
- Monthly restore test
- Documented procedure

## E10. Documentation
**User docs:**
- Getting started
- User guide
- Admin guide
- FAQ

**Developer docs:**
- Architecture overview
- API documentation
- Database schema
- Contributing guide

**Auto-generated:**
- PHPDoc → HTML
- OpenAPI → Swagger UI
- DB schema → ERD

---

# 📋 PRIORYTETY WDROŻENIA

## Faza 1: Stabilizacja (1-2 tygodnie)
- [ ] A1: Walidacja formularzy
- [ ] A2: Obsługa błędów SQL
- [ ] A5: Transakcje
- [ ] B1: Rate limiting API
- [ ] B4: Security headers

## Faza 2: Bezpieczeństwo (2-3 tygodnie)
- [ ] B2: Lepsze szyfrowanie API
- [ ] B3: Session security
- [ ] B5: SQL injection prevention
- [ ] B8: 2FA
- [ ] B9: Password policy

## Faza 3: Architektura (3-4 tygodnie)
- [ ] C1: Dependency Injection
- [ ] C2: Service Layer
- [ ] C6: Caching
- [ ] C10: Error handling
- [ ] E4: Database migrations

## Faza 4: Funkcjonalności (4-6 tygodni)
- [ ] D1: System wygasania
- [ ] D3: Health check playlist
- [ ] D4: Import/Export
- [ ] D6: Powiadomienia
- [ ] D7: API v2

## Faza 5: DevOps (2-3 tygodnie)
- [ ] E1: Docker
- [ ] E2: CI/CD
- [ ] E3: Testy
- [ ] E7: Logging
- [ ] E9: Backup enhancement

## Faza 6: Rozbudowa (ongoing)
- [ ] D5: Dashboard customizable
- [ ] D8: Webhooks
- [ ] D9: Multi-language
- [ ] D10: Reseller portal
- [ ] D12: Ticketing

---

# 📊 ESTYMACJA CZASOWA

| Faza | Czas | Story Points |
|------|------|--------------|
| 1. Stabilizacja | 1-2 tyg | 13 |
| 2. Bezpieczeństwo | 2-3 tyg | 21 |
| 3. Architektura | 3-4 tyg | 34 |
| 4. Funkcjonalności | 4-6 tyg | 55 |
| 5. DevOps | 2-3 tyg | 21 |
| 6. Rozbudowa | ongoing | - |

**Łącznie core: ~12-18 tygodni** (dla 1 developera)

---

*Dokument wygenerowany: 23.12.2025*
*Wersja: 1.0*
