# Agencive HR — Sistem Tasarımı

> Durum: Uygulama öncesi tasarım / Faz 0  
> Hedef teknoloji: PHP 8.2, Laravel, SQLite, Blade + Livewire + Alpine.js, Tailwind CSS

## 1. Yönetici özeti

Agencive HR, verileri kurum bazında kesin biçimde ayrılan, Türkçe öncelikli ve İngilizce destekli çok kurumlu bir İK SaaS ürünüdür. İlk sürüm; kurum ve yetki altyapısı, çalışan/organizasyon yönetimi, izin, belge, puantaj, bordro, takvim, bildirim, raporlama ve denetim kayıtlarını tek bir modüler uygulamada sunar.

Önerilen yaklaşım, tek Laravel uygulaması ve tek SQLite veritabanı içinde satır bazlı tenant ayrımıdır. Her tenant verisi `organization_id` taşır; tenant bağlamı middleware ile belirlenir, model global scope ile sorgulara uygulanır, policy katmanında yeniden doğrulanır ve iki kurumlu özellik testleriyle güvenceye alınır. Süper yönetici için tenant atlama örtük değil, açık ve audit log'a yazılan bir “kurum bağlamına geçiş” işlemi olmalıdır.

İlk teslimatın başarı ölçütü, Faz 1 sonunda kimlik doğrulama, kurum izolasyonu, RBAC, dil/tema tercihleri ve kurum ayarlarının çalışan testlerle birlikte tamamlanmasıdır.

## 2. Gereksinim analizi

### 2.1 Fonksiyonel kapsam

1. **Platform yönetimi:** Kurum yaşam döngüsü, abonelik/kullanım görünümü ve sistem ayarları.
2. **Kimlik ve erişim:** Giriş, parola sıfırlama, isteğe bağlı 2FA, oturum yönetimi, özel roller ve işlem bazlı izinler.
3. **Çalışan ve organizasyon:** Çalışan profili, hassas alan yetkileri, departman/birim/pozisyon, yönetici ilişkileri, organizasyon şeması ve rehber.
4. **Dinamik özlük alanları:** Kuruma özel alan tanımı, hedef kitle ve görünürlük kuralları, seçenekler ve dosya kısıtları.
5. **Belgeler:** Kategori, istek, yükleme, sürümleme, imza/geçerlilik durumu ve kontrollü indirme.
6. **İzin:** İzin türü/politikası, hak ediş ve hareket tabanlı bakiye, çok adımlı onay, iptal ve çalışma günü hesabı.
7. **Takvim ve görevlendirme:** Kurum etkinlikleri, resmi tatiller, izinler ve yetkiye göre maskelenmiş detaylar.
8. **Puantaj:** Takvim tabanlı günlük kayıt, otomatik izin/tatil yansıması, toplu işlem, kilitleme ve değişiklik geçmişi.
9. **Bordro:** Dönem, yapılandırılabilir parametreler, hesaplama kalemleri, yayınlama/kilitleme ve çalışan erişimi.
10. **Bildirim, duyuru ve rapor:** Uygulama içi/e-posta tercihleri, planlı bildirimler ve filtrelenebilir dışa aktarımlar.
11. **Güvenlik ve uyum:** Audit log, hassas alan şifreleme, KVKK dışa aktarma/anonimleştirme, yedekleme ve geri yükleme.

### 2.2 Fonksiyonel olmayan gereksinimler

- PHP 8.2 ve güncel, PHP 8.2 uyumlu Laravel sürümü.
- SQLite geliştirme ve küçük/orta ölçekli kurulum için desteklenir; büyüme halinde PostgreSQL'e geçişi engellemeyen SQL kullanımı.
- Responsive ve klavye ile kullanılabilir arayüz; WCAG 2.1 AA hedefi.
- Kurum saat diliminde gösterim, UTC saklama; tarih-saat hesaplarında DST güvenliği.
- Para alanlarında `decimal`, PHP tarafında para değerleri için minor-unit veya güvenli decimal/value object yaklaşımı.
- Kuyruk ve scheduler işlerinin tekrarlanabilir, idempotent ve tenant-aware olması.
- Dosyaların public dizinin dışında tutulması; tüm erişimin imzalı/kısa ömürlü uygulama rotası veya yetkili controller üzerinden yapılması.
- Kritik işlemlerde transaction, optimistic locking veya durum önkoşulu.
- Servis/action tabanlı iş mantığı; controller yalnızca doğrulama, yetki ve yanıt orkestrasyonu yapar.

### 2.3 Varsayımlar

