Changelog

Platforma eklenen yeni özellikler, iyileştirmeler, düzeltmeler ve güvenlik güncellemeleri.

2026-08-02
Product

Yerel PC Bulut Yedek Monitörü — Duplicati entegrasyonu (Professional+)

Ana bilgisayardaki muhasebe, belgeler ve proje klasörleri artık tenant'ın kendi Google Drive / OneDrive / Dropbox / S3 hesabına AES-256 şifreli otomatik yedeklenir. TD Panel merkezi izler — passphrase kullanıcıda kalır (zero-knowledge).

🔐 Mimari — TD Panel monitor + Duplicati agent

  • Duplicati open-source Windows istemcisi müşteri PC'sine kurulur; AES-256 şifreleme, incremental + dedupe (5 GB backup değişince sadece 50 MB upload), 7-günlük deneme sonrası saldırganlık dostu retention (grandfather-father-son).
  • TD Panel sadece orkestrator + monitor. Yedek içeriği sunucumuzdan asla geçmez — direkt PC → şifreli → kullanıcının cloud hesabı. Passphrase de sunucuda saklanmaz (kaybolursa restore imkansız → UI'da güçlü uyarı).
  • Webhook receiver (backup_cloud_webhook.php): Duplicati --send-http-url her backup sonrası JSON rapor postlar; TD Panel status/boyut/dosya sayısı/hata güncellenir.

📊 Kullanıcı arayüzü — backup_cloud.php

  • Cihaz wizard'ı: sağlayıcı (4 seçenek) + tıklanabilir klasör preset chip'leri (Belgeler, Masaüstü, Muhasebe programları Logo/Mikro/ETA/Netsis, D:/E: sürücü kökü) + "Bilgisayardan Gözat" butonu (webkitdirectory + prefix picker modal).
  • KPI Row: Kayıtlı cihaz sayısı · Son yedek yaşı · Toplam boyut · Sorunlu cihaz sayısı.
  • Cihaz listesi: Status badge (Sağlıklı/Uyarı/Hatalı) · Config indir · Webhook URL kopyala · Sil.
  • 12 adımlık kurulum rehberi (Duplicati indir → OAuth → passphrase → source seç → schedule → advanced webhook 3 ayarı → Run now → doğrulama) + Sık Sorunlar 5 madde.

🚨 Dashboard entegrasyonu + uyarı

  • Bulut Yedek Sağlığı widget'ı dashboard'da: son 5 cihaz + genel status badge (Sağlıklı/Kontrol edin/Aksiyon gerekli).
  • Alert cron (backup_cloud_alerts.php, günlük 09:00): 48 saat yedek yoksa veya status=fail ise tenant admin'lere HTML e-posta uyarısı — cihaz listesi + yaş + hata detayı ile.

💰 Plan matrisi

  • Starter · Free: ❌ Yok
  • Professional: ✅ 1 cihaz · 4 sağlayıcı · günlük yedek · 48h uyarı
  • Business: ✅ + öncelikli destek
  • Enterprise: ✅ + çoklu cihaz + custom retention politikaları

🔒 Güvenlik + KVKK

  • Zero-knowledge encryption: Passphrase Duplicati kurulumunda kullanıcı belirler, sunucuya asla gitmez. Yedek içeriğine ne TD Panel ne de bulut sağlayıcı erişebilir.
  • Webhook secret: 48-char hex, cihaz başına UNIQUE, rate-limited endpoint (60 req/60sn), body 500KB cap.
  • Data ownership KVKK dostu: Yedek kullanıcının kendi bulut hesabında. TD Panel sadece taşıyıcı sinyal (status raporu). Cross-border data transfer sözleşmesi kullanıcının kendi cloud sağlayıcısıyla.
  • Config export: Duplicati JSON import edilebilir; TargetURL provider bazlı (googledrive://, onedrivev2://, dropbox:///, s3://) — kullanıcı sonradan OAuth Login yapar.

Sayı özet: 813 satır kod · 5 yeni dosya (backup_cloud.php + webhook + widget + cron + migration) · 4 provider · 12 adım kurulum rehberi · plan gate (Professional+). MVP production-ready — Demo tenant üzerinde E2E test doğrulandı (POST 200, status/boyut/dosya sayısı/audit log). Kurulum ~10 dk müşteri PC'si başına.

2026-07-30
Product

Landing + panel UX yenilemesi: premium arkaplan, sidebar akordeon, row aksiyonları, Stok terminolojisi

3 günlük yoğun UX yenilemesi. Landing sayfası premium hisseye çıktı, panel içi tutarlılık ve keşfedilebilirlik ciddi seviyede arttı. 40+ commit'in tematik özeti.

🎨 Premium arkaplan — landing + login

  • Aurora + hairline gridpartials/hero_backdrop.php reusable partial. 4 renkli gradient blob (mavi/cyan/mor/emerald) 22-40s organik float animation, mix-blend-mode: screen ile iç içe erir. Statik SVG 40×40 grid, kenar vignette maskesi ile merkezde tam, kenarlarda kaybolur.
  • Uygulama: home.php hero + login.php viewport-full. Sıfır JS (CSS-only), GPU-accelerated translate3d + will-change: transform. prefers-reduced-motion ve mobile guard'ları hazır.
  • Landing 02-product-first patch — canlı badge (pulse dot), preview-frame accent glow, hero-copy içinde bağlamlı "Kurulum Sihirbazını Başlat" butonu, hareketli fake cursor dashboard mockup içinde (Vercel/Linear tarzı).

🌗 Dark mode kontrast fixleri

  • Vercel binary override sorunu--ui-primary dark tema'da #ededed (beyaz-gri) olduğu için birçok yerde "beyaz-üstünde-beyaz" oluşuyordu. Toplam 10+ element düzeltildi:
    • Pagination aktif sayfa, .preset-btn.active, .td-save-bar .btn-save, .sidebar-badge-info, .notes-tab.active, .filter-pill.active, .view-segment a.active, .type-toggle radio labels, AI chat header, e-Fatura OAuth popup butonu
    • Fix: sabit brand mavi (#006AFF) safety override panel-vercel.css chain sonunda
  • Bootstrap 5 body variable override — dark tema için --bs-body-color, --bs-secondary-color, --bs-emphasis-color vb. 10 CSS var eklendi. .text-body, .text-secondary vb. utility'ler artık doğru kontrastta.
  • FullCalendar dark mode — 12 FC CSS variable override (--fc-neutral-bg-color, --fc-list-event-hover-bg-color vs.) + explicit .fc-list-day-cushion safety. Etkilenen sayfalar: it_calendar.php, hr_leaves.php, tour.php, about_panel.php.
  • home.php dark contrast.bento-icon, .pricing-teaser, .testimonial-avatar için color: var(--bg) ile Vercel binary ters kontrast (Sprint 8.30 kalıntı bug).

📂 Sidebar akordeon — Envanter · İK · Destek

  • 13 yeni alt sekme — tab yapılı sayfaların alt tab'larına doğrudan link:
    • Envanter → Donanım: Stok, Hurda, Sunucular (3)
    • Envanter → Sigorta/Belge: Takip, Arşiv, İptal (3)
    • İnsan Kaynakları → İzin Yönetimi: Aktif, Arşiv, Takvim, Kanban (4)
    • Destek → Notlar: Tümü, Notlar, Aktif Görevler, Tamamlanan (4)
    • Destek → Önemli Linkler: Linkler, İndirmeler (2)
  • Akordeon toggle — parent link'in yanında + / düğmesi (CSS-only ::before, icon-agnostic). localStorage state persist. Active sub-tab varsa parent otomatik açık başlar.
  • 3 render path unifiedrenderPrimaryLink (Envanter), HR grubu, Destek grubu — hepsi tek tablosuna bağlı sub-aware active detection.

📋 Row aksiyonları standart sıra

  • Kural: Detay → Düzenle → ... → Sil (Sil her zaman sonda, Detay her zaman başta). 7 sayfada tutarlı: hardware, licenses, services, employees, payments, insurance, customers.
  • Extra aksiyonlar detay modal footer'ına taşındı — row temiz kalır, detay içinde bağlamlı akışlar:
    • hardware.php: Zimmet Tutanağı, Servis Kaydı, QR Etiket, Şubeye Taşı (4)
    • licenses.php + services.php: Yenile (+1 yıl)
    • payments.php: Faturaya Çevir (e-Fatura/e-Arşiv taslağı)
    • insurance.php takip tab: Yenile, Arşivle, İptal Et (3)
  • JS pattern: show.bs.modal event'inde trigger'ın data-* attribute'larından footer buton href/hidden input'ları dinamik set edilir. Permission gate (data-can-manage vb.) ile koşullu görünürlük.

📦 Envanter yönetimi — Stok terminolojisi + yeni özellik

  • "Boştaki Sağlam" → "Stok" yeniden adlandırma (5 kullanıcı-görünür metin: tab label, redirect msg, section header, form etiketi, employee release desc). Sidebar sub-tab, tab label, modal başlığı tutarlı.
  • Yeni: Hardware "Stoğa Taşı" özelliğihardware_form.php'de checkbox ile: cihazı [STOK] placeholder employee'ye çevirir, released_condition, released_at, released_from_employee_id, released_from_name alanları doldurulur. Hurda ile mutex (aynı anda ikisi işaretlenemez). Personel değişimi + audit için.

🎯 Dashboard + tab kart görsel tutarlılığı

  • Vercel Geist palette — 3 kart set'i (KPI glance, metric cards, .mail-kpi support stats) hepsinde üst 3px renk çubuk, hover'da 5px. Palette-bağımsız sabit renkler:
    • Blue #0070f3, Emerald #10b981, Amber #f5a623, Red #ee0000, Cyan #22d3ee, Purple #7c3aed
  • Panel-nav-tabs birleşimi — 8 sayfada (hardware, hr_leaves, insurance, important_links, payments, tools, e-posta admin) aynı .panel-nav-tabs stili. Bootstrap standard + border-bottom active indicator.
  • Dashboard hero orb ambience.panel-hero::before/::after subtle radial blur (mavi + cyan), "Sistem Aktif" trust badge'inde dashLivePulse yeşil nabız animasyonu.

🔧 UX iyileştirmeleri + temizlikler

  • Notlar & Yapılacaklar composer redesign — Textarea üstte tam genişlik + alt bar (Not/Görev pill toggle + büyük Ekle CTA + ⌘↵ kısayol ipucu). Focus'ta subtle brand mavi glow. Linear/Notion tarzı.
  • Görünümler → Görünüm (tekil) — buton stili Filtrele ile birebir aynı (.btn-filter-apply). Filtrele butonunun yanına taşındı (4 sayfa) — CRUD cycle daha akıcı.
  • Dışa Aktar UI kaldırıldıexport_dropdown() boş string döndürüyor. Rapor (colPickerModal) tek export akışı olarak kaldı. 20+ sayfada dokunmadan silindi. Backend ?export=csv/xlsx/pdf handler'ları bulk toolbar için korundu.
  • Kurulum Sihirbazı auto-open kaldırıldı — dashboard'a girişte artık otomatik açılmıyor. Hero'daki "Kurulum Sihirbazını Başlat" butonuna tıklandığında açılır.
  • AI Chat header — brand mavi bg + beyaz metin sabitlendi (Vercel binary'de görünmeme sorunu çözüldü).

⚡ Performans + operasyon

  • SA panel CSS cache-buster — 21 SA sayfasında panel-v2.css ?v=filemtime eklendi. Deploy sonrası SA kullanıcıları eski CSS'i görmez.
  • panel-vercel.css safety override chain — chain'in en sonuna 4 bölüm: Bootstrap dark vars, FC dark, contrast safety, 02-product-first global. panel-v2.css'e dokunmadan tüm bug'lar tek noktadan.
  • Panel Kullanım Rehberiabout_panel.php tab 4 tamamen güncellendi: 6 accordion + 1 yeni bölüm (Filtre, Görünüm, Kurulum Sihirbazı, AI Sohbet), 180 satır TR+EN paralel metin.

Sayı özet: 40+ commit · 60+ dosya düzenlemesi · +2000/-1500 net satır · 5 backup (rollback güvencesi). Panel görsel dili artık tutarlı (Vercel Geist), keşfedilebilirlik ↑ (sidebar akordeon + row-detay ayrımı), landing premium (aurora backdrop).

2026-07-02
Product

HR self-servis izin portalı + takvim view + marka logo yayılımı

Personel kendi izin taleplerini güvenli bir portal üzerinden girer, İK takvim üzerinden onaylar. İş yükü azaltıcı 5-fazlı sprint.

  • Kalıcı personel portalıhr_leave_portal.php
    • İK hr_leave_token.php'de "Kalıcı Portal Linki" seçer → token_type='personal', 365 gün TTL
    • Personel ?t=<hash> ile giriş yapar: dashboard'da kullanılan / bekleyen / kalan yıllık kota tile'ları + yeni talep formu + son 20 talep + bekleyenler için "İptal Et"
    • Mevcut tek-kullanımlık hr_leave_public.php akışı korundu — geriye dönük uyumlu, otomatik yönlendirme
    • Aynı personelde yeni portal linki üretildiğinde önceki otomatik iptal edilir (tek aktif invariant)
  • HR takvim viewhr_leaves.php?tab=takvim (FullCalendar 6.1)
    • Ay / Hafta / Liste view, TR locale, status renk paleti (bekliyor sarı, onaylı yeşil, reddedildi kırmızı, iptal gri)
    • Event click → detay modal: firma, tarih, gün, durum, kaynak, neden + onay/red butonları (canWrite + status='bekliyor' şartıyla)
    • Yeni JSON endpoint hr_leaves_calendar_api.php — customer_id + tarih range + opsiyonel status filtresi, TD_JSON_ENDPOINT pattern
    • Reddedilen / iptal edilen event'ler için toggle checkbox — refetch tetikler
    • Composite index idx_hr_leaves_cal (customer_id, start_date, end_date) range query performansı
  • Akıllı kontroller — portal formu submit öncesi
    • Yıllık kota: hr_leave_types.max_days_per_year aşılırsa HARD BLOCK — "talep 7 gün, kalan hakkınız 3 gün..."
    • Departman çakışması: aynı departmanda o tarihte izinli var mı → SOFT WARNING + zorunlu onay checkbox, kaydolmaz
    • Sticky form değerleri (validation error'da kullanıcı yeniden yazmasın)
  • Bildirim akışılib/HrLeaveMailer.php
    • Yeni onRejected(, , ) — personel'e "izin reddedildi" e-postası (opsiyonel İK notu)
    • Yeni notifyHrOfNewRequest(, ) — portal talebi sonrası İK ekibine (admin + can_write user'lar) toplu bilgi + CTA butonu
    • Best-effort try/catch — mail hatası ana akışı bozmaz
  • Marka logo yayılımı — 15 marketing/public sayfa
    • Eski "TD" text mark → yeni 4-diamond cube (logo-cube-white.svg · siyah karo)
    • pricing, auth_guide, errors, examples, integrations, self_host, webhooks_catalog, changelog, roadmap, legal_page, components, trust, onboarding, status, api
    • Her sayfa kendi lokal .brand-mark CSS'i; background:#0a0a0a + overflow:hidden + child img rule ile normalize edildi

Şema değişikliği idempotent (hr_init.php içinde information_schema check + ALTER pattern'i), ilk HR sayfa yüklemesinde çalışır. sw.js td-v57 → td-v58, endpoint bypass listesine hr_leaves_calendar_api.php eklendi.

2026-06-22
Güvenlik

Webhook secret rotation — Logger entegrasyonu + roadmap güncelleme

Webhook secret rotation altyapısı zaten implement edilmişti (7 gün grace period, X-TD-Signature-Previous header desteği, UI butonu). Bu güncellemede observability pipeline'a bağlandı.

  • Logger::warn('Webhook secret rotated') — rotation event'i audit_log yanında JSON event stream'e de düşer. Sentry uyumlu (anlık alarm).
  • Context: webhook_id, grace_until (7 gün sonrası), rotated_by (user_id)
  • Roadmap güncellemesi: "Webhook secret rotation UI" item'ı "shipped" durumunda olduğu için silindi; yerine "Webhook diff payload coverage genişletme" (insurance renewal, tenant lifecycle event'leri) eklendi.

Aktif rotation akışı: webhooks.php listede 🟡 turuncu butonu → confirm → yeni secret oluşur, eski 7 gün X-TD-Signature-Previous'a gider. Alıcı taraf bu sürede yeni secret'a geçer.

2026-06-22
Product

Public webhook event kataloğu + PWA cilası

Geliştirici keşfedilebilirliği ve mobil deneyim için iki cila.

  • /webhooks_catalog.php — Stripe Events benzeri tek sayfa public referans.
    • 10 entity × 3 action (created/updated/deleted) audit-derived event + 5 destek talebi event + sistem testi = 36 olay listelendi
    • HMAC-SHA256 imzalama (Node.js doğrulama snippet'i dahil), secret rotation grace, idempotency notu
    • Exponential backoff [60, 300, 900, 3600, 21600] saniye, 10s timeout, 60 req/dk rate limit
    • Örnek payload'lar: hardware.created + support_ticket.replied
    • Nav linkleri: api.php, status.php, changelog.php, roadmap.php — tüm dev docs cross-link
  • PWA cilası — mobile install deneyimi tutarlandı.
    • Auto-inject theme-color Vercel blue (#006aff) — eski slate hex'leri kaldırıldı
    • Stale manifest.json silindi (hardcoded /teknikdanisman/ path ile prod'da kırıktı) — manifest.php dinamik APP_BASE çözüyor
    • Offline fallback sayfası Geist Sans + outline icon + online listener auto-reload

Smoke test sayısı 7 → 8 (webhook catalog HTTP 200 + key string'ler doğrulanıyor).

2026-06-22
Yeni

SSO/OIDC PoC — Microsoft Entra ID kanıtlandı (composer'sız)

Kurumsal müşteri unlock'unun ilk adımı: OpenID Connect entegrasyonu. Composer dependency'siz, vanilla PHP + OpenSSL ile RS256 JWT verify. Mevcut login flow'u hiç dokunmaz — PoC ayrı endpoint'te (/sso_test.php, admin-only).

  • lib/SsoOidcClient.php — minimal OIDC client
    • Discovery (.well-known/openid-configuration)
    • Authorization URL üretimi (state + nonce + CSRF guard)
    • Code → ID token exchange
    • RS256 imza doğrulama (JWKS fetch + OpenSSL public key reconstruction)
    • Claims kontrolü: iss, aud, exp, nbf, nonce
  • /sso_test.php — admin-only test endpoint:
    • Config eksikse adım adım kurulum ekranı (Azure Portal step-by-step)
    • Microsoft'a redirect → callback'te ID token decode + claims göster
    • "PoC kullanıcıya login açmadı, mevcut session aynen devam ediyor" disclaimer
  • RFC 0003 — SSO/OIDC Entegrasyonu — OIDC vs SAML kararı, provider strategy (Entra → Google → Okta), JIT provisioning senaryoları, 3 sprint roll-out planı, başarı kriterleri
  • 27 yeni unit test — base64url, JWT format validation, malformed input rejection. Toplam 204 → 231 passing
  • docs/secrets.md bölüm 7 SSO config detayları + rotation prosedürü

Production rollout: Sprint 2'de ayrı RFC ile JIT user provisioning + login.php entegrasyonu + tenant başına SSO config UI. Bu PoC tasarımın kanıtı.

2026-06-22
Platform

Restore otomasyonu — tek tenant + backup envanter scriptleri

DR runbook'taki "15 dk manuel adımlar" otomatize edildi. Drill veya gerçek incident anında zaman tasarrufu + insan hatası riski azalır.

  • ops/restore_tenant.sh — Tek tenant veya master DB restore.
    • Sanity check: DB adı pattern (td_master veya td_tenant_*)
    • Integrity verify: gunzip + SHA256SUMS karşılaştırma
    • Interactive guard: "EVET" yazılmadıkça DROP yapmaz
    • DROP+CREATE → restore → smoke (table/customer/employee count)
    • Logger::warn('Database restored') event Sentry'ye + audit trail
  • ops/list_backups.sh — Backup envanteri.
    • Tüm timestamp'leri tablo halinde (boyut + içerik özeti)
    • Latest symlink hedefi işaretli
    • last_run / last_integrity_check / last_offsite_run meta JSON'ları yazdırır
    • -v flag: her dump dosyası ayrı listelenir
  • DR runbook bölüm 3.1 güncellendi: "A) Otomatik script (önerilen)" + "B) Manuel adımlar (fallback)" iki yöntem. Tahmini süre 15dk → 5dk.

Production'da sadece list_backups test edildi (read-only). restore_tenant gerçek tenant'a karşı çalıştırılmadı (drill kapsamı) — interactive guard sayesinde yanlışlıkla tetiklenemez.

2026-06-22
Yeni

Public /roadmap.php — Şu an / Sırada / Sonra board

/roadmap.php yayında. Linear/Vercel-style "Now / Next / Later" üç sütun board.

  • Şu an (3 item): iyzico aktivasyonu, off-site backup config, Sentry alarm verification
  • Sırada (5 item): SSO production, ilk DR drill, Insurance UX, webhook secret rotation, Lighthouse threshold mandatory
  • Sonra (7 item): Laravel parallel shell, SOC 2 Type 1, multi-currency, Google/Okta OIDC, PWA offline, webhook expansion, RAG AI
  • 5 kategori chip: Enterprise · Ürün · Platform · Güvenlik · DX
  • RFC linki her item için (RFC 0003 SSO, RFC 0004 iyzico vs.)
  • Dark/light otomatik · responsive · prefers-color-scheme
  • Tüm public sayfa navigation'larına eklendi (login/changelog/legal pages footer)

"Söz değil niyet" disclaimer notu açık. Stripe/Linear pattern — şeffaflık + esneklik. Kod-dağıtımıyla güncellenir, GitHub'da diff'lenebilir.

2026-06-22
İyileşti

Ops setup docs + CI shellcheck — onboarding ve script güvenliği

Yeni sunucu setup'ı ve script regression risklerini azaltan üçlü:

  • ops/rclone.conf.example — Hetzner Storage Box / Backblaze B2 EU / Cloudflare R2 için hazır rclone config template'leri (placeholder credentials). Off-site backup 10 dk'da aktivasyon.
  • docs/secrets.md — Tüm config.local.php constant'larının isim/format/amaç referansı. Gerçek değer içermez (KASA'da). DR senaryosunda secret restore akışı dokümante.
  • CI: shellcheck jobops/*.sh dosyaları her push'ta lint edilir. Backup/integrity/offsite script'lerinde silent regression yakalanır.
  • README.md documentation tablosuna 3 yeni link (DR runbook, secrets, ops).
2026-06-22
Yeni

Off-site şifreli yedek upload — DR runbook #1 maddesi kapandı

Tek-bölge backup başarısızlık riski kapatıldı. Sunucuya rclone kuruldu, encrypt+upload script altyapısı hazır. Kullanıcı bir storage provider seçip TD_OFFSITE_REMOTE tanımlayınca otomatik aktif.

  • ops/offsite_upload.sh: Backup tamamlandıktan sonra otomatik tetiklenir · tar -czf - | gpg --symmetric AES256 ile şifreler · rclone'a 10MB/s bant limitiyle push · uzakta varlık doğrular · 30 gün uzak retention · last_offsite_run.json meta
  • Eksik config = graceful skip: TD_OFFSITE_REMOTE tanımlı değilse ana backup'ı bozmaz, meta'ya status: skipped yazar
  • /health.php + /status.php: backup_offsite component eklendi — yapılandırılmamış/eski/başarısız ayrımı
  • Önerilen provider: Hetzner Storage Box (~3€/ay 1TB, EU/KVKK uyumlu, aynı şirket farklı DC). Alternatif: Backblaze B2 EU, Cloudflare R2, AWS S3 Glacier EU
  • DR runbook: Step-by-step Storage Box kurulumu + provider karşılaştırma tablosu + restore drill prosedürü dokümante edildi

Senin yapacakların: Provider seç → rclone config → config.local.php'de TD_OFFSITE_REMOTE tanımla. ~10 dk iş. Sonrası otomatik.

2026-06-22
İyileşti

iyzico subscription PoC — plan catalog tek kaynağa konsolide

Trial→paid funnel altyapısı: mevcut iyzico HTTP client + checkout + webhook + plan catalog mevcut ama legacy 3-plan modern 4-plan ile uyumsuzdu. Konsolidasyon tamamlandı, aktivasyon plan dokümante.

  • Catalog tek kaynak (strangler-fig): iyzico_plans_catalog() artık Subscription::planDefinitions()'tan derive — legacy basic/pro/enterprise → modern starter/professional/business. Enterprise (price=0) sales-led, iyzico checkout dışı.
  • /iyzico_test.php admin-only PoC: config kontrolü + plan catalog görselleme + sandbox checkout test endpoint. Mevcut subscription flow'a hiç dokunmaz.
  • RFC 0004:
    • Plan catalog konsolidasyonu (before/after mimari diagram)
    • iyzico integration full flow (checkout → callback → webhook)
    • 4 alternatif değerlendirme (Stripe TR / PayTR / manuel / Paddle)
    • 4 sprint roll-out planı (PoC → Sandbox → Production → Polish)
    • Risk listesi: webhook race condition, PCI scope, dunning management
  • docs/secrets.md bölüm 8 yenilendi: sandbox vs production, test kart, RFC 0004 link
  • 22 yeni unit test — catalog derive doğrulama (slug eşleşmesi, legacy yokluğu, enterprise filtreleme). Toplam: 231 → 253 passing

Aktivasyon adımı: Senin iyzico sandbox hesabı aç → API key'leri config.local.php'e ekle → Pricing Plans iyzico merchant panel'de oluştur → end-to-end test. RFC 0004 Sprint 2 maddeleri.

2026-06-22
İyileşti

InsuranceRenewalService — strangler-fig 3. resource

Sigorta poliçesi yenileme akışı (yeni INSERT + eski arşivle, atomic transaction) insurance_form.php'den çıkarılıp lib/InsuranceRenewalService.php'e taşındı.

  • 22 satır kod tekrarı silindi — page-level POST handler 9 satıra düştü
  • RenewalService ile paralel pattern — RFC 0002'de "ileride" notu kapandı. İki servis aynı disiplin (auth + audit_log + Logger::info + exception kontratı) ama farklı akış (bump vs archive_and_clone)
  • 7 yeni unit test — toplam 197 → 204 passing. Validation + auth path doğrulandı
  • Domain service çoğul: Artık lib/ içinde 2 renewal service + RenewalRunner pattern, gelecekteki domain extraction'lar (notification, audit) için somut örnek
2026-06-22
Product

Dev surface tamamlandı — Auth/Examples/Cron + 502 incident fix

Public developer dokümantasyonu Stripe-seviyesinde tamamlandı, operatör tarafı için cron görünürlüğü eklendi, aynı gün yaşanan SA 502 incident'i kapatıldı.

Dev docs (public)

  • /auth_guide.php — Authentication getting-started: 4 adımlı ilk key flow, scope tablosu (read/write/admin), 90 günlük rotation prosedürü, env var / HTTPS / per-integration key güvenlik pratikleri, SSS.
  • /examples.php — 5 senaryo × 5 dil (cURL, Node.js, Python, PHP, Go) = 25 snippet. Müşteri listele + pagination, personel oluştur + Idempotency-Key, servis/lisans yenile, webhook receiver (HMAC verify timing-safe), tüm sayfa pagination loop (rate-limit retry).
  • Tab UI — dil seçici sekmeler + hover'da kopyala butonu (1.4s "Kopyalandı" feedback), Geist Sans/Mono tipografi.

Operatör tarafı (super admin)

  • super_admin/audit_search.php — Cross-tenant audit_log arama: filtre (tenant/action/entity/user/IP/free-text/tarih), action pill renkli (create yeşil, update sarı, delete kırmızı, login mavi), CSV export (UTF-8 BOM).
  • super_admin/cron_monitor.php — 8 zamanlanmış görev için son çalışma + status badge + KPI strip. Meta JSON dosyaları (last_run, last_integrity_check, last_offsite_run) + log mtime'larından okur. 2026-06-21 backup silent-failure incident'ine doğrudan yanıt.

Cross-link dev surface

Tüm public sayfalar birbirine bağlı: api ↔ auth_guide ↔ openapi ↔ postman ↔ examples ↔ webhooks_catalog ↔ errors ↔ changelog ↔ roadmap ↔ status.

Bonus: 502 incident kapatıldı

Aynı gün öğleden sonra SA paneli 502 incident'i yaşandı ve resolved. Root cause: super_admin/index.php'te ölü kodun (PDOStatement cast warning) Logger üzerinden FastCGI stderr buffer'ını taşırması. Fix: ölü kod kaldırıldı + master DB'ye audit_log tablosu eklendi + MigrationRunner DDL-safe yapıldı.

Test: prod karşı 335 yeşil (smoke 7 → 12). Investment-readiness: dev experience tarafı artık tam.

2026-06-22
Yeni

Haftalık backup integrity check + Sentry alarm

"Backup alındı" ile "backup gerçekten geri yüklenebilir" arasındaki uçurumu kapatan haftalık otomasyon. Schrödinger backup pattern'ine son.

  • ops/verify_backup_integrity.sh + /etc/cron.d/teknikdanisman-backup-integrity (Pazar 04:00)
  • 6 kontrol katmanı: latest symlink · SHA256SUMS doğrulama · her .sql.gz gunzip -t · application_files.tar.gz tar -tzf · last_run freshness · off-site durumu
  • Hata → Sentry: Script içinden PHP CLI ile Logger::critical() çağrılır — existing observability pipeline reuse (zero ekstra altyapı)
  • /health.php + /status.php: backup_integrity component eklendi — 14 gün üstü stale → fail, 10 gün üstü warn
  • İlk run smoke test: 8 dosya hash'i doğrulandı, 7 sql.gz OK, application files 3380 entry, status warn (sadece off-site eksik)

Bugünün bulgu örüntüsü: 2 ay sessiz backup hatası → Logger latent bug yakaladı → Yeni backup script → Off-site upload skeleton → Haftalık integrity check + Sentry alarm. Observability + DR güveninin somut zinciri.

2026-06-22
Düzeltme

Backup script v2 + DR runbook — 2 aylık silent failure giderildi

Kritik bulgu: Eski backup script config.local.php'de tanımsız olan $DB_NAME environment'ı bekliyordu — 2 ay+ boş (388 byte) yedek üretiyordu. Latest symlink April 28'i gösteriyordu; tüm sistem yedeksizdi.

  • Yeni script (ops/teknikdanisman_backup.sh): Master DB + tüm aktif tenant DB'leri ayrı ayrı dump · application files · SHA256SUMS · atomic latest symlink · 14 gün retention · last_run.json meta dosyası
  • Eski script: /usr/local/bin/teknikdanisman_backup.sh.bak'a yedeklendi
  • İlk başarılı run: Master 27KB + 6 tenant (4.2MB+5×~150KB) + app 47MB · toplam 52MB · 14 günden eski 54 boş klasör otomatik temizlendi
  • /health.php + /status.php: "Yedekleme" component'i eklendi — <30 saat OK, 30-48 saat warn, >48 saat fail. Sentry alarm uyumlu
  • DR runbook (docs/disaster-recovery.md) yazıldı: RPO ≤ 24 saat, RTO ≤ 4 saat hedefleri · 3 senaryo (tek tenant / master / full sunucu) adım adım · quarterly drill takvimi · eksikler listesi (off-site, GPG encryption, integrity test)
  • SECURITY.md Backup & DR + Observability bölümleri eklendi

Production yedek artık doğrulanmış şekilde işliyor.

2026-06-22
Platform

Audit arama + Postman collection + Errors reference

Hem operatör (super admin) hem dev tarafında keşfedilebilirliği büyüten üç ekleme.

  • Super Admin → Audit Arama (super_admin/audit_search.php).
    • Cross-tenant audit_log sorgusu: her aktif tenant'a tek tek bağlanır, filtreli çekim sonra global merge sort yapar.
    • Filtreler: tenant, action, entity_type, user (id veya label), IP, free-text (context/old_values/new_values), tarih aralığı, limit 50–500.
    • Action pill renkli (create yeşil, update sarı, delete kırmızı, login mavi), context kolonu tıklayınca genişler.
    • CSV export — UTF-8 BOM ile Excel uyumlu.
    • Eski şema fallback (user_label/old_values/new_values kolonları yoksa NULL select).
  • /postman.php — Postman v2.1 collection JSON.
    • 5 endpoint, 5 folder, attachment olarak indirilir → Postman/Insomnia/Bruno tek tık import.
    • Bearer auth + {{api_key}}/{{base_url}} variable'ları, query parametreleri keşfedilebilir disabled flag ile.
    • POST'lar {{$guid}} ile dinamik Idempotency-Key.
  • /errors.php — Stripe ErrorReference benzeri public hata kataloğu.
    • Transport/Auth + Resource + Validation hata kodları (toplam 25+) HTTP status, açıklama ve çözüm ile.
    • Rate limit header'ları ve Idempotency-Key kullanımı dahil.
    • Standart hata zarfı + validation_failed alan-bazlı detay örnekleri.

Smoke test sayısı 7 → 11 (errors, postman, webhooks_catalog, audit_search guard). Cross-link'li dev surface: api ↔ openapi ↔ postman ↔ webhooks ↔ errors ↔ changelog ↔ roadmap ↔ status.

2026-06-22
Güvenlik

Critical-path audit Logger entegrasyonu

Security-sensitive operasyonlar artık iki katmanlı audit: DB audit_log() (persistant trail) + Logger::info/warn (JSON event stream → nginx log → Sentry).

  • Tenant lifecycle: super_admin/tenant_form.php tenant created event (slug, db_name, plan_id, billing_cycle, created_by_sa)
  • API key lifecycle: api_keys.php create (info) + revoke (warn) + delete (warn) — key_id + tenant_id + label + scopes context
  • Auth events: login.php success (info) ve failed (warn) — username + remaining attempts
  • System backup download: super_admin/system_backup.php super admin tarafından manuel backup tetiklenmesi (warn) — sa_user + archive_bytes

Niye iki katman? audit_log() DB trail (sorgulanabilir, kim-ne-ne-zaman). Logger::warn/info JSON event stream — Sentry'ye opsiyonel iletim, log aggregator-ready, observability dashboard. Yatırımcı diligence'ta "audit log + observability" sorusuna iki yanıt.

2026-06-21
İyileşti

Versiyonlu migration sistemi — Linear/Stripe pattern

Şema değişikliklerini izlenebilir, sıralı, idempotent şekilde uygulamak için yeni bir runner katmanı eklendi. Mevcut lib/Migrations.php (settings.php başında çalışan idempotent block'lar) coexist eder — sadece yeni migration'lar buraya gelir.

  • Dosya tabanlı: migrations/tenant/YYYYMMDD_NNNNNN_kebab-name.php veya migrations/master/...
  • Tracking: Her DB'de otomatik schema_migrations tablosu
  • Transactional: Her migration kendi transaction'ında; hata → rollback + Logger::critical
  • CLI: php migrate.php status / up / rollback · --master · --tenant=slug filtreleri
  • Observability bağlantısı: Hata Sentry DSN tanımlıysa anında alarm geçer

Detay ve örnek migration: migrations/README.md

2026-06-21
İyileşti

Strangler-fig refactor başlangıcı — RenewalService

Mimari yenilenmenin ilk somut adımı: services.php ve licenses.php'in yenileme handler'larında birebir kopyalanan iş mantığı lib/RenewalService.php'e taşındı.

  • 32 satır kod tekrarı silindi — page-level dosyalar 6 satıra düştü, sadece HTTP routing + flash kaldı
  • Tek konfigürasyon noktası — yeni resource eklemek için RESOURCE_CONFIG'e tek entry yeter (insurance.php ileride bunu kullanabilir)
  • Test edilebilir hale geldi — PDO mock'la unit test mümkün
  • Observability entegre — her yenileme Logger::info('Resource renewed', ...) ile JSON log üretir
  • Dokümantasyon: docs/rfcs/0002-renewal-service.md

Kullanıcı için davranış birebir aynı; bu büyük rebuild değil — strangler-fig pattern'inin canlı kanıtı. Yatırımcı diligence'ta "Refactor edebiliyor musunuz?" sorusuna somut yanıt.

2026-06-21
Yeni

Domain ve lisans listelerinde tek-tıkla "Yenilendi" aksiyonu

Servisler (services.php) ve Lisans (licenses.php) yönetim sayfalarındaki aksiyon kümesine yeşil Yenilendi butonu eklendi. Onay sonrası mevcut yenileme tarihi +1 yıl ileri alınır.

  • Services: Dolu olan end_date, domain_expiry, hosting_expiry, expiry_date alanlarının her birine +1 yıl. Hiçbiri yoksa end_date = bugün+1 yıl
  • Licenses: renewal_date +1 yıl
  • Tüm yenilemeler audit_log'a yazılır

Manuel olarak tarih düzenlemek için Form sayfası açmaya gerek yok — listeden tek tıkla yenilenebilir.

2026-06-21
Yeni

Public API dokümantasyonu — OpenAPI 3.0 + Redoc

Geliştirici dokümantasyonunu açık erişime aldık. Auth gereken eski api_docs.php içerideki referans olarak kalır; yeni public sayfa Redoc ile render edilmiş Stripe/Linear-style üç-kolon layout sunar.

  • /api.php — interaktif Redoc reference
  • /openapi.php — OpenAPI 3.0 spec (YAML, makine-okunur). Postman / Insomnia / kod üreticileri için doğrudan kullanılır.
  • RFC 0001 + 0000 template yayımlandı: docs/rfcs/

Bearer token oluşturmak için panele giriş yapıp Ağ Araçları → API Anahtarları sekmesini kullanın.

2026-06-21
Düzeltme

Mobil menü, tema butonu ve quick-capture UX iyileştirmeleri

Mobil deneyim ve sağ-üst aksiyon kümesinde bir dizi tutarlılık sorunu giderildi:

  • Mobil menü bazı tarayıcılarda off-canvas drawer'ın transform interpolasyonu nedeniyle açılmıyordu — translate3d tabanlı override ile çözüldü
  • Açık/Koyu mod butonu artık her sayfanın sağ-üst köşesinde — daha önce yalnızca dashboard'da görünüyordu
  • Hızlı Not / Görev butonu (Alt+N) sağ-alt floating circle yerine, top bar'a alındı — funnel butonunun yanına
  • Mobil menüden "Tema Değiştir" ve "Yardım İpuçları" kaldırıldı (top bar'da daha sezgisel konumda)
  • Yanıt Şablonları sidebar'dan kaldırıldı, Destek Talepleri sayfasına buton olarak eklendi
  • API Anahtarları ve Webhooks sayfaları Ağ Araçları altında sekme olarak konsolide edildi
2026-06-21
Yeni

GitHub Actions CI — her push otomatik lint, test, spec validation

Repo'ya CI pipeline eklendi (.github/workflows/ci.yml). Her push ve pull_request'te aşağıdaki üç iş paralel/seri çalışır:

  • PHP Lint — tüm *.php dosyaları PHP 8.3 ile syntax check (vendor/uploads/backups hariç)
  • Unit Testsphp tests/run.php unit; lint başarılıysa çalışır (189 test)
  • OpenAPI Spec Validationdocs/openapi.yaml Redocly CLI ile validate edilir; spec implementation'la ayrışmasın

Concurrent run'lar otomatik iptal — son push hep güncel sonuç verir. README'ye CI badge eklendi; master branch'inin sağlığı doğrudan repo sayfasından görünür.

2026-06-21
İyileşti

Personel evrak yönetimi tek ekrana toplandı

Personel düzenleme ekranı (employee_form.php) artık tüm evrak akışının tek merkezi. Daha önce ayrı bir employee_documents.php sayfasında olan yükleme/silme fonksiyonu, form içine konsolide edildi:

  • 8 kategori aynı ekranda: İşe Başlangıç · Zimmet · İzin · İhtar · İşten Çıkış · Sözleşme · Sağlık & SGK · Diğer
  • Her kategoride sistem tarafından oluşturulan formlar (yazdırma sayfaları) ve yüklenmiş ıslak imzalı evraklar yan yana listelenir
  • Her satırda Aç/İndir + Sil butonu — sistem kayıtları için de silme desteği (örn. iptal edilen ihtar kayıtları)
  • Yeni: İşten Çıkış için A4 print sayfası (employee_termination_print.php) eklendi — teslim/iade checklist'i ile

Eski employee_documents.php URL'i artık employee_form.php?edit_id=X#section-documents adresine yönlendiriyor — eski bookmark'lar kırılmaz.

2026-06-21
Güvenlik

Uyum tabanı: security.txt, gizlilik politikası, DPA

Kurumsal müşteri diligence süreçlerinde sıkça istenen üç belgeyi public olarak yayınladık:

Login sayfasının footer'ına tüm hukuki belgelere kısayollar eklendi. Güvenlik raporu için security@teknikdanisman.net aktif.

2026-06-21
Yeni

REST API: yenileme endpoint + rate-limit header dogfood

RenewalService bugün web POST handler'larından çıkarıldı; aynı servis şimdi public API'a da bağlandı. Bir karar = iki kanaldan tüketim — strangler-fig dogfood.

  • Yeni endpoint: POST /api/v1/renew.php — body {"resource": "service" | "license", "id": 42}
  • Yetki: Bearer token + write scope + idempotency key opsiyonel
  • Cevap: { object: "renewal", resource, id, updated_columns, fallback_used }
  • Rate limit header'ları tüm endpoint'lerde aktif: X-RateLimit-Limit / Remaining / Reset · 429'da Retry-After: 60
  • OpenAPI spec güncellendi/api.php sayfasında doğrudan görünür
  • Limit aşımları artık loglanır (Logger::warn 'API rate limit exceeded') → Sentry alarm uyumlu
  • Cleanup query optimize: Eski rate-hit silme her request'te değil, %5 örnekleme ile (master DB yükü -95%)