# ModHotels.net — Mimari Kararlar

> Bu belge, orijinal spec'in **cPanel paylaşımlı hosting** gerçeğine uyarlanmış
> hâlidir. Amaç: özgün, hızlı, SEO uyumlu ve **gerçekten deploy edilebilir** bir
> turizm işe alım platformu.

---

## 1. Hedef ortam ve kısıtlar

| Konu        | Spec (ideal)                     | Gerçek ortam (cPanel)                 | Karar |
|-------------|----------------------------------|---------------------------------------|-------|
| PHP         | 8.2+                             | XAMPP PHP 8.2 / cPanel MultiPHP 8.2–8.3 | ✅ PHP 8.2+ |
| Backend     | Laravel 12                       | Laravel 12 (uyumlu)                   | ✅ Laravel 12 |
| Veritabanı  | PostgreSQL                       | **MySQL / MariaDB** (cPanel standart) | 🔄 **MySQL** |
| Cache/Queue | Redis                            | Redis yok                             | 🔄 **database + file driver** |
| Arama       | Meilisearch                      | Meilisearch yok                       | 🔄 **Laravel Scout `database` sürücüsü + MySQL FULLTEXT** |
| Realtime    | WebSocket                        | Kalıcı soket süreci yok               | 🔄 **short-polling** (bildirim/başvuru) |
| Storage     | S3                               | Yerel disk                            | 🔄 **local disk** (S3 sürücüsü opsiyonel bırakılır) |
| Deploy      | Docker                           | Docker yok                            | 🔄 **klasik cPanel deploy** (aşağıda) |
| Frontend    | Ayrı Next.js                     | Node SSR süreci kırılgan              | 🔄 **Laravel monolit + Inertia/React** |

**Prensip:** Değiştirilen her bileşen, ileride VPS'e taşınırsa tek satır config
ile orijinal spec bileşenine (Redis, Meilisearch, S3) dönebilecek şekilde
soyutlanır. Laravel'in driver mimarisi bunu doğal olarak sağlar.

---

## 2. Render stratejisi — SEO ile SPA'yı birlikte çözmek

Inertia varsayılan olarak istemci tarafında render eder; bu, cPanel'de (Node SSR
olmadan) arama motorları için **kötü SEO** demektir. Bu yüzden **hibrit** yapı:

### Public (SEO-kritik) sayfalar → **Blade** (sunucu render, tam crawlable)
- Ana sayfa
- İş ilanı listeleme + filtre sonuçları
- İş ilanı detay
- Firma profili (public)
- Blog liste + blog yazı detay
- Statik sayfalar (hakkımızda, gizlilik, iletişim)