- İlk sürüm tek ülke mevzuat motoruna kilitlenmez; Türkiye varsayılan ülke, `Europe/Istanbul` varsayılan saat dilimidir.
- Bir kullanıcı ilk sürümde tek bir kuruma bağlıdır. Birden fazla kuruma üyelik gerekirse `organization_user` üyelik tablosu eklenir.
- Çalışan ve kullanıcı ayrı kavramlardır; her çalışanın giriş hesabı olmak zorunda değildir. `employees.user_id` nullable ve kurum içinde unique olur.
- SQLite, ilk üretim ölçeğinde tek uygulama düğümü ve kontrollü queue worker ile kullanılır. Yoğun eşzamanlı yazma veya çoklu sunucu gerektiğinde PostgreSQL önerilir.
- E-posta gönderimi kuyruk üzerinden yapılır; SMTP sağlayıcısı kurulumda seçilir.
- Virüs taraması için yükleme “karantina → tarama → kullanılabilir” durum makinesiyle tasarlanır; tarayıcı (ör. ClamAV veya harici servis) dağıtım kararıdır.
- Bordro modülü hesaplama altyapısı sağlar; hukuki doğruluk ve mevzuat parametrelerinin güncelliği kurum yöneticisinin sorumluluğunda ve sürümlü parametrelerle yönetilir.
- Soft delete, mevzuat veya kayıt bütünlüğü nedeniyle geçmişi korunması gereken ana kayıtlarda kullanılır; finansal/hareket kayıtları silinmez, ters kayıt veya iptal durumuyla düzeltilir.

## 3. Modüller ve sınırlar

| Modül | Temel sorumluluk | Başlıca çıktılar |
|---|---|---|
| Platform | Kurum ve platform ayarları | Kurum yaşam döngüsü, kullanım özeti |
| IAM | Kimlik, rol, izin, oturum | RBAC, 2FA, profil tercihleri |
| Organization | Departman, birim, pozisyon | Organizasyon ağacı ve şema |
| People | Çalışan ve özlük | Profil, rehber, içe/dışa aktarma |
| Custom Fields | Dinamik alan şeması/değeri | Kuruma özel çalışan alanları |
| Documents | Belge ve sürüm yaşam döngüsü | Talep, tarama, indirme, süre uyarısı |
| Leave | İzin politikası ve süreçleri | Bakiye, talep, onay, iptal |
| Work Calendar | Çalışma günleri ve tatiller | Süre hesabı için takvim servisi |
| Attendance | Puantaj | Günlük kayıt, dönem kilidi, özet |
| Payroll | Bordro | Dönem, hesaplama, PDF/yayınlama |
| Calendar | Ortak olay görünümü | Aylık/haftalık/günlük/liste görünümü |
| Communication | Bildirim ve duyuru | In-app/e-posta ve tercihler |
| Reporting | Filtreli raporlar | CSV/XLSX/PDF dışa aktarma |
| Compliance | Audit/KVKK/yedek | İz, dışa aktarma, anonimleştirme |

Modüller ilk aşamada modüler monolit olarak aynı Laravel uygulamasında tutulur. Her modül kendi `Actions`, `DTOs`, `Models`, `Policies`, `Queries`, `Services` ve test alanına sahip olur. Modüller arası etkileşim domain olayı ve açık servis sözleşmeleriyle yapılır.

## 4. Önerilen sistem mimarisi

```mermaid
flowchart LR
    U[Web / Gelecekte Mobil] --> R[Laravel Routes]
    R --> M[Auth + Tenant + Locale Middleware]
    M --> C[Thin Controllers / Livewire]
    C --> A[Actions & Application Services]
    A --> P[Policies / Field Permissions]
    A --> D[Domain Services]
    D --> E[Eloquent Models + Tenant Scope]
    E --> DB[(SQLite)]
    D --> FS[Local / S3 Storage]
    D --> Q[Queue]
    Q --> N[Mail / In-app Notifications]
    S[Scheduler] --> Q
    A --> AL[Audit Writer]
    AL --> DB
```

### 4.1 İstek yaşam döngüsü

1. Kullanıcı doğrulanır ve aktif oturumu kontrol edilir.
2. `ResolveOrganizationContext` middleware kullanıcının kurumunu bağlama alır.
3. Locale, saat dilimi ve tema tercihleri kullanıcı/kurum ayarlarından çözülür.
4. Form Request girdiyi doğrular; Policy işlem ve kayıt erişimini sınar.
5. Action/Service transaction içinde iş kuralını uygular.
6. Domain olayı yayınlanır; bildirim, takvim ve puantaj yan etkileri queue listener'larında çalışır.
7. Kritik değişim aynı transaction veya güvenilir outbox yaklaşımıyla audit log'a yazılır.

### 4.2 Tenant izolasyonu savunma katmanları

- Tenant tablolarında zorunlu `organization_id` ve uygun bileşik indeksler.
- `BelongsToOrganization` trait + global scope; create sırasında kurumun otomatik atanması.
- Route model binding'in tenant scope içinde çözülmesi; bulunmayan/yabancı kayıt için 404.
- Policy içinde hem yetki hem `organization_id` eşleşmesi.
- Unique kuralların kurum kapsamlı olması.
- Queue job payload'ında `organization_id`; job başında bağlam kurulması, sonunda temizlenmesi.
- Cache anahtarlarında kurum öneki.
- Dosya yollarında tahmin edilemez UUID ve kurum öneki; indirme sırasında yeniden policy kontrolü.
- Rapor/export işlemlerinde tenant query nesneleri.
- En az iki kurumla HTTP, policy, queue ve doğrudan ID manipülasyonu testleri.

