# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Domain Dashboard adalah aplikasi manajemen domain dengan integrasi cPanel dan Cloudflare. Aplikasi ini mengotomasi penambahan addon domain ke cPanel, membuat wildcard subdomain (*.domain.com), dan mengkonfigurasi Cloudflare DNS records secara otomatis.

**Stack:**
- Backend: PHP 8.3 dengan strict typing (`declare(strict_types=1)`)
- Database: MySQL/MariaDB dengan PDO
- Frontend: HTML5, CSS3, JavaScript (vanilla), Bootstrap 5
- APIs: cPanel UAPI/API2, Cloudflare REST API
- Cache: APCu (data cache), OPcache (bytecode cache)

## Architecture

### Directory Structure

```
domain-dashboard-final/
├── bootstrap/
│   └── init.php              # Application bootstrap, autoloader, PDO setup, API clients
├── config/
│   └── database.php          # Database configuration helpers
├── src/
│   ├── Integration/
│   │   ├── CpanelApi.php     # cPanel API client (API2/UAPI wrapper)
│   │   └── CloudflareApi.php # Cloudflare API v4 client
│   ├── Repository/
│   │   ├── DomainRepository.php     # Domain data access layer
│   │   ├── ShortlinkRepository.php  # Shortlink data access layer
│   │   └── SettingsRepository.php   # Settings data access + APCu cache
│   └── Service/
│       ├── DomainService.php            # Business logic: cPanel + Cloudflare + DB
│       ├── ShortlinkService.php         # Shortlink management
│       ├── GlobalRedirectService.php    # Global redirect & shim settings
│       └── MiniWAFService.php           # Web Application Firewall
├── public/                  # DASHBOARD (Admin Interface)
│   ├── index.php            # Main dashboard UI dengan tabs
│   └── ajax/                # AJAX endpoints
│       ├── submit-domain.php
│       ├── get-domains.php
│       ├── submit-shortlink.php
│       ├── get-shortlinks.php
│       ├── get-system-settings.php
│       ├── update-system-settings.php
│       ├── get-waf-stats.php
│       ├── whitelist-ip.php
│       └── track-shim-analytics.php
├── redirect/                # SHORTLINKS (Public Document Root)
│   ├── s.php                # Shortlink redirect handler
│   ├── shim.php             # Intermediate redirect page (shim)
│   └── .htaccess            # Clean URL rewrite rules
└── .env                     # Environment variables (NEVER commit)
```

**IMPORTANT - Folder Separation:**

- **`/public`** → Dashboard (admin interface)
  - Untuk mengelola domain, shortlink, system settings
  - **TIDAK untuk document root domain/subdomain**

- **`/redirect`** → Shortlinks (public-facing)
  - **Semua domain/subdomain point ke folder ini**
  - Handles shortlink redirects (s.php)
  - Handles shim page (shim.php)
  - Contains clean URL .htaccess rules

**Document Root Configuration:**
```
Domain yang ditambahkan:    example.com
Document Root cPanel:       /home/user/domain-dashboard-final/redirect
Wildcard subdomain:         *.example.com → /home/user/domain-dashboard-final/redirect

Dashboard access:           https://dashboard.yourdomain.com → /public
Shortlink access:          https://go.yourdomain.com/abc123  → /redirect/s.php
```

### Key Architectural Patterns

**Repository Pattern:**
- `DomainRepository`: Raw database access dengan prepared statements
- `SettingsRepository`: Database + APCu caching layer (read-through cache)

**Service Layer:**
- `DomainService`: Orchestrates complex operations (cPanel → Cloudflare → Database)
- Handles transactions, rollback pada failure

**API Integration:**
- `CpanelApi`: Wrapper untuk cPanel API2/UAPI, handles authentication, error mapping
- `CloudflareApi`: Cloudflare API v4 client dengan auto-zone creation

### Critical Data Flow: Adding Domain

1. User submits form → `public/ajax/submit-domain.php`
2. CSRF validation
3. `DomainService::addDomain()`:
   - Check domain exists di database
   - Generate unique subdomain
   - **Start DB transaction**
   - Add addon domain via cPanel API
   - Add wildcard subdomain via cPanel (*.domain.com)
   - Find/create Cloudflare zone (auto-create jika belum ada)
   - Add wildcard DNS record ke Cloudflare (*.domain.com → SERVER_IP)
   - Save ke database (`domains` table)
   - Log activity (`activity_logs` table)
   - **Commit transaction**
4. Return nameservers jika zone baru dibuat

**Rollback Strategy:**
- Jika Cloudflare/Database fail → Delete domain dari cPanel
- Jika transaction fail → Rollback database changes

## Environment Configuration

### Required .env Variables

