# api/index.php - Részletes Dokumentáció

## 📋 Áttekintés

Ez a fájl a **GraphQL API végpont**, ami fogadja az összes GraphQL kérést az admin rendszerhez.

**Útvonal:** `/api/index.php`  
**Hívás URL:** `https://tapetaajtok.hu/api/` vagy `https://tapetaajtok.hu/api/index.php`

---

## 🔒 Biztonsági Funkciók

### 1. CORS (Cross-Origin Resource Sharing)
- ✅ **Production:** Csak engedélyezett domainekről (`tapetaajtok.hu`, `www.tapetaajtok.hu`)
- ✅ **Development:** Localhost:5173 (Vite), localhost:3000 (React dev server)
- ✅ **Preflight:** OPTIONS kérések kezelése
- ✅ **Credentials:** Cookie/Authorization header támogatás

### 2. Security Headers
```
X-Content-Type-Options: nosniff        // MIME type sniffing védelem
X-Frame-Options: DENY                  // Clickjacking védelem
X-XSS-Protection: 1; mode=block        // XSS védelem
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: application/json
```

### 3. JWT Token Validáció
- ✅ Authorization: Bearer TOKEN formátum
- ✅ Token signature ellenőrzés
- ✅ Expiry time ellenőrzés
- ✅ Context építés: adminId, tenantId, role

### 4. Method & Content-Type Validáció
- ✅ Csak POST és OPTIONS engedélyezett
- ✅ Content-Type: application/json kötelező
- ✅ JSON parsing hiba kezelés

### 5. Error Sanitization
- ✅ **Production:** Stack trace elrejtése
- ✅ **Development:** Debug információk megjelenítése
- ✅ Error logging fájlba: `storage/logs/php_errors.log`

---

## 🔄 Request Flow (Kérés Feldolgozása)

```
1. CORS Headers beállítása
   ↓
2. OPTIONS → 204 válasz (preflight)
   ↓
3. Method Check (csak POST)
   ↓
4. Content-Type Check (application/json)
   ↓
5. JSON Parse (query + variables)
   ↓
6. JWT Token Ellenőrzés
   ├─ Van token? → Verify → Context (adminId, tenantId, role)
   └─ Nincs token? → Tenant feloldás domain alapján
   ↓
7. GraphQL Schema Init (TypeRegistry)
   ↓
8. GraphQL Query Execution
   ├─ Resolvers futtatása (QueryResolver, MutationResolver)
   └─ Context átadása ($context['adminId'], $context['tenantId'])
   ↓
9. JSON Response
```

---

## 📥 Request Format

### Login Mutation (nincs szükség token-re)
```bash
POST /api/
Content-Type: application/json

{
  "query": "mutation($email: String!, $password: String!) { login(email: $email, password: $password) { token admin { id email role } } }",
  "variables": {
    "email": "admin@webszerviz.hu",
    "password": "tapetaajtok747075"
  }
}
```

### Authenticated Query (token szükséges)
```bash
POST /api/
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...

{
  "query": "{ me { id email role } }"
}
```

---

## 📤 Response Format

### Success Response
```json
{
  "data": {
    "me": {
      "id": "1",
      "email": "admin@webszerviz.hu",
      "role": "SUPER_ADMIN"
    }
  }
}
```

### Error Response (Production)
```json
{
  "errors": [
    {
      "message": "Not authenticated",
      "extensions": {
        "code": "AUTHENTICATION_ERROR"
      }
    }
  ]
}
```

### Error Response (Development)
```json
{
  "errors": [
    {
      "message": "Not authenticated",
      "extensions": {
        "code": "AUTHENTICATION_ERROR",
        "debugMessage": "Token expired at 2025-09-30 12:00:00"
      }
    }
  ]
}
```

---

## 🔑 Context Structure

A `$context` változó, ami átadásra kerül minden resolvernek:

```php
$context = [
    'adminId' => 1,                    // Bejelentkezett admin ID (JWT-ből)
    'tenantId' => 1,                   // Aktuális tenant ID (JWT-ből vagy domain-ből)
    'role' => 'super_admin',           // Admin szerepkör
    'isAuthenticated' => true          // Be van-e jelentkezve
];
```

---

## 🎯 Resolver Példa

```php
// QueryResolver.php
public function me($root, array $args, array $context): array
{
    // Context-ből jön az adminId és tenantId
    if (!isset($context['adminId'])) {
        throw new Exception('Not authenticated');
    }
    
    $db = Database::getInstance();
    $db->setTenant($context['tenantId']); // Tenant context beállítás
    
    $admin = $db->fetchOneTenant('admins', ['id' => $context['adminId']]);
    
    return [
        'id' => $admin['id'],
        'email' => $admin['email'],
        'role' => $admin['role']
    ];
}
```

