# Mavi11 Business — Laravel 12 Proje Mimarisi

> **Sürüm:** 1.0 · **Tarih:** 2026-06-06 · **Durum:** Mimari tasarım (kod öncesi)
> **Stack:** PHP 8.3+ · Laravel 12 · MariaDB 10.11 · Redis · Laravel Queue · Sanctum · Spatie Permission
> **İlkeler:** Monolith · Domain-Driven Design · Service Layer · Repository Pattern · REST API-First · Multi-tenant

---

## 0. Mimari İlkeler (Özet)

| İlke | Uygulanış |
|------|-----------|
| **Monolith** | Tek deploy, modüller `app/Domains/*` altında izole. |
| **Domain-Driven** | Her iş alanı kendi domain klasöründe (Model, Service, Repository, Event, Job, Policy). |
| **Service Layer (zorunlu)** | Tüm iş mantığı Service sınıflarında. Controller → Service → Repository. |
| **Repository Pattern** | Veri erişimi `Contracts` (interface) arkasında; Eloquent implementasyonu bağımlılık olarak enjekte edilir. |
| **Controller'da iş mantığı yok** | Controller yalnızca: Request doğrula → Service çağır → Resource döndür. |
| **Tenant izolasyonu** | Middleware + Global Scope + bağlam (context) servisi. |
| **API versiyonlama** | Tüm uçlar `/api/v1`. |
| **Soft delete** | `SoftDeletes` trait + `deleted_at` (şema hazır). |
| **Activity Log** | Spatie Activitylog + domain Event'leri. |
| **Event & Listener** | Domain olayları; yan etkiler (bildirim, skorlama, log) listener/job ile. |
| **Queue** | Ağır işler (AI skorlama, import, bildirim) Redis kuyruğunda Job olarak. |

**Akış kuralı (katman yönü):**
```
HTTP Request
   → Middleware (auth, tenant, throttle, version)
   → FormRequest (doğrulama + yetki ön kontrolü)
   → Controller (ince) 
   → Service (iş mantığı, transaction, event dispatch)
   → Repository (veri erişimi)
   → Model (Eloquent)
   → API Resource (çıktı dönüşümü)
```

---

## 1. Klasör Yapısı

