# 01 — Auth & Tenant Modülü

## Ne İş Yapar?

Flovy'e kayıt olan her işletme bir **tenant**tır. Tenant kendi widget'ını, ürünlerini, bilgi tabanını ve ziyaretçi verilerini yönetir. Tenant verisi diğer tenantlardan tamamen izole edilir.

---

## Tenant Modeli

```
tenants
├── id (UUID)
├── name                    ← İşletme adı
├── email                   ← Giriş e-postası
├── password_hash
├── plan (free/starter/pro/business)
├── plan_expires_at
├── is_active
├── api_key                 ← Widget embed için (public, read-only)
├── webhook_secret          ← PayTR callback doğrulama
├── monthly_message_quota
├── monthly_message_used
├── ai_budget_monthly       ← TL cinsinden AI maliyet limiti
├── ai_budget_used
├── ai_budget_period        ← "2026-06" format
├── created_at
└── updated_at
```

---

## API Endpoint'leri

### Public (auth gerektirmez)
```
POST /api/auth/register          ← Yeni tenant kaydı
POST /api/auth/login             ← Email + password → JWT
POST /api/auth/forgot-password   ← OTP e-posta gönder
POST /api/auth/reset-password    ← OTP doğrula + yeni şifre
```

### Authenticated (Bearer JWT)
```
GET  /api/auth/me                ← Tenant bilgileri
POST /api/auth/logout            ← Token revoke
POST /api/auth/refresh           ← Token yenile
PUT  /api/auth/profile           ← İşletme bilgileri güncelle
POST /api/auth/change-password
```

---

## JWT Yapısı

```json
{
  "sub": "tenant_uuid",
  "email": "tenant@ornek.com",
  "plan": "pro",
  "iat": 1234567890,
  "exp": 1234567890
}
```

Token TTL: 30 gün. Her request'te `Authorization: Bearer <token>` header'ı zorunlu.

---

## Widget API Key

Her tenant'ın public bir `api_key`'i vardır. Widget embed snippet'inde kullanılır:

```html
<script src="https://flovy.tekyerden.co/w.js" data-key="fvy_live_abc123"></script>
```

Bu key ile widget endpoint'leri çağrılır (`/api/widget/*`). JWT gerektirmez — sadece `api_key` doğrulaması. Widget endpoint'leri sadece okuma ve sohbet işlemlerine izin verir; ürün silme/güncelleme gibi operasyonlara izin vermez.

---

## İş Kuralları ve Gotcha'lar

- OTP brute force koruması: Hatalı denemede per-email Redis sayacı (5 denemede kilitle).
- `resetPassword` endpoint'i `isActive()` kontrolü yapar — pasif tenant şifre sıfırlayamaz.
- `api_key` public'tir; widget üzerinden tenant paneline erişim açığı yoktur.
- Quota kontrolü: Her AI mesajında `monthly_message_used < monthly_message_quota` kontrolü yapılır. Dolunca bot sadece kural tabanlı cevap verir (LLM çağrılmaz).
- `ai_budget_period` her ay başında reset edilir (Celery job).

---

## Middleware Zinciri

```
Request
  └── verify_jwt_token()        ← Header parse + imza doğrula
        └── load_tenant()       ← DB'den tenant çek
              └── check_active() ← is_active kontrolü
                    └── route handler
```

FastAPI dependency injection ile:

```python
async def get_current_tenant(token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(get_db)) -> Tenant:
    ...
```

Her route `tenant: Tenant = Depends(get_current_tenant)` alır.