```bash
# Database (mandatory)
DB_HOST=localhost
DB_NAME=database_name
DB_USER=database_user
DB_PASS=database_password

# cPanel API (mandatory untuk domain management)
CPANEL_HOST=server123.hosting.com  # JANGAN include https://
CPANEL_USERNAME=cpanel_username
CPANEL_API_TOKEN=your_api_token_here
CPANEL_PORT=2083  # 2083 for SSL, 2082 for non-SSL

# Cloudflare API (optional, untuk DNS management)
CLOUDFLARE_API_KEY=your_cloudflare_global_api_key
CLOUDFLARE_EMAIL=your@email.com

# Server (required untuk DNS records)
SERVER_IP=123.456.789.012
```

**Settings Priority:**
1. Database settings (via Settings tab) → synced to environment variables at runtime
2. .env file → fallback jika database settings tidak ada

### Database Setup

```bash
# Import schema
mysql -u user -p database_name < database-setup.sql

# Or via cPanel phpMyAdmin:
# - Login ke phpMyAdmin
# - Select database
# - Import → Choose database-setup.sql
```

Schema mencakup:
- `domains`: Domain records dengan Cloudflare zone/record IDs
- `activity_logs`: Audit trail (foreign key ke domains dengan CASCADE DELETE)
- `settings`: Key-value configuration dengan APCu caching

## Common Development Commands

### Local Development (PHP Built-in Server)

```bash
# Start development server
php -S localhost:8080 -t public/

# Access dashboard
# http://localhost:8080/
```

### Testing APIs

```bash
# Test cPanel connection
php public/test-cpanel.php

# Test PHP modules (PDO, cURL, APCu, etc.)
php public/test-modules.php

# Check cache stats
php public/check-cache.php
```

### Code Quality

```bash
# Check PHP syntax (manual)
find . -name "*.php" -exec php -l {} \;

# PSR-12 compliance (jika PHPCS installed)
phpcs --standard=PSR12 src/ bootstrap/

# PHPStan level max (jika installed)
phpstan analyse --level=max src/
```

## Security Requirements

**MANDATORY untuk semua kode PHP:**
1. ✅ `declare(strict_types=1);` di semua file
2. ✅ Prepared statements untuk SEMUA query (ZERO toleransi untuk string concatenation)
3. ✅ `htmlspecialchars()` dengan `ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5` untuk output
4. ✅ CSRF token validation untuk semua POST requests
5. ✅ CSP nonce untuk inline scripts/styles

**Example CSRF Validation:**
```php
// bootstrap/init.php sudah setup session + CSRF token
// Validation di AJAX endpoints:
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Invalid CSRF token']);
    exit;
}
```

**SQL Injection Prevention:**
```php
// ❌ FATAL ERROR - NEVER DO THIS
$sql = "SELECT * FROM domains WHERE domain = '{$_POST['domain']}'";

// ✅ CORRECT - Always use prepared statements
$stmt = $pdo->prepare('SELECT * FROM domains WHERE domain = ?');
$stmt->execute([$_POST['domain']]);
```

## Cache Strategy

### APCu Cache (Settings + Application Data)

**Pattern: Read-Through Cache**
```php
// SettingsRepository::getCached()
$cacheKey = "settings:{$key}";

// Try cache first (TTL: 300s)
if (apcu_exists($cacheKey)) {
    return apcu_fetch($cacheKey);
}

// Cache miss → fetch from database
$value = $this->get($key);

// Store in cache
apcu_store($cacheKey, $value, 300);
return $value;
```

**Cache Invalidation:**
- Automatic: Settings update → clear cache untuk key tersebut
- Manual: Via Cache tab → Clear APCu button

### OPcache (Bytecode Cache)

- Managed oleh PHP engine
- Clear via Cache tab setelah code deployment
- Configuration: `php.ini` atau `.user.ini`

## API Client Guidelines

### cPanel API

**Timeout Strategy:**
- Normal operations: 30s
- Domain creation: 120s (cPanel bisa lambat)
- Health checks: 10s

**Error Handling:**
```php
// CpanelApi always returns array{success: bool, message: string, data?: array}
$result = $cpanelApi->addAddonDomain($domain, $subdomain, $docroot);

if (!$result['success']) {
    // Log error
    error_log("cPanel error: {$result['message']}");

    // Throw exception untuk trigger rollback
    throw new \Exception("cPanel: {$result['message']}");
}
```

### Cloudflare API

**Zone Management:**
- `findZoneByDomain($domain, $autoCreate = true)` → creates zone jika tidak ada
- Returns nameservers jika zone baru dibuat
- User harus update nameservers di domain registrar

**DNS Records:**
- Wildcard subdomain: `*.domain.com` → `A` record pointing to `SERVER_IP`
- `proxied = true` untuk Cloudflare proxy (CDN + SSL)

## Frontend Architecture

### JavaScript Patterns