### 4.3 Güvenlik kararları

- T.C. kimlik, banka/IBAN, maaş ve sağlık verileri Laravel encrypted cast veya ayrı şifreli value object ile saklanır. Arama gerekiyorsa normalize edilmiş HMAC kör indeksi kullanılır.
- Hassas alanlar API Resource/Presenter katmanında izin bazlı dışarı verilir; yalnızca UI gizleme yeterli kabul edilmez.
- Parolalar Laravel'in güvenli varsayılan hasher'ı ile; giriş ve parola sıfırlamada rate limit.
- Oturum yenileme, idle timeout, CSRF, güvenli cookie, CSP ve güvenlik başlıkları.
- Belge indirme olayı ve hassas alan görüntüleme olayı audit'e yazılır.
- Audit kayıtları uygulama üzerinden güncellenemez/silinemez; bütünlük için sıralı hash opsiyonu planlanır.

## 5. Veri modeli

### 5.1 ER diyagramı — ana ilişkiler

```mermaid
erDiagram
    ORGANIZATIONS ||--|| ORGANIZATION_SETTINGS : has
    ORGANIZATIONS ||--o{ USERS : owns
    ORGANIZATIONS ||--o{ EMPLOYEES : employs
    ORGANIZATIONS ||--o{ DEPARTMENTS : structures
    DEPARTMENTS ||--o{ UNITS : contains
    DEPARTMENTS ||--o{ POSITIONS : defines
    POSITIONS ||--o{ EMPLOYEES : assigned
    EMPLOYEES o|--o| USERS : login
    EMPLOYEES ||--o{ EMPLOYEE_MANAGERS : subordinate
    EMPLOYEES ||--o{ EMPLOYEE_MANAGERS : manager
    USERS }o--o{ ROLES : role_user
    ROLES }o--o{ PERMISSIONS : role_permission
    ORGANIZATIONS ||--o{ CUSTOM_FIELDS : defines
    CUSTOM_FIELDS ||--o{ CUSTOM_FIELD_OPTIONS : offers
    EMPLOYEES ||--o{ EMPLOYEE_CUSTOM_VALUES : has
    CUSTOM_FIELDS ||--o{ EMPLOYEE_CUSTOM_VALUES : receives
    EMPLOYEES ||--o{ EMPLOYEE_DOCUMENTS : owns
    DOCUMENT_CATEGORIES ||--o{ EMPLOYEE_DOCUMENTS : categorizes
    EMPLOYEE_DOCUMENTS ||--o{ DOCUMENT_VERSIONS : versions
    LEAVE_TYPES ||--o{ LEAVE_POLICIES : governed
    EMPLOYEES ||--o{ LEAVE_ENTITLEMENTS : granted
    LEAVE_ENTITLEMENTS ||--o{ LEAVE_BALANCE_TRANSACTIONS : ledger
    EMPLOYEES ||--o{ LEAVE_REQUESTS : requests
    LEAVE_REQUESTS ||--o{ LEAVE_APPROVALS : approvals
    WORK_CALENDARS ||--o{ WORK_CALENDAR_DAYS : days
    WORK_CALENDARS ||--o{ PUBLIC_HOLIDAYS : holidays
    TIMESHEET_PERIODS ||--o{ TIMESHEET_ENTRIES : includes
    EMPLOYEES ||--o{ TIMESHEET_ENTRIES : tracked
    PAYROLL_PERIODS ||--o{ PAYROLLS : contains
    EMPLOYEES ||--o{ PAYROLLS : paid
    PAYROLLS ||--o{ PAYROLL_ITEMS : itemizes
    ORGANIZATIONS ||--o{ ANNOUNCEMENTS : publishes
    USERS ||--o{ NOTIFICATIONS : receives
    ORGANIZATIONS ||--o{ AUDIT_LOGS : records
```

### 5.2 Ortak kolon kuralları

- Tenant tabloları: `id`, `organization_id`, `created_at`, `updated_at`; gerektiğinde `deleted_at`, `created_by`, `updated_by`.
- Harici/URL kimliklerinde tahmin edilebilir integer yerine UUID/ULID `public_id`.
- Zamanlar UTC datetime; salt tarihler `date`; kurum saat dilimi yalnızca giriş/çıkış ve hesaplamada uygulanır.
- Para: `decimal(19,4)` ve `currency char(3)`; oran/katsayı: bağlama göre `decimal(12,6)`.
- Durumlar uygulama enum'u + DB check constraint destekliyorsa constraint.
- Kritik ledger tablolarında update/delete yerine ters kayıt.