```
public_html/
├── app/
│   ├── Console/
│   │   └── Commands/                 # artisan komutları (örn. leads:rescore)
│   ├── Domains/                      # ⭐ DDD çekirdeği — her modül bir domain
│   │   ├── Tenancy/                  # kiracı bağlamı, middleware, scope
│   │   ├── Identity/                 # auth, users, teams, roles
│   │   ├── Lead/                     # firma/lead, sektör, tag, import
│   │   ├── Scoring/                  # AI lead skorlama
│   │   ├── Assignment/               # atama kuralları, görev dağıtımı
│   │   ├── Crm/                      # aktivite, görüşme, hatırlatma, dosya
│   │   ├── Pipeline/                 # aşamalar, fırsatlar (deals)
│   │   ├── Ai/                       # AI analiz, kullanım/maliyet
│   │   ├── Notification/             # bildirim (in-app/e-posta/...)
│   │   ├── Reporting/                # rapor, dashboard, snapshot
│   │   └── Catalog/                  # ürün kataloğu (6 ürün)
│   ├── Shared/                       # domain'ler arası ortak çekirdek
│   │   ├── Abstracts/                # BaseService, BaseRepository, BaseModel
│   │   ├── Contracts/                # ortak arayüzler
│   │   ├── Concerns/ (Traits)        # BelongsToTenant, HasUuid, Filterable
│   │   ├── Casts/                    # özel cast'ler
│   │   ├── Enums/                    # ortak enum'lar (Priority, Channel...)
│   │   ├── Exceptions/               # domain exception'ları + Handler
│   │   ├── Rules/                    # ortak validation rule'ları
│   │   ├── DTOs/                     # ortak DTO temelleri
│   │   ├── Pagination/               # standart sayfalama
│   │   └── Http/
│   │       ├── Middleware/           # global middleware
│   │       └── Resources/            # ortak resource yapıları
│   ├── Support/                      # yardımcılar (helpers, formatters)
│   ├── Providers/                    # AppServiceProvider, DomainServiceProvider,
│   │                                 #   RepositoryServiceProvider, EventServiceProvider,
│   │                                 #   AuthServiceProvider, RouteServiceProvider
│   └── Http/
│       ├── Kernel-eşdeğeri ayarlar   # (Laravel 12: bootstrap/app.php içinde)
│       └── Controllers/Controller.php# temel controller
├── bootstrap/
│   └── app.php                       # ⭐ Laravel 12 — middleware, routing, exception burada
├── config/
│   ├── domains.php                   # domain kayıt listesi
│   ├── tenancy.php                   # tenant ayarları
│   ├── scoring.php                   # skorlama ağırlık/eşik varsayılanları
│   ├── ai.php                        # Claude API (model, limit, maliyet)
│   ├── permission.php                # spatie
│   └── sanctum.php
├── database/
│   ├── migrations/                   # (şema mevcut: schema_mariadb.sql referans)
│   ├── factories/
│   ├── seeders/
│   ├── schema_mariadb.sql            # ⭐ uygulanmış şema
│   └── seed_mariadb.sql              # ⭐ uygulanmış referans veri
├── routes/
│   ├── api.php                       # v1 grup yükleyici → domain route'larını toplar
│   ├── console.php
│   └── channels.php                  # broadcast (in-app bildirim)
├── tests/
│   ├── Unit/                         # Service/Repository birim testleri
│   └── Feature/                      # API endpoint testleri (domain bazlı)
├── docs/                             # ürün + mimari dokümanları
└── storage/, public/, vendor/ ...
```

### 1.1 Tek bir Domain'in iç yapısı (standart şablon)

Her `app/Domains/{Domain}/` aynı iskeleti taşır:

```
app/Domains/Lead/
├── Models/                  # Eloquent modelleri (Lead, Sector, Tag, LeadImport)
├── DTOs/                    # CreateLeadData, UpdateLeadData, LeadFilterData
├── Contracts/              # arayüzler
│   ├── LeadServiceInterface.php
│   └── LeadRepositoryInterface.php
├── Services/               # iş mantığı (LeadService, DedupService, ImportService)
├── Repositories/           # Eloquent implementasyonları (LeadRepository)
├── Actions/                # tek-sorumluluklu işlemler (NormalizeCompanyName)
├── Events/                 # LeadCreated, LeadAssigned, LeadStatusChanged
├── Listeners/              # ScheduleLeadScoring, NotifyOwner
├── Jobs/                   # ScoreLeadJob, ProcessLeadImportJob
├── Policies/               # LeadPolicy
├── Observers/              # LeadObserver (dedup_hash üretimi vb.)
├── Enums/                  # LeadStatus, LeadSource
├── Http/
│   ├── Controllers/Api/V1/ # (sonra) LeadController, LeadImportController
│   ├── Requests/           # StoreLeadRequest, UpdateLeadRequest, ImportLeadRequest
│   └── Resources/          # LeadResource, LeadCollection
├── Providers/              # LeadServiceProvider (binding + route + policy kayıt)
└── routes/
    └── api_v1.php          # domain'e ait v1 uçları
```

> Bu şablon tüm domain'lerde tekrarlanır → tahmin edilebilir, ekibe öğretilebilir yapı.

---

## 2. Domain Yapısı

### 2.1 Domain Listesi (Analiz modülleriyle eşleme)