**Global State:**
```javascript
// CSRF token (synced from server)
let csrfToken = '<?= escape($_SESSION['csrf_token']) ?>';

// Client-side cache
let systemStatusCache = null;
let systemStatusCacheTime = 0;
const CACHE_DURATION = 10000; // 10s
```

**AJAX Error Handling:**
```javascript
try {
    const response = await fetch('ajax/endpoint.php', {
        method: 'POST',
        body: formData,
        credentials: 'same-origin'
    });
    const data = await response.json();

    if (data.success) {
        // Update CSRF token jika server rotated
        if (data.csrf_token) syncCsrfToken(data.csrf_token);

        // Handle success
    } else {
        showToast(data.message, 'error');
    }
} catch (error) {
    showToast('Network error', 'error');
}
```

### UI Components

**Monochrome Design System:**
- Colors: Black & white dengan grayscale (no colors kecuali border variants)
- Border styles untuk severity: solid (success), dashed (info), dotted (warning), double (error)
- Border radius: 0.3rem (global)

**Toast Notifications:**
```javascript
showToast(message, type); // type: 'success', 'info', 'warning', 'error'
```

**Confirmation Dialogs:**
```javascript
const confirmed = await showConfirm('Are you sure?', {
    confirmText: 'Yes',
    cancelText: 'No'
});

if (confirmed) {
    // Proceed
}
```

## Troubleshooting

### Database Connection Issues

```bash
# Check .env file exists
ls -la .env

# Verify database credentials
mysql -h DB_HOST -u DB_USER -p DB_NAME

# Check PDO extension
php -m | grep PDO
```

### cPanel API Not Working

1. Verify credentials: `CPANEL_HOST` tidak boleh ada `https://`
2. Check API token masih valid (cPanel → Security → Manage API Tokens)
3. Test connection: `php public/test-cpanel.php`
4. Check firewall: Port 2083 (SSL) atau 2082 (non-SSL) harus open

### Cloudflare API Not Working

1. Verify Global API Key (bukan API Token)
2. Email harus match dengan Cloudflare account
3. Test via System Status card → Cloudflare API status

### Wildcard Subdomain Issues

**cPanel:**
- Check via cPanel → Domains → Subdomains
- Should see: `*.domain.com` pointing to `redirect` folder
- If missing: Dashboard will recreate pada domain re-add

**Cloudflare:**
- Check via Cloudflare Dashboard → DNS Records
- Should see: `A` record for `*` (wildcard) → SERVER_IP
- Proxied status: Orange cloud (recommended)

### Cache Issues

```bash
# Clear all caches
# Via Dashboard: Cache tab → Clear All Cache button

# Manual APCu clear
php -r "apcu_clear_cache();"

# Manual OPcache clear
php -r "opcache_reset();"
```

## Production Deployment

### Pre-Deployment Checklist

- [ ] Copy `.env.example` to `.env` dan configure
- [ ] Import `database-setup.sql`
- [ ] Set file permissions: `chmod 644` files, `chmod 755` directories
- [ ] Verify `redirect/` folder exists di home directory
- [ ] Test cPanel API connection
- [ ] Test Cloudflare API connection (optional)
- [ ] Enable OPcache di `php.ini` / `.user.ini`
- [ ] Disable debug mode: `ini_set('display_errors', '0')` di `bootstrap/init.php`

### Shared Hosting (cPanel)

1. Upload semua files kecuali `.env` ke `public_html/dashboard/`
2. Create `.env` via cPanel File Manager (mode 644)
3. Document root: `public_html/dashboard/public/`
4. PHP version: 8.0+ (via cPanel → MultiPHP Manager)
5. Enable APCu: Add to `.user.ini`:
   ```ini
   extension=apcu.so
   apc.enabled=1
   apc.shm_size=32M
   ```

### Security Headers

Already configured via `bootstrap/init.php`:
- Content-Security-Policy dengan nonce
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- Referrer-Policy
- HSTS (jika HTTPS)

## API Response Format

**Standard Response:**
```json
{
  "success": true,
  "message": "Operation successful",
  "data": { ... },
  "csrf_token": "new_token_if_rotated"
}
```

**Error Response:**
```json
{
  "success": false,
  "message": "Error description",
  "csrf_token": "new_token_if_rotated"
}
```

## Important Notes

1. **Document Root:** Semua domain point ke `~/redirect/` folder (shared content)
2. **Wildcard Subdomain:** Otomatis dibuat untuk setiap domain (*.domain.com)
3. **Cloudflare Zone:** Auto-created jika belum ada, returns nameservers untuk update di registrar
4. **Transaction Safety:** Domain operations wrapped dalam database transaction dengan rollback
5. **CSRF Protection:** Token rotated setelah critical operations
6. **Cache Layering:** APCu (settings) → Database → External APIs
7. **Error Logging:** All errors logged ke PHP error_log untuk debugging