### 5.3 Tablo kataloğu ve önemli kısıtlar

| Tablo | Kritik alanlar / ilişkiler | İndeks ve kısıtlar |
|---|---|---|
| `organizations` | ad, kısa ad, vergi, iletişim, ülke, para, saat dilimi, dil, marka, durum | unique vergi no (nullable); status index |
| `organization_settings` | organization_id, çalışma günleri/saatleri JSON, tatil takvimi, izin ve güvenlik ayarları | unique organization_id |
| `users` | organization_id nullable(super admin), employee_id nullable, ad, email, password, locale, theme, 2FA, active | unique `(organization_id,email)`; employee unique |
| `employees` | organization_id, user_id, employee_no, kimlik/iletişim/iş/SGK/banka/maaş alanları, department/unit/position/manager/workplace | unique `(organization_id,employee_no)`; kurum e-postası için kurum kapsamlı unique; filtre indeksleri |
| `departments` | organization_id, name, code, manager_employee_id, parent_id | unique `(organization_id,code)`; parent index |
| `units` | department_id, parent_id, name, code | unique `(organization_id,code)` |
| `positions` | department_id, name, code, description | unique `(organization_id,code)` |
| `employee_managers` | employee_id, manager_employee_id, type, valid_from/to, is_primary | self-management engeli; tarih ve employee index |
| `roles` | organization_id nullable(system role), name, code, immutable | unique `(organization_id,code)` |
| `permissions` | module, action, code, sensitivity | unique code |
| `role_user` | organization_id, user_id, role_id, granted_by/at | unique `(user_id,role_id)` |
| `role_permission` | role_id, permission_id | unique pair |
| `custom_fields` | code, label translations, type, rules JSON, visibility/update flags, list flag | unique `(organization_id,code)` |
| `custom_field_options` | custom_field_id, value, labels JSON, sort | unique field/value |
| `custom_field_targets` | field_id, target_type(department/position), target_id | unique target |
| `employee_custom_values` | employee_id, field_id, typed value columns/JSON | unique `(employee_id,field_id)` |
| `document_categories` | name, sensitivity, retention_days, accepted types/size | unique `(organization_id,name)` |
| `document_requests` | employee_id, category_id, requested_by, due_at, status | employee/status index |
| `employee_documents` | employee_id, category_id, current_version_id, expiry, signed status, scan status | expiry/status index |
| `document_versions` | document_id, storage_disk/path, mime, size, checksum, uploaded_by | unique `(document_id,version_no)` |
| `leave_types` | name, unit, paid, balance flag, inclusion rules, min/max, notice, document, color | unique `(organization_id,name)` |
| `leave_policies` | leave_type_id, audience/rules JSON, insufficiency behavior, approval_flow_id, effective dates | effective-date index |
| `leave_entitlements` | employee_id, leave_type_id, period dates, entitled | unique employee/type/period |
| `leave_balance_transactions` | entitlement_id, request_id nullable, amount signed, type, reason, actor | immutable; entitlement/date index; idempotency key unique |
| `leave_requests` | employee/type, start/end date-time, segment, calculated amount, substitute, status, reason | employee/date/status index; range validation |
| `leave_approvals` | request_id, step, approver/user-or-role, decision, note, acted_at | unique request/step/approver |
| `approval_flows/steps` | organization_id, name; ordered approver rules | unique flow/step order |
| `work_calendars` | name, country, timezone, scope, effective dates | scope/effective index |
| `work_calendar_days` | calendar_id, weekday, start/end, paid coefficient | unique calendar/weekday/validity |
| `public_holidays` | calendar_id, date, name, fraction, source, recurring | unique calendar/date/name |
| `assignments` | employee, start/end, type, location, visibility | employee/date index |
| `attendance_types` | code, name, coefficient, paid, color | unique `(organization_id,code)` |
| `timesheet_periods` | year, month, status, locked_by/at, reopen_reason | unique `(organization_id,year,month)` |
| `timesheet_entries` | period, employee, date, attendance_type, hours, coefficient, source/ref, note | unique `(period_id,employee_id,date,source/ref)` |
| `timesheet_entry_revisions` | entry, before/after JSON, reason, actor | immutable |
| `payroll_periods` | year/month, status, parameter_version_id, published/locked metadata | unique org/year/month |
| `payroll_parameters` | country, code, value, effective dates, version | unique org/code/version |
| `payrolls` | period, employee, gross/net/tax/deductions totals, status, calc snapshot | unique `(period_id,employee_id)` |
| `payroll_items` | payroll_id, code, type, base, rate, amount, source | payroll/type index |
| `calendar_events` | type, source polymorphic, start/end, visibility, department/employee | range/category index |
| `announcements` | title/body translations, audience, publish/expiry, author | publish/status index |
| `notifications` | Laravel notification fields + organization_id, read_at | user/read index |
| `notification_preferences` | user, event code, in_app/email flags | unique user/event |
| `audit_logs` | actor, organization, event, subject, old/new redacted JSON, ip, agent, occurred_at, hash | org/date, subject, actor indexes; immutable |
| `exports` | type, filters, status, storage path, requester, expiry | requester/status index |