---

## 🧪 Tesztelés

### 1. CURL Teszt (Login)
```bash
curl -X POST https://tapetaajtok.hu/api/ \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { login(email: \"admin@webszerviz.hu\", password: \"tapetaajtok747075\") { token admin { id email role } } }"
  }'
```

### 2. CURL Teszt (Me Query)
```bash
curl -X POST https://tapetaajtok.hu/api/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -d '{
    "query": "{ me { id email role } }"
  }'
```

### 3. Postman / Insomnia
```
Method: POST
URL: https://tapetaajtok.hu/api/
Headers:
  Content-Type: application/json
  Authorization: Bearer YOUR_TOKEN_HERE
Body (raw JSON):
{
  "query": "{ me { id email role } }"
}
```

### 4. Apollo Sandbox
```
URL: https://tapetaajtok.hu/api/
Headers:
  Authorization: Bearer YOUR_TOKEN_HERE

Query:
query {
  me {
    id
    email
    role
  }
}
```

---

## 🐛 Hibakeresés

### Error Log Helye
```
/home/ablakhug/tapetaajtok.hu/storage/logs/php_errors.log
```

### Gyakori Hibák

#### 1. "CORS Error"
**Probléma:** Frontend nem tud kérést küldeni  
**Megoldás:** Ellenőrizd az `allowedOrigins` tömböt (sor 67-72)

#### 2. "Invalid JSON"
**Probléma:** Rossz formátumú JSON body  
**Megoldás:** Ellenőrizd a Content-Type headert és JSON szintaxist

#### 3. "Not authenticated"
**Probléma:** JWT token hiányzik vagy érvénytelen  
**Megoldás:** 
- Ellenőrizd az Authorization header formátumot: `Bearer TOKEN`
- Ellenőrizd, hogy a token nem járt-e le (24 óra)

#### 4. "Method not allowed"
**Probléma:** Nem POST kérést küldtél  
**Megoldás:** Használj POST metódust

---

## 🔧 Konfiguráció

### Production Mode Átváltás
```php
// Sor 32
define('IS_PRODUCTION', !in_array($_SERVER['HTTP_HOST'] ?? '', ['localhost', '127.0.0.1']));
```

Automatikus:
- `localhost` vagy `127.0.0.1` → Development
- Egyéb (pl. `tapetaajtok.hu`) → Production

### CORS Origins Hozzáadása
```php
// Sor 67-72
$allowedOrigins = [
    'https://tapetaajtok.hu',
    'https://www.tapetaajtok.hu',
    'https://ujdomain.hu',  // ← Új domain
    'http://localhost:5173',
];
```

### Error Log Path Módosítás
```php
// Sor 29
ini_set('error_log', __DIR__ . '/../storage/logs/php_errors.log');
```

---

## 📊 HTTP Status Codes

| Code | Jelentés | Mikor történik |
|------|----------|----------------|
| 200  | OK | Sikeres GraphQL kérés (még error esetén is!) |
| 204  | No Content | OPTIONS preflight válasz |
| 400  | Bad Request | Hibás JSON, hiányzó query |
| 405  | Method Not Allowed | Nem POST kérés |
| 415  | Unsupported Media Type | Nem application/json Content-Type |
| 500  | Internal Server Error | (GraphQL errors mindig 200-ban mennek) |

**FONTOS:** A GraphQL spec szerint minden GraphQL error 200 OK válaszban megy, az `errors` tömbben!

---

## 🚀 Deployment Checklist

- [ ] `api/index.php` feltöltve
- [ ] `storage/logs/` mappa létezik és írható
- [ ] Composer `vendor/` mappa jelen van
- [ ] Config fájlok (`config/database.php`, `config/jwt.php`) beállítva
- [ ] Összes osztály (`Database`, `Auth`, `TenantContext`, `TypeRegistry`, stb.) feltöltve
- [ ] CORS origins production domainre beállítva
- [ ] Error log writable (`chmod 755 storage/logs/`)
- [ ] Login tesztelve (curl vagy Postman)
- [ ] Me query tesztelve tokennel

---

## 📞 Support

Ha bármi nem működik:
1. Ellenőrizd az error log-ot: `storage/logs/php_errors.log`
2. Kapcsold development mode-ra (localhost-ról tesztelj)
3. Nézd meg a browser Network tab-ban a Request/Response-t
4. Ellenőrizd, hogy minden osztály betöltődik-e (`require_once`)

---

*Version: 1.0*  
*Készült: 2025.09.30*  
*Következő: Frontend React Admin (Fázis 2)*
