# REST API

Bütün yanıtlar JSON'dur. API kökü uygulama köküne göre `./api` olarak kullanılır. Uygulama `/yildiz-savasi` alt yolundaysa örnek uç `https://kampuskafe.tr/yildiz-savasi/api/health` olur.

## Kimlik doğrulama

Korunan uçlarda kişisel erişim anahtarı Bearer olarak gönderilir:

```http
Authorization: Bearer KK-...
```

Anahtarlar veritabanında düz metin değil, `AUTH_TOKEN_PEPPER` ile güçlendirilmiş SHA-256 özetleri olarak saklanır.

## Hata biçimi

```json
{
  "ok": false,
  "error": "İnsan tarafından okunabilir hata",
  "code": "MACHINE_READABLE_CODE",
  "request_id": "uuid"
}
```

## Sağlık

### `GET /api/health`

Uygulama sürecinin ayakta olduğunu doğrular.

### `GET /api/ready`

MySQL bağlantısını da sınar. Trafik yönlendirme ve canlılık kontrolü için bunu kullanın.

### `GET /api/config`

İstemcinin bilmesi gereken güvenli değerleri döndürür:

```json
{
  "ok": true,
  "min_board_size": 4,
  "max_board_size": 20,
  "required_review_count": 10,
  "stars_per_unit": 1
}
```

## Erişim doğrulama

### `POST /api/auth/verify`

Gerekli rol ve kullanıcı profilini döndürür. Bearer anahtarı zorunludur.

```json
{
  "ok": true,
  "user": {
    "id": "uuid",
    "display_name": "Ayşe Yılmaz",
    "university": "Ege Üniversitesi",
    "community_name": "Mantık ve Bulmaca Topluluğu",
    "can_create": true,
    "can_review": true,
    "is_admin": false
  }
}
```

## Yayınlanan topluluk bölümleri

### `GET /api/community/published-summary`

Kimlik doğrulaması gerektirmez. Ana zorluk kartlarının doğrudan toplam bölüm sayısını gösterebilmesi için yayınlanmış topluluk bölüm sayılarını döndürür:

```json
{
  "ok": true,
  "counts": {
    "easy": 1,
    "medium": 3,
    "hard": 2
  },
  "total": 6
}
```

Bu sayılara her zorluktaki beş başlangıç bölümü istemci tarafında eklenir. Örneğin `easy: 1`, Kolay kartında `6 bölüm` olarak görünür.

### `GET /api/community/published`

Sorgu alanları:

- `difficulty`: `easy`, `medium`, `hard`
- `limit`: en fazla 100
- `offset`: sıfır veya pozitif sayı

Yanıt, numaraların kalıcı olması için `published_at` ve `id` alanlarına göre eskiden yeniye sıralanır. İlgili zorluktaki ilk yayın `6. Bölüm`, sonraki yayın `7. Bölüm` olur.

Örnek kayıt:

```json
{
  "id": "uuid",
  "title": "Kampüsler Arası 1",
  "final_difficulty": "easy",
  "n": 6,
  "k": 1,
  "regions": [0, 0, 1],
  "published_at": "2026-08-27T17:00:00.000Z",
  "creator_name": "Kampüs Üreticisi",
  "university": "Ege Üniversitesi",
  "community_name": "Mantık ve Bulmaca Topluluğu"
}
```

Çözüm yıldızları hiçbir zaman bu yanıtta gönderilmez. Yayınlanan kayıtlar ana katalogda görünürken Topluluk Laboratuvarı → Yayınlanan listesinde de kalır.

## Test kuyruğu

### `GET /api/community/review-queue`

Testçi yetkisi gerekir. Kendi oluşturduğu veya daha önce değerlendirdiği bölümler kullanıcıya verilmez.

## Üreticinin gönderimleri

### `GET /api/community/submissions`

Üretici yetkisi gerekir. Kullanıcının testte, yayınlanmış veya reddedilmiş gönderimlerini döndürür.

## Bölüm doğrulama

### `POST /api/community/validate`

Üretici yetkisi gerekir. Bölümü kaydetmeden sunucu tarafında doğrular.

```json
{
  "title": "Gece Kütüphanesi",
  "proposed_difficulty": "medium",
  "n": 14,
  "k": 1,
  "regions": [0, 0, 1],
  "solution": [5, 21, 37]
}
```

Gerçek `regions` dizisinin uzunluğu `n × n`, çözüm yıldızlarının sayısı `n` olmalıdır.

Doğrulamalar:

- Tahta boyutu `.env` aralığında mı?
- Tam `n` bölge var mı?
- Her bölge tek parça mı?
- Her satır, sütun ve bölgede tam bir yıldız var mı?
- Yıldızlar yatay, dikey veya çapraz temas ediyor mu?
- Bulmacanın çözümü var mı?
- Çözüm tam olarak bir tane mi?
- Çözümleyici süre ve node sınırlarını aşıyor mu?

## Bölüm gönderme

### `POST /api/community/puzzles`

Üretici yetkisi gerekir. Gövde `validate` ile aynıdır. Başarılı yanıtta HTTP 201 döner.

Aynı tahta/bölge yapısının tekrar gönderilmesi `409 DUPLICATE_PUZZLE` ile engellenir.

## Geri bildirim

### `POST /api/community/puzzles/:id/reviews`

Testçi yetkisi gerekir.

Oynanabilir bölüm:

```json
{
  "playability": "playable",
  "difficulty_vote": "hard",
  "comment": "Küçük tahta olmasına rağmen çıkarımı zor.",
  "elapsed_seconds": 185,
  "move_count": 42,
  "stars": [5, 21, 37]
}
```

Oynanmaz bölüm:

```json
{
  "playability": "unplayable",
  "difficulty_vote": null,
  "comment": "Çözüm mantığı adil görünmüyor.",
  "elapsed_seconds": 120,
  "move_count": 30,
  "stars": [5, 21, 37]
}
```

`stars` yine de geçerli çözüm olmak zorundadır. Böylece testçinin bölümü çözmeden oy vermesi engellenir.

## HTTP güvenliği

- Yazma uçlarında `Content-Type: application/json` gerekir.
- İstek gövdesi `.env` boyut sınırına tabidir.
- Aynı origin veya izin verilen origin kontrol edilir.
- Public/auth/write istekleri ayrı rate limit kotalarına sahiptir.
- API yanıtları service worker cache'ine girmez.
- SQL sorguları parametriktir.