SQLite foreign keys uygulama açılışında etkinleştirilmelidir. Tenant tablosundan başka tenant tablosuna referanslarda, yalnız `id` foreign key'ine güvenmek yerine uygulama/policy doğrulamasına ek olarak uygun yerlerde bileşik `(organization_id,id)` referansları değerlendirilmelidir.

## 6. Rol ve yetki matrisi

Gösterim: **T** tüm yetki, **K** kendi kurumu, **E** bağlı ekip, **Ö** yalnız kendisi, **—** yok, **A** ayrıca açık yetki gerekir.

| Modül / işlem | Süper yönetici | İK yöneticisi | Departman yöneticisi | Çalışan |
|---|---:|---:|---:|---:|
| Kurum oluştur/güncelle/pasifleştir | T | — | — | — |
| Kurum verisine bağlam değiştirerek eriş | A + audit | K | E kapsamı | Ö |
| Kurum ayarları | A | K | Görüntüle | Görüntüle |
| Rol oluştur ve izin ata | Sistem rolleri | K, kendi yetkisini aşamaz | — | — |
| Çalışan listele | A | K | E | Rehber alanları |
| Çalışan oluştur/güncelle | A | K | A/E | İzinli kendi alanları |
| Kimlik/banka/maaş/sağlık gör | A | Alan izni | — | İzinli kendi alanı |
| Organizasyon yönet | A | K | Görüntüle E | Görüntüle |
| Dinamik alan yönet | A | K | — | — |
| Belge talep/incele | A | K | A/E | Ö yükle/gör |
| İzin türü/politika/bakiye yönet | A | K | — | Ö bakiye gör |
| İzin talebi oluştur | — | Ö | Ö | Ö |
| İzin onayla/ret | A | Akışa göre K | Akışa göre E | Vekil adımında |
| Takvim | A | K detay | E sınırlı | K maskeli/Ö detay |
| Puantaj düzenle/kilitle/aç | A | K; açma özel izin | A/E | Ö görüntüle (izinli) |
| Bordro hesapla/yayınla | A | K + özel izin | — | — |
| Bordro görüntüle | A | K + hassas izin | — | Ö yayımlanmış |
| Rapor/dışa aktarma | A | Yetkili K | Yetkili E | — |
| Audit log | Platform kapsamı | K + özel izin | — | Ö güvenlik oturumu |

Özel roller şu eylemlerle tanımlanır: `view`, `create`, `update`, `delete`, `approve`, `export`, `publish`, `lock`, `reopen`, `view_sensitive_*`. İK yöneticisi yalnız kendisinde bulunan izinleri devredebilir; rol/izin değişiklikleri audit edilir.

## 7. Ana ekranlar ve kullanıcı akışları

### 7.1 Ekran listesi

- **Ortak:** Giriş, parola sıfırlama, 2FA, profil, dil/tema/bildirim tercihleri, bildirim merkezi, erişim reddedildi.
- **Dashboard:** İK dashboard'u, çalışan dashboard'u, özelleştirilebilir kart düzeni.
- **Çalışanlar:** Liste/filtre, yeni çalışan, profil sekmeleri, toplu içe aktarma, dışa aktarma, rehber.
- **Organizasyon:** Departmanlar, birimler, pozisyonlar, organizasyon şeması.
- **Özlük alanları:** Alan listesi, alan tasarım formu, hedef ve görünürlük kuralları.
- **Belgeler:** Kategoriler, belge talepleri, çalışan belgeleri, sürümler, yaklaşan süreler.
- **İzinler:** Talep listesi, hızlı talep, talep detayı/zaman çizelgesi, onay kutusu, izin türleri, politikalar, bakiyeler ve hareketler.
- **Takvim:** Ay/hafta/gün/liste, filtre paneli, olay detayı.
- **Puantaj:** Dönemler, aylık ızgara, çalışan/departman görünümü, toplu atama, kilit/açma.
- **Bordro:** Dönemler, hesaplama, çalışan detayı/kalemler, parametre sürümleri, yayınlama.
- **Raporlar:** Rapor kataloğu, filtreler, export geçmişi.
- **Duyurular:** Liste, oluşturma, hedef kitle ve yayın planı.
- **Ayarlar:** Kurum profili, marka, çalışma takvimi/tatiller, bildirim, güvenlik, roller/izinler, entegrasyon/depolama.
- **Platform:** Kurumlar, kullanım/abonelik, platform ayarları, yetkili bağlam geçişi.

### 7.2 İzin talebi akışı