→ Sunucuda render edilir, Google birebir indeksler, Core Web Vitals yüksek,
   Node gerektirmez. İçine React "island"ları (filtre widget'ı, harita) gömülebilir.

### Uygulama (auth-gerektiren, etkileşimli) alanlar → **Inertia + React + TS**
- İş arayan paneli (CV oluşturucu, başvurularım, favoriler)
- İşveren paneli (ilan yönetimi, başvurular, aday filtreleme, mülakat)
- Süper Admin paneli (tüm yönetim)

→ Zengin SPA deneyimi; bu alanların SEO'ya ihtiyacı yok (noindex).

**Sonuç:** React + TypeScript + Tailwind spec'teki gibi kullanılır, SEO ve hız
korunur, cPanel'de Node çalıştırma zorunluluğu ortadan kalkar.

---

## 3. Teknoloji yığını (nihai)

- **Framework:** Laravel 12, PHP 8.2+
- **Auth + Inertia scaffold:** Laravel Breeze (Inertia + React + TypeScript stack)
- **Frontend:** React 18 + TypeScript + TailwindCSS + Vite (Blade tarafında Vite + Alpine.js küçük etkileşimler için)
- **Veritabanı:** MySQL 8 / MariaDB 10.6+ (InnoDB, utf8mb4)
- **Arama:** Laravel Scout `database` sürücüsü (MySQL FULLTEXT indeksleri)
- **Cache:** `file` (varsayılan) — VPS'te Redis'e geçilebilir
- **Queue:** `database` sürücüsü + cron ile `queue:work`
- **Zamanlanmış işler:** cPanel cron → `php artisan schedule:run` (dakikada bir)
- **PDF (CV):** `barryvdh/laravel-dompdf`
- **Rol/İzin:** `spatie/laravel-permission` (super-admin, employer, jobseeker + ince izinler)
- **Çok dil (içerik):** `astrotomic/laravel-translatable` — blog/ilan alanları TR/EN/RU
- **Çok dil (arayüz):** Laravel lang dosyaları + `mcamara/laravel-localization` (URL: `/tr`, `/en`, `/ru`)
- **Slug:** `spatie/laravel-sluggable`
- **Aktivite/log:** `spatie/laravel-activitylog`
- **Medya:** basit path kolonları (veya `spatie/laravel-medialibrary` — sonra)
- **AI:** Anthropic Claude API (HTTP) — CV/ilan üretimi, analiz, sohbet asistanı
  (uygulama sırasında güncel model seçilir: Opus 4.8 / Sonnet 5 / Haiku 4.5)

---

## 4. Klasör yapısı (özet)

```
mothotels/
├─ app/
│  ├─ Models/            # User, JobSeekerProfile, Company, JobPost, Application, BlogPost, Ad ...
│  ├─ Http/
│  │  ├─ Controllers/
│  │  │  ├─ Public/      # Blade: Home, JobListing, JobDetail, Company, Blog
│  │  │  ├─ JobSeeker/   # Inertia
│  │  │  ├─ Employer/    # Inertia
│  │  │  └─ Admin/       # Inertia
│  │  ├─ Requests/       # FormRequest doğrulamaları
│  │  └─ Middleware/     # role, locale, ...
│  ├─ Services/          # AiService, CvPdfService, SearchService, AdService ...
│  └─ Support/
├─ resources/
│  ├─ views/             # Blade (public + layout + pdf şablonları)
│  ├─ js/
│  │  ├─ Pages/          # Inertia sayfaları (JobSeeker/ Employer/ Admin/)
│  │  ├─ Components/
│  │  └─ Layouts/
│  ├─ css/
│  └─ lang/              # tr / en / ru
├─ database/
│  ├─ migrations/
│  ├─ seeders/           # şehir/ilçe, pozisyon, departman, rol, demo veri
│  └─ factories/
├─ routes/
│  ├─ web.php            # public Blade
│  ├─ jobseeker.php
│  ├─ employer.php
│  ├─ admin.php
│  └─ api.php            # ileride Flutter/mobil için REST
├─ docs/                 # bu belgeler
└─ public/
```

---

## 5. Geliştirme & deploy modeli (FTP-only, kabuksuz)

**Ortam gerçeği:** Sunucuda **SSH/kabuk YOK** — `composer`, `php artisan`, `npm`
sunucuda çalıştırılamaz. Senkron **VSCode SFTP eklentisi** ile (FTP, `uploadOnSave`,
hedef `/public_html`). Bu yüzden tüm komut-gerektiren işler **lokal XAMPP'ta**
yapılır, sonuç FTP ile yüklenir. Ayrıntılı adımlar: **`docs/DEPLOY.md`**.

**Lokal (geliştirme + test):**
- XAMPP: PHP 8.2 + MySQL. `composer install`, `php artisan ...`, `npm run dev/build` hep lokalde.
- Test: `php artisan serve` / `http://localhost`. Canlı site geliştirmede kırılmaz.

**Deploy (lokal → sunucu, FTP):**
1. **vendor/** FTP ile yüklenir (sunucuda `composer install` yok). composer değişince klasör elle yeniden yüklenir.
2. **Vite build** lokalde (`npm run build`) → `public/build/` yüklenir. Sunucuda Node yok.
3. **Web kök & güvenlik:** cPanel'de domain **Document Root → `public_html/public`** yapılır.
   Böylece `app/`, `config/`, `.env`, `vendor/` web kökünün *üstünde* kalır (dışarıdan erişilemez).
   Docroot değiştirilemiyorsa: `public_html/.htaccess` ile tüm trafik `/public`'e yönlendirilir + hassas klasörler `deny` edilir (fallback, bkz DEPLOY.md).
4. **Migration:** sunucuda `artisan migrate` yok → ya lokal DB'nin SQL'i **phpMyAdmin**'den import edilir,
   ya da **token korumalı** `/__deploy/migrate?token=...` web-route'u ile çalıştırılır (bkz DEPLOY.md).
5. **storage:link YOK:** symlink FTP ile kurulamaz. Kullanıcı yüklemeleri doğrudan
   `public/uploads` altına yazılır (`filesystems.php`'de `public` disk kökü `public_path('uploads')`).
6. **APP_KEY:** lokalde `key:generate`, `.env`'e yazılır, `.env` yüklenir (docroot üstünde → güvenli).
7. **Config/route cache:** sunucuda **kullanılmaz** (yollar farklı + kabuk yok). MVP için gerek yok; ileride web-route ile.
8. **`.env` (production):** `APP_ENV=production`, `APP_DEBUG=false`, `DB_CONNECTION=mysql`,
   `CACHE_STORE=file`, `QUEUE_CONNECTION=database`, `SESSION_DRIVER=database`, `FILESYSTEM_DISK=public`.
9. **Cron (varsa):** `* * * * * php .../artisan schedule:run` → kuyruk `queue:work --stop-when-empty` tetikler.
   Cron yoksa MVP'de mail/işler **senkron** gönderilir (queue bağımlılığı yok).
10. **Mail:** cPanel SMTP.

---

## 6. Güvenlik & performans notları

- Tüm form girişleri FormRequest ile doğrulanır; kütle atama (mass assignment) kapalı.
- Dosya yüklemeleri: tip/boyut doğrulama, public dışı geçici alan, rastgele isim.
- Rate limiting: login, başvuru, AI uçları.
- Cache: public ilan/blog sayfaları için query + fragment cache.
- Görseller: yükleme sırasında WebP dönüşümü + boyutlandırma (intervention/image).
- Index'ler: ilan filtre kolonları (city_id, position_id, employment_type, status) ve FULLTEXT (title, description).
- CSRF, HTTPS zorunlu, güvenli header'lar.
```