| Domain | Karşılık (Analiz Modülü) | Ana Tablolar |
|--------|--------------------------|--------------|
| **Tenancy** | Çok kiracılık altyapısı | tenants, settings |
| **Identity** | M1 Auth/RBAC | users, roles, permissions, teams, team_members, sessions |
| **Catalog** | M11 Ürün | products, product_sector_map |
| **Lead** | M2 + M3 Lead/Toplama | leads, sectors, tags, lead_tags, lead_imports |
| **Scoring** | M4 AI Skorlama | lead_scores, scoring_rules |
| **Assignment** | M5 Görev & Dağıtım | assignments, assignment_rules, tasks |
| **Crm** | M6 Etkileşim | activities, attachments, reminders |
| **Pipeline** | M7 Satış Hunisi | pipeline_stages, deals, deal_stage_history, lost_reasons |
| **Ai** | M8 AI Analiz | ai_analyses, ai_usage_logs |
| **Notification** | M9 Bildirim | notifications, notification_preferences, notification_logs |
| **Reporting** | M10 Raporlama | report_snapshots (+ tüm tablolardan okuma) |

> Audit/Activity Log ve Jobs çapraz kesen (cross-cutting) bileşenlerdir → `Shared` + Spatie paketleri.

### 2.2 Domain bileşenlerinin rolleri

| Bileşen | Sorumluluk | Kural |
|---------|-----------|-------|
| **Model** | Eloquent — ilişki, cast, scope, soft delete | İş mantığı içermez |
| **DTO** | Katmanlar arası tip-güvenli veri taşıma | Immutable; Request'ten üretilir |
| **Service** | İş mantığı, orkestrasyon, transaction, event | Repository'ye bağımlı (interface) |
| **Repository** | Yalnızca veri erişimi (CRUD, sorgu) | İş kuralı içermez |
| **Action** | Tek bir atomik işlem (yeniden kullanılabilir) | Service tarafından çağrılır |
| **Event** | "Olan biten"i ilan eder | Yan etki içermez |
| **Listener/Job** | Olaya tepki (senkron listener / asenkron job) | Ağırsa → Job |
| **Policy** | Yetki kararı (kim ne yapabilir) | Spatie izinleri + ownership |
| **Observer** | Model yaşam döngüsü kancaları | Hafif; ağır iş Job'a |
| **Resource** | API çıktı dönüşümü | Sunum katmanı |
| **FormRequest** | Girdi doğrulama + ön yetki | Controller'ı korur |

---

## 3. Service Katmanı

**Kural:** Tüm iş mantığı Service'te. Controller iş mantığı barındırmaz.

### 3.1 Sözleşme + Temel sınıf
- `Shared\Abstracts\BaseService` — ortak yardımcılar (transaction sarmalayıcı, event dispatch helper).
- Her domain bir `Contracts\{X}ServiceInterface` tanımlar; `Services\{X}Service` implemente eder.
- Binding `RepositoryServiceProvider`/`DomainServiceProvider`'da yapılır → controller'a interface enjekte edilir (gevşek bağ).

### 3.2 Sorumluluklar
- Girdi olarak **DTO** alır (Request değil).
- İş kurallarını uygular (ör. lead atanınca SLA hesapla, status güncelle).
- **Transaction** yönetir (`DB::transaction`).
- İş tamamlanınca **Event** fırlatır (`LeadAssigned::dispatch(...)`).
- Veri erişimini **Repository interface** üzerinden yapar — Eloquent'i doğrudan çağırmaz.

### 3.3 Örnek servis envanteri (kod değil, sorumluluk haritası)
| Domain | Servisler |
|--------|-----------|
| Identity | AuthService, UserService, TeamService, RoleService |
| Lead | LeadService, LeadDedupService, LeadImportService, SectorService, TagService |
| Scoring | ScoringService (hibrit: RuleScorer + AiScorer), ScoreRecalculationService |
| Assignment | AssignmentService, AssignmentRuleEngine, TaskService, SlaService |
| Crm | ActivityService, ReminderService, AttachmentService |
| Pipeline | DealService, PipelineStageService, ForecastService |
| Ai | AiAnalysisService, AiClientService (Claude API), AiUsageTracker |
| Notification | NotificationService, NotificationDispatcher, PreferenceService |
| Reporting | ReportService, DashboardService, SnapshotService |
| Catalog | ProductService, ProductMatchingService |