```mermaid
stateDiagram-v2
    [*] --> Taslak
    Taslak --> Bekliyor: Gönder
    Bekliyor --> VekilOnayi: Vekil onayı gerekli
    Bekliyor --> YoneticiOnayi: Yönetici adımı
    VekilOnayi --> YoneticiOnayi: Kabul
    VekilOnayi --> Reddedildi: Ret
    YoneticiOnayi --> IKOnayi: İK adımı gerekli
    YoneticiOnayi --> Onaylandi: Nihai onay
    IKOnayi --> Onaylandi: Nihai onay
    YoneticiOnayi --> Reddedildi: Ret
    IKOnayi --> Reddedildi: Ret
    Onaylandi --> IptalTalebi: İptal iste
    IptalTalebi --> IptalEdildi: Onayla ve ters bakiye hareketi
```

Talep gönderilmeden önce tarih/saat sırası, çakışma, çalışan aktifliği, politika, bakiye ve belge zorunluluğu kontrol edilir. Hesaplanan süre ve hangi günlerin dışlandığı kullanıcıya özetlenir. Nihai onay transaction'ında bakiye hareketi idempotent şekilde yazılır; ardından takvim ve puantaj olayları kuyruğa alınır.

### 7.3 Çalışan oluşturma akışı

1. İK temel kimlik ve iş bilgilerini girer.
2. Sistem kurum içi çalışan no ve e-posta benzersizliğini doğrular.
3. Departman/birim/pozisyon seçimleri aynı tenant içinde doğrulanır.
4. Hassas alanlar yalnız ilgili izne sahip kullanıcıya gösterilir ve şifreli saklanır.
5. İsteğe bağlı kullanıcı hesabı oluşturulur; rol atanır ve davet gönderilir.
6. Eksik zorunlu belge/özel alanlar görev olarak dashboard'a yansır.

### 7.4 Puantajdan bordroya akış

```mermaid
flowchart LR
    C[Çalışma takvimi] --> T[Puantaj dönemi]
    L[Onaylı izin] --> T
    H[Resmi tatil] --> T
    T --> V[Kontrol ve düzeltme]
    V --> K[Kilit]
    K --> P[Bordro dönemi]
    PP[Sürümlü parametreler] --> P
    P --> O[Onayla / yayımla]
    O --> N[Çalışana bildirim ve PDF]
```

Kilitli puantaj değiştirilemez. Yeniden açma özel izin ve gerekçe ister. Bordro hesaplaması kullanılan puantaj ve parametrelerin snapshot'ını tutar; geçmiş sonuçlar yeni parametrelerden etkilenmez.

## 8. Arayüz tasarım sistemi

- Sol menü masaüstünde daraltılabilir; mobilde hamburger/drawer ve sık kullanılan işlemler için alt gezinme.
- Üst çubuk: kurum, global arama, hızlı ekle, bildirim, dil, tema, kullanıcı.
- Kart ve tablo yoğunluğu sade; kritik durumlar yalnız renkle değil ikon/metinle de belirtilir.
- Kurum ana rengi CSS değişkenleriyle uygulanır; erişilebilir kontrastı sağlamayan marka rengi otomatik güvenli tona çekilir.
- Açık tema yumuşak nötr zemin, koyu tema koyu gri yüzeyler; tema `system/light/dark` olarak kullanıcı bazında saklanır.
- Klavye odağı görünür, form alanları label ve yardım metinli, hata özeti ekran okuyucuya duyurulur.
- Para/tarih/sayılar locale ile; saklanan UTC zamanlar kurum saat diliminde görüntülenir.
- Mobil tablolar kart görünümüne dönüşür; en önemli eylemler erişilebilir kalır.
- Boş durumlar sonraki adımı açıklar; destructive işlemler gerekçe ve onay ister.

## 9. Servis ve iş kuralı tasarımı

Önemli servisler:

- `OrganizationContext`, `TenantQueryGuard`
- `EmployeeService`, `SensitiveFieldAuthorizer`, `EmployeeImportService`
- `WorkCalendarService`, `LeaveDurationCalculator`
- `LeaveRequestService`, `LeaveApprovalService`, `LeaveBalanceLedger`
- `TimesheetGenerationService`, `TimesheetLockService`
- `PayrollCalculationEngine`, `PayrollParameterResolver`, `PayrollPublisher`
- `DocumentUploadPipeline`, `DocumentAccessService`
- `AuditLogger`, `ExportService`, `DataAnonymizationService`

İş kuralları servislerde tek kaynaktan uygulanır; web, queue ve gelecekteki REST API aynı action/service katmanını çağırır. Onay, bakiye, puantaj kilidi ve bordro yayınlama işlemleri transaction ve idempotency key kullanır.

## 10. REST API hazırlığı

