# Plan: Fikatia lisans kanalını Socket.IO v2 istemcisine dönüştürme

## Durum özeti (araştırma sonucu)

Fikatia-local'de lisans yönetimi için **iki ayrı WebSocket sunucusu** var:

| Ucu | Protokol | Uzunluk | Ne yapar |
|-----|----------|---------|----------|
| `/lisans-ws` | raw WebSocket (gorilla/websocket) | kısa | ECDSA imzalı lisans kararları (engelle/izin) |
| `/socket.io/` | **Socket.IO v2.5.0** (zishang520 Go portu) | uzun | Cihaz yönetimi olayları (`cihaz_kimlik`, `komut`, `olay`) |

Sunucu `SetAllowEIO3(true)` ile **engine.io v3 istemcilerini** de kabul eder. Yani client `?EIO=3` ile bağlanabilir.

**Mevcut lisans istemcisi** (`uygulama/fikocad/lisans_canli.cpp`, 460 satır) ham WinHTTP WebSocket ile `/lisans-ws`'ye bağlanır ve `canliKararCoz` ile `tip=="karar"` şartı koşar.

## KRİTİK BULGU — lisans kararı Socket.IO üzerinden GÖNDERİLMEZ

Sunucuda lisans kararı client'a gönderen **bir Socket.IO olayı yoktur**. Lisans kararları yalnızca `/lisans-ws` raw WebSocket üzerinden (`apps/lisans_kontrol/lisans_kontrol.go`) akar. Merkezi modül (`fikoyt_ctx` + `socket_ortak`) sadece cihaz yönetimi olaylarını konuşur.

Bu demek ki: lisans kanalını Socket.IO'ya geçirirsek, **sunuda bir değişiklik (yeni lisans olayı) olmadan lisans kararı client'a ulaşmaz.** Bu kuralımıza (`sunuda bir şey değiştirme`) çarpar. Planın "Riskler" bölümünde bu açıkça belgelenmiştir.

## vcpkg durumu

vcpkg'de C++ için **socket.io / websocket / asio / websocketpp kütüphanesi YOK**. Bu yüzden tüm protocol WinHTTP'e sıfırdan implemente edilecek.

## Yaklaşım

Ham WebSocket'i bırakıp, `/socket.io/` üzerinden engine.io v3 çerçeveleri + socket.io v2 payload'ı konuşan bir C++ istemcisini sıfırdan yazacağız. Lisans karar doğrulama (`canliKararCoz`) aynen korunur.

### 1. Yeni modül: `motor/platform/include/fiko/platform/socket_io_istemci.{hpp,cpp}`

Tek sorumluluk: bir `wss://host/socket.io/?EIO=3` adresine bağlan, engine.io v3 handshake'ini yap, websocket'e yükselt, socket.io v2 mesajlarını çerçeveler.

Protokol adımları:
- **Handshake (long-polling):** `GET https://host/socket.io/?EIO=3&transport=polling` → sunucu `{"type":0,"upgrades":[...],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000,"sid":"<sid>"}` döndürür.
- **WebSocket yükseltme:** `GET https://host/socket.io/?EIO=3&transport=websocket&sid=<sid>` → HTTP 101.
- **CONNECT:** engine.io MESSAGE (`05`) içine socket.io connect payload → namespace default için `050` (+ opsiyonel token).
- **Gelen mesaj ayrıştırma:** `05<event>,<json>` → öndeki `0` socket.io namespace default'u, `5` engine.io message tipidir. `<event>` alanı çıkarılır.

### 2. `lisans_canli.cpp` yeniden yazım

- `wsOturumu` (WinHTTP raw WS) → `socket_io_istemci` üzerinden `/socket.io/`'ye bağlanır.
- URL formatı güncellenir: `wss://host/socket.io/?EIO=3` (eski `/lisans-ws` artık geçerli yol değil — kullanıcı URL'yi güncellemeli).
- Bağlantıdan sonra `merhaba` yerine socket.io CONNECT + mevcut cihaz olaylarını (cihaz_kimlik ile) kullanarak tanıtırma yapılır.
- Gelen lisans olayı için dinleyici eklenir — ancak sunuda olay olmadığından bu kısmın çalışması için sunuda bir karar olayı gerekir (bak "Riskler").

### 3. `canliKararCoz` uyumluluğu

Mevcut doğrulama (`tip=="karar"`) korunur. Sunucu kararı `{seri, engelli, mesaj, zaman, imza}` şeklinde yollar; yeni istemci bu mesajı socket.io olayı üzerinden alıp `canliKararCoz`'a gönderir.

### 4. Build

`motor/platform/CMakeLists.txt` ve `uygulama/fikocad/CMakeLists.txt`'e yeni modül eklenir. `ws2_32`/`winhttp` zaten linkli.

## Riskler

1. **Lisans olayı yok.** Yukarıda açıklandı. Bu plan lisans kill-switch'i gerçekten çalıştırmaz; sunuda yeni bir lisans olayı bağlanması gerekir (kuralımıza aykırı) ya da lisans kararının mevcut bir cihaz olayı üzerinden taşınması gerekir.
2. **Protocol riski.** engine.io v3 + socket.io v2 çerçeveleri WinHTTP'e sıfırdan implemente edilecek. Buffer/çerçeve ayrıştırma hataları sessizce bağlantı kopmasına yol açabilir. Test için bir mock sunucu şart.
3. **EIO3 desteği.** Sunucu `SetAllowEIO3(true)` — client `?EIO=3` kullanmalı, aksi halde handshake reddedilir.
4. **Ping/timeout.** Sunucu pingInterval 25s, pingTimeout 20s. İstemci 20s içinde pong göndermeli.

## Test

- Mock engine.io v3 sunucusu üzerinde handshake + connect + event akışı.
- `canliKararCoz` unit testi (mevut `test_lisans_uzak.cpp`) aynen yeşil kalmalı.
- Test tabanı: geometri ≥304, sahne ≥1081, io ≥241 (değilse build reddedilir).

## RUNTIME TEST

Derleme + birim test sonrası `/lisans-kontrol` panelinde bağlı fikocad görünüp görünmediği manuel doğrulama.