---

## 4. Repository Katmanı

**Kural:** Veri erişimi soyutlanır; Service somut Eloquent'e bağımlı olmaz.

### 4.1 Yapı
- `Shared\Abstracts\BaseRepository` — ortak CRUD (find, create, update, delete/softdelete, paginate, filtre uygulama).
- Her domain: `Contracts\{X}RepositoryInterface` + `Repositories\{X}Repository extends BaseRepository`.
- **Binding:** `RepositoryServiceProvider` içinde
  `$this->app->bind(LeadRepositoryInterface::class, LeadRepository::class);`

### 4.2 Sorumluluklar
- Sadece sorgu/CRUD; iş kuralı yok.
- Tenant scope otomatik uygulanır (Global Scope — bkz. §10).
- Filtreleme/sıralama/sayfalama standart (`Shared\Pagination`, `Filterable` trait).
- Karmaşık sorgular Query Builder/Eloquent ile repository içinde kapsüllenir (controller/service'e sızmaz).

### 4.3 Avantaj
- Test edilebilirlik: Service testlerinde repository **mock** edilir.
- Değiştirilebilirlik: ileride okuma için ayrı read-model/CQRS'e geçiş kolaylaşır.

---

## 5. Middleware Yapısı

`bootstrap/app.php` (Laravel 12) içinde kayıt edilir. Alias ve grup tanımları:

| Middleware | Alias | Görev |
|------------|-------|-------|
| **Authenticate (Sanctum)** | `auth:sanctum` | Token doğrulama |
| **EnsureTenantContext** | `tenant` | Token'dan/istekten tenant'ı çözüp bağlama (context) yerleştirir |
| **SetTenantScope** | `tenant.scope` | Global scope için aktif tenant_id'yi ayarlar |
| **CheckPermission (Spatie)** | `permission:` | İzin kontrolü (`permission:leads.view.all`) |
| **CheckRole (Spatie)** | `role:` | Rol kontrolü |
| **ApiVersion** | `api.version` | İstek sürümünü çözer/işaretler (v1) |
| **ForceJson** | `json` | `Accept: application/json` zorlar, hata formatını standardize eder |
| **ThrottleRequests** | `throttle:api` | Rate limiting (Redis tabanlı) |
| **LogActivityContext** | `activity.context` | Aktif kullanıcı/IP'yi activity log'a bağlar |

**API grup zinciri (kavramsal):**
```
api  → [force.json, throttle:api, api.version]
v1+auth → [auth:sanctum, tenant, tenant.scope, activity.context]
uç bazlı → [permission:..., role:...]
```

---

## 6. Policy Yapısı

**Yetkilendirme = Spatie izinleri + Policy (ownership) birleşimi.**

### 6.1 Katmanlı yetki
1. **Middleware** (kaba): `permission:leads.view.all` — uca giriş hakkı.
2. **Policy** (ince): `LeadPolicy@update` — *bu* kayda erişim (ownership: `lead.owner_id === user.id` veya yönetici).
3. **FormRequest@authorize**: hızlı ön kontrol.

### 6.2 Policy envanteri
| Policy | Korunan | Örnek kurallar |
|--------|---------|----------------|
| LeadPolicy | leads | view/update/delete/assign — sahiplik + rol seviyesi |
| DealPolicy | deals | sahiplik / ekip yöneticisi |
| ActivityPolicy | activities | yalnızca ilgili lead sahibi |
| TaskPolicy | tasks | atanan kullanıcı / oluşturan |
| UserPolicy | users | yalnızca admin |
| ReportPolicy | reports | view.own vs view.all |

- Roller (seed'de hazır): `super_admin` > `admin` > `sales_manager` > `sales_rep` > `analyst`.
- Policy'ler `AuthServiceProvider` veya domain provider'ında kayıt edilir.
- "Sahiplik" kuralı `Shared\Concerns\ResolvesOwnership` ile ortaklaştırılır.

---

## 7. Event Yapısı

**Event & Listener mimarisi zorunlu.** Yan etkiler olaydan tetiklenir; servis sıkı bağ kurmaz.

### 7.1 Çekirdek olaylar (domain events)
| Event | Tetikleyen | Dinleyiciler / Sonuç |
|-------|-----------|----------------------|
| `LeadCreated` | LeadService | → `ScheduleLeadScoring` (Job), `LogActivity` |
| `LeadEnriched` | LeadService | → `ScheduleLeadScoring` |
| `LeadScored` | ScoringService | → `NotifyHotLead` (skor yüksekse), `MaybeAutoAssign` |
| `LeadAssigned` | AssignmentService | → `NotifyAssignedRep`, `SetSlaTimer`, `LogActivity` |
| `LeadStatusChanged` | LeadService | → `LogActivity`, `MaybeCreateDeal` |
| `ActivityLogged` | ActivityService | → `UpdateLeadLastActivity`, `ClearColdLeadFlag` |
| `DealStageChanged` | DealService | → `RecordStageHistory`, `NotifyManager` |
| `DealWon` / `DealLost` | DealService | → `LogActivity`, `FeedScoringFeedback` (skor kalibrasyonu) |
| `SlaBreached` | SlaService (scheduler) | → `NotifyManager`, `MaybeReassign` |

### 7.2 İlkeler
- Event **immutable** veri taşır (DTO/ID), iş yapmaz.
- Ağır listener'lar `ShouldQueue` ile **kuyruğa** alınır → Job'a dönüşür.
- Kayıt: `EventServiceProvider` (veya domain provider) — event→listener haritası.
- Activity Log: hem Spatie Activitylog (model değişiklikleri) hem domain event listener'ları (iş olayları).

---

## 8. Job Yapısı

**Kural:** Queue gerektiren her iş bir Job. Sürücü: **Redis**.

### 8.1 Kuyruklar (öncelik bazlı)
| Kuyruk | İçerik | Öncelik |
|--------|--------|---------|
| `notifications` | e-posta/in-app/SMS gönderimi | yüksek |
| `scoring` | AI lead skorlama | orta |
| `ai` | AI analiz/özet (Claude API) | orta |
| `imports` | CSV/Excel toplu lead işleme | düşük |
| `reports` | rapor snapshot üretimi | düşük |
| `default` | genel | normal |

### 8.2 Job envanteri
| Job | Görev | Notlar |
|-----|-------|--------|
| `ScoreLeadJob` | Tek lead'i skorla (rule + AI) | retry + backoff; AiUsageTracker'a yaz |
| `BulkRescoreJob` | Toplu yeniden skorlama | `Bus::batch` |
| `ProcessLeadImportJob` | Import dosyasını satır satır işle | chunk + dedup; idempotent |
| `RunAiAnalysisJob` | Müşteri analizi / sonraki adım | Claude API |
| `SendNotificationJob` | Bildirim kanalına teslim | kanal başına |
| `CheckSlaBreachesJob` | SLA ihlali tarama | scheduler ile periyodik |
| `DetectColdLeadsJob` | Soğuyan lead tespiti | scheduler |
| `GenerateReportSnapshotJob` | Zamanlanmış rapor | scheduler |

### 8.3 İlkeler
- `tries`, `backoff`, `timeout` her job'ta tanımlı.
- **Idempotency** (özellikle import & bildirim).
- Başarısızlık → `failed_jobs` + alarm; AI job'larında maliyet/kota koruması.
- Zamanlama: `routes/console.php` scheduler (SLA, soğuk lead, raporlar).

---

## 9. API Versiyonlama

**Tüm uçlar `/api/v1`.**

### 9.1 Route organizasyonu
- `routes/api.php` → yalnızca **yükleyici**: `v1` prefix + middleware grubu altında her domain'in `routes/api_v1.php` dosyasını toplar.
- Her domain kendi route dosyasını taşır (`app/Domains/{Domain}/routes/api_v1.php`).
- `RouteServiceProvider` domain route'larını otomatik kaydeder (config `domains.php` üzerinden).

```
/api/v1/auth/...           (Identity)
/api/v1/leads/...          (Lead)
/api/v1/leads/{id}/score   (Scoring)
/api/v1/assignments/...    (Assignment)
/api/v1/activities/...     (Crm)
/api/v1/deals/...          (Pipeline)
/api/v1/ai/...             (Ai)
/api/v1/notifications/...  (Notification)
/api/v1/reports/...        (Reporting)
/api/v1/products/...       (Catalog)
```

### 9.2 İleride v2
- `app/Domains/{Domain}/Http/Controllers/Api/V2/` + `routes/api_v2.php`.
- Resource'lar sürümlenir (`V1\LeadResource`, `V2\LeadResource`).
- v1 deprecate sürecinde paralel çalışır.

### 9.3 Standartlar
- Tutarlı zarf: `{ data, meta, links }`; hata: `{ message, errors, code }`.
- Sayfalama, filtreleme (`?filter[status]=`), sıralama (`?sort=-created_at`).
- `Accept: application/json` zorunlu; `Idempotency-Key` yazma uçlarında.

---

## 10. Tenant Mimarisi

**Tek veritabanı, satır seviyesi izolasyon (`tenant_id`).** İzolasyon **middleware + global scope** ile.

### 10.1 Bileşenler (Domain: `Tenancy`)
| Bileşen | Görev |
|---------|-------|
| `EnsureTenantContext` (middleware) | Sanctum token'ından `tenant_id`'yi çözer, `TenantContext`'e koyar |
| `TenantContext` (singleton) | İstek yaşam döngüsünde aktif tenant'ı tutar |
| `BelongsToTenant` (trait) | Model'e: (a) `creating` sırasında `tenant_id` otomatik doldur, (b) global scope ekle |
| `TenantScope` (global scope) | Tüm sorgulara `WHERE tenant_id = ?` ekler |
| `tenancy.php` (config) | Muaf modeller (tenant'ı olmayanlar: permissions, global sectors) |

### 10.2 Akış
```
İstek → auth:sanctum → tenant middleware
   → token.user.tenant_id okunur → TenantContext::set($tenantId)
   → tenant.scope: modellerdeki TenantScope bu id'yi kullanır
   → Repository/Service tenant'tan habersiz çalışır (izolasyon şeffaf)
```

### 10.3 Kurallar
- `tenant_id` **asla** istekten alınmaz (yalnızca kimlikten) → cross-tenant sızıntı engellenir.
- Global (tenant'sız) veriler: `permissions`, sistem `roles`, global `sectors` → trait/scope uygulanmaz.
- Arka plan job'larında tenant bağlamı job payload'ında taşınır ve handler başında set edilir.
- İleride **bayi/partner** modeli: aynı mekanizma, tenant başına ayar `settings` tablosunda.

---

## 11. Auth Mimarisi

**Laravel Sanctum (API token) + Spatie Permission (RBAC).**

### 11.1 Kimlik doğrulama (Authentication)
- **Sanctum** kişisel erişim token'ı (SPA/mobil/3. parti).
- `AuthService`: login, logout, refresh, token iptal, 2FA (opsiyonel — `users.two_factor_*` alanları hazır).
- Token'a tenant ve rol bağlamı taşınır; her istek `auth:sanctum` ile doğrulanır.
- Oturum kaydı `sessions` tablosunda (token_hash, ip, expires_at, revoked_at).

### 11.2 Yetkilendirme (Authorization)
- **Spatie Permission**: roller + izinler (seed'de hazır: 5 rol, 20 izin, eşleştirmeler).
- Rol hiyerarşisi `roles.level` ile (super_admin 100 … analyst 20).
- İki kademe: **izin** (uca giriş, middleware) + **policy** (kayda erişim, ownership).
- `users.role_id` (şema) ↔ Spatie rol senkronizasyonu `RoleService`'te yönetilir.

### 11.3 Güvenlik kuralları
- Şifre `bcrypt`/`argon2`; `password_hash` alanı.
- Rate limit (login brute-force koruması) Redis throttle ile.
- Audit: login/logout, yetki değişimi, kritik aksiyonlar `audit_logs` + Spatie Activitylog.
- Yıkıcı işlemler (silme, toplu) ek policy + audit gerektirir.

---

## 12. Modül Bazlı Geliştirme Planı

> Her modül **dikey dilim** (vertical slice): Migration(✓ mevcut) → Model → DTO → Repository → Service → Policy → Event/Listener → Job → Request → Resource → Controller → Route → Test.

### Faz 0 — Çekirdek Altyapı (temel)
1. **Proje kurulumu** — `composer create-project laravel/laravel`, paketler (Sanctum, Spatie Permission, Spatie Activitylog, Predis), `config/*`.
2. **Shared katmanı** — BaseService, BaseRepository, BaseModel, traits (BelongsToTenant, HasUuid), exception handler, API response standardı.
3. **Tenancy** — TenantContext, middleware, global scope.
4. **API iskeleti** — v1 route yükleyici, versiyonlama, standart Resource/zarf.

### Faz 1 — Kimlik & Erişim
5. **Identity** — Auth (Sanctum), User, Team, Role/Permission (Spatie senkron), Policy temeli.
   *Çıktı: giriş yapan kullanıcı, roller, tenant izolasyonu uçtan uca çalışır.*

### Faz 2 — Veri Çekirdeği
6. **Catalog** — Ürün kataloğu + sektör eşleştirme (skorlamanın girdisi).
7. **Lead** — Lead CRUD, sektör, tag, **dedup**, **CSV/Excel import** (Job), Event'ler.
   *Çıktı: lead toplama + listeleme + import.*

### Faz 3 — Zeka & Operasyon
8. **Scoring** — Hibrit skorlama (RuleScorer + AiScorer/Claude), `ScoreLeadJob`, yeniden skorlama, açıklamalı çıktı.
9. **Assignment** — Atama kuralları (round-robin/sektör/skor), kapasite, SLA, görevler.
10. **Crm** — Aktivite/görüşme kaydı, timeline, hatırlatma, dosya.

### Faz 4 — Satış & İletişim
11. **Pipeline** — Aşamalar, fırsat (deal), aşama geçmişi, forecast, kazanım/kayıp.
12. **Notification** — In-app + e-posta (Job + kanal tercihleri); SLA/sıcak lead/soğuk lead tetikleyicileri.
13. **Ai** — Müşteri analizi & "sonraki adım" (Claude), kullanım/maliyet takibi.

### Faz 5 — Görünürlük
14. **Reporting** — Dashboard'lar (rol bazlı), temel raporlar, snapshot job'ları, export.

### Faz 6 — Sağlamlaştırma
15. **Test & sertleştirme** — Feature/Unit test kapsamı, rate limit, audit tamamlama, performans index doğrulama, dokümantasyon (OpenAPI).

---

## Ek: Kalite Kapıları (her modül için "bitti" tanımı)
- [ ] Controller'da iş mantığı yok (yalnızca Service çağrısı).
- [ ] Service yalnızca Repository interface'ine bağımlı.
- [ ] Tenant izolasyonu testle doğrulandı (cross-tenant erişim engelli).
- [ ] Policy + izin iki kademesi mevcut.
- [ ] Ağır iş Job'a alındı; Event/Listener bağlandı.
- [ ] Soft delete + Activity Log aktif.
- [ ] Feature testleri yeşil; API zarf/hata formatı standart.
```