- Sürümlü rota: `/api/v1`.
- Web session auth'tan bağımsız token tabanlı mobil auth daha sonraki fazda Laravel Sanctum ile eklenebilir.
- API Resource'lar hassas alanları policy sonucuna göre filtreler.
- Liste uçları tutarlı filtre/sıralama/sayfalama sözleşmesi kullanır.
- İşlem uçları kaynak CRUD yerine niyet odaklıdır: `/leave-requests/{id}/approve`, `/timesheet-periods/{id}/lock`.
- Hatalar alan bazlı doğrulama, sabit hata kodu ve lokalize mesaj taşır.

## 11. Test stratejisi

- **Unit:** İzin süre hesabı, tatil/hafta sonu, yarım/saatlik izin, ledger, bordro kalemleri.
- **Feature:** Auth, parola sıfırlama, roller, çalışan CRUD, onay akışı, kilit/yayın durumları.
- **Tenant isolation:** İki kurum, aynı görünen kimlikler ve çapraz ID/URL/API/export/job denemeleri.
- **Authorization:** Her rol için allow/deny matrisi; hassas alanların response içinde bulunmadığının testi.
- **Integration:** Storage erişimi, queue notification, mail fake, scheduler işleri, export.
- **Localization/UI:** TR/EN mesajları, locale tarihleri, tema kalıcılığı ve temel erişilebilirlik kontrolleri.
- **Security regression:** Rate limit, CSRF, mass-assignment, dosya MIME/boyut, imzasız/yabancı belge erişimi.

Kritik modüllerde iş kuralı ve policy testleri tamamlanmadan sonraki fazın “çalışan sürümü” kabul edilmez.

## 12. Kurulum ve geliştirme planı

### Faz 0 — Tasarım (bu doküman)

- Gereksinim analizi, varsayımlar, modül sınırları.
- RBAC matrisi, ER modeli, akışlar, mimari, risk ve karar listesi.

### Faz 1 — Temel altyapı

- Laravel iskeleti, SQLite ve çevre dosyaları.
- Auth, parola sıfırlama, opsiyonel 2FA hazırlığı.
- Tenant context/scope/middleware/policy ve izolasyon testleri.
- RBAC ve başlangıç roller/izinleri.
- TR/EN localization, kullanıcı dili ve açık/koyu tema.
- Kurum profili/ayarları, demo kurum/kullanıcı seed'leri.

**Çıkış kriteri:** İki kurum kullanıcısı birbirinin kayıtlarına HTTP, model binding ve tahmin edilmiş ID ile erişemez; auth/RBAC/localization/theme testleri geçer.

### Faz 2 — Çalışan ve organizasyon

- Çalışan CRUD, hassas alan yetkileri, filtreleme ve CSV içe/dışa aktarma.
- Departman/birim/pozisyon, yönetici ilişkileri, organizasyon şeması.
- Dinamik özlük alanları ve çalışan rehberi.

### Faz 3 — Belgeler, izinler ve takvim

- Kontrollü belge yükleme/erişim, kategori/talep/sürüm/geçerlilik.
- İzin türü/politika, çalışma takvimi, tatiller, hareket tabanlı bakiye.
- Talep/onay/iptal akışları, bildirimler ve takvim.

### Faz 4 — Puantaj

- Dönem ve günlük kayıtlar, katsayılar, otomatik izin/tatil yansıması.
- Toplu işlemler, revizyon geçmişi, kilitleme/açma ve raporlar.

### Faz 5 — Bordro ve raporlama

- Parametre sürümleri, hesaplama motoru, dönem ve kalemler.
- Onay/yayın/kilit, PDF, çalışan görünümü, Excel/CSV/PDF raporları.

### Faz 6 — Güvenlik ve kalite

- Audit kapsamı, KVKK dışa aktarma/anonimleştirme/saklama.
- Performans, güvenlik sertleştirmesi, yedek/geri yükleme.
- Production, queue, cron/scheduler ve operasyon dokümanı.

Her fazda migration, factory/seeder, test, README ve değişiklik günlüğü birlikte teslim edilir. Faz sonunda temiz veritabanında `migrate:fresh --seed` ve test paketi çalıştırılır.

## 13. Riskler ve önlemler

| Risk | Etki | Önerilen önlem |
|---|---|---|
| SQLite eşzamanlı yazma sınırı | Puantaj/bordro toplu işlemlerinde kilit | WAL, kısa transaction, tek worker; ölçek eşiğinde PostgreSQL |
| Tek DB'de tenant veri sızıntısı | Kritik güvenlik ihlali | Çok katmanlı tenant guard, policy, tenant test paketi |
| Dinamik alanlarda kontrolsüz JSON | Raporlama ve doğrulama zorluğu | Alan tipine göre typed value kolonları + metadata JSON |
| Mevzuat değişikliği | Yanlış bordro | Sürümlü ve tarih etkili parametre; hesap snapshot'ı; hukuk/mali müşavir doğrulaması |
| Dosya zararlısı veya doğrudan erişim | Güvenlik/KVKK ihlali | Karantina/tarama, private storage, policy kontrollü indirme |
| Onay yan etkilerinin iki kez çalışması | Çifte bakiye/puantaj | Idempotency key, unique constraint, transaction/outbox |
| Saat dilimi/DST hataları | Yanlış izin süresi | UTC saklama, kurum TZ hesaplama, sınır testleri |
| Audit içinde hassas veri sızıntısı | KVKK riski | Alan bazlı redaction/maskeleme; erişim ve saklama politikası |
| Çok geniş ilk sürüm | Süre ve kalite riski | Faz çıkış kriterleri; önce tenant/auth ve izin çekirdeği |

