# cPanel Deploy Talimatı — Cari Takip Sistemi

> **Hedef:** Lokal geliştirilen sistemi cPanel hostingli bir Linux sunucuya yükleme.

---

## 0. Ön Gereksinimler

### Hosting Tarafı
- **PHP 8.2+** (cPanel → Select PHP Version'dan kontrol et)
- **MySQL 8.0+** veya MariaDB 10.6+
- **Composer** (cPanel SSH veya Cron Jobs üzerinden çalıştırılacak)
- **SSH erişimi** (önerilir; yoksa adımlar uzar)
- **HTTPS / SSL sertifikası** (cPanel → SSL/TLS Status, AutoSSL/Let's Encrypt)
- **PHP Extensions**: `bcmath`, `ctype`, `curl`, `dom`, `fileinfo`, `gd`, `intl`, `mbstring`, `openssl`, `pdo_mysql`, `tokenizer`, `xml`, `zip`

### Önerilen TR Hosting'ler
| Sağlayıcı | Notlar |
|---|---|
| Natro | Yaygın, PHP 8.2 + Composer destekli paketler |
| Hostinger | Hızlı SSD, LiteSpeed (Apache uyumlu) |
| Turhost | KVKK için Türkiye lokasyon |
| GuzelHosting | SSH'lı paketler |

---

## 1. Lokal: Deploy Paketi Hazırlama

Lokal bilgisayarında, proje klasöründe PowerShell aç ve çalıştır:

```powershell
.\deploy-paketle.ps1
```

Bu script:
1. `composer install --no-dev --optimize-autoloader` ile production bağımlılıkları
2. `npm run build` ile React/JS asset'lerini derler
3. SQLite verisini `data.sql` dosyasına çevirir
4. **Hassas dosyaları hariç tutarak** `cari-takip-deploy.zip` oluşturur

**Çıktı:** `deploy/` klasöründe:
- `cari-takip-deploy.zip` — sunucuya yüklenecek dosya
- `data.sql` — MySQL'e import edilecek veri
- `.env.production.example` — config şablonu
- `KURULUM.md` — bu dosya

---

## 2. cPanel: Veritabanı Hazırlığı

1. cPanel → **MySQL® Databases**
2. **Create New Database**: `caritakip` → "Create Database"
   (cPanel öneki ile genelde `kullaniciadi_caritakip` olur, not al)
3. **Add New User**:
   - Kullanıcı adı: `cari_admin` (kısa tut, prefix eklenir)
   - Şifre: **Password Generator ile en az 16 karakter** üret, sakla
4. **Add User to Database**:
   - User: az önce oluşturduğun
   - Database: az önce oluşturduğun
   - Privileges: **ALL PRIVILEGES** (sadece bu DB için)

> Not al:
> - DB adı: `kullaniciadi_caritakip`
> - DB kullanıcı: `kullaniciadi_cari_admin`
> - DB şifre: `(generated)`

---

## 3. cPanel: Dosyaları Yükle

### Yöntem A — File Manager (Web)
1. cPanel → **File Manager**
2. `public_html/` altına git
3. **Upload** → `cari-takip-deploy.zip` yükle (50-100 MB olabilir)
4. ZIP'e sağ tık → **Extract** → `public_html/cari-takip/`

### Yöntem B — FTP (Daha hızlı, büyük dosyalarda)
- FileZilla / WinSCP ile FTP bağlantısı
- ZIP'i yükle, cPanel File Manager'dan extract et

### Klasör Yapısı (önemli)
```
public_html/
├── cari-takip/              ← Laravel projesi (private dosyalar burada)
│   ├── app/
│   ├── bootstrap/
│   ├── config/
│   ├── database/
│   ├── public/              ← Web kökü buraya yönlendirilecek
│   ├── routes/
│   ├── storage/
│   ├── vendor/
│   ├── .env                 ← Sonra oluşturulacak
│   └── artisan
└── (varsa diğer siteler)
```

---

## 4. Document Root: `public/` klasörüne yönlendirme

Laravel'in **public/** klasörü web kökü olmalı, üst klasör değil.

### Yöntem A — Subdomain (önerilen, temiz)
1. cPanel → **Subdomains** → `muhasebe.firma.com.tr`
2. Document Root: `public_html/cari-takip/public`
3. Create

### Yöntem B — Add-on Domain veya Ana Domain
- cPanel → **Domains** → ilgili domain için Document Root değiştir → `public_html/cari-takip/public`

### Yöntem C — Symlink (SSH varsa)
```bash
cd public_html
ln -s cari-takip/public muhasebe
# Sonra https://firma.com/muhasebe çalışır
```

---

## 5. .env Dosyası Oluştur

cPanel → File Manager → `public_html/cari-takip/`

1. `.env.production.example`'i kopyala, **`.env`** olarak adlandır.
2. Dosyaya sağ tık → **Edit**, şu alanları doldur:

```ini
APP_NAME="Cari Takip Sistemi"
APP_ENV=production
APP_KEY=                      # ← Sonra üreteceğiz
APP_DEBUG=false               # ← KESİNLİKLE false
APP_URL=https://muhasebe.firma.com.tr

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=kullaniciadi_caritakip
DB_USERNAME=kullaniciadi_cari_admin
DB_PASSWORD=BURAYA_GUCLU_SIFRE

SESSION_SECURE_COOKIE=true    # ← HTTPS olduğu için
SESSION_DRIVER=database
SESSION_LIFETIME=30
```

3. Kaydet.

---

## 6. Veriyi MySQL'e Import Et

### Yöntem A — phpMyAdmin (web)
1. cPanel → **phpMyAdmin**
2. Sol panelden DB'yi seç (`kullaniciadi_caritakip`)
3. Üstte **Import** sekmesi
4. **Browse** → lokal'deki `deploy/data.sql` dosyasını seç
5. Format: SQL → **Go**

> **Önce migrate çalıştır** ki tablolar oluşsun, sonra data.sql import et.

### Yöntem B — SSH (varsa, daha hızlı)
```bash
cd ~/public_html/cari-takip
mysql -u kullaniciadi_cari_admin -p kullaniciadi_caritakip < /yol/data.sql
```

---

## 7. Laravel Kurulum Komutları

### SSH Varsa (Önerilen)
```bash
cd ~/public_html/cari-takip

# 1. Application key üret
php artisan key:generate --force

# 2. Tabloları oluştur (data.sql import etmediysen)
php artisan migrate --force

# 3. Cache optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# 4. Storage symlink (belge erişimi için)
php artisan storage:link

# 5. İzinler
chmod -R 755 storage bootstrap/cache
chown -R $(whoami):$(whoami) storage bootstrap/cache
```

### SSH Yoksa — cPanel "Cron Jobs" üzerinden
cPanel → **Cron Jobs** → "Add New Cron Job":
- Common Settings: **Once per minute** (geçici, sadece bir defa çalıştır)
- Command:
  ```bash
  cd /home/KULLANICI/public_html/cari-takip && php artisan key:generate --force && php artisan migrate --force && php artisan config:cache && php artisan storage:link
  ```
- 1-2 dakika sonra Cron'u **sil**.

---

## 8. TCMB Otomatik Kur Cron'u

cPanel → **Cron Jobs**:

```
* * * * * cd /home/KULLANICI/public_html/cari-takip && php artisan schedule:run >> /dev/null 2>&1
```

> Bu satır her dakika `schedule:run` tetikler; Laravel kendi içinde günde 15:30'da `kur:guncelle`'yi çalıştırır.

---

## 9. .htaccess Kontrolü

`public_html/cari-takip/public/.htaccess` dosyası **mevcut olmalı**. Yoksa Laravel kuruluştan gelen şu içerikte olmalı:

```apache
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>
    RewriteEngine On
    RewriteRule ^(.*)/$ /$1 [L,R=301]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```

### HTTPS Force (.htaccess'e ek)
```apache
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```

### Storage Klasörü Koruma
`public_html/cari-takip/storage/app/public/belgeler/.htaccess` deploy ile geliyor — PHP execution engelliyor. **Var olduğunu kontrol et**, yoksa kopyala.

---

## 10. SSL & HTTPS

cPanel → **SSL/TLS Status**:
- Domain için **AutoSSL** veya **Let's Encrypt** sertifikası kur (genelde otomatik)
- HTTPS aktif olduktan sonra `.env`'de **`SESSION_SECURE_COOKIE=true`**

---

## 11. İlk Giriş & Test

`https://muhasebe.firma.com.tr` aç:

| Test | Beklenen Sonuç |
|---|---|
| Login sayfası açılır mı? | ✅ Modern login formu, KVKK link'i |
| `admin@cari.local` / `admin123` (lokal'de bu şifre vardı) | Lokal'deki şifreyi kullan; **derhal değiştir** |
| Profil → Şifre Değiştir | ✅ Min 10 karakter zorunlu |
| Browser DevTools → Network → Response Headers | ✅ X-Frame-Options, CSP, HSTS görünmeli |
| `/kvkk` | ✅ Aydınlatma metni açılır |
| Cariler → Yeni → kayıt | ✅ Çalışır, audit log'da görünür |

---

## 12. Üretim Sertleştirme Kontrol Listesi

### Sunucu Tarafı
- [ ] `APP_DEBUG=false` ✅
- [ ] `APP_ENV=production` ✅
- [ ] `SESSION_SECURE_COOKIE=true` (HTTPS varsa)
- [ ] `.env` dosyası **644** veya **600** izinli (`chmod 600 .env`)
- [ ] `storage/`, `bootstrap/cache/` **755** izinli, web kullanıcısı writable
- [ ] **HTTPS aktif** + Let's Encrypt sertifikası
- [ ] **HSTS** header (production'da otomatik gelir)
- [ ] phpMyAdmin'de admin şifresi değiştirildi
- [ ] cPanel'de **Two-Factor Auth** açıldı (kendi cPanel hesabınız için)
- [ ] **Düzenli yedekleme** ayarı (cPanel → Backup → Schedule)

### Uygulama Tarafı
- [ ] Default `admin@cari.local / admin123` şifresi **değiştirildi**
- [ ] Yeni admin kullanıcı + güçlü şifre eklenmiş
- [ ] Eski admin pasife alındı veya silindi
- [ ] Roller/Yetkiler kontrol edildi
- [ ] TCMB otomatik kur Cron'u çalışıyor (`php artisan schedule:list` ile kontrol)
- [ ] Test girişleri (cari/kasa/hareket) yapıldı

### KVKK
- [ ] Kullanıcı verisi **Türkiye lokasyonlu sunucuda**
- [ ] `/kvkk` sayfası işletmenize göre düzenlendi (kurum adı, iletişim)
- [ ] **Aydınlatma metni** kullanıcılara duyuruldu
- [ ] Audit log'lar düzenli inceleniyor

---

## 13. Güncellemeler / Yeni Sürüm Yükleme

İleride kod değişikliği yaptığında:

```powershell
# Lokal'de
.\deploy-paketle.ps1 -DbAktarmaAtlA   # DB'yi atla, sadece kod
```

Sonra `cari-takip-deploy.zip`'i sunucuya yükle, **eski dosyaların üzerine** extract et (sadece değişenler güncellenir). `.env` ve `storage/` korunur.

```bash
# Sonra cPanel terminal/SSH'da:
cd ~/public_html/cari-takip
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

---

## 14. Sorun Giderme

### "500 Internal Server Error"
- `storage/logs/laravel-YYYY-MM-DD.log` dosyasına bak (cPanel File Manager'dan).
- En sık nedenler:
  - `.env`'de `APP_KEY` boş → `php artisan key:generate`
  - DB credentials yanlış
  - `storage/` veya `bootstrap/cache/` izinleri eksik (chmod 755)

### "419 Page Expired"
- Session driver'ı yeniden config'le (cache temizle: `php artisan cache:clear`)
- `SESSION_SECURE_COOKIE` HTTPS olmadan true ise → false yap

### Asset'ler yüklenmiyor (CSS/JS 404)
- `public/build/` klasörü deploy ZIP'inde mi?
- `APP_URL` doğru mu?
- HTTPS varsa `APP_URL=https://...`

### "MySQL access denied"
- DB credentials doğru mu (cPanel'deki **prefix dahil** kullanıcı adı/DB adı)
- DB user'a o DB için yetki verildi mi (cPanel → MySQL Databases)

### Belgeler görüntülenmiyor
- `php artisan storage:link` çalıştırıldı mı?
- `public/storage` symlink olarak mevcut mu?
- `storage/app/public/belgeler/` izinleri 755 mi?

---

## 15. Yedekleme Stratejisi (Tavsiye)

### cPanel
- Daily MySQL Backup (cPanel → JetBackup veya cron + mysqldump)
- Weekly Full Account Backup

### Uygulama içinden (gelecek özellik)
- Yedekleme paneli — admin → "Yedekleri İndir" → ZIP

### Manuel — SSH
```bash
# Günlük cron
0 3 * * * mysqldump -u USER -p'SIFRE' DBNAME | gzip > ~/yedekler/db_$(date +\%F).sql.gz
```

---

**Hazır!** Sorun çıkarsa `storage/logs/` dosyalarını ve cPanel "Errors" bölümünü kontrol et.