## 14. Açık kararlar ve netleştirme soruları

Uygulamaya başlamadan önce aşağıdaki ürün kararları onaylanmalıdır:

1. İlk üretim hedefinde yaklaşık kurum, aktif kullanıcı ve eşzamanlı kullanıcı sayısı nedir? Bu karar SQLite'ın üretim için uygunluğunu belirler.
2. Bir kullanıcı birden fazla kuruma üye olabilecek mi, yoksa kurum başına ayrı hesap mı kullanılacak?
3. İlk sürümde abonelik/faturalama gerçekten işlevsel mi olacak, yoksa yalnız kullanım ve paket alanları mı tutulacak?
4. 2FA ilk sürümde zorunlu bir teslimat mı, yoksa altyapı hazırlığı yeterli mi?
5. E-posta, S3 ve virüs tarama sağlayıcıları hangileri olacak?
6. Türkiye bordrosu yalnız parametrelenebilir kayıt/hesap altyapısı mı, yoksa mevzuata göre doğrulanmış tam otomatik hesaplayıcı mı olmalı?
7. İzin onay akışları seri mi, paralel adımları ve vekâlet/delege mekanizmasını da desteklemeli mi?
8. Resmi tatil verisi harici bir servisten mi alınacak, yoksa seed + manuel yönetim yeterli mi?
9. KVKK saklama süreleri, silme/anonimleştirme onay süreci ve yasal hold kuralları nelerdir?
10. Kurum logosu/renkleri dışında özel alan adı (domain), e-posta şablonu ve white-label beklentisi var mı?
11. Excel içe aktarma için beklenen maksimum satır ve dosya boyutu nedir?
12. Bordro ve belgelerde elektronik imza veya KEP entegrasyonu kapsamda mı?

## 15. Önerilen başlangıç kararı

Faz 1'e; tek kurum üyeliği, SQLite + WAL, Blade/Livewire/Alpine, private local storage, queue için database driver, seri izin onay akışı ve 2FA altyapısı varsayımlarıyla başlanabilir. Yukarıdaki açık kararlar değişirse veri modelini etkileyecek maddeler (özellikle çoklu kurum üyeliği ve tam bordro motoru) kod başlamadan kesinleştirilmelidir.

## 16. Onaylanan ürün kararları — 24 Ağustos 2026

- İlk kurulum tek kurum ve yaklaşık 50 çalışan içindir; SQLite bu ölçek için uygundur. Veri modeli, ileride yeni kurumların kendi izole verileriyle eklenmesini desteklemeye devam eder.
- Kullanıcı hesabı tek kuruma bağlıdır. Aynı gerçek kişi ileride başka bir kurumda çalışırsa o kurumda ayrı çalışan ve kullanıcı kaydı açılır.
- Abonelik ve platform faturalaması kapsam dışıdır; satış doğrudandır.
- İlk sürümde 2FA için veri ve servis altyapısı hazırlanır; zorunlu kullanım sonraki karardır.
- E-posta sağlayıcısı sabit değildir. İK yöneticisi kurum SMTP bilgilerini arayüzden girer; parola şifreli saklanır.
- Türkiye bordrosu otomatik hesaplanır; oranlar kaynak koda gömülmez, yetkili İK yöneticilerinin yönetebildiği sürümlü parametrelerden çözülür. Üretim öncesinde hesap sonuçları mali müşavir/hukuk uzmanı tarafından doğrulanmalıdır.
- İzin onayı seridir: çalışan talebi İK'ya gider; sonuç çalışana ve varsa yerine bakacak kişiye uygulama içi/e-posta bildirimi olarak gönderilir. Vekilin ayrıca onay vermesi gerekmez.
- Resmi tatiller seed verisiyle gelir ve yetkili kullanıcı tarafından manuel yönetilebilir.
- KVKK süreçleri Türkiye mevzuatına göre tasarlanacaktır. Veri türüne göre saklama yükümlülükleri farklı olabildiği için Faz 6'da güncel mevzuat ve hukuk uzmanı onayıyla sürümlü saklama politikaları oluşturulur; tek bir genel süre kaynak koda sabitlenmez.
- White-label domain/e-posta şablonu, KEP ve elektronik imza ilk kapsamda değildir.
- Excel içe aktarma hedefi 50 çalışan ölçeğine göre ilk sürümde 1.000 satır ve 10 MB güvenli üst sınırıdır; kuyruk üzerinden işlenir.
