🚀 Canlı: https://auraglobalcare.com (AURA kanonik domaini, v6.201 · 2026-09-02; eski telehealth-mvp-roan.vercel.app host'u da 200 döner, canonical yeni domaini gösterir) · Demo girişi: [email protected] / 1234
Çok ülkeli sağlık turizmi + telehealth platformunun çalışan sürümü.
Farkı nerede: sınır ötesi sağlığın asıl zor problemi veri/güven/uyum — ve çözülen kısım bu.
KVKK hash-zincirli onam + RFC 3161 zaman damgalı Onay Kanıtı, FHIR R4 dışa aktarım
(Composition/Consent + denetim izi) ve uçtan uca AI klinik (triyaj, belge analizi, SOAP,
epikriz, post-op vision). Bir hafta sonunda klonlanamayan parça budur.
Üstüne uçtan uca akış canlıda: hasta triyajından doktor kokpitine, gerçek WebRTC video
görüşmeye, sağlık turizmi paketine ve post-op takibe — üç paralel hasta akışıyla (Talk to
Doctor genel triyaj, İkinci Görüş, Ücretsiz Sağlık Hizmeti ücretsiz gönüllü konsültasyon).
Bilgi tabanı (Obsidian vault) komşu ../Air klasöründedir. Güncel mimari için
Air/output/guncel-yazilim-mimarisi.md, modül detayları için Air/wiki/moduller/,
canlı durum/sürüm geçmişi için Air/wiki/mvp.md + Air/wiki/todo.md.
Teknoloji
Next.js 16 (App Router) + React 19 + TypeScript 5
Tailwind CSS 4, lucide-react ikonlar
Prisma 6 + PostgreSQL (Neon) — yerel .env Neon development branch'ine bağlanır; üretim
ayrı branch'tedir ve yalnız PROD_* env'i AÇIKÇA verilerek dokunulur (Ray B2 ortam ayrımı,
DEPLOY.md §B2; SQLite kullanılmaz)
AI:@anthropic-ai/sdk (Claude — triyaj/SOAP/epikriz/çeviri/vision) · @google/genai
(Gemini Live — gerçek zamanlı ses→ses tercüme)
Gerçek zamanlı: WebRTC P2P (sinyalleşme: Ably realtime birincil + DB Signal yedeği, v4.15) + Cloudflare Realtime TURN relay (yedek: Metered)
DICOM:dicom-parser + dcmjs + @cornerstonejs/codec-openjpeg + codec-charls +
jpeg-lossless-decoder-js + jpeg-js — codec'ler hem tarayıcıda görüntüleme hem sunucuda
burned-in PHI maskeleme için (v6.37; WASM ikilileri next.config.tsoutputFileTracingIncludes
ile serverless bundle'a dahil edilir)
PWA / bildirim: service worker + web-push (VAPID)
Çalıştırma
npm install
cp .env.example .env # değerleri doldur (DATABASE_URL, SESSION_SECRET zorunlu)
npx prisma migrate deploy # migration geçmişini Neon'a uygula (taze DB'de tüm şemayı kurar)
npm run db:seed # demo veri: kullanıcılar + 30 doktor + 20 vaka + takip/şikayet
npm run dev # http://localhost:3000
Yerel .env Neon development branch'ine yazar (dev'e özgü KEK/SESSION_SECRET, seed'li) ve
AURA_DB_GUARD="block" üretim-dışı sürecin prod'a bağlanmasını engeller (src/lib/db.ts).
Üretim işlemi = ayrı onay + PROD_DATABASE_URL açıkça (runbook: DEPLOY.md §B2).
ANTHROPIC_API_KEY yoksa triyaj kural tabanlı motora düşer; GEMINI_API_KEY yoksa canlı
tercüme dormant kalır — uygulama yine çalışır.
npm script'leri
Script
İşlev
npm run dev
Geliştirme sunucusu
npm run build
prisma generate && next build
npm run start
Üretim sunucusu
npm run lint
ESLint — v6.183'ten beri 0 uyarı bekler (React Compiler kuralları error; istisna = gerekçeli eslint-disable-next-line, bkz. eslint.config.mjs)
npm test
Birim testleri (vitest — saf mantık, DB yok; pricing/journey/deidentify/crypto/ownership/rate-limit[Upstash mock+fail-open]/postop/storage/ai-minimize/chain-seal/session-sv)
npm run test:integration
Entegrasyon testleri (gerçek DB — TEST_DATABASE_URL Neon dev branch gerekir; yoksa atlanır, bkz. tests/integration/README.md)
npm run test:e2e
E2E testleri (Playwright — 3 demo-kritik akış + erişilebilirlik smoke paketi [salt-okur: axe · tek-h1 · klavye · reduced-motion · RTL; WCAG İDDİASI DEĞİL] + mobil projesi [v6.154, salt-okur: halka açık sayfalar + /ar yatay taşma @360/@390 + /doctorium mobil header sözleşmesi; yalnız mobil.e2e.ts, akış testleri mobilde koşulmaz]; Ray B2'den beri normal npm run dev sunucusu yeterli, bkz. tests/e2e/README.md)
npm run db:seed
prisma/seed.ts — demo veri (tam reset)
npm run db:migrate
prisma migrate deploy — üretim şema değişikliği yolu (db push değil; akış: DEPLOY.md Adım 2)
npx tsx scripts/enrich-profiles.ts
profil/vaka zenginleştirme (idempotent backfill; yalnız boş alan: doktor procedures/markets/akademik + vaka FHIR lab/icd10/belge — silmez)
Giriş iki ekrana ayrıdır (v4.21): /giris = Hasta Girişi · /kurumsal-giris =
Doktor/Koordinatör/Etik Kurul/Partner/Sağlık Turizmi Acentesi/Sağlık Uzmanı. İkisi de vitrin
AURA giriş kapılarıdır (letterform panel + yan video; components/aura/auth-gates.tsx).
Kapı-içi form (v6.84, 2026-08-06 — v5.9.1 kapı/form ayrımı SÜPERSEDE): Google ve Apple butonları
doğrudan OAuth başlatır (/api/auth/{google,apple}/start?intent=patient|doctor); "E-posta ile
devam et" formu kapının içinde açar (components/aura/gate-email-form.tsx — giriş + doğrulama
yeniden-gönder + demo hızlı-giriş kilidi). Üyelik daveti kapının KALICI öğesidir (2026-08-12):
form kapalıyken de "veya" ayracının altında görünür; kurumsal kapıda rol seçimine göre değişir
(Doktor→/kayit · Partner→/kayit/partner · Uzman→/kayit/saglik-uzmani · Acente→/kayit/acente
· Koordinatör/Etik Kurul→"davetle katılım" notu — 9 dil corporate.rolePrompts). Eski
/giris/e-posta ve /kurumsal-giris/e-posta rotaları kalıcı yönlendirmedir (parametre
koruyarak kapıya). OAuth hata/?verify dönüşleri kapıya düşer ve formu otomatik açar. Hasta
üyeliği /kayit/hasta → POST /api/auth/signup-patient (lib/patient-signup); doktorlar
/kayit ile kendileri kayıt olabilir (Google/Apple [env-gated] / e-posta; OAuth niyeti
g_oauth_intent/a_oauth_intent cookie'siyle taşınır — mevcut kullanıcıda yok sayılır). Giriş
sonrası tek seferlik KVKK onam kapısı (/onam) vardır (sürümlü; lib/consent-config.CONSENT_VERSION artarsa bir kez
yeniden alınır — v6.269: sürüm 4, EKRAN = HASH: hasta A01 aydınlatma + A02 koşullar tam metnini (TR/EN) okur ve onaylar
[AuraConsentGate]; personel A09 aydınlatması + yalnız kendi ROL maddesini onaylar [StaffConsentGate, STAFF_KVKK kapsamı,
hash rol × dil]).
Hasta akışı (v5.8 basitleştirme):/basla 4'lü seçim ekranı KALDIRILDI — giriş hunisi doğrudan
Branş Doktoru akışına (/triyaj) iner; dönen hasta (başvurusu olan) girişte vaka merkezine
(/vakalarim; SO yolculuğunda /second-opinion/vakalarim) iner (lib/patient-journey.patientHome);
her vakanın tek merkezi /vaka/[caseId] hub'ıdır (teklif/rezervasyon gömülü, eski rotalar redirect).
Diğer kulvarlara erişim: Vakalarım üstündeki kulvar kartları + kendi sayfaları (İkinci Görüş →
/second-opinion/basvur · Sağlık Turizmi → /saglik-turizmi · Ücretsiz Sağlık → /ucretsiz-saglik/basvur).
User.patientJourney artık başvurulan akışta damgalanır (stampPatientJourney → intake API'leri) ve
üst bandı belirler (lib/nav.ts navItemsFor); profil hafızası (Faz 0/1): intake'te girilen
ülke/dil/telefon(şifreli)/iletişim tercihi User'a yaz-geri edilir, sonraki intake'ler kompakt
"Kayıtlı bilgileriniz" şeridiyle prefill eder (GET /api/patient/profile + ProfilePrefill).
Demo kullanıcıları (parola 1234; hasta demo /giris'te, personel demoları /kurumsal-giris'te):
Doktor Ana Sayfası (pencere-tabanlı) + onboarding, video görüşme, klinik kodlama, post-op izleme, klinik nöbet, Ücretsiz Sağlık Hizmeti, Konsültasyon Talepleri
Rol bazlı erişim src/proxy.ts (Next 16 proxy konvansiyonu) ile zorlanır. Yetkisiz erişim /giris'e, yanlış rol
kullanıcının kendi marka-duyarlı ana sayfasına (deniedRoleHome, v6.203 — eskiden köke atıyordu;
Doctorium deploy'unda kök = landing), onamsız oturum /onam'a yönlendirilir. Parolalar bcrypt ile hash'lenir; .env
içinde SESSION_SECRET tanımlı olmalıdır.
Modüller (canlı)
7 çekirdek modül
#
Modül
Durum
1
Triyaj
✅ Ön-konsültasyon kapısı (ücret — kartla demo ödeme; sigortayla ödeme yolu v6.78'de kaldırıldı, anlaşmalı sigorta şirketi yok) → 5 adımlı sihirbaz, gerçek Claude branş+aciliyet (30 branş, ~198 dinamik branş sorusu), belge yükleme + AI ön-değerlendirme (vision/PDF → tür+TR çeviri+özet+anormal bayrak) + lab→FHIR oto-dolum. Belge-bekleyen başvuru (DOCS_PENDING, 2026-07-24, kullanıcı kararı): eksik zorunlu belgeyle (docAck) oluşturulan aciliyet ≤3 vaka doktor havuzuna DÜŞMEZ (doktor kuyruğu/nöbetçi/İcapçı/bildirimler görmez; koordinatör "Belge Bekleniyor" rozetiyle görür) — hasta vaka merkezindeki PendingDocsPanel'de kalemleri yükleyip işaretleyince POST /api/cases/[id]/pending-docs (hasta-only+BOLA+rate-limit+audit CASE_DOCS_COMPLETED) vaka NEW'e geçirir ve NEW_CASE bildirimi O ANDA gider. Aciliyet 4-5 İSTİSNA: belge beklemeden havuza düşer (klinik risk; MISSING_DOCS bildirimi yalnız bu yolda). Bekleyen kalemler Case.pendingDocs (düz JSON; migration 20260724014426). Periyodik hatırlatma (v6.36): günlük bakım cron'u (purge-deleted, ~06:30 TR) remindPendingDocs koşar — bekleyen hastaya günde 1, en fazla 3 hatırlatma (lib/pending-docs-reminder.ts; durum ayrı kolonda değil, MISSING_DOCS bildirim kayıtlarından türetilir; tavan dolunca susar, hasta panelden her an tamamlayabilir)
2
Doktor Paneli + Video
✅ Aciliyet sıralı kuyruk, kokpit, gerçek WebRTC video + canlı transkript (Web Speech) + AI-SOAP + medikal çeviri + AI Epikriz + Gemini canlı tercüman (iki yönlü ses+altyazı; v6.30 tek-sıçrama: konuşan KENDİ mikrofonunu karşının diline çevirtir, çeviri replaceTrack ile karşıya gider — sessiz-ölüm bekçisi + fail-open mikrofona dönüş) — transkript herhangi taraftan, tercüme YEREL ilk konuşma sesinde otomatik başlar (VAD; başlat düğmesi yok), tercüme yalnız diller farklıysa + DICOM görüntüleyici (5 sıkıştırılmış codec; v6.33: hastanın triyajda yüklediği .dcm ASLIYLA+şifreli saklanır — kokpitte "Hasta yüklemesi" olarak demo çalışmalarla yan yana, auth'lu /api/cases/[id]/documents/[docId]/dicom ucundan açılır; AI belge değerlendirmesi DICOM'u atlar) + klinik kodlama (FHIR)
3
Kongre modülü v2 (v6.63, 2026-08-03) — KÜRATÖRLÜ VERİTABANI (⚠️ v6.120'de KISMEN SÜPERSEDE — aşağıdaki Etkinlik notuna bak): otomatik agregatör YOK (kongreuzmani/doktorbun/emedevents/clocate ölçüldü: bot korumalı · JS-render · ToS engelli) → branşların ulusal + uluslararası kongreleri resmî sitelerinden derlendi. v6.121 (2026-08-19) genişlemesi: kullanıcının 30 branşlık rehberi (177 kalem) 12 ajanlı turla (9 araştırma + 3 doğrulama) işlendi → 212 satır / 35 branş (DB'ye giren 166 tarihli kayıt; tarihsiz 46 kayıt kaynakta bekler), officialUrl'siz kayıt 0, prisma/seed-data/congresses.json + vault output/kongre-veritabani-2026-08-03.md. Şema (20260803120000): source/externalId (+unique → idempotent seed; elle kayıtlarda null, çakışmaz) · scope · edition · frequency · venue · format · language · cmeCredit · registrationNotes · themes · warning · coverImage · sourceUrls · confidence · verifiedAt. Arayüz: branş tercihi artık Kongre sekmesinde de GÖRÜNÜR (🐛 v6.48'den beri süzüyordu ama seçici çizilmiyordu — doktor göremediği filtreyle eksik liste görüyordu) · ulusal/uluslararası filtresi (?s=, paylaşılabilir URL) · etkinlik kartı/doktor/doctorium/etkinlik/[id] (v6.120'ye kadar /kongre/[id], artık 308) (künye + kayıt koşulları + ⚠️ uyarı bandı [ERA·IDWeek·EPA sahte kayıt sitesi ihbarı yayımlıyor] + kaynak listesi + doğrulama tarihi) · takvime ekle (⚠️ v6.144'te KALDIRILDI — aşağıdaki v6.129 notuna bak: artık .ics değil, iç takvime yazan takip mekanizması). Görsel (v6.67, 2026-08-04): kapaklar scripts/fetch-congress-covers.ts ile doldurulur — og:image (yedek twitter:image) yerelden indirilir, sharp ile ~320px webp'e re-encode edilir (SVG/aktif içerik sökülür) ve Claude vision elemesinden geçenler (yalnız "kongreyi tanıtan afiş"; dernek logosu/soyut süs/stok foto/yanlış edisyon RED — şüphede RED, ANTHROPIC_API_KEY yoksa script koşmaz) data URI olarak coverImage'a yazılır. ⛔ CSP img-src 'self' data: dış hostu engeller — politika gevşetilmedi, data: zaten izinliydi; görseli olmayan/elenen kongrede branş amblemi çizilir. İlk prod koşusu: 102 adaydan 17 kapak, 17 AI-elendi, 62 og:image'sız. v6.121 koşusu: 149 adaydan , 25 AI-elendi, 99 og:image'sız, 10 hata → prod kapaklı 31. ⚠️ Liste sorguları ( + admin) AÇIK select'lidir — data URI'lar listeyi şişirmesin; kongre kartına yeni alan eklerken select'e de ekle. (telif + kongreden 1-2 ay önce kesinleşir → bayat bilgi riski): tema + resmî programa bağlantı. kademeli iş listesi üretir — 🔴 kritik tarihi ≤90 gün (haftalık; bu tarihler UZATILIYOR) · ⚫ geçmiş (sonraki edisyon arama kuyruğu) · 🟡 kısmi (aylık) · · 🟢 soğuk (3 aylık); 'e bakar, aynı kaydı gereksiz taramaz. 🪤 kuyruk yalnız DB'den okuyordu, seed ise zorunlu olduğu için tarihsiz satırları ATLIYOR → o kongreler hiçbir kademede görünmüyordu (kimse bakmıyordu). Kuyruk artık seed KAYNAĞINI da okur. ⚠️ Kuyruk bir , araştırmayı kendisi yapmaz ve — haftalık besleme nöbetinde elle koşulur. acil-tip · radyoloji · anesteziyoloji · patoloji · tibbi-genetik (). Doctorium süzgeçlerinde ve doktor profilinde YAŞAR, (triyaj · sağlık turizmi · ikinci görüş · partner talebi kullanır) — konsültan dallardır ve "Acil Tıp"ı telesağlıkta hastaya seçtirmek yanlış yönlendirmedir. ⚠️ Yeni branş eklerken dört eşleniği BİRLİKTE doldur ( · · · ) — hepsi geri düşüşlü, eksiklik derleme hatası VERMEZ, modül sessizce boş görünür. Sözleşme testi: . ⚠️ Kongre verisi ASLA tahmin edilmez — bilinmeyen alan boş kalır (uydurma tarih = yanlış alarm = doktorun gerçek kaybı).
Doctorium'un 7. sekmesi (, Kongre'den sonra · Hukuk'tan önce). Alt-sekmeler = (; v6.86 deseninin eşleniği — ⚠️ sektörel kategoriye ait, çakışmaz). Özel İstihdam Büroları mevzuatı "başvur butonu, üyelik sistemi ya da kayıt işlemi OLMAKSIZIN" ilan gösteren siteyi muaf tutuyor; üyelik arkasında ilan sunmak sayılıyor → İŞKUR özel istihdam bürosu izni şart (aksi halde idari para cezası) + iş arayandan (doktordan) ücret ALINAMAZ. Doctorium üyelik arkasında olduğundan bu fazda ; ekranda bunu söyleyen kalıcı not var ("Bu bölüm iş ilanı içermez"). İzin alınırsa AYRI sekme açılmaz — aynı 'a eklenir ve v6.87'de toplanan rızası ORADA kullanılır (kullanıcı kararı). ( + + ; kaynak belgesi vault ): resmî otorite siteleri makine erişimine KAPALI (2026-08-12 ölçümü — , ; TTB/RG ile aynı sınıf) → otomatik toplayıcı imkânsız, kongre modülünün deseni uygulandı. Almanya Approbation · Dubai DHA · Suudi SCFHS · UK GMC · ÜAK doçentlik · İyi Hal (Good Standing) belgesi. + (kaynağı olmayan kayıt yazılamaz) · ( — kısmi kayıt kartta ibaresiyle çıkar) · (kayda özgü uyarı: Almanya'da eyalet farkı · BAE'de tek lisans olmadığı · Good Standing'de ) · / JSON. ⚠️ — hiçbir süre resmî kaynaktan doğrulanamadı, ikincil kaynaktaki "3-6 ay" YAZILMADI (tahmini süre = doktorun yanlış planlaması). Kartlarda görünür (bayatlık gizlenmez). Danışmanlık şirketi blogları kaynak olarak KULLANILMAZ (ticari çıkar + denetimsiz güncellik) — yalnız resmî otorite adresleri. Ekranlar: liste () + detay (adımlar · belge listesi · resmî kaynak · "bu bilgi nereden geliyor" · kaldırılamaz "hukuki/idari danışmanlık değildir" uyarısı); ortak parçalar 'te (route dosyasından bileşen import etmek Next.js'te kırılgan). Almanya Berufserlaubnis · Abu Dhabi DOH · TUS/YDUS · mecburi hizmet —
Doctorium ÜÇ KATMANLI ÜYELİK (v6.232–v6.245, 2026-09-05 — 🚀 CANLI; deneme bayrağı iki Vercel projesinde AÇIK): kitle
çözücü lib/doctorium-tiers (VERIFIED | STUDENT | TRIAL | LOCKED | NONE; öncelik optOut > diploma > öğrenci > deneme) +
istek-önbellekli lib/doctorium-audience currentDoctoriumAudience(); pazarlama yüzeyleri (sponsor kartı · anket · puan · ödül)
YALNIZ VERIFIED (audienceFlags; api/survey/respond, api/rewards/redeem, api/sponsor/click, api/doctor/sponsor-consent
derin savunmalı). Deneme (30 gün):/doctorium/kayit kullanıcı parolasıyla kayıt (ad soyad · e-posta · parola · branş · şehir) →
POST /api/auth/signup-trial (bayrak DOCTORIUM_TRIAL_ENABLED="1", 🔴 İKİ Vercel projesine AYRI girilir) → e-posta doğrulaması GET /api/auth/verify-email ve ardından e-posta+parola girişi. Eski parolasız hesapların giriş
bağlantısı GET /api/auth/verify-login-link uyumluluk için korunur (sha256 özet, 20 dk, atomik tek kullanım; lib/login-link) · her yeni doktor
hesabı trialWindow damgası alır (Doctor.trialStartedAt/trialEndsAt/trialAlertsSent, migration 20260905060000) · Header
DENEME · N GÜN rozeti (/api/auth/metrial) · süre sonu kilit /doktor/baslangic?from=doctorium&trial=ended (hesabı kapatma
dâhil) · trial-sweep cron 10:20 TR (7/3/1 hatırlatma · bitti · +60 g imha bildirimi · +90 g fail-closed imha, klinik bağ/bekleyen
belge varsa atlar). + Branş uyarısı (v6.330, 👤 2026-10-06): aynı cron, deneme süpürmesinden SONRA, branşı sınıflandırılmamış
(boş · listede yok · "Diğer (Sınıflandırılmamış)") ve akış branşı seçmemiş portal üyelerine portal bildirimi + e-posta (lib/branch-reminder; ayrı try,
düşerse ayrı alarm; durum bildirim kayıtlarından, kolonsuz) → Tercihler "Uzmanlık branşınız" kartı (SpecialtyBranchCard) → POST /api/doctor/specialty-branch: branşı BİR KEZ seçer (yalnız DOCTOR + kendi kaydı · yalnız sınıflandırılmamış branş, sınıflandırılmış 409 ·
admin onaylı doktorda 403 — Doctor.branch klinik havuzu belirler · liste kayıt formlarıyla aynı, Diğer hariç; lib/specialty-branch). Metin TEK kaynak lib/doctorium-trial-copy.ts (👤 kanonik: deneme yalnız doğrulama içindir, ücretli
üyeliğe dönüşmez, ödeme bilgisi istenmez). Öğrenci yüzeyi: raf HERKESTE aynı 8 durak (Takvim en sonda); öğrencide Kariyer
sekmesi koral (doktorun yol haritası çizilmez). öğrencide 1. kademe çubuk
(, ; Fırsatlar = + tür çipleri
, ), TUS ayrı rota ve orada 2. kademe
( · ; Veriler = yerleştirme + kurumlar + tıp fakülteleri, Rehberler = kılavuz özetleri + resmî
kaynaklar + kaynakça, Sınav dönemleri = tablo + Takvim). Başlık "Staj, Değişim Programları, Burs ve TUS" (👤). Doktor Özelleştir →
"Kariyer içinde TUS bölümünü göster" (; kısa: KPI + üç bölüm kartı); → Fırsatlar'a yönlendirme
(eski bağlantılar). (metinler öğrenciye göre) + Kariyer satırında
açılış tercihleri ( module ; Fırsatlar türü · TUS bölümü ·
TUS branşı — /, URL parametresi ezer, "Hepsi" çipi tercih varken ); Header öğrenci lockup'ı gerçek metin (U4, v6.251: küre 28 px + Inter 600 wordmark +
altında koral parantezli STUDENT; globals.css; v6.239 webp varlığı kaldırıldı). aynı lockup portal footer'ında da (, küre 44 + wordmark 26 px; markup paylaşılan ; STUDENT rengi dolgu koralı , iki temada #fb923c); Faz B1'in kancası + kaldırıldı.
aksanı = marka zümrüdü, öğrenci kapsamı KORAL (gece #fb923c; gündüz metin
#ea580c + dolgu #fb923c; + koral sekme — 👤 pano B v6.255; %28 koral ve "KOR %12" süpersede) — portalda
sabit yazılmaz; semantik başarı . belge seti
Sürüm 1.2 (02 madde 2 "Deneme Erişimi", 3.2 a–d, 10.2-e; 01 madde 3.1/6/8), 1.2 · 5 Eylül 2026,
2→3 (mevcut Doctorium üyeleri ilk girişte bir kez yeniden onaylar).
2024/1→2026/2 (ÖSYM duyuruları kaynaklı, ) + Takvim ();
13 fırsat — + (migration ;
statik liste = seed kaynağı, ); yüzeyler 'dan okur; öğrenci "Takip et"
() → Takvim (onaylı hepsi) + 7/3/1 gün kala bildirimi ve e-posta (,
içinde); küratör paneli (+ ). ( null = hiçbir yüzeyde GÖRÜNMEZ; dönemsel kayıt takvime düşmez;
resmî alan adı allowlist'i + İŞKUR dili).
gizlenmez — ile listenin SONUNA iner (açık tarihliler → dönemsel → kapananlar), satır "başvuru kapandı · <gün>"
yazar, takip düğmesi çıkmaz (; "geçti" Türkiye takvim gününe göre — , son başvuru günü dahil açık). Portal
Fırsatlar listesi ve landing "Öğrenciler" penceresi aynı kuralı okur; yönetim listesi () bilinçli olarak eski sırada kalır (süresi geçen
üstte = güncelleme sinyali). Nöbet: . Sonraki fazlar (E2 kalıcı model + hatırlatma · T2
kontenjan/taban puan): vault .
TUS veri katmanı (v6.246–v6.248, 2026-09-05/06 — 🚀 CANLI): üç kaynak, tek ilke — onaysız veri hiçbir yüzeyde görünmez
(kayıt defterlerinde 👤 approvedAt), tahmin/simülasyon/tavsiye YOK, her grafik altında kaynak + "tercih tavsiyesi değildir".
K1 ÖSYM yerleştirme:scripts/tus-ingest.ts (kalıcı; "Yerleştirme Sonuçlarına İlişkin Sayısal Bilgiler" sayfası → en küçük/en
büyük puan PDF'i; 🪤 dokuman.osym.gov.tr Referer yoksa 200 + "Erişim Engellendi" HTML) → lib/tus-normalize (üç PDF düzeni) →
src/data/tus/<yıl>-<dönem>.json + summary.json → lib/tus-data TUS_SNAPSHOTS (10 dönem 2021/2→2026/1 onaylı) →
TusPlacementSection + tus/TusCharts (Recharts 3, client-only TusChartsLoader ssr:false). K3 rehberler:lib/tus-guides
(8 rehber, yalnız ÖSYM kılavuzu özeti, kılavuz madde ref'li; /doktor/doctorium/tus/rehber/[slug]; onaysız/bilinmeyen 404).
K4 künye dizini:lib/tus-resources (4 hazırlık kurumu + 9 kaynak; ad/kurum/resmî site/biçim — fiyat/puan/sıralama/öneri YOK,
"sponsorlu değil, tanıtım değil"). K5 YÖK Atlas:scripts/yok-atlas-ingest.ts (POST /api/tercih-kilavuz/search gövde {} → tüm
programlar tek JSON ~87 MB, repo dışı; 🪤 sorgu parametresi 418) → src/data/yok/tip-programlari-<yıl>.json (242 Tıp programı) →
lib/yok-normalize + lib/yok-data YOK_SNAPSHOTS → TusYokSection + tus/YokCharts (giriş kontenjanı ↔ TUS GENEL kontenjanı ·
kurum türü · il · başarı sırası + süzgeçli tablo). K5(a) YÖKSİS mezunları:scripts/yoksis-mezun-ingest.mjs (Playwright; ZK widget olayları,
zAu.cmd0.download yaması, sayfa içi SheetJS — istatistik.yok.gov.tr'de JSON API yok) → Tablo 12'den yalnız "TIP FAKÜLTESİ" birimleri →
src/data/yok/mezun-tip-<yıl>.json ×7 → lib/yok-mezun YOK_MEZUN_SNAPSHOTS → "Tıp mezunu" serisi + mezun kartı + KPI (🪤 sayfa yılı ≠
mezun yılı; eski dosyalarda ek İLÇE sütunu → sütunlar başlıktan). K2 kurum tablosu (v6.253):scripts/tus-ingest.ts --kind ek → src/data/tus/ek-<dönem>.json
×10 (ÖSYM ek yerleştirme min/max; lib/tus-data TUS_EK_SNAPSHOTS) · lib/tus-institutions (branş × dönem kurum satırları, son 3 dönem eğilimi, ek eşlemesi) ·
TusInstitutionsSection (RSC; süzgeçler URL sorgusunda brans·donem·tur·kt·q·sirala, ).
token'ı (grafik/bant dolgusu; öğrencide iki temada #fb923c), gündüz metin aksanı #ea580c, raf bandı koral %28.
Yeni dönem ekleme: (ve ek yerleştirme çıkınca ) → kayıt
defterine satır → 👤 onay; testler · (kaynak allowlist, yasak dil, defter ↔ dosya).
her Pazartesi 08:37 TR koşar (saf yardımcılar , test ): ÖSYM sıradaki 2 dönem (yerleştirme + ek + kılavuz slug'ları) · YÖK Atlas API (yeni yıl / kontenjan kayması) · YÖKSİS menüsü (, Playwright) · 18 künye/kaynak bağlantısı · Kariyer EDU seed bayatlığı. Yeni kaynak → ingest + kayıt defterine satırı (yüzeyde GÖRÜNMEZ) → dalı + PR; salt sinyaller tek açık issue'ya. Onay = PR'da tarihi doldur + merge. Elle: (yalnız kontrol, ~20 sn) · · . 🪤 ÖSYM ana sayfası gzip akışını bitirmiyor → , bağlantı kontrolü gövdesiz; listede olmayan dönemi slug'dan türetir.
Etkinlik modülü (v6.120, 2026-08-19) — "Kongre" sekmesi ETKİNLİK oldu + TTB akredite türler:
kullanıcı kararı tam rename (etiket + rota + iç anahtar). Modül anahtarı kongre → etkinlik;
?m=kongrealias'lı (MODULE_ALIASES) ve /doktor/doctorium/kongre/[id]308 ile taşındı —
yer imleri ve gönderilmiş bildirim href'leri kırılmaz. Admin paneli /admin/etkinlik.
🔴 "Otomatik kaynak YOK" varsayımı çürüdü: dernek siteleri makine-okunur takvim yayımlamıyor ama
kredilendirme otoritesi yayımlıyor — TTB STE/SMG akredite etkinlik kaydı (kredilendirme.ttb.dr.tr)
kimliksiz, açık ve sorgulanabilir (scripts/ingest-ttb-events.ts). Küratörlü veri İKAME EDİLMEDİ:
source değerleri ayrı (curated ↔ ttb-kredilendirme), unique çakışmaz, ikisi bir arada yaşar.
Şema (20260819140000): eventType (9 tür Türkçe slug — kongre·sempozyum·kurs·egitim·konferans·
calistay·seminer·atolye·diger) · ttbCode (TTB'nin kendi kodu birebir) · scope'a üçüncü değer
uluslararasi-katilimli · @@index([eventType,startDate]). Aynı migration Doctor.feedModules
JSON'unda "kongre" → "etkinlik"göçünü yapar — parseFeedModules fail-open olduğu için
göç edilmeseydi o bölümü seçmiş doktor onu HATASIZ kaybederdi.
Arayüz: tür çipleri (çoklu seçim + "Hepsi", ?t=), varsayılan kongre + sempozyum (kurs TTB
kaydının en büyük kovası — süzgeçsiz bırakılsa kongre gürültüde kaybolurdu); Akışım'ın 3 kartlık
etkinlik kotası da varsayılan türlerle sınırlı; kart + detayda tür rozeti ve TTB akreditasyon satırı.
⚠️ Kredi SAYISI hiçbir yerde yazılmaz — TTB kodu "akredite" der, "şu kadar puan" DEMEZ: puan
katılım süresine + Kurul kararına bağlı oluşur ve TTB programında üst/alt oturumlar ayrı satır
olduğu için süreden türetmek de yanıltıcı olurdu. Dayanak + kredi kuralları (EK-1: 40 dk = 1 kredi,
günde en fazla 6): vault output/ste-kredilendirme-arastirmasi-2026-08-19.md.
🪤 İngest periyodik koşmalı, tek seferlik dolum DEĞİL: düzenleyiciler etkinlikten en az 30 gün
önce başvurduğu için kaydın geleceği daima seyrek (2026-01→2027-06 penceresinde yaklaşan yalnız 3
etkinlik çıktı). Henüz cron'a bağlı değil — elle koşuluyor (v6.205 cron düzeninde de ayrı iş olarak açılmadı; bağlamak istenirse lib/cron-guard CRON_SCHEDULES + vercel.json'a yeni satır).
v6.129 — TAKVİM + takip süzgeci + TTB bölümü + raf/mobil turu (2026-08-19, kullanıcı oturumu):
• /doktor/doctorium/takvim — ORTAK TAKVİM (rafın 08 durağı + Header hesap menüsü
"Takvimim"): ay ızgarası (Pazartesi başlangıçlı, UTC gün anahtarları — MedicalCongress tarihleri
UTC-fmt'li, yerel saate düşülseydi etkinlik bir gün kayardı), ?ay=YYYY-MM gezinme + BUGÜN, gün
tıklayınca günün listesi (?gun=). İçerik OTOMATİK: takip edilen etkinliklerin aralığı +
bildiri ve erken kayıt son günleri kendi günlerine ayrı çiplerle düşer. ⚠️ Takipler
KOPYALANMAZ — CongressFollow'dan TÜRETİLİR (lib/calendar.ts); kopya kayıt senkron borcu
doğururdu (etkinlik tarihi değişince kopya bayatlar). CalendarEntry tablosu (migration
20260820010000) nöbet/icap/kişisel kayıtların evi — AURA Aşama-2 nöbet+icap planı AYNI tabloyu
kullanacak ("ortak database", kullanıcı kararı); kind bilinçli String (yeni tür migration'sız),
başlık klinik veri değil → şifresiz (hasta bağı taşıyan tür eklenmeden ÖNCE şifreleme kararı verilir).
MVP'de tabloya yazan yüzey yok, birleşim kodu açık — Aşama 2 yazmaya başlayınca görünüm kendiliğinden
dolar. Bugünkü klinik nöbet hâlâ ANLIK toggle (lib/clinical-duty.ts); takvim onun planlı hâlinin
zemini. ⚠️ v6.144'te KALDIRILDI: dış takvime aktarım (.ics) — iki ayrı "takvime ekle" deneyimi
(dosya indir vs uygulama-içi takip) kafa karıştırıyordu (kullanıcı bildirimi). Etkinlik kartındaki
"Takvime ekle" düğmesi artık CongressFollow'u açan AYNI mekanizmayı kullanıyor (FollowButton
"action" varyantı) — dosya üretmez, etkinlik doğrudan BU iç takvime düşer.
• "Takip ettiklerim (N)" süzgeci (?f=takip): etkinlik listesini takip edilenlere indirir.
⚠️ Bu yol branş/tür/kapsam süzgeçlerinden BAĞIMSIZ (upcomingCongressesonlyIds) — doktor branş
dışından da takip etmiş olabilir, "takip ettim ama listede yok" sürprizi üretilmez. Sayaç
followed.size DEĞİL upcomingCountByIds (takip kaydı etkinlik geçince silinmiyor → çip listeyle
aynı sayıyı söylesin). Çip takipli-yaklaşan 0 ise çizilmez; süzgeç AÇIKKEN 0'da da çizilir (yoksa
kapatma yolu kaybolur).
• Etkinlik kartında TTB akreditasyonu artık AYRI BÖLÜM (künyedeki tek satırdan yükseldi; "Takvime
ekle" ile aynı eylem dili): kod + iki dış bağlantı (etkinliğin TTB kaydı · doktorun kredi puanları).
🔴 Kredi SAYISI yazılmama kuralı korunur.
• Doctorium kromu: mobil alt çubuk (3 grup ikonu) EMEKLİ → = masaüstü rafının
birebir eşleniği (aynı 01-08 durakları, yatay kaydırma, aynı zemin; TEK kaynak). Kayıtlı +
Puanlarım Header menüsüne taşındı, page-içi mobil grup şeridi kalktı (çift navigasyon bitti).
'in / prop'ları artık okunmuyor (imza geriye-uyum için duruyor —
çağıranlardaki hesabıyla birlikte ayrı temizlik turunda sökülecek).
• (kullanıcı seçimi; doz+ton taraması sonrası v6.125'in "Zümrüt
Nefesi %8"ini süperseder): — parlak zümrüt tabanı "renkli bant"
gibi duruyordu, KOYU zümrüt tabanı yeşili derinlikten alır.
(/; kazananı bağlamı seçer): eski tek-hex inline style
gündüz temasında da gece tonunu basıyordu ve globals'ın gündüz-kontrast güvencesi (sınıf-seçici). Raf içi tüm renkler token'ından okunur → zemin varyantı tek
sınıfla değişir ( = tema-bağımsız açık raf; denendi, seçilmedi, kodda duruyor).
• "Doctorium" yazısı mobilde di (yalnız 23px sembol kalıyordu, geçiş
imkânı belli olmuyordu) → mobilde 13px görünür, AURA wordmark 12px'e ölçekli.
| 6 | Doktor Tanıtım | ✅ Doktor dizini + doğrulanmış profil (verified-kapılı — doğrulanmamış doktor public profil alamaz), gerçek profil fotoğrafı (Doctor.photo per-doktor / cinsiyet-fallback) + tanıtım videosu (cinsiyete göre), yorumlar (gerçek Review; üretim-fallback "örnek değerlendirme" etiketli), akreditasyon (JCI — yalnız gerçek veri, uydurma varsayılan yok), kalıcı akademik (düzenlenebilir) |
| 7 | Etik Kurul | ✅ Şikayet (hasta ilgili/karşı tarafı beyan eder, v6.81: Doktor/Acente/Hastane yetkilisi/Platform-diğer — zorunlu), anonimleştirilmiş (data masking) inceleme, karşı taraftan savunma/bilgi talebi (v6.81: kurul kimlik GÖRMEDEN talep açar → Sistem Mesajları'ndan hedefe düşer [atanmış doktora kişisel; acente rol-yayın; hastane/platform/atanmamış-doktor → koordinatör vekaleten]; karar formu talep açıkken kilitli — yanıt VEYA 3 gün, cron'suz zaman-bazlı, PATCH da 409 reddeder; yanıt kurula "Karşı taraf (tip)" anonim etiketiyle iner + DEFENSE_REPLY bildirimi; audit DEFENSE_REQUEST/REPLY içeriksiz), karar/yaptırım (v6.81: Yaptırım kapalı select → 5 açık kart; escrow'suz vakada iade kartları gri) — kurul yüzünden AI gerekçe + aciliyet rozeti kaldırıldı (veri minimizasyonu), Escrow iade tetikleyicisi |
| — | Tedavi Kararı → STA akışı (2026-07-10) | ✅ Görüşme ekranında birleşik Klinik Kodlama + Tedavi Kararı paneli (ClinicalDecisionPanel): ICD-10 tanı → "Sağlık Turizmi Planlaması" tuşu (v6.4 — tedavi/işlem + süre + hastane planı yalnız bu tuşla açılır; basınca tanıya göre AI işlem önerisi otomatik sıralanır, doktor seçer; tuş öncesi plan kapalı) → tanıya eşlenmiş işlemler (küratörlü statik eşleme data/icd-procedures.ts + AI işlem önerisi/api/ai/suggest-procedures) → taban↔tavan slider ücret (onboarding artık ücret SORMAZ; doktor fiyat hafızası karar kaydında güncellenir) → öngörülen tedavi süresi (gün aralığı) → hastane seçimi (HealthTürkiye dizini) → Kaydet = dosya Sağlık Turizmi Acentesine iletilir (agencySentAt + AGENCY bildirimi). Eski "Paketi oluştur / AI Teklif hazırla / Sağlık Turizmi Paketi" düğmeleri kaldırıldı — teklifi acente hazırlar (/acente, kısıtlı dosya, mode=offer). AI Epikriz post-op ekranına taşındı (/takip/[caseId] personel görünümü); hasta aynı ekrandan talebi açar ( + doktora bildirim) |
| — | | ✅ resmi dizini günlük senkron ( — web-api.healthturkiye.gov.tr; ~10.000 doktor + ~4.600 tesis; soft-delete diff) → //; → (günde 1, ) → + ADMIN bildirimi. signup'ta ad-soyad dizin eşleşmesi → → 'da yeşil rozet / . Tedavi kararındaki hastane seçici bu dizinden (). tesislerin (, ör. "ST-0292") sitenin SSR detay JSON'undan doldurulur ( — cron'da 40/gün + ilk toplu doldurma ; belge-no backfill ); hastane seçici sonuçlarında 🌐 diller + 🏅 akreditasyonlar + ; rozet de görünür (teklif + rezervasyon paket kartında, çevrili etiketle) ve acente dosyasında hastane kartında. liste-API alanlarının kısa hash'i () satırda tutulur; günlük senkron yalnız hash'i değişen kayıtları günceller (ad/şehir/branş değişimleri; tavan 1000 — aşımı rapor notuna düşer, enrichment alanları etkilenmez); ilk doldurma , rapor sayfasında "✎ güncellendi" sayacı |
| — | | ✅ Doktor Ana Sayfa (Uygulama/WhatsApp/SMS — WA+SMS , env anahtarı eklenince gerçek gönderime hazır; kayıt formunda cep telefonu alanı, at-rest şifreli) · (triyaj/SO/turizm/ücretsiz) telefon + "hangi yoldan ulaşalım?" (Uygulama/SMS/E-posta) → (şifreli) + · (7'de kırmızı, 9'da iki tarafa uyarı; otomatik kesme yok) |
| — | | ✅ Roller (hasta/doktor/koordinatör/kurul/admin//), bcrypt + JWT + proxy + KVKK onam kapısı + (; e-posta + Google OAuth + [ikisi de env yoksa dormant; Apple girişte PEM'e normalize edilir]) + (v5.6, yoksa dormant: yeni e-posta kayıtları doğrulama bağlantısı almadan giriş yapamaz [mevcut/demo hesaplar muaf, Google doğrulanmış sayılır]; + + + ) |
| — | | ✅ ( + rolü, ): hasta DB erişimi YOK, anonim konsültasyon talebi açar (+ → AI: tür/TR çeviri/özet/anormal bayrak/LOINC lab) → (: yapısal de-id + TC/pasaport/e-posta/telefon scrub) + partner yükleyebilir — kimlik/kurum/doktorlar/tarih etiketleri kayıt ÖNCESİ boşaltılır (PS3.15 alt kümesi; UID'ler yenilenir, private tag'ler silinir, açıklamalar scrub'lanır; sıyrılamayan dosya fail-closed REDDEDİLİR) + görüntünün İÇİNE işlenmiş yazılar da kapatılır — sunucuda piksel çözme (6 transfer syntax: sıkıştırmasız · RLE · JPEG Baseline · Lossless · JPEG-LS · JPEG 2000) → maskeleme → sıkıştırmasız yeniden yazma; maskeler (a) standarda dayalı OTOMATİK kurallar (US dışı · cihaz bilgi şeridi · sinyali) ve (b) yükleyenin 'da çizdiği kutulardan gelir (auth'lu PNG önizlemesi; , istemci yalnız koordinat gönderir). (klinik alanı yanlış karartma riski) → beyan kutusu KALIR, metni sorumluluğu açıkça yükleyende bırakır. Maskeleme yalnız HAVUZ kopyasına; vakadaki asıl dosya değişmez ( + ne yapıldığını yazar) → anonim dosya auth'lu ucundan mevcut 'da açılır (yanıtlayan doktor + talebi açan partner; audit'li; AI değerlendirme DICOM'a uygulanmaz) + vakaya ATANAN doktor kokpitten "Havuzdan görüş iste" — anonim özet taslağı (düzenlenebilir; yine scrub+redact'ten geçer) + seçilen belgeler (DICOM'lar aynı tag-strip'ten) → kendi talebi havuzda kendisine GÖSTERİLMEZ (), gelen görüş vaka sayfası "Havuz Görüşü" kartına + bildirime düşer; TR özet 'ye çevirisiz yazılır → (at-rest şifreli; 'da kayıtlı doktorlar görüş + verir: lab/görüntüleme=ServiceRequest, ilaç=MedicationRequest ATC). (özet→TR doktor · görüş→hasta dili partner) + (). Yanıt başına ödeme simüle. partner↔doktor çift-yönlü (at-rest şifreli + AI oto-çeviri; doktor nihai görüş öncesi de soru sorabilir → talebi atomik sahiplenir, IN_DISCUSSION). presence/heartbeat () + İcapçı offer/respond randevu () + WebRTC oda (; sinyalleşme yeniden kullanımı + fallback chat) |
Paralel hasta akışları
İkinci Görüş (Second Opinion): genel triyajdan bağımsız akış — 12 durumlu state machine, 7
Prisma modeli, CRM oto-atama + hoca kabul, 4 bölümlü yazılı görüş + video randevu teklifi, izole
video oda (AI canlı tercüme + transkript — M2 paritesi, ilk konuşma sesinde otomatik). SLA:
600 USD · 5-7 iş günü · video 15 gün. (lib/second-opinion.ts)
Başvuruda branş kapısı (v6.43): "İlgili tıbbi branşı biliyor musunuz?" → biliyorum = branş
seçici; bilmiyorum = tanı/durum alanı öne gelir + "Branşı belirle" → triyajın mevcut ucu
(POST /api/triage/analyze) branşı önerir (kart: branş + güven + "doğru değilse değiştirebilirsiniz")
ve hasta düzeltebilir. Yeni AI hattı YOK (runTriage LLM yoksa kural motoruna düşer ⇒ akış AI'a
bağımlı değil); yeni rıza da gerekmez (AiConsentGate bu kulvarı zaten kapsıyor).
Ücretsiz Sağlık Hizmeti: sağlığa erişimi kısıtlı hastaları gönüllü doktorlarla ücretsiz video görüşmede
buluşturan akış — atomik eşleştirme, doktor konsolu + haftalık kontenjan. (lib/free-care.ts)
Kesişen yetenekler
Doctorium Post — günlük özet gazetesi (v6.159-160, 2026-08-25): abone doktora her sabah
(daily-digest cron'u 06:30 TR — içerik cron'ları 05:00/05:20 TR'de ve özet çevirisi 05:40 TR'de önce biter, v6.205 · v6.206) akış tercihlerine göre derlenen kişisel özet.
🔒 Alan başına 2 kuralı: seçilen her ilgi alanından en fazla 2 başlık (1 alan→2, 6 alan→12;
bölümler tercihlerdeki 6 içerik alanıyla birebir: Akademik · İlaç & Cihaz · Sektörel · Mevzuat ·
İçtihat · Doktrin). Baskı DailyDigest ANLIK GÖRÜNTÜSÜ (doktor+gün unique — e-posta ↔ web aynı
baskı; boş gün = baskı YOK; sponsorlu içerik/anket GİRMEZ). Abonelik /doktor/doctorium/tercihler
"Doctorium Post" bölümünden (null=kapalı VARSAYILAN — ⚖️ opt-in · app · email); gazete sayfası
/doktor/doctorium/ozet (7 günlük arşiv şeridi). E-posta: tipografik/görselsiz şablon
(lib/digest-email.ts — 🔴 text-transform:uppercase YASAK: büyütme belge diline bağlı, Türkçe
sabitler sunucuda toLocaleUpperCase("tr"), kaynak adları büyütülmez) + RFC 8058 tek-tık çıkış
(List-Unsubscribe(-Post) başlıkları; çıkış audit'li, kanalı null'a çeker). Resend dormant'ken
simülasyon; doğrulanmamış adrese gönderilmez. Motor: lib/daily-digest.ts (pencere = son
baskıdan beri, 72 saat tavan). Tasarım: vault output/doctorium-gunluk-ozet-tasarimi-2026-08-24.md.
i18n (8+ dil) + RTL: tüm hasta yüzeyleri çevrilir (Arapça/Farsça RTL dâhil); Translation
cache + lib/i18n.ts + /api/i18n + useT. Klinik veri TR kanonik (doktor/AI etkilenmez).
Klinik/PHI serbest-metin (epikriz/SOAP/uzman görüşü/talep açıklaması) hastaya çevrilirken ayrı
yoldan geçer: translateClinical + /api/i18n/clinical + useClinicalT — önbelleksiz (düz-metin
PHI Translation'a yazılmaz = at-rest şifrelemeyi baypas etmez) + hasta adı [HASTA] ile maskeli
(de-id'siz dış AI'ya gitmez, KVKK/GDPR). Cache'li useT/getTranslations yalnız statik UI etiketleri için.
Bildirim Merkezi: Header zili; rol- ve kullanıcı-hedefli Notification.
Doctorium — ayrı ürün
AURA hastaya bakan telehealth platformuyken Doctorium doktora bakan ayrı bir üründür: profesyonel
içerik akışı, topluluk ve kariyer aracı. Aynı repoda büyüdü ama artık kendi markası, kendi vitrini
(/doctorium, canonik doctorium.tr) ve kendi Vercel projesi var — mekanik detay aşağıda Deploy →
İki marka, iki Vercel projesi'nde. Modül gerçeği (lib/doctorium.tsModuleKey, kullanıcı kararı
2026-08-01):
Akış + tercih — kişiselleştirilmiş haber/mevzuat/akademik akış, branş+ilgi alanı filtreleri.
Sektörel / mevzuat — Resmî Gazete + hukuk/içtihat/doktrin arama (özet+link, telif gereği tam metin yok).
Akademik + AI özet — literatür taraması, Claude ile klinisyen-diline özet.
Doctorium Post — abone doktora günlük özet gazetesi (daily-digest cron'u 06:30 TR; opt-in kanal, e-posta/app).
Puanlar + ödüller — anket katılımı puan kazandırır → ödül kataloğuna (kongre/kitap) dönüşür
(puan≠nakit; honorarium'lu anket hukuki netleşene dek yayın kilitli). Sponsorlu içerik
(ilaç-dışı reklamveren) ayrı bir gelir kalemi, /admin/kampanya'dan yönetilir.
Kariyer — Modül D gibi PARK: İŞKUR özel istihdam bürosu izni olmadan ilan/aracılık fazı açılmaz (mevzuat gereği).
Modül D (ilaç tanıtımı/e-mümessil) BİLİNÇLİ PARK — TİTCK tanıtım yönetmeliği + ruhsat sahibi sıfatı hukuki görüş ister.
AURA ile ilişki: hesap/DB ortak, ama erişim iki aşamalı (lib/doctor-activation.ts) — diploma
e-Devlet ile doğrulanan doktor önce yalnız Doctorium'a girer (activatedAt boş: Doctorium +
/doktor/baslangic + /doktor/profil + /doktor/haberler; klinik yüzeyler KAPALI). Aşama 2'de
(activatedAt set, hasClinicalAccess açılır) AURA'nın klinik yüzeyleri (post-op izleme, vaka
havuzu, nöbet) erişilir hale gelir. Yani Doctorium AURA'nın "önce kapısı" değil — kendi başına
yeterli bir ürün; AURA üyeliği onun üstüne eklenen bir katman.
Hesabım — /doktor/doctorium/hesap (v6.187, 2026-08-29): üyenin kendi hesap yüzeyi; header hesap
menüsünde (tema anahtarının üstü, doctoriumActive || stage1 koşullu). Dört panel: üyelik bilgileri
(salt okunur; öğrencide üniversite/bölüm varyantı) · parola (değiştir; User.passwordSetAt null
ise "belirle" — OAuth hesabının gölge hash'i kullanıcı tarafından bilinmez; başarıda tüm oturumlar
düşer, bu cihaz taze token alır) · giriş etkinliği (AccessLogLOGIN kayıtları — ⚠️ AÇIK OTURUM
LİSTESİ DEĞİL: oturum JWT claim'i, Session tablosu yok; arayüz bunu açıkça söyler) · üyeliği kapat /
Doctorium'dan çık. Kapatma yolu klinik bağ ÖLÇÜLEREK seçilir (countClinicalTies, fail-closed):
bağ yoksa hesap dahil her şey o anda silinir (Doctorium'da saklanacak klinik kayıt yok — AURA'nın
"kilitle + saklama süresi" modeli buraya uygulanmaz); bağ varsa yalnız Doctorium katmanı silinir +
Doctor.doctoriumOptOutAt damgalanır, hesap ve AURA erişimi sürer.
⚖️ Tamamlanmış işlem geri alınmaz (kullanıcı kararı 2026-08-29): anket yanıtları ve ödül
kullanımları SİLİNMEZ — Doctor'a FK olmadıkları için doctorId yetim kalır, yani anonimleşir.
Puanlar ileriye dönük hak olduğu için silinir ve geri yüklenmez; arayüz bunu kapatmadan önce uyarır.
Panel metni kitle-duyarlı (v6.266, 2026-09-12): sponsor/anket/puan/ödül yüzeyleri audienceFlags'te yalnız VERIFIED'a açık olduğundan
öğrenci/deneme/kilitli hesapta "anket yanıtlarınız / puanlarınız" maddeleri ve puan uyarı bandı HİÇ çizilmez — MembershipPanelhadMarketingSurfaces prop'unu çağıran sayfadan alır (hesap/page.tsx → audienceFlags(audience).canSeeSurveys; Stage1 kilitli-deneme yolu → false).
Hukuki belgeler — /doctorium/{aydinlatma,kosullar,cerez,icerik-politikasi,kvkk-basvuru} (v6.210, 2026-09-03):
Doctorium'un yayımlanan beş hukuki metni (KVKK aydınlatma · üyelik sözleşmesi · çerez · içerik/telif +
bildir-kaldır · KVKK m.11 başvuru usulü). Tek kaynak lib/doctorium-legal/: index.ts kayıt (slug/rota/
başlık/sürüm 1.0), texts/*.ts yayın kesitleri (vault output/doctorium-hukuki-belgeler/ 20 belgelik NİHAİ
setin 01/02/03/04/06 numaralı belgelerinden kesit script'iyle üretilir — elle düzenlenmez, kaynak vault'tur),
markdown.ts saf ayrıştırıcı (bağımlılıksız; tablo/liste/blockquote/bağlantı; React düğümü basar, HTML
enjeksiyonu yok), anket-kosullari.ts (anket kartındaki "Katılım koşulları"). Sayfalar
components/aura/doctorium-legal/ (LegalShell açık kabuk + LandingFooterV3; AURA kromu girmez —
chrome-routes CHROME_FREE_ROUTES'ta, birim testle bağlı), canonical DAİMA doctorium.tr, Doctorium
deploy sitemap'inde; AURA sitemap'ine bilinçli girmez. Footer bağlantı satırı iki footer'da da
LEGAL_LINKS'ten çizilir. Canlı rıza/koşul sabitleri de aynı setle NİHAİ oldu: lib/sponsor.ts
(08), lib/hr-consent.ts (09; yürürlük İŞKUR izniyle), lib/rewards.ts REWARD_TERMS_ITEMS (10; vergi
maddesi mali müşavir görüşüne kadar kataloğu kapalı tutar) — "(TASLAK)" ibareleri kalktı. Tüzel kişilik
kurulana dek metinlerde "Doctorium platform işleticisi" ifadesi kullanılır; unvan/adres/MERSİS/KEP/
VERBİS vault Kılavuz §8 kimlik tablosundan tek geçişte doldurulur (_kimlik-doldur.py) ve kesitler
yeniden üretilir. ⚖️ Kural: kişisel veri işleyen yeni bir modül eklendiğinde vault'taki işleme
envanteri (17) + aydınlatma (01) + saklama politikası (05) birlikte güncellenir, kesit yeniden üretilir.
Onam mimarisi — Seçenek A + C (v6.211, 👤 karar 03.09.2026, vault belge 15 §7): Doctorium'dan kayıt olan
doktor/öğrenci telesağlık metnini (GENERAL_KVKK) DEĞİL, Doctorium setini onaylar — DOCTORIUM_KVKK
(belge 01) + DOCTORIUM_TERMS (belge 02), her ikisi v1; ekran = hash (onam ekranı lib/doctorium-legal
metnini LegalMarkdown ile gösterir, sunucu aynı string'i hash'ler). Tek kaynak lib/doctorium-consent.ts:
requiredConsentScopes(role, aşama, deploy) (v6.269, AURA deploy'u: PATIENT → GENERAL_KVKK v4 + AURA_TERMS · personel → STAFF_KVKK · Aşama 1
doktor/öğrenci → Doctorium seti · Aşama 2 doktor → STAFF_KVKK + Doctorium · Doctorium'dan çıkan → STAFF_KVKK). v6.275 (2026-09-19) — DEPLOY EKSENİ:deploy 'dan çözülür (; testler parametreyle verir) — DOCTOR her aşamada (profilsiz dahil) → yalnız 01+02 · Doctorium'dan çıkmış → boş · personel/ADMIN → boş (STAFF_KVKK ve personel aydınlatması AURA host'unda yaşar) · PATIENT → AURA kuralı (oturum zaten açılmaz); / aynı ekseni taşır; Doctorium'da 'ı yok sayar, kimliksiz → ; Doctorium'da yalnız + , AURA kapsamı ; bayat oturumlar → resign ile kendiliğinden düzelir. 👤 bulgu 2026-09-19: v6.269'un yeni STAFF_KVKK'sı doctorium.tr girişine AURA personel aydınlatmasını düşürüyordu (18 Eyl "admin doğrudan iniş" teyidi aynı hatanın ADMIN yüzüydü). Nöbet: (deploy parametresi) + (400/200). (JWT : set
tamsa CONSENT_VERSION, değilse 0 — proxy kuralı DEĞİŞMEDİ; login/OAuth/signup bunu yazar),
(/onam DB-taze karar: · [hasta] · [personel / clinical] · [set tam, JWT eski →
kayıtsız yeniden imza; proxy↔/onam döngüsü kapanır]). (): eski üretimde Header ön-yüklemelerinin bayat-çerezli proxy 307'sini ön-yükleme önbelleğinden kullanıp /onam'a geri dönüyor, kullanıcı "Onay durumunuz doğrulanıyor…" spinner'ında elle yenileyene dek kalıyordu (dev'de görünmez — prefetch yalnız üretimde; ile tekrarlandı). hedefi ile süzülür ( ve reddedilir; OAuth aynı kurala devreder). Nöbet: .
onamsız yazmaz; onboarding "bitir" 409 → form
'a gider (StaffConsentGate + A09 madde 10.1 DOCTOR kesiti), kaydı sonra
çağırır. Mevcut aktif doktorlar etkilenmez (damga korunur); Doctorium seti olmayan her
doktor ilk girişte Doctorium metnini onaylar (👤 yeniden onay kararı). (belge 11 §B, 6 madde):
DIPLOMA kartında kutu işaretlenmeden dosya seçilemez;
ister ve belge işlenmeden ÖNCE kaydını yazar (her yükleme ayrı
satır, fail-closed). gövdesi : general | staff | doctorium | resign (+ tr/en — hash gösterilen
dilin metni). kapsam sekmeli (; her kapsam kendi kanonik metin ADAYLARIYLA [TR + EN;
personelde rol kesiti] "metin eşleşmesi" ölçer — ; geri alınabilir kovalarda geri alma durumu).
E2E helper'ı kapıdaki tüm kutuları işaretler ().
eski üyelik-yazısı (CHAMBER) kalıntıları koddan/şemadan kaldırıldı ( DROP + CHAMBER satırları — migration , ; Blob'lar ile önce imha) · 180→90 (belge 11 §C.3) · öğrenci kaydında doğum tarihi beyanı — 18 yaş altı fail-closed red, tarih SAKLANMAZ (, form + API) · diploma ret bildirimi şablonu nihai (gerekçe + 15 gün bilgi@ itiraz + 30 gün yanıt; klinik belge tipleri AURA paketine bırakıldı). — terk edilmiş hesap süpürmesi + audit IP/cihaz boşaltma + başvuru kütüğü/platform içi KVKK formu (detay aşağıda). AURA telesağlık onam metni + rol maddeleri (ConsentGate "taslak" etiketi) ayrı gözden geçirme turunda (👤 03.09.2026).
v6.263 (2026-09-10) — hukuki set Paket 2 (05 madde 3.1b/3.10, 06 madde A.2/B.2):Doctor.lastLoginAt
(lib/login-activity.ts recordLogin tek dokunuş noktası) + lib/abandoned-sweep.ts — doğrulanmış (diploma/
öğrenci) ama son girişten 3 yıl + 30 gün bildirim sonra terk edilmiş hesap silinir (klinik bağ/PENDING
belge fail-closed, purgeAbandonedAccount — purgeTrialAccount deseni). AccessLog.purgedAt +
lib/audit.ts purgeStaleAuditMeta — 2 yıl sonra ip/userAgent boşaltılır; verifyAccessChain'e
ConsentRecord.purgedAt İLE AYNI "bağ-koruyan" mühür-atlama deseni (purgedSeals sayacı) — naif bir UPDATE
zinciri KIRIK gösterirdi, bu desen onu önler. lib/kvkk-applications.ts + /doctorium/kvkk-basvuru formu
(LegalShell artık children alır) + /admin/kvkk-basvurulari yönetim ekranı — KVKK m.11 başvuru kütüğü,
3 yıl saklama; form artık CANLI (önceden yalnız metin sayfasıydı, [email protected]'ye yönlendiriyordu).
Üçü de purge-deleted cron'una (06:30 TR) entegre. Migration 20260909120000_kvkk_paket2 (yalnız nullable
kolon + yeni tablo) dev+prod'a uygulandı. 🚀 CANLI 46e4559.
v6.282 (2026-09-20) — Doctorium hukuki belgeler revizyon turu 5 (Doctorium 1.5; 👤 R21/R9): ortak iç belgeler 16–19'a AURA
telesağlık ekleri işlendi (vault: tek ihlal prosedürü · envanter 2.15–2.27 + sağlayıcı 3.1 · veri işleyen A.3 kontrol listesi + B madde 13 ·
taahhütname klinik roller + 9–13) + R9 süre birimi takvim günü — üç kod kesiti cerrahi yama: icerik-politikasi.ts bildir-kaldır
5 iş günü → 7 gün · rewards.ts ödül talebi 10 iş günü → 15 gün (belge 10 program koşulları kesiti) · anket-kosullari.ts itiraz
15 iş günü → 15 gün; DOCTORIUM_LEGAL_VERSION "1.5" · 20 Eylül 2026. DOCTORIUM_CONSENT_VERSION 4 SABİT — 01/02 hash'i değişmedi, yeniden onam yok.
Teslim hattı: PDF artık Chrome (_pdf-uret.py) + TAM ZIP betiği (_zip-uret.py).
v6.278 (2026-09-20) — K10: geri alınan açık rıza yeniden VERİLEBİLİR + H10 kapı sunucu okuması:ConsentRecord (kullanıcı, kapsam,
sürüm) tekil + recordConsent idempotent → geri alınan AI/beyan rızası aynı sürümde yeniden verilemiyordu (200, satır yok, kalıcı 403).
Çözüm (👤 "REGRANT"): recordRevocableConsent (lib/aura-consent) — aktifse no-op · verme yoksa verme · verme var + geri alınmışsa
<KAPSAM>_REGRANT sayaç-sürümlü kayıt (aynı zincir, aynı metin hash'i); decideActive(grant, revoke, version, regrant) son OLUMLU olayı
(verme ya da sonraki yeniden verme) sayar; consentStatus.regrantedAt. GET /api/consent/ai + AiConsentGate mount'ta sunucudaki
aktif rızayı okur (H10; kontrol bitene dek form mount edilmez). Kanıt/Rızalarım "yeniden verildi". Migration YOK.
v6.274 (2026-09-19) — AURA hukuki set kod Paket D (formlar; S3 · R6 · R12; migration YOK):18+ kapısı — PatientSignupForm doğum
tarihi beyanı (saklanmaz, loglanmaz; lib/patient-age.ts, student-age deseni); e-posta kaydı signup-patient gövdede yeniden hesaplar
(18 altı 400 UNDERAGE); OAuth yoluPOST /api/auth/age-gate → imzalı 15 dk p_age_gate damgası (lib/age-gate.ts, HMAC
SESSION_SECRET; tarih/yaş TAŞIMAZ; üretimde sameSite none — Apple form_post cross-site) → Google/Apple callback damgasız YENİ hasta hesabı
AÇMAZ (/kayit/hasta?oauth=age); formda sosyal düğmeler tarih girilene dek kapalı (SocialAuthButtons gate). Mevcut hesabın girişi etkilenmez.
Yakını adına başvuru (A02 madde 3.4): Ücretsiz Sağlık formunda "Bu başvuru kimin için?" (Kendim / Yakınım) + yakınım → ad alanı + beyan
kutusu ZORUNLU (lib/free-care-declaration.ts TR/EN; apply 400 kutusuz); beyan denetim zincirine FREECARE_ON_BEHALF_DECLARATION
(başvuru başına; metin sürümü + sha256). Turizm sorumluluk bildirimi A08 B.3 (R12): metin artık VAULT'tan (_yayin-kesiti.py →
texts/turizm-bildirimi.ts TR/EN; "cezai" çıktı, kasıt/ağır ihmal saklı); planlayıcı EN kanonik doğrudan, diğer diller çalışma-anı çevirisi;
tourism-request bildirimi hasta dilinde + zincire TOURISM_DISCLAIMER_NOTICE. autocomplete: hasta + personel formları
(STAFF_AUTOCOMPLETE_BY_KEY config'te, test kilitli). Testler tests/unit/paket-d-formlar.test.ts (10). DEV canlı prova: form kapısı
(kapalı → 18 altı ret → 18+ çerez + açık), signup-patient 400/400/200, free-care/apply kutusuz 400.
⚖️ AURA belge-kod kuralı (Doctorium ile aynı): kişisel veri işleyen YENİ modül/alan eklerken A01 (aydınlatma) + A06 (saklama) +
ortak envanter (Doctorium 17 / A17 eki) BİRLİKTE güncellenir; yayımlı metin değişirse _yayin-kesiti.py yeniden koşulur ve onam sürümü artar.
v6.272 (2026-09-18) — AURA hukuki set kod Paket C (saklama/haklar; A06 madde 3.1b · 3.16 · 5.1 · 6):User.lastLoginAt +
User.abandonedNoticeSentAt (migration 20260918110000_aura_paket_c — migration-ÖNCE; AccessLog LOGIN zincirinden geri doldurma) —
recordLogin artık User'ı da damgalar ve girişte bildirim damgasını NULL'lar; lib/aura-abandoned-sweep.tshasta/personel pasiflik
süpürmesi (DOCTOR dışı tüm roller; 3 yıl + 30 gün bildirim — Doctorium abandoned-sweep ile AYNI saf karar fonksiyonu; TR/EN e-posta
lib/aura-abandoned-email.ts; korkuluklar: klinik bağ [lib/aura-account-purge.ts countAuraTies — sahiplik + eylem izi + denetim zinciri
deny-list] · bekleyen KVKK/kurumsal başvuru · son ADMIN; audit AURA_ABANDONED_PURGE) + isNoticeCurrent (bildirimden sonra giriş →
damga bayat; iki süpürmede de — eski damga bildirimsiz imhaya yol açmasın) · kurumsal başvuru ret imhasıpurgeRejectedStaffApplications
(REJECTED + 90 gün → başvuru + belgeler + hesap; audit STAFF_APPLICATION_PURGE) · ikisi purge-deleted cron'unda (audit detayı aura-pasiflik ·
kurumsal-ret-imha) · deleteAccount: KVKK m.11 kütüğüne otomatik SILME kaydı (ANSWERED, ip yok) + politika↔kod boşluğu kapandı
(patientHealthHistory ve token özetleri de boşaltılır) · RETENTION_YEARS etiketi NİHAİ (A06 3.2) · DeleteAccountPanel metni A06 5.1 /
A01 madde 8 ile hizalı ("vaka" → "başvuru"; kütük + yeniden kayıt notu). Testler: tests/unit/aura-abandoned-sweep.test.ts (13). DEV'de canlı
prova: 7 senaryo (bildirim · imha · bayat damga · bekleyen · bağlı · ret 91/89 gün) + giriş damgası + silme kütüğü + cron uçtan uca.
v6.269 (2026-09-13) — AURA hukuki set kod Paket B (onam mimarisi, ekran = hash):CONSENT_VERSION 3→4 — hasta /onam kapısı artık A01 aydınlatma + madde 14 açık rıza ve A02 kullanım koşullarının TAM metnini (TR kanonik / ? EN ikinci kanonik, hash dil başına — S4) gösterir ve iki kapsam yazar (GENERAL_KVKK v4 + AURA_TERMS v1, AuraConsentGate); personel ve Aşama 2 doktoru A09 aydınlatması + yalnız kendi rol maddesini onaylar (STAFF_KVKK v1, StaffConsentGate, staffKvkkText kesiti — hash rol × dil; klinik aktivasyon şartı artık STAFF_KVKK); AI_TRIAGE/AI_INTERPRET v2 (A04 b/c, sağlayıcı adıyla; TASLAK dönemi kapandı) — tercüme kapısı YALNIZ görüşme dilleri farklıysa + "Tercümesiz devam et" (R4; oda sessionStorage opt-out ile tercümanı kurmaz); HEALTH_DECLARATION v1 (A04-d) — /paket beyan formu rıza kapısının arkasında, sunucu 403 HEALTH_DECLARATION_CONSENT_REQUIRED; STAFF_APPLICATION_KVKK v2 (A10, form LegalMarkdown); Hesabım → Rızalarım (AI/beyan rızalarını geri alma: <KAPSAM>_REVOKE ispatlı kayıt, activeConsent geri-alma duyarlı — triyaj/beyan uçları bunu denetler); /onam/kanit 10 kapsam sekmesi + TR/EN adaylı metin eşleşmesi (canonicalTextsFor). Metinler vault _yayin-kesiti.py ile lib/aura-legal/texts/{personel,acik-riza,kurumsal-basvuru}.ts. Hasta/personel/Aşama 2 doktoru bir kez yeni kapıya düşer (proxy cv < 4). Testler: tests/unit/aura-consent.test.ts + güncellenen doctorium-consent.test.ts.
v6.300 (2026-09-22) — 7-C düzeltmesi: tek birimli hukuki çeviri SKALER araçla: üretim ısıtmasında her koşuda aynı 4 birim eksik kalıyordu (koşullar 5.1/5.5/6.1 + çerez hücresi; Almanca/Bulgarca): dizi şemasında model uzun paragrafı ("→" adımları, (a)/(b)/(c) sıralaması) 2–3 öğeye bölüyor → "sayı uyuşmuyor" → çeviri atılıyor; birim-birim yedek de tek öğede aynı nedenle KALICI başarısızdı. Parçaları birleştirmek denendi ve reddedildi (bölünme noktasındaki tırnaklar düşüyor, " ." artığı). Çözüm translateLegalBatch: tek öğe → translateLegalSingle (submit_translation, translation: string — model bölemez, noktalama korunur; ham metin gönderilir); çok öğe dizi şemasında kalır (kısmi doldurma yine YOK). DEV Bulgarca koşullar 110→113/113 doğrulandı. Isıtma betiği sayacı dürüst: "özgünle aynı kalan N (dil adları/özel adlar dâhil)" — eskiden özdeş dizeler "eksik" görünüyordu. Test: legal-translate-batch (5). 🪤 .aura-preview/ (başka oturumun yapı artığı, git-ignore'lu) tsconfig include "**/*.ts" yüzünden yerel tsc/build'e girer — temiz worktree'de build alınır.
v6.328 (2026-10-06) — İÇERİK TAKVİMİ, Faz 1 (👤 kararlar: 3 rubrik · hukuk günü: sistem aday + taslak üretir, "Doktor için çıkarım"ı İNSAN yazar · tek aşamalı onay (hazırlayan = onaylayan) · PNG önizleme kart servisine bağlı · kimlik onay kutusu ZORUNLU + otomatik tarama): günlük seçki (omurga) AYNEN sürer; üstüne hafta içi rubrik yuvaları — Çar Karar masası (Yargıtay kararı incelemesi) · Pzt Etkinlik radarı · Cum Öğrenci köşesi (lib/social-calendar/series.ts kayıt defteri; ikisi hafif onay, üreticileri Faz 3). Tablo ContentPlanItem (rubrik × Türkiye günü; migration 20261006120000_content_plan_item — yeni tablo → migration-önce, bkz. DEPLOY.md; durum düz String: PLANNED→DRAFT→APPROVED→PUBLISHED, +SKIPPED/FAILED). Onaylı içerik DÜZENLENİRSE onay düşer; approvedHash (kanonik içeriğin sha256'sı) yayın hattının "onaydan sonra değişmedi" kanıtıdır (plan.isApprovedIntact). /admin/icerik-takvimi (hafta görünümü; yuva satırı yalnız "Yuvayı aç" ile oluşur, GET yazmaz) + /[id] (kaynak seç → taslak → PNG önizleme → onay; Yönetim dizini kartı). Uç POST /api/admin/icerik-takvimi (action: open|candidates|pick|save|approve|unapprove|skip|restore|preview; yalnız ADMIN; yazmalar version (=updatedAt) ister → eşzamanlı yazım 409; kapılar geçmezse 422 + rapor; önizleme hız sınırı 30/10 dk; audit CONTENT_PLAN_APPROVE|UNAPPROVE|SKIP — içerik audit'e YAZILMAZ; maxDuration 120). Karar masası üreticisi (deterministik, AI YOK):NewsArticle (source yargitay · category ictihat) → karar.ts modern iskeleti ayrıştırır (V. TEMYİZ → A. Temyiz Sebepleri → B. gerekçe → VI. KARAR; gerekçe başlığı ÜÇ adla gelir, başlık ADINA değil "Temyiz Sebepleri'nden sonraki başlık"a bağlanır; numaralı alt başlıklar/paragraf numaraları/satır kırıkları temizlenir); aday = hukuk dairesi + sonuç net (onama/bozma/düzelterek onama) + "Uyuşmazlık, … ilişkindir." cümlesi + alıntıda kimlik taraması temiz (DEV'de 246 karardan ≈130 uygun; scripts/karar-masasi-olc.ts ölçer); puan = güncellik + gerekçe zenginliği + kanun atfı − yakın tema/sonuç tekrarı; havuzdan 3 aday (mümkünse farklı tema). Taslak 7 slayt: kapak · uyuşmazlık [BİREBİR alıntı] · mahkeme zinciri · gerekçe [BİREBİR alıntı, atlama "[…]" ile; olgu yoğunluğuna göre alternatif kesitler → editör "Başka kesit"] · sonuç [sabit tanım, "kim kazandı" iddiası YOK] · Doktor için çıkarım [İNSAN] · kaynak + uyarı. Onay kapıları (gates.ts, saf): kaynak · slayt · uzunluk · çıkarım (≥3 madde) · uyarı ("bilgilendirme amaçlıdır; hukuki görüş değildir") · (karar metni onayda TAZE okunur) · yasak ifade (YALNIZ kendi metnimiz: "hekim"/"uçtan uca"/"akredit"/garanti…; alıntı slaytı mahkemenin sözüdür, olduğu gibi kalır) · (TCKN/telefon/e-posta/unvanlı ad/taraf adı — gerçek metinde "davacının Mina'nın…" gibi sızıntı görüldü) + . Vercel → n8n webhook köprüsü ( — sırsız, yürütme kaydı KAPALI) → servisi (; Bearer doğrulaması KARTTA; sosyal üretim sürerken 503, eşzamanlı önizlemede 429) → 7 slayt 1080×1350 PNG ≈6 sn (yerel); env (yoksa önizleme 503, takvimin geri kalanı çalışır). Yayın hattı (n8n, Faz 3) YOK — onaylanan içerik şimdilik YAYINLANMAZ. Testler: · .
v6.332 (2026-10-06) — İÇERİK TAKVİMİ, Faz 2-A: yayın durumu + elle yayın yardımcıları (👤 "ilk adım 2-A"; migration/env YOK): otomatik yayın hattı (n8n) henüz yok → onaylı içerik ELLE paylaşılır, durum kaydı dürüst tutulur. /admin/icerik-takvimi/[id]"Yayın" paneli (APPROVED · FAILED · PUBLISHED'da): "PNG'leri indir (ZIP)" (KAYITLI/onaylı içerik kart servisinde çizilir — preview payload'sız çağrılır → onay mührüyle aynı içerik; tarayıcıda bağımsız store-ZIP 01-kapak.png … 07-kaynak.png + altyazi.txt; lib/zip-store.ts, ek bağımlılık YOK) · "Altyazıyı + etiketleri kopyala" (buildCaptionText) · "Elle yayınlandı olarak işaretle" (kanal: Instagram/LinkedIn/Facebook/X/Diğer + isteğe bağlı https gönderi bağlantısı → APPROVED → PUBLISHED, TERMİNAL: içerik kilitlenir, geri alınamaz; onay mührü sağlam değilse REDDEDİLİR — "yayınlanan = onaylanan"). Servisler (plan.ts): markPublished (elle/otomasyon) · markPublishFailed (APPROVED → FAILED, mühür KORUNUR, hata notu ≤300 kr temizlenmiş) · retryPublish (FAILED → APPROVED) — Faz 3 otomasyonunun kullanacağı AYNI servisler; admin ucu yalnız publish (manual:true uçta sabit) + retry açar (action listesine publish|retry eklendi). Kayıt biçimi publishedRefs (JSON String, lib/social-calendar/publication.ts: kanal beyaz listesi, yalnız https bağlantı; bozuk kayıt sayfayı çökertmez); audit CONTENT_PLAN_PUBLISH|PUBLISH_FAIL|RETRY (kanal adı yazılır, bağlantı/içerik YAZILMAZ). Hatalı yayından atlanırsa eski hata notu temizlenir. Testler: zip-store (CRC bilinen vektörler + bağımsız okuyucuyla gidiş-dönüş) · social-calendar-{publication,publish-panel} + plan/route genişletmeleri (mutasyon provalı); uçtan uca (Playwright, DEV): gerçek ZIP indirme + tar -xf ile açma (7 PNG 1080×1350 + altyazı), pano, işaretleme (http:// sunucuda reddedilir), FAILED → yeniden dene, 375 px taşma yok. Belge düzeltmesi: RUBRIK_RENDER_URL YALNIZ doctorium projesine girer (SOCIAL_DIGEST_TOKEN yalnız orada; DEPLOY.md Adım 4 + .env.example).
v6.334 (2026-10-07) — İÇERİK TAKVİMİ, Faz 2-B1: MAKİNE yüzeyi — YAYINLANIYOR kilidi + POST /api/social-calendar/yayin (👤 iki karar: "Yayınlanıyor durumuyla kilitle" + "Ayrı CONTENT_PLAN_TOKEN"; migration YOK, uç DORMANT): Faz 3 otomasyonunun (kart → n8n) içerikle konuşacağı TEK kapı. Durum makinesine PUBLISHING ("Yayınlanıyor") + claim olayı: APPROVED → PUBLISHING (otomasyon içeriği ALIR) → PUBLISHED (sonuç ok) · FAILED (sonuç hata) · APPROVED (insan "yeniden dene"); publish-ok artık PUBLISHING'den de gelir (editör takılı kilidi elle işaretler). At-most-once: bir içeriği yalnız BİR çağrı alabilir (satır başına updateMany CAS — sürüm + durum; ikinci kart/n8n koşusu 0 satır alır) ve ALINMIŞ içerik hiçbir otomatik yolla yeniden alınmaz — çökme/zaman aşımında içerik PUBLISHING'de takılı kalır, çift paylaşım yerine İNSAN karar verir ("Elle yayınlandı olarak işaretle…" ya da "Yayınlanmadı — yeniden dene" + window.confirm çift paylaşım uyarısı; FAILED'dan yalın "Yeniden dene" uyarısızdır). Uç (action: bak|al|sonuc): bak YALNIZ OKUMA (KURU/deneme; her gün için serbest; mühür bozuk yuva atlanana düşer, slotlar durumlarıyla) · al YALNIZ bugünün (Türkiye günü, SUNUCUDA hesaplanır — gövdedeki bugun yok sayılır) ONAYLI + mührü sağlam içeriklerini alır, dönen version YENİDİR · sonuc (durum: ok|hata; ok: kanallar + isteğe bağlı kısmi basarisiz [kanal+hata]; hata: ≤300 kr temizlenmiş metin; gövdedeki manual yok sayılır — uçta manual:false SABİT) — İDEMPOTENT yalnız otomasyonun KENDİ sonucu için (ağ yeniden denemesi → 200 tekrar:true; editör elle işaretlediyse 409 GERÇEK çakışma, sessizce yutulmaz). Jeton AYRI CONTENT_PLAN_TOKEN (sabit-zamanlı karşılaştırma; SOCIAL_DIGEST_TOKEN KABUL EDİLMEZ — o yalnız-okuma bülten/önizleme jetonudur, yuva durumunu DEĞİŞTİREMEZ); env boşsa uç 503 (DORMANT) — aktivasyon Faz 3'tür (kart .env.kart + Vercel doctorium env; n8n'e GİRMEZ). Beklenmeyen hata 500, iç mesaj SIZMAZ. Aktör null ("otomasyon"); audit CONTENT_PLAN_CLAIM (+ mevcut PUBLISH/PUBLISH_FAIL/RETRY; kanal adı yazılır, bağlantı/içerik YAZILMAZ). Panel/hafta ekranı: PUBLISHING rozeti (amber), bilgi bloğu, kısmi başarısızlık satırları (kaçışlı). Doğrulama: birim 2118/2118 (177 dosya) · + 0 uyarı · ✓ · (yaşayan 1 = CAS'ındaki koşulu: sürümü her Prisma yazımında ilerlediği için kemer-askı, denk mutant) · uçtan uca (Playwright, DEV, gerçek ): — iki devre (insan çözümü + otomasyon başarısı); denetim satırları + hash zinciri koşudan önce/sonra aynı bütünlükte. Testler: durum makinesi tablosu · makine servisleri (audit zinciri ) · (kapı/idempotensi/hata eşlemesi) · + genişletmeleri.
v6.335 (2026-10-07) — İÇERİK TAKVİMİ, Faz 2-B2: KART yayın uçları — /rubrik/bugun · /rubrik/sonuc · /rubrik/dosya (👤 "2-B2'ye başla"; Vercel tarafında additive render alanı; migration YOK, jeton DORMANT): Faz 3 n8n akışının içerikle konuşacağı TEK yüz = infra/kart (lib/rubrik-yayin.mjs, server.mjs'e bağlı). CONTENT_PLAN_TOKEN YALNIZ kartta (.env.kart) ve Vercel doctorium env'inde yaşar — n8n'e GİRMEZ; jeton yoksa uçlar 503 (DORMANT: kodu sunucuya koymak davranışı değiştirmez). POST /rubrik/bugun?kuru=1[&gun=…] = Vercel bak (SALT OKUMA; durum DEĞİŞMEZ) → çiz + arşivle (deneme); POST /rubrik/bugun = Vercel al (YAYINLANIYOR; en fazla BİR KEZ; YALNIZ bugün — Türkiye günü kartta hesaplanır) → 1080×1350 PNG'ler <SOSYAL_DIR>/rubrik/<gün>/ (sosyal işinin gün klasöründen AYRI; bitti.json atomik, kimliğe göre birikir; en yeni 3 gün) + öğe başına altyazi (ZIP'teki altyazi.txt ile AYNI biçim) · POST /rubrik/sonuc Vercel sonuc'a beyaz listeyle iletir (durum kodu + gövde aynen; idempotensi Vercel'de) · GET|HEAD /rubrik/dosya/<gün>/<ad>.png yalnız listeli adları sunar (ad regex'i ikinci kapı). Değişmezler: görsel = onaylanan önizleme (kart gövdesi Vercel bak/al yanıtındaki render alanından — önizlemeyle AYNI renderRequestBody; kart rubrik adını/şablonunu KENDİ bilmez) · render hatası → kart sonuc hata bildirir (YAYIN HATASI; yayınlanmadığı kesin; KURU'da bildirim YOK) · taşan slayt (tasma) FAIL-CLOSED (kırpılmış görsel paylaşılmaz; "slayt N metni asgari puntoda sığmadı — kısaltın") · ağ/yanıt belirsizliği 502 belirsiz:true (n8n aynı içeriği yeniden almaya ÇALIŞMAZ; insan çözer) · 07:55 sosyal işi sürerken 503 · jeton yanıt/günlükte yok (davranışsal testle kilitli). Vercel tarafı: DueItem.render + bilinmeyen rubrik anahtarı atlanan: "seri-bilinmiyor" (tek bozuk satır tüm anlık görüntüyü düşürmez). 🐛 Birim testi gerçek hata yakaladı: gunGecerli("2026-13-01")Invalid Date.toISOString() fırlatırdı (?gun= 400 yerine 500). Doğrulama: birim 2367/2367 (201 dosya) · tsc + eslint src 0 uyarı · next build --webpack ✓ · mutasyon provası 32/32 (kart 30 + plan 2; yaşayan ad-regex mutantı için "kurcalanmış marker" testi eklendi) · (DEV veritabanı + YEREL KART gerçek Chromium): KURU durumu değiştirmez · canlı alma + ikinci çağrı boş · · sonuç idempotent + çakışma 409 aynen · geriye uyumu · taşan çıkarım slaytı → KURU'da hata, canlıda YAYIN HATASI + arayüz + insan "yeniden dene". Testler: (51) + genişletmesi. Ayrıntı: "İçerik takvimi YAYIN uçları".
v6.286 (2026-09-20) — 7-C hukuki çeviri ONAY KUYRUĞU (👤 karar: rozet dili "İncelenmiş çeviri"): TR/EN dışı 9 dildeki hukuki belge çevirileri hastaya "Otomatik çeviri (yapay zekâ). Henüz hukuki incelemeden geçmedi." rozetiyle gösterilir (belge kabuğu çeviri kutusunun ilk satırı + onam kapısında bölüm başı; TR/EN kanonik görünümde rozet yok). ADMIN /admin/hukuki-ceviri kuyruğunda (Yönetim dizini kartı) belge × dil × kanonik sürüm başına TR kanonikle yan yana inceler; "Onayla" → metin DONDURULUR (LegalTranslationApproval.markdown, migration 20260920190000_legal_translation_approval) ve rozet "İncelenmiş çeviri. Hukuki inceleme tarihi: " olur; onam kapısındaki aydınlatma/koşullar aynı onayı kullanır (ConsentRecord.shownTextHash = dondurulmuş metnin hash'i → hastanın incelenmiş metni okuduğu sonradan kanıtlanır; mühür formülü değişmedi). TR kaynak hash'i ya da AURA_LEGAL_VERSION değişince onay kendiliğinden eskir (sayfa otomatiğe döner, kuyruk "Onay eskidi"); "Onayı kaldır" revokedAt. Uç POST /api/admin/hukuki-ceviri (action: approve|revoke|generate; onay adminin GÖRDÜĞÜ textHash ile — sunucu önbellekten yeniden kurar, değiştiyse 409; eksik/önbelleksiz çeviri onaylanamaz; yalnız ADMIN; audit LEGAL_TRANSLATION_APPROVE|REVOKE|GENERATE; maxDuration 120). Kuyruk ve inceleme önbellekten okur (peekLegalTranslations, Claude'a istek yok); üretim "Çeviriyi üret" düğmesi ya da scripts/translate-legal.ts / scripts/translate-legal-prod.mjs (üretim; .envAURA_DB_GUARD=block ise kabukta bilinçli warn). 🐛 Tamlık ölçütü düzeltildi: özgün metne özdeş çeviri ("Vercel", "session" gibi özel ad/kod) artık "eksik" sayılmaz (Rusça aydınlatma yanlışlıkla %96 "eksik" görünüyordu); başarısız birim haritaya yazılmaz. Düzenleme editörü (2026-10-03): inceleme sayfasında "Düzenle" → paragraf (birim) düzeyinde yerinde düzeltme (Türkçe kaynak her birimin üstünde; başlık/liste/tablo yapısı kilitli, yalnız metin değişir; tek satır · ≤4000 karakter); "Düzenlemelerle onayla" düzenlenmiş metni dondurur (approve + edits, taban hash'i uyuşmazsa 409), onaylı çeviri sonradan da düzenlenebilir (önceki düzeltmeler korunur); kuyruk/başlıkta "düzenlenmiş çeviri" etiketi (dondurulmuş hash ≠ otomatik hash, sütunsuz); audit "düzenlenen N birim". Kapsam dışı (bilinçli): TR kanonik metin düzenleme (vault'tan gelir), AI rıza metinleri (arayüz çeviri hattı), Doctorium belgeleri (TR). Testler: · · .
v6.285 (2026-09-20) — Paket 7 hukuki metin TAM LOKALİZASYON (👤 karar A): hukuki belgeler + hasta onam kapısı + KVKK formu artık hastanın seçtiği dilde (11 arayüz dili). Kaynak DAİMA TR kanonik markdown → lib/legal-markdown-split (başlık/liste/blockquote/tablo/hr çeviri DIŞI; paragraf = birim) → lib/i18n getLegalTranslations (Translation önbelleği, legal: ad alanı legalHash; hukuki prompt translateLegalBatch; chunk 8 öğe/2400 kar., sayı uyuşmazlığında birim-birim yedek; düşen birim TR kalır, önbelleğe yazılmaz) → lib/legal-translate translateLegalMarkdown (complete=false = kısmi; motor yoksa null → EN kanonik). Gösterim dili lib/aura-legal/display resolveLegalDisplay(?lang=<kod|ad>, hastaProfilDili): tr → TR · en → EN · diğer → EN kanonik + o dilde bilgilendirme çevirisi (auraLegalLang() TR/EN dışı tanınan dilde en döner); belge sayfaları çeviri görünümünde noindex, kabuk "bağlayıcı metin Türkçe (ikincil İngilizce)" notu + kanonik bağlantı + dil seçici (Türkçe · English · diğer diller), ar/fa rtl; KVKK formu etiketleri useT. Hasta onam kapısı (/onam): TR/EN dışı dilde çeviri BİRİNCİL okuma, her bölümün altında kanonik EN açılır; onay POST'u lang:"en" (kanonik hash) + shown:{lang, aydinlatmaHash, kosullarHash} → parseShownTranslation → ConsentRecord.shownLang/shownTextHash (migration 20260920150000_consent_shown_translation; mühür formülü v2 DEĞİŞMEDİ — ispat eki; kanıt sayfası "Okuduğunuz dil" + hash satırı). Ön-ısıtma: npx tsx scripts/translate-legal.ts [--lang=Rusça] (ilk hasta beklemesin; DEV .env — ÜRETİM önbelleği için DATABASE_URL'i PROD_* ile AÇIKÇA ver). Sözlükler saf modüllerde (lib/aura-consent-gate-ui, lib/aura-legal/shell-ui) — "use client" modülünden veri export'u RSC'de proxy olur. Testler: legal-markdown-split (5 belge yapısal gidiş-dönüş) · legal-display · consent-shown-translation. Sonraki adım (👤): C — /admin çeviri onay kuyruğu ("otomatik" → "onaylı çeviri").
v6.260 (2026-09-09) — hukuki belgeler revizyon turu 4 (tam tur kontrol, 👤 "tek pakette"): deneme üyeliği ve öğrencinin fırsat takibi (Kariyer EDU 7/3/1 hatırlatma) envanter/aydınlatma/saklama belgelerine işlendi; TUS/YÖK verileri için 02 madde 4.8 ("tercih tavsiyesi değildir"), 04 A.2.7; AI kapsamı çeviri + içerik özeti; 02 madde 2 "doğrulanmış doktor" (terim kuralı, doctorium-legal.test artık "hekim"/"§" bekçisi); 05 madde 3.4 "öğrenci doğrulama kaydı silinir" — kod karşılığı clearStudentRecordOnTransition (diploma doğrulanınca öğrenci alanları temizlenir). Belge sürümü 1.4 · 9 Eylül 2026, DOCTORIUM_CONSENT_VERSION 3→4 (mevcut Doctorium üyeleri bir kez yeniden onaylar). Rapor: vault output/doctorium-hukuki-tam-tur-kontrol-2026-09-09.md.
v6.221 (2026-09-04) — hukuki belgeler revizyon turu 1 (👤 avukat): sözleşme madde başlıkları BÜYÜK HARF (02), iç atıflarda "§" yerine "madde N" (tüm belgeler), 02 madde 1.3 (Taraf/Taraflar tanımı), 01 madde 2 kutusu tek cümle. Belge sürümü 1.1 · 4 Eylül 2026 (DOCTORIUM_LEGAL_VERSION), beş yayın kesiti yeniden kesildi; DOCTORIUM_CONSENT_VERSION 1→2 — hash'lenen metin değiştiği için mevcut Doctorium üyeleri ilk girişte bir kez yeniden onaylar (kayıtlar zincirde kalır). Kaynak: vault output/doctorium-hukuki-belgeler (çalışma .md; teslim .docx/.pdf _teslim-uret.py).
Rotalar için bkz. aşağıdaki Rotalar tablosu; sürüm geçmişi (V3 landing, marka ayrışması fazları,
monetizasyon) için Air/wiki/changelog.md ve bu dosyanın alt kısmındaki tarihli notlar.
AURA sinematik landing (v5.9 — vitrinden taşındı: hero video+letterform, 4 chapter destesi, gsap+lenis; 9 dil statik lib/aura-landing/copy.ts, dil anahtarı air_lang). Bölüm akışı (v6.8): hero → chapters → nasıl çalışır (+AI sorumluluk notu) → doktorlar → güven (6 ürün-kanıtlanabilir kart) → kapanış; eski Şeffaflık bölümü v6.8'de Güven'e birleştirildi (transparency.tsx kaldırıldı — aynı iddiayı iki kez veriyordu). İddia kuralları: aşağıda "Vitrin iddia dürüstlüğü (v6.8)" · SEO (v5.9.2): canonical + OpenGraph/Twitter kart + 9-dil og:locale:alternate (tek URL — lib/aura-landing/seo.ts) + JSON-LD MedicalOrganization/WebSite · hasta + kurumsal giriş kapıları (kapı-içi e-posta formu v6.84; /giris/e-posta ve /kurumsal-giris/e-posta → kalıcı yönlendirme; kapılar components/aura/auth-gates.tsx + gate-email-form.tsx; kurumsal noindex) · doktor kaydı · hasta üyeliği · KVKK onam + Onay Kanıtı
/how-it-works
Nasıl Çalışır rehberi (v5.9 — vitrinden taşındı): 4 yolculuğun adım listeleri + tıkla-oynat rehber videoları + HowTo JSON-LD + OpenGraph (title template %s · AURA); global Header/SiteFooter bu rotada ve /'de gizli (sayfa kendi aura nav/footer'ını taşır). Eski vitrin aura-health.higgsfield.app tüm sayfaları buraya 301 yönlendirir
/guven-ve-gizlilik
Güven ve Gizlilik (v6.12): iddia dürüstlüğü sayfası — 10 bölüm × 9 dil (copy.tstrustPage), 5'inde "neyi iddia etmiyoruz" kutusu + FAQPage JSON-LD (cevap gövde+sınırı birlikte taşır) + OG 9 dil; global Header/SiteFooter burada da gizli (kendi aura nav/footer'ı). /trust → 308. ⚠️ Gizlilik Politikası değildir. Kurallar: Güvenlik notları "Güven ve Gizlilik sayfası (v6.12)"
/v2
Yeni ana sayfa ÖNİZLEMESİ (v6.14 · · , 9 dil). — aynı içeriğin iki URL'de indekslenmesi 'nin SEO'sunu bölerdi. Canlı . nav (tek bakım mimarisi, v6.16) → hero (sahneli açılış) → entry-paths (video-arkalı 4 kart, ) → mevcut how ()/doctors/trust → closing. eski landing'e (geri dönüş) → → → +noindex kalkar → sitemap'e girer → ⚠️ seçicileri artık landing'i de kapsar, → ⚠️ kök 'in yerini alır ve içindeki hedefleri (logo · çapası) . Sözleşme: aşağıda "/v2 hero + entry-paths (v6.14)" + "/v2 nav (v6.16)"
API (route handler grupları — src/app/api/)
Rota modülü sözleşmesi (v6.306, 2026-10-02):route.ts YALNIZ HTTP handler'ları (GET/POST…) ve segment yapılandırmasını (runtime · maxDuration · dynamic …) dışa aktarır; paylaşılan sabit/yardımcı src/lib/'e gider (olay: LIVE_TRANSLATE_MODEL, api/realtime/token/route.ts'ten lib/live-translate-model'e — token rotası + LiveInterpreter yedek model adı TEK KAYNAK). Fazladan export const, webpack NextTypesPlugin'in .next/types koruma dosyasındaki checkFields<Diff<…>> denetimini kırar (npx next build --webpack: "Property 'LIVE_TRANSLATE_MODEL' is incompatible with index signature", 2026-09-22); Turbopack build'i ve CI bu denetimi yapmadığı için hata GİZLİYDİ. Nöbet: tests/unit/route-module-exports.test.ts (178 rota dosyası; izinli liste eklenti kaynağı next-types-plugin/index.js ile sözleşmeli).
src/lib/triage-llm.ts → runTriage() gerçek Claude (zorlanmış tool_use) ile branş + aciliyet
(1-5) + güven + Türkçe gerekçe üretir. Model env-ayarlı: TRIAGE_MODEL (varsayılan
claude-sonnet-4-6). ANTHROPIC_API_KEY yoksa/hata olursa src/lib/triage.ts içindeki kural
tabanlı analyzeTriage()'a düşer (anahtar kelime eşleştirme + kırmızı bayrak → aciliyet 5).
Ortam değişkenleri
Tümü .env.example'da: DATABASE_URL (pooled) · DIRECT_URL (direct) · SESSION_SECRET · DATA_ENCRYPTION_KEK (üretim build'i bu anahtar boş/32 byte değilse BAŞLAMAZ — v6.279 scripts/check-kek.ts; iki Vercel projesine AYRI) ·
ANTHROPIC_API_KEY · GEMINI_API_KEY · VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY/VAPID_SUBJECT ·
CF_TURN_KEY_ID/CF_TURN_API_TOKEN (WebRTC TURN birincil — Cloudflare Realtime) ·
METERED_API_KEY/METERED_DOMAIN (TURN yedek) · GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET (doktor
kaydında "Google ile devam et"; boşsa dormant) · BLOB_READ_WRITE_TOKEN (Vercel Blob object storage;
boşsa belgeler şifreli base64 olarak DB'de — fallback) · EDEVLET_VERIFY_ENABLED (e-Devlet çevrimiçi
belge teyidi — 2026-08-19'dan beri üretimde AÇIK; kapalıyken ağa dokunulmaz) · AURA_LAYER_GATE (Aşama 2
katman kapısı: SMS OTP + kurum bağı şartı — DORMANT, açmadan önce kanallar aktive edilmeli) ·
SMS_API_KEY/SMS_SENDER_ID (NetGSM; ⚠️ gönderici başlığı TESCİLLİ olmalı) · (opsiyonel) TRIAGE_MODEL · (opsiyonel) NEWS_TRANSLATE_MODEL (gece haber çeviri hattı modeli,
varsayılan claude-haiku-4-5, daha doğal Türkçe için claude-sonnet-5 — v6.292'de Opus 5'ten indirildi) · (opsiyonel) NEWS_SUMMARY_MODEL (Doctorium AI özet modeli, varsayılan claude-haiku-4-5 — v6.293'te Sonnet 4.6'dan indirildi; klinik belge modeli etkilenmez).
Deploy
Vercel (serverless) + Neon Postgres üzerinde canlı. GitHub airburakk/telehealth-mvp
(main) → Vercel otomatik deploy. Adım adım kılavuz: DEPLOY.md.
İki marka, iki Vercel projesi (AURA↔Doctorium ayrışması Faz A — 2026-08-24, v6.152)
Aynı repo iki Vercel projesine bağlıdır; her main push'u ikisini de deploy eder:
Proje
BRAND_MODE
Davranış
telehealth-mvp (AURA)
(tanımsız)
Bugüne kadarki her şey birebir — hasta vitrini, klinik paneller, cron'lar
doctorium
doctorium
Kök / → Doctorium landing'e rewrite; AURA vitrin/hasta/giriş/kayıt/locale rotaları AURA kanoniğine 307 (next.config.ts AURA_ONLY_PREFIXES); sitemap yalnız Doctorium; cron'lar no-op (çift koşum kesilir — CRON_SECRET bu projeye bilinçle SET EDİLMEZ)
DB ORTAK (tek Neon): içerik boru hattı, hesap modeli ve Aşama-2 geçişi tek yerde;
geri-birleştirme = doctorium projesini silmek. Mimari kaydı vault'ta
(wiki/kavramlar/aura-doctorium-baglanti-sistemi.md + teknik ayrışma planı).
Doctorium projesinde Google/Apple env'leri bilinçle boş → butonlar "Yakında"; yeni domain
OAuth konsollarına eklenince açılır. Yerel Doctorium provası:
BRAND_MODE=doctorium npx next build && BRAND_MODE=doctorium npx next start.
Gözlemlenebilirlik (Faz 5 Ray C, 2026-07-16)
İki katman + bir bağlayıcı kural:
Sentetik rota kontrolleri — .github/workflows/synthetic.yml ~30 dk'da bir
scripts/synthetic-checks.mjs koşturur (8 halka açık rota: durum · süre · title · h1 · kritik CTA ·
noindex beklentisi + TLS sertifika bitimi + statik asset). Zamanlayıcı GitHub Actions'ta çünkü
kurulduğunda Vercel Hobby cron limiti doluydu (plan 2026-09-02'den beri Pro; GH Actions, Vercel'den bağımsız koşucu olarak bilinçli korunuyor); koşu düşünce GitHub otomatik e-posta atar. Elle koşu:
node scripts/synthetic-checks.mjs (--base= ile yerel/preview'a yöneltilebilir). Vitrin
metni bilinçli değişirse script'teki beklentiler de güncellenir.
Kod-içi kritik alarmlar — src/lib/alerts.ts (sendAlert): consent yazım hatası
(fail-closed) · onam/audit zincir bütünlük kırığı (purge cron'u günlük nöbette doğrular) ·
audit yazım hatası (istek bozulmaz ama boşluk birikimi görünür) · KEK yokluğu (SEV-1) ·
decrypt hata kümesi (10 dk'da 5+) · cron başarısızlıkları. Kanal: her zaman [ALERT] <olay>
log satırı (Vercel log'unda grep'lenir); ALERT_EMAIL + RESEND_API_KEY set ise e-posta
(aynı olay 30 dk'da bir). Test ortamında alarm susar (kasıtlı kurcalama testleri için).
✅ E-posta kanalı üretimde AÇIK (2026-09-12):ALERT_EMAIL iki Vercel projesine AYRI girildi;
konu satırı marka etiketi taşır ([AURA ALARM] / [DOCTORIUM ALARM], gövdede Proje:) — aynı kod
iki deploy'da koştuğu için alarmın kaynağı ayırt edilir. Tatbikat:/admin → "Alarm kanalı"
bloğu (alıcı maskeli + sağlayıcı durumu = iki projenin env paritesi bir bakışta) → "Test alarmı
gönder" (POST /api/admin/alarm-test, ADMIN self-auth, olay alarm-test, aynı cooldown) — kanal
gerçek gönderimle kanıtlanır.
🚫 Asla loglama (bağlayıcı kural)
İzleme, sağlık verisini log'a kopyalamadan hata tespit eder. Şunlar hiçbir log/alarm/hata
mesajına giremez: semptom metni · tanı/teşhis · belge içeriği ve belge adı · görüşme/transkript
içeriği · hasta bilgisi taşıyan görüntü metadata'sı · sağlık verisi içeren AI prompt'ları · tıbbi
bağlamda gerçek ad-soyad · erişim token'ları · şifreleme anahtarları/materyali · oturum çerezleri.
Yerine iç ID (userId/caseId), olay kategorisi, hata kodu, süre/adet kovası kullanılır. Kural kodda
src/lib/alerts.ts başlığında da durur; yeni log satırı eklerken oradaki listeye uy.
Sonraki adımlar (backlog)
Güncel yol haritası vault'ta: Air/wiki/todo.md + Air/wiki/acik-isler-envanteri.md (2026-07-19'da
kod kanıtıyla yeniden yazıldı). Öne çıkanlar (altyapı/hukuk gerektirir):
gerçek ödeme + Escrow gateway (Iyzico/Stripe — şu an simülasyon; kullanıcı kararı: Ray A/şirketleşme
netleşene dek PARK) · object storage ✅ Vercel Blob
(belgeler artık Blob'ta şifreli; token yoksa base64-in-DB fallback) · ileri E2EE fazları (Faz 0+1 ✅ at-rest/audit; Faz 2A ✅ post-op erişim daraltma + geri-alma; 2B kriptografik allowlist + Faz 3 gerçek sıfır-erişim kalan) · gerçek RFC 3161 TSA (şimdilik simüle) ·
e-posta/SMS proaktif bildirim ✅ kod tarafı v6.28 (notify.ts routePatientChannel — hasta tercihi
EMAIL/SMS, içeriksiz dürtü; aktivasyon = RESEND_API_KEY / SMS sağlayıcı anahtarı) · canlı durum ✅
v6.29 (3sn UI polling → Ably live: dürtü kanalı + 30sn güvenlik ağı; Ably yoksa eski davranış) ·
DICOM PHI ✅ TAM (v6.32-33 tag-strip + v6.37 burned-in piksel maskeleme) — kalan tek boşluk:
maskeleme kullanıcı kutularına + standart kurallara dayanır, otomatik yazı TESPİTİ (OCR) yoktur
(bilinçli karar) · veri ikametgâhı (data residency) — çok ülkeli pazar girişi için.
Güvenlik notları (demo)
Bu bir demo sürümüdür: hızlı rol girişi açık, parolalar 1234. Gerçek kullanımdan önce
bunları kaldırın; güçlü parola politikası + e-posta doğrulama ekleyin.
SESSION_SECRET üretimde mutlaka güçlü ve gizli olmalı.
JWT iptali (v4.17):User.sessionVersion + token sv claim'i — POST /api/auth/logout-all
(Header'daki "Tüm cihazlardan çıkış") sürümü artırır, dolaşımdaki tüm token'lar düşer;
getCurrentUser her istekte DB karşılaştırması yapar (istek-içi cache()'li). Eski (sv'siz)
token'lar 0 kabul edilir. Proxy bilinçli DB'siz (yaptırım veri katmanında).
Kontrol raporu Paket 1A/1B/1C-a/1C-b/2/3/4 (v6.276 / v6.277 / v6.287 / v6.289 / v6.280 / v6.281 / v6.283–284, 2026-09-19/21) — erişim ve AI kapıları TEK KAYNAK, iddialar kod kanıtlı, sayaç/hakediş/liste sözlükleri açık, hasta/doktor yüzeyleri dürüst:
· Vaka LİSTE kapsamılib/case-access.ts (doctorQueueScope / staffQueueScope / scopedWhere / CASE_LIST_SELECT) — doktor ana
sayfası ve GET /api/cases aynı üretici (atanan + KENDİ branşı atanmamış NEW/IN_REVIEW; deletionLockedAt:null; doğrulanmamış/
aktivasyonsuz/branşsız → boş küme). Yeni liste/sayım sorgusu elle where KURMAZ. API DTO hasFiles/lane (ham attachments dönmez).
· Doktor ana sayfası: kimliksiz/iptal edilmiş oturumda (proxy imzayı geçirir, getCurrentUser=null) HİÇBİR sorgu koşmadan /giris;
profilsiz/onaysız DOCTOR sorgusuz kapı ekranı (personel dalına DÜŞMEZ); sayım/filtre/sıralama/sayfalama iki dalda sunucuda.
· Sayfa-tarafı klinik okuma sırası: ownership → staffAccessClosed (post-op) → recordAccess(CASE_VIEW, headersMeta()) → decrypt —
/doktor/vaka/[id] ve /vaka/[caseId] JSON ucuyla aynı politikada; audit yazımı fail-safe (alarm + sayfa bozulmaz).
· Görüşme başlatmaPOST /api/cases/[id]/consult: yetki canStartConsultation (YAZMA kapısı — hasta yalnız atanmış doktorla · doktor
kendi vakası ya da kendi branş havuzunu üstlenir · koordinatör/admin yalnız atanmış) · aktif görüşme 200 · NEW/IN_REVIEW → IN_CONSULT ·
DONE/DOCS_PENDING 409 · post-op kapalı 403 · atomik updateMany (yarış 409) · CONSULT_START audit.
· Havuz = KİMLİKSİZ ÖNİZLEME (K06 1C-a, v6.287 — 👤 karar A "kod metne uyar", 2026-09-20):lib/ownership caseAccessLevel →
; YALNIZ (38 çağrı noktası — belge/DICOM/lab/kodlama/AI/FHIR/görüşme/işlem uçları —
havuz vakasında otomatik fail-closed). Aynı branştaki ATANMAMIŞ vakada doktor yalnız 'yu görür
(branş/aciliyet/ülke/dil/tarih + adı maskeli şikâyet + dosya SAYISI; ad/kimlik/telefon/belge/triyaj yanıtı/AI gerekçesi YOK —
tip sınırı + birim testi): önizleme ekranı (belge üstverisi hiç sorgulanmaz) + önizleme DTO'su;
kuyruk havuz satırı "Anonim hasta" (sayfa + ; SO OFFERED deseni). (yalnız
doğrulanmış + aktive doktor · kendi branşı · NEW/IN_REVIEW · koşullu atomik , yarış 409 · idempotent 200) →
atama → tam erişim; audit . Görüşmeyi doğrudan başlatmak da havuzu atar (personel metni A09 madde 10.1 "kabul ettiğiniz").
Önizleme de yazar (detail "kimliksiz havuz önizlemesi"). Koordinatör/yönetici/Etik Kurul klinik içerik kapısı =
(ayrı paket; kapsam envanteri 👤 onayına).
·
→ : COORDINATOR/ADMIN → (A09 10.2/10.4), ETHICS → (10.3 — yalnız anonim panel);
yine yalnız → belge/DICOM/lab/kodlama/AI/FHIR/görüşme/işlem uçları PERSONELE de fail-closed. Lojistik
görünüm (kimlik + iletişim + ülke/dil + branş/aciliyet + durum + kulvar + atanan doktor + ödeme +
turizm planı/rezervasyon + bekleyen belge ETİKETLERİ + dosya SAYISI; şikâyet/triyaj yanıtı/AI gerekçesi/belge/lab/epikriz/sağlık beyanı/
görüşme notu YOK — tip sınırı + test kilidi): koordinatör görünümü (; belge üstverisi sorgulanmaz)
Üç modül sitesi — bağımsız alan adları (v6.305, 2026-10-02) [S1+S2+S3]
İkinci Görüş, Sağlık Turizmi ve Medikal Estetik vitrinleri bu depoda SUNULMAZ: aurasecondopinion.com, auramedicaltourism.com ve auramedicalaesthetics.com adreslerinde, üç ayrı Vercel projesinde statik site olarak yaşar (21.09.2026'dan beri canlı; kaynak ve yeniden yayın yöntemi komşu vault output/aura-modul-uygulama/domain-sites/README.md; GitHub otomatik dağıtımına bağlı değildir). AURA ana sitesinde yalnız BAĞLANTI olarak geçerler: footer "Aura World" (components/aura/aura-footer.tsx), hizmet kartlarındaki "Özel Sitesi" kutuları (components/aura/care-site-links.tsx) ve iki kartın hedefi (components/aura/v2/entry-paths.tsx). Alan adı ile dokuz dilli modül adı sözlüğü src/lib/aura-modules/ altındadır (yalnız catalog.ts + copy.ts).
👤 karar (2026-10-02): AURA'da /care sayfası YOKTUR. v6.304'te (2026-09-30) eklenen /care/[module] ve [guide] rotaları, modül bileşenleri, rehber verileri, görseller, sitemap girdileri ve alan adı → /care yönlendirmeleri v6.305'te kaldırıldı; aynı içerik iki adreste yayınlanmaz. Bu depoya /care rotası ya da modül landing'i GERİ EKLENMEZ; içerik değişikliği modül sitelerinin kendi kaynağında yapılır.
Eski /care adresleri yönlendirilir (2026-10-02): v6.304'te iki buçuk gün yayında kalan 19 adres (3 vitrin + 16 rehber) kırılmasın diye next.config.tsredirects() onları KALICI (308) olarak alan adlarına taşır: /care/<modül> → alan adı kökü, /care/<modül>/<rehber> → aynı slug (alan adı sitelerinde rehberler kökte yaşar). Kural tablosu CARE_REDIRECTS; alan adları CARE_MODULE_DOMAINS içinde lib/aura-modules/catalog.ts ile sözleşmeli tekrarlanır (config @ alias'ını çözemez). Yalnız AURA deploy'unda geçerlidir; çıplak /care ve tanınmayan modül 404 kalır. Yönlendirme sayfa değildir — /care altında içerik sunulmaz. Nöbet: tests/unit/care-redirects.test.ts.
araştırma ajanı çıktısını (*-sonuc.json) küratörlü kaynağa birleştirir (v6.121). Üç sessiz hatayı kilitler: dokunulmayan kayıt kaybolmaz · yeniden adlandırılan hayalet bırakmaz · çok-branşlı satırlar eşitlenir. Kimlik koruması: ada yıl veya sondaki parantez eklenmesi reddedilir (yoksa her tur yeni satır doğar). Aggregator süzgeci: kongreuzmani/10times/waset vb. sourceUrls'ten düşer, officialUrl'e sızmışsa null'lanır. Doğrulama çıktısı gören dosyayı ATLAR
doğrulama turu hükümlerini (hukum/duzeltmeler) kaynağa işler (v6.121); doktor-yüzü alanlardan iç süreç notunu ayıklar. YALNIZ hukum taşıyan dosyayı kabul eder (merge ile iki yönlü kilit)
TTB akredite etkinlik ingest'i (v6.120: kredilendirme.ttb.dr.tr ay ay taranır — yanıt 50 kayıtta tavan yapar; test kaydı elenir; tür kod önekinden okunur [KNG/SMP/KRS…]; branş eşlemesi sözlük taramasıyla; idempotent, dry-run varsayılan)
RSS çift kayıt temizliği — iki mod (2026-10-02). MOD 1 (varsayılan; v6.307) kimlik geçişi ikizleri:1438e05 RSS externalId'yi link → guid yaptı, eski satırlar taşınmadığı için 30 Eylül gecesi dernek beslemelerindeki eski kalemler yeniden yaratıldı; aynı kaynak + AYNI URL ikizinde ESKİ satır kalır [ilk görülme tarihi + kaydetmeler], yeni ikiz silinir, eski satır guid'e anahtarlanır. MOD 2 --ayni-baslik (v6.309) tarihi değişen yazı: aynı kaynak + aynı başlık + FARKLI URL; her adres CANLI istenir ve yalnız üç kanıt sınıfında silinir — yonlendirme (bayat adres canlıya yönleniyor) · ayni-hedef (iki adres de aynı yazıya varıyor; ilk görülen kalır) · olu-adres (404/410). İki ayrı canlı yazı ve erişilemeyen adres DOKUNULMAZ ("erişilemedi" kanıt değildir); --kanit=yonlendirme,… sınıfı daraltır. İki modda ortak: SavedArticle / DailyDigest.itemsJson başvuruları kalan satıra çevrilir, AI özeti taşınır, çift başına tek transaction; karar kuralları lib/rss-twins (scanRssTwins · decideRedated); dry-run varsayılan, idempotent; --prod yalnız PROD_DATABASE_URL. Kod tarafı: ingestRss → adoptLegacyRssKey (eski link-anahtarını tanıyıp taşır) + syncRssEdition (başlık + adres birlikte değişirse eski sayı arşivlenir ve yeni sayı yeni kayıt olur; yalnız adres değişirse adres güncellenir)
Haber özeti ONARIMI — v6.316 kök neden düzeltmelerinin ESKİ satırlara uygulanması (2026-10-02; karar çekirdeği lib/summary-repair, birim testli). ADIM 1 etiket (ağ yok): Europe PMC/DOAJ özetlerinde yapışık bölüm etiketleri ("BackgroundGas…"; çevrilmiş satırda yalnız özgün metin onarılır, Türkçe giriş korunur). ADIM 2 sayfa (ağ var): sektörel satırda summary 500 karakterden uzunsa (eski fetchDocumentText sayfa-metni yazımı: başlık + gezinme menüsü + alt bilgi) kaynak sayfa yeni çıkarıcıyla (lib/document-text, yalnız makale gövdesi) yeniden okunur; gövde yoksa özet BOŞALTILIR, sayfaya ERİŞİLEMEZSE dokunulmaz (ağ hatası "içerik yok" sayılmaz; aday başına tek istek + 1,2 sn bekleme, art arda 3 düşen kaynak o koşuda atlanır). aiSummary'ye dokunulmaz; --ai-sifirla değişen satırların AI özetini null'lar (gece cron'u temiz metinle yeniden üretir). v6.319 (2026-10-03):--kaynak=klimik,tjod iki adımı o kaynaklara daraltır (kesilen koşuyu / sınırlayan kaynağı yalnız o kaynakla yeniden koşmak için); "erişilemedi" ve "atlandı" sayıları kaynak kırılımıyla basılır. Dry-run varsayılan, idempotent; --prod yalnız PROD_DATABASE_URL, yazma yalnız --yaz.
PubMed yayın tarihi onarımı (v6.85: PubMed'in pubdate/sortpubdate alanı derginin KAPAK tarihidir — sürekli-yayın dergileri makaleyi "31 Aralık"a, aylık dergiler gelecek sayıya yazar; gerçek tarih epubdate. Mevcut NewsArticle kayıtlarını esummary'den yeniden hesaplar, toplayıcının KENDİ pubDate()'iyle [tek doğruluk kaynağı]. Dry-run varsayılan · dokunulan tek alan publishedAt · idempotent · 2026-08-12'de koşuldu — dev 74/74, prod 95/95 [gelecek tarihli 92→0])
Yargıtay içtihat dolumu (v6.86): karararama.yargitay.gov.tr → NewsArticle (category=ictihat; kamuya açık, kaynağında anonim yargı kararları — PHI yok). Dry-run varsayılan; prod yalnız --prod+PROD_DATABASE_URL. ⚠️ Kaynağın belge ucunda oturum kotası (~17-31 belge/koşu) + IP hız freni (HTTP 429 / FMTY=ERROR) var → dilimli koş: aralıklarla tekrar, idempotent devam; fren görünce 10-15 dk bekle. v6.343 (2026-10-10): TEK besleme yolu budur — kaynak yurt dışı / veri merkezi IP'lerini TCP düzeyinde engelliyor (Vercel fra1 + Hetzner DE zaman aşımı; Türkiye bağlantısı 200), cron artık çekmez. Kullanıcının bilgisayarındaki haftalık Windows görevi --prod --yaz koşar; her yazma koşusu audit'e nabız satırı bırakır (CRON_MAINTENANCE / ingest-yargitay-yerel, `tarama=tam
Doktrin (TR-Dizin) dolumu/tazeleme (v6.92): hakemli makale metadata'sı → NewsArticle (category=doktrin). Tek aşamalı ve ucuz (ikinci belge isteği yok); dry-run lib ile AYNI matchesQuery ibare süzgecini koşar ("ES sonucu N · ibare-doğrulanan M" raporlar). TELİF: yalnız başlık+yazar+özet+link
Hukuk içerikleri branş-etiket backfill'i (v6.93): mevcut İçtihat+Doktrin kayıtlarının branchSlugs'ını extractBranches ile yeniden hesaplar, YALNIZ değişenleri yazar (İçtihat minHits:2 · Doktrin başlık+özet). BRANCH_PATTERNS sözlüğü değişince yeniden koşulur — idempotent, dokunulan tek alan branchSlugs
Sağlık Turizmi
✅ Tier'lı paket, dinamik fiyat, 3 kademeli sigorta (1 zorunlu · 2 operasyon teminat poliçesi [toplam fatura×oran×branş riski] · 3 malpraktis — doktorun yüklediği MMSS'inin bıraktığı boşluğu doldurur; lib/pricing.tscomputeInsurance, parametrik/endikatif) + hasta sağlık beyanı → risk çarpanı (v6.31: /paket'te hasta-only form [kronik/ilaç/sigara/ameliyat, triyaj+profil prefill'li] → computeHealthRiskMult çarpımsal-tavanlı, yalnız Katman 2/3'e; beyan Case.healthDeclarationşifreli+vaka-sabit + User.patientHealthHistory profil kopyası; personel/acente ham beyan GÖRMEZ, yalnız çarpan; prim client+server aynı fonksiyondan), lojistik Patient Journey takibi (durum+tarih+not; koordinatör yönetir, hasta görür) + hastaya teklif gönderme (link/PDF); api/ai/package-proposal (SOAP'tan AI paket teklifi) ucu v6.290'da kaldırıldı — hiçbir arayüz çağırmıyordu, fiyat motoru lib/pricing computePackage yerinde. ⚠️ Sağlık turizmi kulvarı ÖDEMESİZ (2026-07-23, kullanıcı kararı): teklif onayı ödeme/escrow İÇERMEZ — tourism bayrağıyla OfferView/ReservationView escrow bandı+split GÖSTERMEZ, buton "Teklifi Onayla", backend escrowStatus PENDING kalır (HELD yazılmaz; respond+booking route). Escrow+split Branş Doktoru kulvarındaki paket akışında yaşamaya devam eder
4
Post-Op Takip
✅ Günlük kontrol (ağrı/ateş/ilaç/foto), branş protokolü, doktor izleme + Güvenli Dijital Paylaşım (token/TTL/şifre/audit/iptal) + alıcı dilinde görüntüleme + AI foto analizi (Claude vision). v6.64-66 görsel/terminoloji turu (2026-08-04): şiddet etiketleri tıp literatürüne çekildi — Stabil · Yakın izlem · Alarm bulgusu (eski Normal/İzlemde/Kırmızı bayrak; triyaj metinleri bilinçli DEĞİŞMEDİ) · kartlar /vakalarim CaseCard anatomisiyle birebir (BranchAvatar + kulvar şeridi + sağda rozet; tema-duyarlı token'lar — sabit emerald/violet gündüz temada okunmuyordu) · 45° durum alanı: kartın sağında %15'ten başlayan tam-45° kesik (globals .postop-slant skewX tekniği; elle yüzde değil), şiddete göre yeşil/sarı/kırmızı, RED'de Doctorium temposuyla parlar (postop-alert-aura; reduced-motion'da sabit %20) · vital kutucukları: ağrı/ateş iç kutularda, renk eşikleri alarm hesabıyla TEK KAYNAK (painSeverity/feverSeverity — assessCheckIn de aynılarını kullanır) · tıklanır KPI filtreleri (RecoveryList client bileşeni; CaseQueue stat deseni; PHI çözümü sunucuda kalır)
5
Doktor Adaptasyon
✅ Self-signup (/kayit — Google/Apple[ikisi de CANLI, env-gated]/e-posta → User+Doctorverified:false, lib/doctor-signup + lib/oauth) + Doktor Ana Sayfası — pencere-tabanlı (v6.42 düzeni [Bildirim Tercihi v6.98'de /doktor/profil'e taşındı]: Eşleşen Vakalar / Uzaktan Sağlık [eski "Klinik Nöbet" penceresi; 3'lü nöbet tercihi pencere içinde "Klinik Nöbet" bölümü] / İkinci Görüş / Sağlık Turizmi / Ücretsiz Sağlık Hizmeti / Konsültasyon Talepleri [tam genişlik, alt alta]), her doktora ünvan+opt-in'e göre koşullu (lib/doctor-home.ts). v6.56–58 mobil/oturum düzeni: paneller mobilde kapalı başlar + tek-açık akordeon (DashboardPanel — başlık aç/kapa, chevron yalnız mobil, sm+ hep açık CSS'te; kardeş client adaları aura-panel-open CustomEvent'iyle koordine; başlık satırı flex-wrap — rozet dar ekranda metni ezmez); header hesap menüsü (sağda yalnız avatar+okunmamış rozeti; menüde Bildirimler [NotificationBellvariant="menu-item" + onUnreadChange; menü paneli koşullu render DEĞİL hidden — bell hep mount, 30 sn yoklama yaşar] · Profilim [nav bandından taşındı] · Finans · Tema [ThemeToggleasMenuItem; misafirde ikon en sağda] · çıkışlar); /doktor/finans — kulvar-ayrımlı hakediş sayfası (Uzaktan Sağlık · İkinci Görüş [gerçek SecondOpinionPayment'tan, teslim koşullu; PAID değilse "Ödeme bekleniyor"] · Sağlık Turizmi [⚠️ Booking split'inde doktor payı KALEMİ YOK — hastane kalemi içinde örtük; tutar uydurulmaz, rezervasyon+escrow durumu listelenir, toplam dışı] · Konsültasyon Talepleri [kümülatif answeredStatsForDoctor]); profildeki hakediş bölümü ve /doktor/konsultasyon üstündeki hakediş penceresi KALDIRILDI (tek merkez Finans). v6.55 Doctorium kimliği: nav/sayfa başlığı zümrüt AURA lockup ("Doctorium"; AuraMark tone="emerald", TONES paleti — gradient id'leri ton-başına AYRI) + sabit slogan "Bilim, sizin ritminizde." + nav'da yazı-lockup (yanıp sönen ium, doctorium-ium-breathe); BookOpen ikonu projeden tamamen çıktı. Doctorium — doktor bilgi portalı (v6.46-48): Haberler penceresi ana sayfadan ÇIKTI → üst bant linki + /doktor/doctorium (eski /doktor/haberler 308). 4 modül (lib/doctorium): Akışım (doktorun seçtiği branşlar — Doctor.newsBranches JSON slug dizisi, /doktor/doctorium/tercihler; seçim yoksa kendi branşı) · Akademik (v6.109: PubMed E-utilities + Europe PMC + DOAJ hakemli açık kaynaklar [lib/doctorium-academic-sources.ts — OPEN_ACCESS/HAS_ABSTRACT süzgeçli, preprint DIŞI; DOI/PMID çapraz-kaynak tekilleştirme, branş birleştirme]; branş→MeSH NEWS_QUERIES [açık kaynaklara meshToKeywords çevirisiyle], gerçek dergi+yazar+DOI; 1 yıllık backfill: npx tsx scripts/backfill-doctorium-academic.ts --days 365 [dev 2026-08-18: +991 kayıt, havuz 1.065]) · Sektörel & Mevzuat (T.C. Resmî Gazete günlük fihristi, sağlık anahtar kelime süzgeci — ⚠️ RG/TİTCK/SGK makine-okunur besleme YAYIMLAMIYOR, HTML kazınır; kırılgan) · Kongre Takvimi (otomatik kaynak YOK → ADMIN küratörlü /admin/kongre). Modül D (ilaç tanıtımı/e-mümessil) PARK — TİTCK tanıtım yönetmeliği + ruhsat sahibi sıfatı hukuki görüş ister. Toplama: günlük bakım cron'u (purge-deleted, Hobby cron 2/2 dolu) ingestDoctorium() çağırır → NewsArticle tablosu (~90 kayıt/gün, ölçüm 83 sn); sayfa DB'den okur, dış API'ye GİTMEZ. 2 dk klinik özet:summarizeArticleForClinician (zorlanmış tool_use) → NewsArticle.aiSummary, TEMBEL (yalnız yayın açılınca; okunmayan için AI parası ödenmez) + kaldırılamaz "klinik karar aracı değildir" uyarısı. Başlıklar EN→TR Translation önbelleğiyle (6 sn bütçe). İçerik PHI DEĞİL → şifrelenmez. v6.49 kişiselleştirme: branş tercihleri ayrı sayfa değil, modül sekmelerinin ALTINDA açılır alt menü (BranchPrefsMenu; /tercihler → yönlendirme) · Akışım'daki branş çipi tıklanır → yalnız o branş (?b=slug, singleBranchFeed; mevzuat odakta gizlenir; yalnız doktorun KENDİ akışındaki slug kabul edilir) · Sektörel geriye-dönük aralık (?d= — günlük/haftalık/aylık/6 aylık/1 yıllık; geçersiz değer 30 güne düşer) · Kongre alarmı: ⭐ takip (CongressFollow) + v6.63'te ÜÇ ayrı eşik (Doctor.congressAlertDays başlangıç · congressAbstractAlertDays bildiri son gönderim · congressEarlyBirdAlertDays erken kayıt); hatırlatma günlük bakım cron'unda (remindCongressFollows), tekrar koruması CongressFollow.sentAlerts (start/abstract/earlybird ayrı anahtar), eşik değişince sıfırlanır. ⚠️ v6.49-62'de bildiri+erken kayıt TEK eşikteydi ve "önce gelen" gönderilince öbürü SUSUYORDU (gerçek kayıp riski) — migration eski değeri iki yeni alana kopyalar. v6.50 — 6 MODÜL + gerçek sektörel kaynaklar: Mevzuat ile Sektörel AYRILDI, İlaç & Cihaz eklendi (DOCTORIUM_MODULES sırası v6.51 kullanıcı kararı: akis · akademik · sektorel · ilac · kongre · mevzuat EN SONDA) + 6 sektörel kategori (SECTOR_CATEGORIES: mevzuat · sut · turizm · yonetim · teknoloji · ilac-cihaz; NewsArticle.category). Akışım artık akademikten ibaret DEĞİL — mevzuat/sektörel/ilaç kalemleri branş ayrımı olmaksızın akışa girer. Kaynak matrisi (lib/doctorium-sources.ts, hepsi 2026-08-01'de ölçüldü): ✅ Resmî Gazete (günlük + 1 yıl geriye backfill: scripts/backfill-gazette.ts, 3.482 kalem→125 kayıt) · ✅ OHSAD (SUT/geri ödeme/mevzuat aktarımı; v6.157'den beri SGK-aktarımı kalemleri SGK_RELAY ile SÜZÜLÜR — tek duyuru tek kaynaktan) · ✅ SGK — GSS GM duyuruları (v6.157 ingestSgkGss: SGK v3 sitesi 2026-08-24'te yeniden ölçüldü, /Duyuru/Index SUNUCU-render [eski "JS yüklüyor" hükmü bayattı]; YALNIZ Genel Sağlık Sigortası GM — birim sayfası menüden damgalı slug'la taze çözülür; ✅ v6.164 — Vercel'den erişim 2026-08-26'da ÖLÇÜLDÜ — SORUNSUZ [RG/OHSAD sınıfı IP engeli YOK, günlük cron kendiliğinden yazıyor]; 6+ aylık geçmiş backfill'i de ingest-tr-sources.ts --sgk-sayfa=N'e eklendi [?page=N ile GSS birim sayfası geriye sayfalanır, varsayılan 7 sayfa ≈7-8 ay; ilk koşu prod'da 60 yeni kayıt yazdı, toplam 70]. v6.165 — Akışım sektörel resmi-kaynak payı (2026-08-26): SGK/TTB/OHSAD günlük onlarca haber üreten medicalxpress/medscape'in gerisinde kalıp Akışım'da pratikte hiç görünmüyordu (SGK'nın en yeni kaydı 344 kayıtlık havuzda #114. sıradaydı) → Akışım'ın ilk sayfasında sektörel kotanın (8 slot) içinde her resmi kaynaktan (varsa) en yeni 1 kart garantilenir, kalan slotlar normal sıralamayla dolar; sonraki sayfalar normal davranışa döner. Cursor bütünlüğü kaynak-başına ayrı sorgu + zincirlenen excludeIds ile sağlandı — PROD'a karşı sektörel havuzun tamamı (344 kayıt) sıfır tekrar/kayıpla doğrulandı) · ✅ TTB (doktor özlük) · ✅ openFDA drug+device/enforcement (geri çekme) · ✅ ClinicalTrials.gov v2 (faz/lansman) · ✅ WHO RSS · ❌ EMA/TİTCK/SGK/AA (besleme YOK → uydurma içerik üretilmez). Dijital prospektüs:/api/doctorium/prospektus → openFDA drug/label; ⚠️ ABD verisi — "FDA (ABD) onaylı ürün bilgisidir, Türkiye KÜB/KT farklı olabilir" uyarısı KALDIRILAMAZ ve metin ÇEVRİLMEZ (dozaj hatası riski). 🪤 Kazıma tuzakları: RG ARŞİVİ windows-1254 / ANA SAYFA utf-8 (karıştırınca 93 bozuk karakter + filtre sessizleşiyor) · anahtar kelime kelime başında aranır, yoksa "aşı" → "t·aşı·ma" eşleşip BOTAŞ petrol ilanları ilaç kategorisine düşüyor · veteriner/gıda/petrol/enerji dışlama listesi · ops aracı scripts/ingest-doctorium.ts. v6.51 mevzuat özeti: fihrist yalnız BAŞLIK verdiği için detay sayfası boş görünüyordu → ensureRegulationSummary TEMBEL iki aşamalı: (1) kaynak belgenin metni çekilir (fetchDocumentText; 🪤 RG /eskiler/ belgeleri de windows-1254) ve summary'ye yazılır, (2) summarizeRegulationForClinician (zorlanmış tool_use) → Doktor özeti + Aksiyon maddeleri + Kimi etkiliyor + Yürürlük (aiSummary). İlk açılış ~13 sn, sonraki 0,3 sn. ⚠️ "hukuki görüş değildir, bağlayıcı olan resmî metindir" uyarısı KALDIRILAMAZ. PDF kaynakta metin çıkarımı YOK → özet üretilmez, arayüz bunu açıkça söyler (uydurmaz). v6.52-54: tüm ayarlar TEK "Özelleştir" penceresinde (DoctoriumFilters: aralık · kategori · kongre alarmı · branş tercihleri) — bölüm yoksa düğme hiç çizilmez; branş tercihi yalnız akışa etki eden sekmelerde (Akışım + Akademik). doktor→doktor süpürmesi yapıldı — ⛔ arama anahtarları (HEALTH_KEYWORDS/CATEGORY_RULES içindeki "doktor", "diş doktor", "asistan doktor") ve rota adları (/doktorlar, /admin/doktor-onay) BİLİNÇLİ DEĞİŞMEDİ: resmî metinler o kelimeyi kullanıyor, değiştirmek mevzuat filtresini kırardı. TR kaynak erişimi — teşhis TAMAMLANDI (v6.57-60, 2026-08-03): tek "fetch failed" perdesinin altından ÜÇ ayrı hastalık çıktı (describeFetchErrorerror.cause zincirini kazıyor): TTB = eksik TLS ara sertifikası → ÇÖZÜLDÜ (lib/ttb-ca.ts Sectigo ara sertifikası + httpsGetWithCa; prod cron'da 45 tarandı/21 yazıldı) · Resmî Gazete = UND_ERR_CONNECT_TIMEOUT, TCP el sıkışması hiç kurulmuyor (veri-merkezi IP aralığı DROP) · OHSAD = Cloudflare 403, gerçekçi Chrome başlıkları YETMEDİ (IP itibarı). Son ikisi Vercel'den yapısal olarak erişilemez → yerelden besleme (scripts/ingest-tr-sources.ts, kullanıcı kararı): dry-run varsayılan, prod yalnız --prod+PROD_DATABASE_URL, AURA_DB_GUARD kalıcı gevşetilmez. v6.62 (4e4ae68) — özet zinciri tamam: script boş summary'li RG/OHSAD kayıtlarının resmî metnini de yerelden doldurur (tembel özetin metin-çekme adımı Vercel'de daima düşüyordu → metin DB'de hazırsa yalnız AI adımı orada koşar) + fetchDocumentText TTB'de özel-CA istemcisine geçti (v6.59 onarımı yalnız fihristteydi — sektörel TTB özetleri artık üretilebilir). İlk prod besleme 2026-08-04: RG 8 kalem + 7 metin (30 gün; RG'nin ~%3'ü sağlık çıkıyor); OHSAD origin'i o saatte yanıtsızdı (IP engeli değil) — idempotent koşu tamamlar. Tazelik yerel koşuya bağlı: haftalık npx tsx scripts/ingest-tr-sources.ts --prod --yaz (ritim 2026-08-14'te kuruldu; son-koşu tarihi vault todo "Doctorium — İşletim Ritmi" kaleminde izlenir). v6.94 (2026-08-14) — RG TLS onarımı: RG sunucusu ara sertifikayı zincirde sunmaz oldu (leaf-only; leaf CN=*.tccb.gov.tr, eksik halka "GeoTrust TLS RSA CA G1") → yerel koşu bile UNABLE_TO_VERIFY_LEAF_SIGNATURE verir olmuştu; TTB deseniyle onarıldı — lib/rg-ca.ts (AIA'dan PEM + yenileme runbook'u) + üç RG yolu (fetchGazetteArchive · fetchGazetteToday · fetchDocumentText RG dalı) özel-CA istemcisi httpsGetWithCa'da (referer + ham-bayt desteği eklendi; windows-1254 decode'u çağıranda). ⏰ RG leaf'i 2026-08-28'de doluyor — yenilemede farklı ara sertifikaya geçilirse aynı hata döner; PEM, rg-ca.ts başlığındaki runbook'la değiştirilir. İlk gerçek prod beslemesi 2026-08-14: RG 3 + OHSAD 19 (0 hata). v6.86 — HUKUK bölümü (2026-08-11, kullanıcı kararı): "Mevzuat" modülünün kullanıcı-yüzü adı "Hukuk" oldu (iç anahtar mevzuat DEĞİŞMEDİ — migration'sız dönüşüm; DB, akış sorguları, URL'ler kırılmaz); ?h= alt-sekmeleri Mevzuat · İçtihat (+ sekme-üstü <details> tanıtım bloğu: bölümlerin içeriği ve kullanımı; Doktrin v6.92'de gerçek içerikle AÇILDI — aşağıya bak). İçtihat = Yargıtay Karar Arama'dan idempotent toplama (lib/hukuk-ingest.ts; tırnaklı 7 sorgu — tırnaksız çok-kelime GEVŞEK eşleşir [54k gürültü]; resmî/belgeli API DEĞİL, sözleşme 2026-08-06 canlı ölçümü; tarih filtresi sunucuda İŞLEMİYOR → artımlılık (source, externalId) idempotenciyle; kararlar kaynakta anonim, yayın dayanağı FSEK m.31). Anahtar kelime sistemi TAMAMEN DETERMİNİSTİK (AI YOK — kullanıcı kararı):lib/hukuk-keywords.ts 16 terimlik sözlük (tek dosya, hukukçu düzenler; çok geniş tek kelime EKLENMEZ) + kanun-maddesi çıkarımı ("6098 sayılı … Kanunu'nun 49" ve "TCK'nın 85/1" biçimleri; temyiz USUL maddeleri [HMK 366-373 vb.] çip olmaz — her kararda geçen onama kalıbı gürültüsü) + kart alıntısı (öncelik: Suç/Hüküm satırları > "Uyuşmazlık, … ilişkindir." > I. DAVA bölümü). İçtihat UI: ?k= çip filtresi (metin-içi ILIKE, paylaşılabilir URL) · kartta alıntı+kanun+terim çipleri · detayda TAM karar metni (hukuki metin kesilmez) + kaldırılamaz "hukuki mütalaa değildir / E.-K. ile resmî sistemden doğrulayın" bandı · url null (SPA kaynakta derin link yok) · mevzuat AI-özet akışına GİRMEZ. 🪤 Saha frenleri (2026-08-11 ilk dolum): ~20 istekte HTTP 429 → GAP_MS=2500+65sn soğuma-retry · belge ucu oturum kotası ~17-31/koşu → 30sn timeout + ardışık-3-hata kuralı (tekil hata atlanır) · uzun IP freni FMTY=ERROR → 10-15 dk bekle; ilk dolum scripts/ingest-yargitay.ts ile dilimli (prod arşiv: 492 karar). v6.92 — DOKTRİN AÇILDI (2026-08-13): üçüncü alt-sekme gerçek içerikle yayında — TR-Dizin hakemli makale akışı (lib/doktrin-ingest.ts; DergiPark araması bot-doğrulamalı KAZINAMAZ, OAI'de konu-araması yok → fizibilite kararı TR-Dizin; tek aşamalı — metadata arama yanıtında tam gelir, ikinci belge isteği yok; ⚠️ order paramı ZORUNLU ve searchUrl() içinde sabit [yokluğu sunucuda json_parse_exception]; TR öncelikli başlık/özet; DOI varsa doi.org yoksa TR-Dizin detay sayfası). TELİF sınırı veri modelinde: yalnız başlık+yazar+ÖZET+link (dizinin herkese açık metadata'sı) — tam metin/PDF ASLA (makalelerde FSEK m.31 serbestisi yok); kart/detay daima yayıncıya link verir, detayda telif bandı + "Özet (TR-Dizin)". 🪤 ES q GEVŞEK skorlar ("sağlık hukuku" → alakasız makaleler) ve tırnaklı sorgu SUNUCUYU KIRAR (failed to parse [must]) → istemci-taraflı tam-ibare doğrulamasımatchesQuery (505 ES sonucu → 192 gerçekten ilgili; prod dolu). Cron sorgu başına İLK sayfayı tarar; ilk dolum/tazeleme scripts/ingest-doktrin.ts. v6.93 — ÇOK-BRANŞ ETİKETİ (2026-08-14, kullanıcı isteği): İçtihat+Doktrin içerikleri branşlara etiketlenir — bir içerik birden çok branş alabilir (branchSlugs dizi; kart çipleri + Akışım eşleşmesi otomatik). Deterministik: lib/hukuk-keywords.ts BRANCH_PATTERNS (30 branşın tamamı, elle desenler; slug'lar triage BRANCHES ile sözleşme-testli) + extractBranches (⚠️ aşırı geniş tek kelimeler bilinçli desen DEĞİL: "doğum" [her kararda "doğum tarihi"], "göz", "kanser", "bebek" ["tüp bebek" IVF'tir]; İçtihat'ta minHits:2 — uzun metinde tek yan-cümle geçişi topikal sayılmaz). Eski kayıtlar scripts/backfill-hukuk-brans.ts ile etiketlendi (prod: 492 karardan 284'ü — kadın-doğum 80 · estetik 37 · genel cerrahi 30; Doktrin 192/192); desen sözlüğü değişince yeniden koşulabilir (idempotent, dokunulan tek alan branchSlugs). v6.87 — İKİ AŞAMALI GİRİŞ (2026-08-11): doktor üyeliği iki aşamaya ayrıldı. Aşama 1 (Doctorium üyeliği): 🔄 v6.124 SÜPERSEDE — tek kapı e-DEVLET DOĞRULAMALI DİPLOMA (Doctor.diplomaVerifiedAt; DIPLOMA belgesi ACCEPTED olunca damgalanır · öğrenci yolu studentVerifiedAt sürer). Kapı doctorium/layout.tsx segment bekçisidir ([id]/oduller dahil TÜM alt rotalar — eski "URL bilen onboardsuz doktor girer" boşluğu kapandı; mevcut aktif doktorlar backfill'siz geçer). v6.212 (2026-09-03): eski üyelik-yazısı yolunun kalıntıları (kolon + etiketler + satırlar) koddan ve şemadan TAMAMEN kaldırıldı (migration 20260903140000_drop_chamber_letter, kod-önce; Blob'lar scripts/purge-chamber-docs.ts ile önce imha). Aşama-1 ekranında iki isteğe bağlı rıza (Stage1Doctorium; kartta özet + <details> TAM metin): sponsor kişiselleştirmesi (mevcut SPONSOR_TARGETING öne çekildi; GÖSTERİM onayı bilinçli eklenmedi) + İK iletişim onamı (lib/hr-consent.ts — HR_CONTACT/_REVOKE zinciri + hrContactOptInAt damgası; metin ⚖️ TASLAK; İK modülü henüz yok, onam şimdiden birikir). Aşama 2 (klinik havuz): gereksinimler AYNEN (diploma+MMSS+işlem+qualification → activatedAt); belge tipi listesi KAPALI (birim test kilidi, bire bir). v6.105 (2026-08-17) — AŞAMA = MARKA + ÜÇ AŞAMA + PANEL TERCİHLERİ: aşama adları markalaştı (Aşama 1 = Doctorium Üyeliği · Aşama 2 = AURA Üyeliği, eski ad "klinik havuz") ve /doktor/baslangic üç aşamaya çıktı — Aşama 3 = Tercihler (beş panel, yeknesak "… Paneli" adlandırması: Uzaktan Sağlık [duty, DAİMA açık/StatusCard] · İkinci Görüş · Sağlık Turizmi · Ücretsiz Sağlık Hizmeti · Konsültasyon Talepleri). ⚠️ MMSS aktivasyon şartından ÇIKTI ("şimdilik", kullanıcı kararı): REQUIRED_DOC_TYPES=["DIPLOMA"], canActivate artık mmssComplete ARAMAZ → tek zorunlu mesleki belge tıp diploması; MMSS kartı/formu İHTİYARİ durur ve teminat limiti /paket M3 Katman-3 primini beslemeye devam eder (geri alma tek satır — imzalardaki _mmss bilinçli korundu). ⚠️ Panel görünürlüğü tercihe bağlandı (Doctor.soOptIn + tourismOptIn, migration 20260817180000): önce so=ünvanla otomatik / tourism=koşulsuz açıktı, artık so = soEligible(title) && soOptIn · tourism = tourismOptIn. REGRESYON KORUMASI: kolonlar DEFAULT false ama migration MEVCUT satırları true damgalar (prod 35/35) — havuzdaki doktorlar panelini kaybetmez; soOptIn ünvan kapısını AŞMAZ (damga herkeste true olduğu için kritik → tests/unit/doctor-panels.test.ts kilidi, panelVisibility'nin ilk testi). DoctorPanelFields'e iki alan ZORUNLU (select'e koymayan çağıran derlemede kırılır). Aşama 1 doktorunun kromu Doctorium'a ait: nav bandı boş (navItemsFor {stage1}), hesap menüsünde Profilim/Finans yok, marka toggle'ının AURA yarısı her yerde soluk+pasif — tetikleyici KAYNAK değil DURUM (!activatedAt), Aşama 2 bitince krom kendiliğinden AURA'ya döner; yükseltme yolu korundu (soluk AURA → /doktor?from=doctorium → ?from=aura-gecis uyarı ekranı). /api/doctor/academic KISMİ güncellemeye çevrildi — akademik form iki bağımsız kutuya bölündüğü için (AcademicEducationBox Mesleki Belgeler'in içinde, CertificatesBox kendi başlığı altında; eski AcademicEditor export'u geriye uyumlu sarmalayıcı, /doktor/profil dokunulmadı) ayrı kaydet düğmeleri var; uç eskiden gövdedeki TÜM alanları koşulsuz yazıyordu → sertifika kaydı licenseNo/specBoard'ı null yapıp hesabı SESSİZCE deaktive ederdi. Artık yalnız gövdede geçen alan yazılır (if ("alan" in b)). Sayfa düzeni: almaşık tam-genişlik bant AÇIK→KOYU→AÇIK (sabit renk değil theme-* SINIFI — --c-* kalıtsal olduğundan kutular ve semantik tonlar kendiliğinden uyar); Aşama 2 sırası Mesleki Belgeler [Tıp Diploması → Akademik & Eğitim → MMSS] → Sertifikalar ve Akademik Çalışmalar → Yaptığım İşlemler. Marka:AuraWordmark — AURA metin içinde yazıyla değil LOGOYLA yazılır (wordmark PNG'si CSS maskesi, arkasına marka turkuazı #28C8D8; currentColor KULLANILMAZ) 🪤 Doctorium lockup'ı JSX'te SATIR KIRILMAZ (araya düşen satır sonu boşluğa dönüşüp "Doctor ium" çizer). /kayitta iki-aşama özet kartı + public /kayit/asamalar açıklama sayfası. OAuth kimlik boşluğu kapandı: Google/Apple yalnız ad+e-posta verir, hesap branch:""/city:"" açılıyordu ve hiçbir ekran doldurtmuyordu → yeni /doktor/profil-tamamla ara sayfası (POST /api/doctor/complete-profile) + üç katmanlı bekçi: callback yönlendirmesi → baslangic bekçisi (branch/city boşsa ara sayfaya; ?from=doctorium taşınır) → finish kapısı (missingOnboardingStepse Branş+Şehir). Migration 20260811090000 (iki nullable kolon, idempotent). v6.88 — Anket ÖDÜL PUANLARI (2026-08-12): anketler puan kazandırır (Survey.points, admin belirler; tüm türlerde) → yanıtla AYNI transaction'da PointEntryledger'ına yazılır (bakiye kolonu YOK — bakiye=SUM(delta); satır güncellenmez/silinmez, ret-iptal İADE SATIRI üretir; @@unique(doctorId,surveyId) çift puanı DB'de keser) → doktor /doktor/doctorium/oduller "Puanlarım"da biriktirir (başlıkta bakiyeli rozet; sayfa v6.87 segment-layout kapısı ALTINDA) → katalogdan talep eder (RewardItem: Yurt içi kongre · Uluslararası kongre · Tıbbi kitap; RewardRedemption REQUESTED→APPROVED→FULFILLED daima insan onaylı, doktor yalnız REQUESTED'ını iptal eder; puan talep ANINDA rezerve düşer — çifte-harcama pg_advisory_xact_lock ile serili, ⚠️ $executeRaw şart [$queryRaw void'de P2010]). Admin: /admin/oduller (katalog + talep kuyruğu; kalem girişi öncesi ⚖️ ayni-menfaat uyarısı [vergi + 657 kamu doktoru] kaldırılamaz) + /admin/anket formunda puan alanı. Katalog BOŞ başlar — doktor "yakında" görür, vaat ilk kalemle başlar (👤 hukuki değerlendirme sonrası). Puan ≠ nakit: parasal değer atfedilmez ("1 puan = ₺X" hiçbir yüzeyde yok), koşul metni TASLAK etiketli/kaldırılamaz; nakit honorarium ACTIVE-kilidi bu sistemden BAĞIMSIZ sürer. API: GET /api/rewards · POST/PATCH /api/rewards/redeem · /api/admin/rewards (+/redemptions) — hepsi self-auth. v6.95 — TIP ÖĞRENCİSİ ÜYELİĞİ (2026-08-14, kullanıcı kararı): üçüncü Aşama-1 damgası — e-Devlet öğrenci belgesi (STUDENT_CERT, tekil) yüklenince Doctor.studentVerifiedAtOTOMATİK damgalanır; Doctorium kapısı diplomaVerifiedAt ∨ studentVerifiedAt (∧ ¬doctoriumOptOutAt; hasDoctoriumAccess alanları ZORUNLU tutar — eksik select derlemede kırılır, deletionLockedAt deseni). Ayrı huni:/ogrenci (giriş+kayıt; vitrin footer'ında 9 dilde link) → /api/auth/signup-student (unvan/telefon/dil sorulmaz; title sabit STUDENT_TITLE "Tıp Öğr." — DOCTOR_TITLES'ta DEĞİL, test kilidi; HealthTürkiye dizin doğrulaması ATLANIR — öğrenci dizinde olmaz, yanlış NOT_FOUND bayrağı üretilmez) → hesap Doctor.studentTrack:true doğar → /doktor/baslangicöğrenci modu: yalnız StudentStage1Card (diploma/MMSS/rıza blokları HİÇ render edilmez) + "Mezun oldum" çıkışı (POST /api/doctor/graduate — studentTrack:false; yetki AÇMAZ, yalnız onboarding modu değişir). Pazarlama süzgeci isStudentOnly (damga ∧ ¬aktivasyon; öğrenci sağlık meslek mensubu DEĞİLDİR — meslek-mensubuna-tanıtım rejimi ona uygulanamaz): sponsor kartı + anket (COMMUNITY dahil) + ödül puanı rozeti ÇİZİLMEZ, survey/respond + rewards/redeem403 (talep İPTALİ [PATCH] bilinçli açık — rezerve puan iadesi hak), /oduller akışa redirect. Sade krom:navItemsFor {student} → üst bant yalnız Doctorium; hesap menüsünde Profilim/Finans gizli; mono rol etiketi "Tıp Öğrencisi". .edu.tr/.edu/.ac.xx e-posta yalnız ROZET (isEduEmail — kapı açmaz; kanıt daima belge). Klinik kapılar (activatedAt) ve v6.90 ters-yön kesikleri DEĞİŞMEDİ. Migration'lar 20260814150000 + 20260814170000 (idempotent, IF NOT EXISTS). Mezuniyette diploma+MMSS ile aynı hesaptan doktor üyeliğine geçilir (süzgeç kendiliğinden kalkar; öğrenci belgesi Aşama-2 listesine sızmaz). v6.97 — DOCTORIUM ÇALIŞMA ALANI (2026-08-14, 6 turlu kullanıcı-onaylı görsel oturum): Doctorium "sekmeli sayfa"dan sol bantlı çalışma alanına dönüştü. Sol bantDoctoriumSidebar + DoctoriumShell (SERVER component — ilk deneme layout'ta useSearchParams'lı client banttı, Next 16'da Suspense $RC tamamlanma sinyali hiç gelmedi ve bant div[hidden]'da asılı kaldı; aktifliği zaten bilen page'ler Shell'i kurar, layout kapı-only kaldı): viewport soluna fixed, gruplu (BİLGİ/MESLEĞİM/KİŞİSEL — grup başlıkları tıklanmaz), modül-renkli aktiflik (3px şerit+%10 dolgu, Cover deseni), 15px punto; içerik md:pl-[max(13.25rem,calc((100vw-64rem)/2))] ile /doktor hizasında (dar ekranda bant payına düşer); mobil M2 alt çubuk (Akışım·Bilgi·Mesleğim·Kayıtlı·Puanlarım) + page'de grup şeridi. Bölüm renk/sembol kararları: Akışım kıvılcım/sarı #facc15 · Akademik şişe/zümrüt (branş rengi kartlarda KALKTI — tüm akademik yeşil) · Sektörel bina/mor · İlaç hap/camgöbeği · Kongre takvim/tema-duyarlı ink · Kariyer yükseliş/mavi #60a5fa · Hukuk gül#fb7185; amber yalnız ticaretin işareti; sembol takası: terazi=mevzuat · çekiç=içtihat ([id] "Doktor özeti" başlığı ScrollText'e geçti; Etik Kurul/DecisionForm çekiçleri karar bağlamında KALDI). Krom katmanı--c-chrome (Header cam-mix'i + SiteFooter + bant; gece #08090b / gündüz #E7ECEB — v6.133'te mineral griye geçti, eski #eaede8; Doctorium Üst Rafı bunu "Derin Orman %12" formülünde TABAN alır → chrome değişince raf zemini birlikte kayar) + html{scrollbar-gutter:stable} (kısa sayfalarda [Post-Op/Sistem Mesajları/Profilim] scrollbar kaybolunca ortalı blok kayıyordu — sekme geçişi "oynaması"nın kökü) + /doktor·Post-Op·Doctorium genişlikleri 5xl'de eşitlendi (takip 4xl→5xl; "daralıp açılma" hissinin diğer yarısı). Modül üst alanları (mono etiket [modül renginde] + 30px display başlık + tek satır açıklama; metinler kullanıcı onaylı: "Sizin için seçilenler" · "Branşınızda hakemli yayınlar" · "Sağlık gündeminin nabzı" · "Geri çekmeler ve klinik fazlar" · "Kongre takvimi" · "Doktorluk yollarının haritası" · "Sağlık hukuku, tek yerde") — v6.48 pill nav + Puanlarım pill'i KALKTI. KART STANDARDI (ArticleCard.tsx'e taşındı — Kaydettiklerim de aynı kartı kullanır; Post-Op kartı birebir örnek): 112px kapak bölmesi YOK — kartın sol kenarında 3px BÖLÜM şeridi + üst satırda küçük sembol+bölüm etiketi (sağ üstte Kaydet) + altında tür rozeti (KIND_LABEL) ve keyword'ler (kategori+branş çipleri; içtihat kanun/terim çipleri) + başlık/alt-başlıklar (kaynak·tarih) + hairline çizgi + tür-uygun linkler ("Detay" jeneriği YOK: "2 dk klinik özet" · "Kararı oku →" · "Kongre kartı →" · "Süreç adımları →" · "Devamını oku →" + "kaynağı aç"); sponsor + sponsorlu-anket TÜM ÇEVRE kalın amber (border-2 border-amber-400/70; kapakları da kalktı), topluluk anketi gök şeritli standart kutu; Kongre/Kariyer bölüm listeleri de aynı anatomide (kongrede Kaydet, Takip'in yanında). KAYDETTİKLERİM:SavedArticle (CongressFollow deseni — ilişkisiz düz id, @@unique(doctorId,articleId); migration 20260814210000) — ÜÇ KAYNAKLI kaydetme: makale id · kongre id · kariyer SLUG (POST /api/doctorium/save üç tabloda doğrular; savedFeed üç kaynaktan birleştirir, silinen kaynak sessizce atlanır) + SaveButton (optimistic toggle) + /doktor/doctorium/kaydettiklerim + bantta KİŞİSEL'in İLK sırası; puan ÜRETMEZ; öğrenci-sınırlı üye de kaydedebilir (içerik işlevi — pazarlama yüzeyi değil). AKIŞ TERCİHLERİ:Doctor.feedModules (nullable; null/boş=TÜMÜ; migration 20260814213000) + POST /api/doctor/feed-modules (bölüm anahtarları süzülür; TÜMÜ seçiliyse null yazılır — bölüm listesi büyürse eski kayıt yenisini otomatik görür). v6.132: Hukuk ÜÇE ayrıldı (hukuk-mevzuat · hukuk-ictihat · hukuk-doktrin; toplam 8 anahtar) — şema DEĞİŞMEDİ, feedModules zaten JSON dizi; eski tek mevzuat anahtarı okunurken üçe genişletilir (parseFeedModules), yoksa mevcut doktorlar içtihat ve doktrini sessizce kaybederdi. Tercihler artık /doktor/doctorium/tercihler sayfasında (v6.49'dan beri yönlendiren iskelet gerçek sayfa oldu): katlanır liste, Klinik/Mesleki iki grup + altı bölüm, Hukuk'un üç alt kaynağı ayrı anahtar; branş tercihleri, etkinlik alarmları, tür + kapsam tercihi (Doctor.congressEventTypes · Doctor.congressScope, migration 20260820020000; URL ?t=/?s= tercihi YALNIZ kendi ekseninde ezer, tercihi değiştirmez) ve sponsor rızası orada. ⚠️ Sekme içindeki Özelleştir paneli artık YALNIZ görünüm süzgeci taşır (aralık · kategori · kaynak kapsamı) — aynı ayar iki ekranda yaşamaz (v6.49 dersi). Akış = BÖLÜM-KOTALI KARIŞIM (personalFeed yeniden yazıldı): eski tek "en yeni 40" sorgusu yoğun sektörel/haber akışının altında hukuku (hele ARŞİV tarihli içtihat/doktrini) TAMAMEN boğuyordu → her seçili bölümden kendi kotası (akademik 14 [branş-eşleşmeli] · sektörel 8 · ilaç 6 · hukuk 4+2+2 kind-alt-kotalı · kongre 3 · kariyer 3), tek listede tarihe göre birleşir; kongre/kariyer akışa normal KART olarak girer (createdAt ile — startDate gelecek tarihli tepeyi işgal ederdi; kariyer kartı id=slug, kartlar kendi detay rotalarına). Bant "Tercihler" öğesi ÇİZİLMEZ (/tercihler v6.49'dan beri redirect — koşullu-href ilkesi). v6.98 PROFİL YENİDEN DÜZENİ + MEDYA: Bildirim Tercihi Ana Sayfa kartından /doktor/profil bölümüne taşındı (sıra: Eşleştirme Kalite Skoru [varsayılan-KAPALI <details> akordeonu — chevron'da açılınca sönen ışıma, Doz 1 bilinçli istisna] → Bildirim Tercihi → Profil Tercihleri → Yaptığım İşlemler; 5 kutu başlığı mono-etiketten aura-display 17px h2'ye — onboarding'deki ProcedureSelector/AcademicEditor de aynı görünümü alır). Profil Tercihleri YENİ içerik: Profil Resmi (≤5MB) + Video Kart (URL VEYA dosya; ≤60 sn İSTEMCİ-doğrulamalı [sunucu süre ölçemez — gerçek tavan 50MB] ) + Hakkımda (2000 kr → vitrin richBio kaynağı) + Birim katılımı KORUNDU; dil/pazar/kapasite düzenleme YÜZEYİ kalktı (/api/doctor/preferences KISMİ güncellemeli — yalnız gövdede gelen alan yazılır, geriye-uyumlu). Medya = @vercel/blob client-upload:POST /api/doctor/media-upload token bekçisi (4.5MB fonksiyon gövde limiti nedeniyle tarayıcı→Blob DOĞRUDAN; public store — profil medyası PHI DEĞİL, klinik belgeler lib/storage.ts şifreli private'ta kalır); medya değişiminde eski blob silinir; CSP dar genişletme (connect-src vercel.com + *.blob.vercel-storage.com; img/media-src blob storage). Doctor.introVideo (migration 20260814230000; ⚠️ şema satırı paylaşımlı-dosya kazasıyla v6.97 commit'ine karışmıştı — kolon prod'a o deploy'la gitti, migration dosyası v6.98'de tarihçeye girdi). Hero'da yüklenen foto baş harf avatarının yerine geçer. v6.99 — AKIŞ DİSİPLİNİ + GÖRSEL KATMAN (2026-08-15/16, çok turlu kullanıcı-onaylı oturum): (1) Doktrin hukuk süzgecilib/doktrin-filter.ts — konuma duyarlı skor (başlık+3 · keyword+2 · özet+1 · hukuk-dergisi+3; özetteki rutin "onam alındı/etik kurul" kalıbı özet kanalını SUSTURUR [kirliliğin kökü buydu — matchesQuery ibareyi özette buluyordu]; tıp bağlamı şart, veteriner kesin dışlanır; desenler KÖK biçimde ["tıbbi uygulama hata"] + EN karşılıkları); arşiv temizliği scripts/temizle-doktrin.ts (dry-run varsayılan) — dev+prod 57'şer kayıt silindi → 135'er hukuk-odaklı. (2) Akademik seçkin-dergi katmanılib/academic-journals.ts — 113 dergilik küratörlü beyaz-liste (hepsi PubMed [ta] doğrulamalı; ⚠️ NLM "core clinical journals"[sb] ÖLÜ — 0 sonuç) + kanıt tipleri (RCT/meta/sistematik/çok-merkezli/rehber; editöryel-mektup dışlanır); katman 1 eksik kalırsa katman 2 (kanıt-only) tamamlar — 30 branşın 29'unda K1 dolu. (3) Sektörel "doktor haberleri": İstanbul Tabip Odası (🪤 /haberler JS-boş — sayfanın kendi Ajax ucu views/haber/gethaber.view.php POST Limit) + Medscape + Medical Xpress (ingestRss; 🪤 Medscape tarayıcı-UA'lı Node isteğine 403, BAŞLIKSIZA 200 [OHSAD dersinin tersi] → 403/429'da başlıksız yeniden dener) — hepsi isProfessionallyRelevant süzgecinden (reklam/advertorial + tüketici içeriği + kurum-içi etkinlik gürültüsü elenir); kategoriler 6→8 (meslek + kuresel; WHO teknoloji→kuresel) + Özelleştir'de Kaynak filtresi (?s= ulusal/uluslararası; SECTOR_SOURCE_SCOPES ingest kaynak setiyle sözleşme-testli) + branş bölümünde menekşe "Tüm branşları seç". (4) Haber detayında kaynak görseli:NewsArticle.imageUrl (migration 20260816100000; hotlink + kaldırılamaz "GÖRSEL: {kaynak} — KAYNAĞA AİTTİR" atfı — next/image bilinçli değil [optimizasyon=kopya]; çıkarım TEMBEL yalnız yeni kayıtta: RSS media → og:image; TTB özel-CA yolu dahil) — NEWS_IMAGE_HOSTS allowlist ↔ CSP img-src dar genişleme SÖZLEŞME-testli; yalnız ULUSAL kaynak fotoğrafı gösterilir, uluslararasıda (Getty/thumbnail kalitesizliği) kaynak LOGOSU bandı: Medscape (siyah-yazılı logo → BEYAZ plaka) · MedicalXpress · WHO (sitenin kendi h-logo-white.svg'si) + künye şeridinde açık URL. (5) Kapak/band katmanı CoverArt.tsx: kart 72px koyu plaka — akademik+branşlı içerik lucide BRANŞ İKONU (components/branch-icons.tsx — BranchAvatar setiyle TEK kaynak; üç netleştirme turu sonrası kullanıcı kararı), diğer bölümler Higgsfield sembol webp'leri (public/doctorium/; stil referansı kardiyoloji branş sembolü; kongre=tıp-artılı takvim, ilaç=tek kapsül [sade — "küçülünce anlam kaybı" ilkesi]); detay bandı öncelik: kaynak logosu → hukuk yassı bandı (mevzuat=terazi+§ · içtihat=tokmak+yankı halkaları · doktrin=kitap+sütun; letterbox üretim + içerik-kırpma ~4.2-5.4:1; 🪤 sabit 120px kutu+object-cover bandı KIRPIP büyütüyordu → w-full h-auto; 🪤 stil referansından MOTİF sızabilir [ilk mevzuat bandına kardiyoloji kalbi girdi — gözle yakala]) → branş ikonu → modül sembolü. TEMA: koyu zemin webp'lere gömülü → public/doctorium/light/ gündüz varyantları (zemin şeffaf + çizgi %48 koyulaştırma) ve seçimi CSS yapar ([.theme-light_&] — 🪤 SUNUCUDA cookie okumak YANLIŞTI: ThemeToggle yalnız html class'ını anında değiştirir, RSC yeniden render olmaz). (6) Detaylarda ham metin dökümleri KALKTI (akademik "Özgün abstract" + mevzuat/sektörel/ilaç "Resmî metinden"; İçtihat karar metni ve Doktrin özeti esas içerik — kaldılar). Testler: tests/unit/doctorium-filtreler.test.ts (26 sözleşme testi, vakalar canlı veriden).
Operasyon Paneli (S2):/operasyon — KPI, dönüşüm hunisi, gelir/Escrow, dağılımlar, trend, kapasite ·
Lojistik takip (/operasyon/lojistik — rezervasyonların Patient Journey aşamalarını yönet; lib/journey.ts) ·
Kayıt defteri tarayıcısı (/operasyon/kayit-defteri — HealthTürkiye doktor+tesis dizinini ara/filtrele/sayfala;
ST yetki-belgesi rozeti + dil/akreditasyon chip'leri; doktor kayıtlarında şehir kaynakta boş → filtre veri gelene dek gizli)
Consent Manager + RFC 3161 ispat:/onam tek seferlik KVKK onamı (GENERAL_KVKK scope — v6.269: v4, A01 tam metin +
AURA_TERMS v1 A02; personel STAFF_KVKK v1 A09 rol kesiti; ekran = hash, dil başına); sürümlü ConsentRecord +
hash-zinciri + zaman damgası + Onay Kanıtı (/onam/kanit, 10 kapsam sekmesi, TR/EN adaylı metin eşleşmesi). Geri alınabilir
rızalar (AI · beyan) Hesabım → Rızalarım: POST /api/consent/revoke → <KAPSAM>_REVOKE ispatlı kayıt; activeConsent
geri-alma duyarlı (lib/aura-consent.ts); yeniden verme (v6.278, K10)<KAPSAM>_REGRANT sayaç-sürümlü kayıt (recordRevocableConsent). (lib/consent.ts, lib/timestamp.ts, lib/aura-consent-texts.ts)
AI karşılama açık rızası (AI_TRIAGE scope, v6.4): 4 kulvarda (triyaj · ikinci görüş · sağlık turizmi ·
ücretsiz sağlık) semptom/tanı girişinden ÖNCE ayrı açık rıza kapısı (components/AiConsentGate.tsx) — AI'nın
yalnız doğru branşa yönlendirme + yüklenen belgelerin çevirisi için işleyeceğini, tanı/tedavi kararı için
kullanılmayacağını bildirir. "Açık Rızam Vardır" rızayı aynı ispat altyapısıyla kaydeder (POST /api/consent/ai,
idempotent, /onam/kanit'te görünür), "Süreci Sonlandır" hastayı ana sekmeye döndürür. Rıza verilene dek asıl
form mount edilmez. v6.269: metin A04-b Sürüm 1.0 NİHAİ (v2, sağlayıcı adıyla: Anthropic/Claude, ABD; ad iletilmez) —
kanonik TR/EN LegalMarkdown ile gösterilir, POST gövdesi lang (hash gösterilen dilin metni); TR/EN dışı arayüz dillerinde
hash DIŞI bilgilendirme çevirisi eşlik eder. (lib/ai-consent.ts, AI_CONSENT_VERSION sürümlü). Ayrı migration
gerektirmez (ConsentRecord scope zaten kompozit); lib/consent.ts scope-parametreli. (lib/ai-consent.ts)
Simültane tercüme açık rızası (AI_INTERPRET scope, v6.5): dijital bekleme odasında
(components/PreConsultLobby.tsx — cross-cutting; hem Talk /gorusme/[id] hem ikinci görüş
SoVideoRoom görüşmelerinin önünde → 4 kulvar tek noktadan) canlı görüşmeden ÖNCE ayrı rıza kapısı —
görüşme sesinin AI tarafından yalnız simültane tercüme için işleneceğini bildirir. "Açık Rızam Vardır"
rızayı aynı ispat altyapısıyla kaydeder (POST /api/consent/ai-interpret, idempotent), "Süreci Sonlandır"
hastayı ana sekmeye (/vakalarim) döndürür. Doktor görünümünde çıkmaz; rıza verilene dek kamera/mikrofon
izni istenmez. v6.269 (R4): kapı YALNIZ görüşme dilleri farklıysa (hasta dili ≠ Türkçe) gösterilir ve üçüncü seçenek
"Tercümesiz devam et" rıza yazmadan lobiyi açar (oda sessionStorageair_interpret_optout_<id> ile tercümanı kurmaz;
SO odası onInterpretChoice callback'i). Metin A04-c Sürüm 1.0 NİHAİ (v2, Google Gemini Live, ABD). Ayrı migration
gerektirmez. (lib/ai-consent.ts)
Sigorta sağlık beyanı açık rızası (HEALTH_DECLARATION scope, v6.269, A04-d):/paket hasta görünümünde beyan formu
rıza kapısının arkasındadır (components/HealthDeclarationConsent.tsx, POST /api/consent/health-declaration); sunucu
POST /api/cases/[id]/health-declaration aktif rıza yoksa 403 HEALTH_DECLARATION_CONSENT_REQUIRED (geri alma duyarlı).
Değiştirilemez erişim denetimi (E2EE Faz 0): klinik veriye her anlamlı erişim (vaka görüntüleme,
klinik not, FHIR dışa aktarım, belge görüntüleme, klinik kodlama / lab yazımı, AI belge analizi,
epikriz üretimi) AccessLog'a mühürlenir — append-only hash-zinciri + zaman damgası, küresel bir
advisory kilit altında sıralanır (eşzamanlı yazımda çatallanmaz). Hasta /erisim-kaydi'da kendi
kaydını; denetçi (Etik Kurul / Admin) /denetim'de küresel zincir bütünlüğünü doğrulanmış görür. (lib/audit.ts)
Uygulama-katmanı at-rest şifreleme (E2EE Faz 1): hassas klinik kolonları (belge içeriği, transkript,
SOAP, epikriz, triyaj semptom/gerekçe, post-op not/foto, İkinci Görüş içeriği, hasta kimliği (ad + kimlik no)) AES-256-GCM envelope ile şifrelenir (per-record DEK + env-KEK); sunucu
gerektiğinde çözer → defense-in-depth (DB-dump + KEK'siz operatör). DATA_ENCRYPTION_KEK yoksa üretimde
yazım fail-closed (dev/test'te düz metin). KMS swap-point hazır. (lib/crypto.ts)
KEK rotasyonu (v6.273, 2026-09-18): motor şema-güdümlü (lib/kek-rotation — envanter yok, tüm metin
kolonları taranır; betik scripts/rotate-kek.ts + break-glass ucu/api/admin/kek-rotate: Vercel'deki
KEK geri okunamadığından insan-okur kopya kaybında yeni anahtara sunucu içinde rotasyon; KEK_ROTATION_SECRET
ile kurulur [normalde 404], ADMIN + gövdede gizli değer + onay ifadesi, dry-run varsayılan, audit
KEK_ROTATION/KEK_ROTATION_DENIED + alarm; anahtar hiçbir satıra girmez, yalnız sha256 önekleri).
/admin "Şifreleme anahtarı" bloğu bu dağıtımın KEK parmak izini gösterir (escrow/iki-proje paritesi).
Build-time korkuluk (v6.279, 2026-09-20 — tatbikat #1 A6/B4): üretim build'i (VERCEL_ENV=production) DATA_ENCRYPTION_KEK
boş ya da base64 çözümü 32 byte değilse BAŞLAMAZ — package.jsonbuild = tsx scripts/check-kek.ts && prisma generate && next build (lib/kek-build-guard saf değerlendirme, birim testli; preview/yerel/CI atlanır; bypass YOK). KEK'siz/bozuk anahtarlı
deployment hiç oluşmaz, önceki Ready deployment canlı kalır (eskiden encryptField yazımı fail-closed durdurur ama deployment
canlıya çıkar, hasta yüzeyi 500 → SEV-1 geç fark edilirdi). Ön koşul: iki Vercel projesinde autoExposeSystemEnvs: true
(VERCEL_ENV build'e gelir; KAPATILIRSA korkuluk sessizce atlanır — 2026-09-20 ölçüldü) + Build Command boş (npm run build).
Kanıt: build günlüğünde "✓ KEK korkuluğu: DATA_ENCRYPTION_KEK mevcut ve 32 byte" (iki proje). Runbook: vault
wiki/yonetisim/sir-envanteri.md §3.3.
Post-op erişim daraltma (E2EE Faz 2A): post-op takip tamamlanınca (doktor "Takibi tamamla" veya
branş protokol süresi + tampon otomatik/lazy) klinik personel erişimi kapanır → hasta-only;
daraltılan noktalar (kokpit, vaka API, FHIR, görüşme, check-in, kodlama/lab/AI) 403/409 döner +
POSTOP_ACCESS_DENIED audit, tamamlama RECOVERY_COMPLETE audit. Hasta erişimi korunur. Hasta dilerse
erişimi yeniden açar (geri-alma; recovery/reopen → RECOVERY_REOPEN audit + Recovery.reopenedAt,
otomatik kapanma penceresi buradan yeniden başlar). Açma hasta kararıdır — klinik personel kendi
erişimini geri açamaz. M4 paylaşımda iptal ileriye dönüktür (yeni erişimi durdurur; görülen veri geri
alınamaz — bu UI'da net belirtilir). (lib/postop-access.ts)
CRM eşleştirme kalite indikatörleri (9 metrik): doktor seçimi branş/müsaitlik dışında performans
metadata'sıyla ağırlıklandırılır — rating · başarı · ücretsiz sağlık hizmeti · icap dönüş oranı · yanıt süresi
(Doctor.respCount/respTotalSec) · iptal oranı (ConsultAppointment+SO CANCELLED) · tamamlanan vaka
hacmi · yorum hacmi · güncellik. Veri-olgunluk-farkında: verisi olmayan oran/zaman metrikleri
skoru dilute etmez (ağırlık aktif kümeye yeniden normalize) → "ölçekle değer artar". Uygulandığı yerler:
Nöbetçi · SO oto-atama (+ yük dengeleme) · İcapçı fan-out. Doktor /doktor/profil'de kendi kalite
kartını (genel skor + metrik dökümü), hasta /doktorlar/[id]'de güven rozetlerini (eşik-bazlı, anlam-renk,
hover tooltip) görür. Ücretsiz Sağlık Hizmeti FIFO kalır. Metadata = klinik içerik değil → E2EE uyumlu. (lib/match-score.ts)
Hasta–doktor uyumu (soft boost): kalite (mutlak) yanına vaka-özel uyum (göreceli) eklenir —
pazar (Doctor.markets ⊇ Case.country) + acil vakada deneyim (Case.urgency≥4 → Doctor.experienceYears).
Uyumlu doktor sıralamada öne çıkar; uyumsuz ELENMEZ, yalnız geri sıralanır (erişim korunur). markets boş =
"tüm pazarlar". Dil kasıten kriter değil (simultane tercüme kapsar). Nöbetçi · İcapçı · SO oto-atamada etkin.
Şema değişmez; "ölçekle değer artar" (doktorlar markets girdikçe etki büyür). (fitScore → lib/match-score.ts)
Görüşme öncesi oda (bekleme odası): cihaz testi + geri sayım + 3 alt-durum + atanan doktor
özet kartı (tıkla-genişlet: bio/akademik/güven rozeti/akreditasyon + video kartvizit + tam profil
linki; lib/doctor-card.ts) + hasta soru notu (görüşme odasında da görünür+düzenlenebilir,
PatientQuestionsPanel). 3 akış ortak (Talk/Ücretsiz Sağlık Hizmeti/İkinci Görüş) (PreConsultLobby).
Video kartvizit hasta dilinde: karttaki tanıtım videosu (DoctorVideoCard) hasta dilini alır —
varsa dil-bazlı varyant public/videos/doctor-{male,female}-{dilkodu}.mp4 (ör. -ar) oynar, dosya
yoksa varsayılana düşer (bilinen-404 tekrar denenmez); her durumda kanonik tanıtım metni
(VIDEO_CARD_SCRIPT, lib/constants.ts) AI çevirisiyle hastanın dilinde WebVTT altyazı olarak
basılır (video süresine eşit dağıtım, RTL dahil). Dil varyantı eklemek = mp4'ü klasöre koymak.
Sesle dikte (v6.0): 4 hasta intake kulvarının (triyaj / İkinci Görüş / Ücretsiz Sağlık Hizmeti /
Sağlık Turizmi) semptom/hedef alanına konuşarak metin girişi — tarayıcının Web Speech API'si ile;
harici servis/kütüphane YOK, ses tanıma tamamen istemcide çalışır (PHI sunucuya ekstra gitmez).
Çok dilli (air_lang→BCP-47); API'yi desteklemeyen tarayıcıda düğme gizli. (components/DictationButton.tsx)
30 branş görsel kimliği (v6.0): her klinik branşa semantik renk + SVG amblem + renk-türevi CSS banner
(BRANCH_COLORS + branchBannerBg; BranchBanner + BranchAvatar; public/branches/*.svg ×30 — Recraft
vector). Yerleşim: triyaj bandı + /vaka/[id] banner + /vakalarim amblemleri (genel + İkinci Görüş).
resolveBranchKey kritik köprü: Case.branch (LABEL) ile triyaj effectiveBranch (KEY) farkını tek
noktada normalize eder (hem key hem label kabul eder). (lib/branch-visuals.ts)
IS_DOCTORIUM_DEPLOY
CURRENT_CONSENT_DEPLOY
Doctorium deploy'u (doctorium.tr) YALNIZ kendi belgelerini sorar:
missingConsentScopes
gateConsentVersion
/onam
?scope=clinical
/doctorium/giris
/api/consent
doctorium
resign
400
cv=0
/onam
doctorium-consent.test
consent-route-brand.test
Yeni onam kapsamı eklerken "hangi deploy'da sorulur?" sorusu zorunlu.
gateConsentVersion
cv
missingConsentScopes
DoctoriumConsentGate
AuraConsentGate
StaffConsentGate
ConsentResign
v6.270 (2026-09-15) — kapılardan ÇIKIŞ TAM SAYFA gezintisi
app/onam/leave-gate.ts leaveConsentGate
router.push(dest)+router.refresh()
<Link>
next start
next
lib/safe-path isSafeInternalPath
//host
/\host
isSafeNextPath
tests/unit/safe-path.test.ts
Klinik aktivasyon STAFF_KVKK (v6.269; eskiden GENERAL_KVKK) onamına bağlı:
SEO altyapısı (v5.9.2 · v6.12):app/sitemap.ts yalnız 8 halka açık rota (/, /how-it-works, /guven-ve-gizlilik, /giris, /kayit, /kayit/hasta, /second-opinion, /ucretsiz-saglik) · app/robots.ts hassas panel/API disallow + sitemap referansı. SITE_URL tek kaynak lib/aura-landing/seo.ts (domain taşınırsa tek nokta)
Doctorium hukuki belgeleri (v6.210, 2026-09-03) — tek kaynak lib/doctorium-legal/ (bkz. "Doctorium — ayrı ürün → Hukuki belgeler"); açık kabuk (LegalShell), AURA kromu yok, canonical doctorium.tr, Doctorium sitemap'inde. Platform içi KVKK başvuru formu CANLI (v6.263) — yalnız oturum açmış üyeye açık, POST /api/doctorium/kvkk-basvuru; /admin/kvkk-basvurulari'nde (ETHICS/ADMIN) yanıtlanır
AURA hukuki belgeleri (kod Paket A, v6.268, 2026-09-13) — tek kaynak lib/aura-legal (vault output/aura-hukuki-belgeler Sürüm 1.0 NİHAİ; texts/*.ts vault'taki _yayin-kesiti.py ile üretilir, elle düzenlenmez); TR kanonik + ?lang=en İngilizce ikinci kanonik (S4; çelişkide TR esastır; canonical TR, hreflang tr/en); vitrin kabuğu AuraLegalShell (V2Nav + AuraClosing, gövde açık .aura-light şeridi; CHROME_FREE_ROUTES); footer "Hukuki" grubu 9 dil; sitemap yalnız yayımlı rotalar; AURA_ONLY_PREFIXES (doctorium.tr → AURA 307). Kimlik alanları tüzel kişilik kurulana dek "AURA platform işleticisi" yer tutucusu; e-posta kanalı kutu açılana dek yayımlanmaz (platform içi form). /kvkk-basvuru: A07 bölüm A metni + oturumlu üyeye (hasta + personel) başvuru formu (POST /api/kvkk-basvuru = Doctorium işleyicisi, ortak KvkkApplication kütüğü). /tele-saglik: published:false → 404 + noindex (A03 yayın şartı: klinik hizmet sağlayıcı kimliği + USHAŞ yetki belgesi alanları). Hasta kayıt formunda aydınlatma bağlantısı. Kod Paket B (ekran = hash, GENERAL_KVKK v4 TR+EN) bu metin modülünü tüketir. Sözleşme testi tests/unit/aura-legal.test.ts.
/basla
KALDIRILDI (v5.8) — eski linkler için /triyaj'a kalıcı redirect
/sifremi-unuttum · /sifre-sifirla
Parola kurtarma (v6.194) — sistemde HİÇ yoktu (parola değiştirme oturum ister; unutan üye kilitleniyordu). İstek → e-postadaki tek kullanımlık bağlantı (1 saat) → yeni parola. MARKA-NÖTR ve LOGOSUZ: iki deploy'da da aynı rotadan servis edilir, chrome-routes'ta (yoksa doctorium.tr'de AURA Header/Footer çizilirdi). "Parolamı unuttum" bağlantısı ORTAK GateEmailForm'da → üç kapıda birden çıkar, metin 9 dilde ve prop ZORUNLU (opsiyonel olsaydı bir dilde sessizce kaybolurdu). noindex
/saglik-turizmi
Sağlık Turizmi hasta-yüzü planlama (v4.24-25): tercih (branş/ülke/seviye/gece) + endikatif paket önizlemesi (computePackage) + öz-yeterli "Talep Oluştur" → POST /api/patient/tourism-request (runTriage → tourism-etiketli Case, Case.tourismPlan JSON; doktor /paket PackageBuilder ön-değeri + kokpit 🧳 rozeti). Klinik-önce: bağlayıcı fiyat/rezervasyon daima doktor onayı sonrası (simüle/park; USHAŞ yetki belgesi + TÜRSAB hukuki zemini vault'ta belgeli)
Tek hasta vaka merkezi (v5.8 F6): süreç tracker + 3-seçenek kapısı + vaka bilgisi + aktif görüşme CTA + teklif (#teklif) + rezervasyon (#rezervasyon) gömülü; eski hasta rotaları (/triyaj/[id] · /teklif/[bookingId] · /rezervasyon/[bookingId]) buraya kalıcı redirect
/vakalarim · /erisim-kaydi
Hastanın vaka ana ekranı · erişim denetim kaydı ("verime kim erişti")
Doktor Ana Sayfası (pencere-tabanlı, v6.41 birleşik vaka listesi), ilk-giriş onboarding (v6.87'den beri iki aşamalı — Aşama 1: 🔄 v6.124'ten beri e-Devlet doğrulamalı diploma → yalnız Doctorium; Aşama 2: klinik havuz — diploma TEKRAR İSTENMEZ, yerine güvenlik katmanları v6.126), OAuth profil-tamamlama ara sayfası (v6.87 — Google/Apple hesabı branş/şehir boş açılır, bu ekran doldurtur), kokpit, izleme, profil, Ücretsiz Sağlık Hizmeti, klinik nöbet, Konsültasyon Talepleri kutusu
/partner (+/talep)
Partner Doktor paneli (tüm arayüz partner dilinde + RTL, haber akışı dahil) · anonim konsültasyon talebi oluşturma (belge yükleme, hasta DB erişimi yok). 2026-08-12: doğrulanmamış partner (staffVerifiedAt yok) /kayit/durum'a düşer
Yönetim panosu (ADMIN, v6.351): tek ekranda Doctorium üyeleri (toplam + bugünkü erişim katmanı bileşimi · son 24 sa / 7 g / 30 g yeni üye ve önceki eşit dönem · 30 günlük TR-günü grafiği · BAĞIMSIZ doğrulama eksenleri [huni değil] · en acil bekleyenler · son katılanlar) + beş sosyal hesap kartı. Üye tanımı /admin/uyeler ile aynı; hesap SAF lib/admin-dashboard. Sosyal ölçüler SocialMetricDaily'den (son 7 TR günü toplamı; lib/social-metrics.summarizeSocialMetrics); satır yoksa kart "—" + bağlantı aşaması (lib/admin-social) — sahte sayı YOK. İstemci JS'i yok (grafik sunucu SVG'si).
/admin/ai-kullanim
AI kullanım sayacı (ADMIN, v6.298):AiUsageDaily gün (UTC) × özellik × model çağrı/token toplamları + tahminî USD (fiyat listesi tarihli; Console esas). İçerik/PHI yok; her Anthropic çağrısı lib/ai-usage.trackedCreate ile sayılır, Gemini oturumu adet. Sayaç fail-open. v6.312: "Güne ve özelliğe göre" matrisi (usageByDayFeature — her gün için özellik başına tahminî tutar + çağrı; tek günlük tepenin kaynağı sayfadan okunur). 🪤 Yönetici oturumu doctorium.tr host'unda → sayfa doctorium.tr/admin/ai-kullanim'da açılır.
/admin/landing-analitik
Doctorium landing analitiği (ADMIN): kimliksiz agregat sayaçlar (landing_view · section_view · student_click; LandingEventBeacon + events.ts yerleşim haritası) + "Öğrenci hunisi" paneli (v6.275, 2026-09-19) — lib/doctorium-landing/student-funnel.ts (saf, birim testli): 09 Öğrenciler bölümü görüntülenme · öğrenci düğmesi tıklaması (ogrenci · final · identity yerleşimleri) · tıklama/görüntülenme · hero sonrası ulaşan pay · ziyaret tabanı · gün tablosu; STUDENT_FUNNEL_SINCE = 10 Eyl 2026 (betik LANDING_SINCE ile aynı); örneklem <30 → "oranlar yorumlanmaz". Prod betiği probe-membership-stamps yedek. 2026-09-19 prod ölçümü: student_click 0 (kablo doğru, örneklem yetersiz → tetikleyici-bazlı izleme)
/paylasim/[token] · /paylasimlarim
Güvenli paylaşım görüntüleyici · paylaşım yönetimi
Master paneli (v6.0, env-dormant impersonation) — MASTER_ACCOUNT_ENABLED + MASTER_ACCOUNT_EMAILS env'i açıkken allowlist'teki e-posta (rol değil, e-posta yetkisi) herhangi bir kullanıcıya bürünüp ekranlarını görebilir; gerçek master kimliği imp claim'inde (imzalı JWT), her bürünme IMPERSONATE_START/END ile değiştirilemez audit'e; üç katmanlı kapı (proxy + sayfa + API), env kapalıysa 404 (özellik sızmaz); üstte kırmızı "Master'a dön" bandı (MasterBar)
notifications · push · system-messages
Bildirim merkezi · Web Push aboneliği · Sistem Mesajları (v6.81): GET kendi mesajların (+?count=1 rozet sayımı; body/reply sunucuda çözülür, repliedByUserId yanıtlara ASLA konmaz — anonimlik) · POST okundu · [id]/reply atomik TEK yanıt (updateMany-guard → yarışta 409; kişisel mesaja yalnız hedef kullanıcı — ADMIN dahi değil)
digest · doctor/digest
Doctorium Post (v6.159):digest/unsubscribe — e-posta tek-tık çıkış (GET=onay sayfası [istemci link ön-yüklemesi işlem YAPMAZ] · POST=RFC 8058; oturumsuz, audit'li DIGEST_UNSUBSCRIBE). ⚠️ Token v6.198'de DB'ye taşındı (Doctor.digestUnsubToken — doktor başına rastgele + kalıcı): eskiden HMAC(SESSION_SECRET) idi, ama bülten AURA projesinden gönderilip bağlantı doctorium.tr'de doğrulanıyor ve iki projenin sırrı FARKLI ölçüldü (2026-09-02) → çıkış 403 verecekti; DB ortak olduğu için env paritesi ihtiyacı kalktı. Bağlantı TABANI da SITE_URL değil DOCTORIUM_CANONICAL_URL (v6.197 — Doctorium markalı bülten AURA host'una göndermesin) · doctor/digest — abonelik kanalı tercihi (null/app/email; self-auth, feed-modules deseni)
social-metrics
Sosyal medya günlük ölçüleri (v6.351): POST — Bearer SOCIAL_METRICS_TOKEN (env yoksa dormant 503, yanlış anahtar 401; v6.353: boşluk/satır sonu kırpılır, "Bearer " öneki isteğe bağlı — lib/social-metrics-auth; hız sınırı 60/sa anahtardan önce; gövde ≤ 64 KB). Yön n8n → uygulama: platform jetonları n8n'de KALIR. Gövde {platform, day, metrics} ya da {items:[…]} (≤ 50); platform instagram·facebook·linkedin·x·youtube, gün TR takvim günü (gelecek / 400 günden eski RED), ölçüler followers·reach·views·likes·comments·saves·shares·profileClicks·posts = 0..1e9 tam sayı ya da null; bilinmeyen ölçü adı 400 (sessizce yutulmaz). Upsert (platform, day): YALNIZ gönderilen alanlar yazılır (Instagram 48 saat gecikmesiyle aynı gün yeniden gönderilir). Kişisel veri YOK (ham API yanıtı tutulmaz). Sözleşme lib/social-metrics + tests/unit/social-metrics.test.ts; plan vault output/doctorium-pano-sosyal-veri-kaynaklari-2026-10-17.md.
social-digest
Kamuya açık gazete seçkisi (v6.190): GET — Bearer SOCIAL_DIGEST_TOKEN (env yoksa dormant 503, yanlış anahtar 401); 6 akıştan 1'er başlık (TEASER — Post'un tam hâli kamuya çıkmaz), gün-deterministik branş rotasyonu (aynı TR günü aynı yanıt — çift paylaşım kazasına kapalı), kişisel veri YOK. Tüketici: Hetzner doctorium-n8n sunucusundaki sabah akışı (07:45 → kart-render servisi → bulten-arsiv/; detay hafıza hetzner-n8n-sunucu). Akademik + ilaç başlıkları ingest'te Türkçe doğar (2026-09-02, lib/translate-news — Claude ile toplu çeviri, fail-open + hiza güvenliği; birikmiş kayıtlar scripts/translate-titles-backfill.ts ile çevrildi: 410 akademik + 305 ilaç). v6.206 (2026-09-02 gece): ÖZET GİRİŞİ de Türkçeleşir — başlık çevrilip özet İngilizce kalıyordu (kart/Post/bülten ona basıyordu); ayrı cron api/cron/translate-news (05:40 TR, lib/translate-summaries; kapsam lib/news-language.needsSummaryTranslation = akademik + ilaç + İngilizce sektörel) summary=Türkçe giriş (~700 kar., cümle sınırı — summaryLead), summaryOriginal=özgün tam metin yazar; yeni→eski, birikmişi gecelik bütçeyle kendisi kapatır (PROD backfill script'i yok); AI özetleri (ensureClinicalSummary/ensureRegulationSummary) kaynak olarak özgün metni okur. v6.202 (2026-09-02): sektörel İngilizce kaynaklar (Medscape / Medical Xpress / WHO) da ingest'te çevrilir — kapı tek yerde lib/news-language.needsTitleTranslation (Türkçe doğan kaynaklar geçmez; sözleşme testi news-language.test); seçkide sektörel akış yerli kaynağı önceler (pickSocialDigest — yerli yoksa yabancı kalır); RG ana sayfa fihrist artığı ("…İLÂN BÖLÜMÜ") parseGazetteTodayHtml (başlık yalnız <a> içinden) + stripGazetteSectionSuffix ile düzeltildi, scripts/ingest-tr-sources.ts'e idempotent "başlık onarımı" adımı eklendi. 🔁 v6.288 (2026-09-21, 👤 kural EKİ — tekrar yerine donör): "her akıştan 1" korunur; bir akışta O GÜN yeni başlık yoksa (son 24 saatte akışa düşen yok — SOCIAL_FRESH_MS, tazelik ekseni createdAt) dünkü başlık TEKRARLANMAZ, yuva o gün en çok yeni başlık gelen akıştan (eşitlikte akış sırası; donör tükenince sıradaki) kullanılmamış taze bir başlıkla dolar — yuva sırası korunur, başlık donör akışın etiketini taşır, items[].replaces hangi akışın yerine girdiğini söyler; donör yoksa eski başlık stale:true ile kalır (boş kart yerine fail-soft), v6.336 (2026-10-07, 👤 "her zaman 6 yuva"): 48 saatte hiç içeriği olmayan akışın yuvası da artık donörle dolar (eskiden düşüyordu → 5–7 Ekim kartı hukuk akışları boş diye 3 başlığa inmişti); donör de tükenirse yuva düşer (sahte/boş öğe yok); items[].id + yanıt fill{replaced,stale} eklendi (alan EKLEME — kart tarafı eski alanları aynen görür). Durumsuz (dünkü seçki DB'den okunmaz); birim testi 16 sözleşme. Faz öneki (2026-10-02): klinik araştırma başlıklarında önek kodda ve Türkçe üretilir, çeviriye GİRMEZ (lib/trial-phase: "Faz 3 · …", "Faz 2/3 · …"; translate-news protectTrialPhase gövdeyi çevirip öneki geri ekler) — ham önek çeviriyle birlikte kimi gün "PHASE4 ·" kalıyor, kimi gün "FAZE 3 ·" diye bozuluyordu; eski satırlar bu uçta ve doctorium.toFeedItem'da okunurken kanonik biçime gelir (DB düzeltmesi yok). Kartın BÜYÜK HARF etiketleri Hetzner şablonunda lang="tr" ile yazılır (AKADEMİK · CİHAZ). 🔗 Herkese açık sayfa (v6.315, 2026-10-02, 👤 "bio'daki seçki sayfasını yapalım"): Instagram'da tıklanabilir link YOK (API'de parametre yok; uygulamada ücretli Meta Verified'a bağlı) → Reels/hikâye/altyazıdaki "Detaylar bio'daki bağlantıda" cümlesinin hedefi doctorium.tr/secki (iç yol /doctorium/secki; kısa adres YALNIZ Doctorium deploy'unda next.config rewrite — AURA'da 404; canonical daima doctorium.tr/secki; ISR 10 dk). Veri lib/social-digest-public — bu uçla AYNI seçki kuralı + AYNI sorgu (loadSocialArticles); sayfa kartı SABİT AN'da (son 07:45 TR = 04:45 UTC ≤ now) yeniden kurar: öğleden sonra bile sabah kartıyla aynı başlıklar, anchor sonrası ingest edilen satır dışlanır, 07:45'ten önce dünkü seçki. Özet GÖSTERİLMEZ (veri kalitesi: akademik özet İngilizce + "BackgroundGas" yapışık başlık, KLİMİK özeti site menüsü artığı, RG özeti boş) — başlık + kaynak + "Kaynağa git · alan adı"; DB hatasında sayfa çökmez, SAHTE içerik göstermez (hata kutusu). Metinler tek yerde lib/doctorium-secki/copy.ts (iddia-disiplini testi taranır); sözleşmeler tests/unit/doctorium-secki.test.ts; sentetik kontrol DOCTORIUM_ROUTES. 📸 summaryLong (v6.317, 2026-10-03, 👤 "n8n ile hikâye + Reels"): her öğede hikâye/Reels açıklaması için summaryLong (≤400 kr, CÜMLE sınırından kırpılmış; lib/social-summary-long) + summaryLongFallback — kaynak 👤 kararı "DB özeti + dürüst yedek" (Haiku yeniden yazımı ve aiSummary REDDEDİLDİ: halka açık tıbbi metinde çarpıtma riski, aynı gün aynı çıktı garantisi yok). Özet kaynak artıklarından arındırılır (HTML etiketi, WordPress "The post … first appeared on …" kuyruğu, sondaki "Devamını oku / Read more / […]"); boş / <30 kr / ÇEVRİLMEMİŞ-İNGİLİZCE ise metin UYDURULMAZ → " kaynağında <TR günü> tarihinde yayımlandı; ayrıntı kaynak bağlantısında." (yalnız ≤40 kr kaynak adı cümleye girer) + summaryLongFallback:true. summary (160 teaser) DEĞİŞMEDİ; halka açık /secki sayfası summaryLong'u GÖSTERMEZ (test kilitli); alan EKLEME — kart/n8n eski alanları aynen görür. Sözleşme tests/unit/social-summary-long.test.ts; trDateLabel ortak modülde (lib/tr-date-label). v6.318 (2026-10-03, 👤 onaylı; üretim canlı ölçümünden): Resmî Gazete kaleminin summary'si bir özet değil, belgenin HAM metni ("3 Ekim 2026 CUMARTESİ Resmî Gazete Sayı : 33389 YÖNETMELİK … MADDE 1- …") → künyeyle başlayan metin (looksLikeRawGazetteText) kullanılamaz sayılıp DÜRÜST YEDEK cümleye düşer; cleanSummary görünmez karakterleri (U+200B, U+00AD, U+2060, U+FEFF) de ayıklar (ZWJ/ZWNJ bilerek silinmez)
account · doctorium/membership
Hesabım (v6.187):account/password — parola değiştir/belirle (mod User.passwordSetAt; başarıda revokeUserSessions + bu cihaza taze oturum [iptal ÖNCE, mint SONRA]; bürünmede 403; 5/saat limit — current doğrulaması bir parola oracle'ıdır; 🚫 parola audit'e YAZILMAZ) · doctorium/membership — intent:"close" (hesap dahil siler, oturumu sonlandırır) veya "leave" (yalnız Doctorium katmanı + doctoriumOptOutAt). Onay kelimesi zorunlu (KAPAT/ÇIK); close isteği klinik bağ varsa 409 CLINICAL_TIES ile reddedilir (sessizce leavee çevrilmez)
AŞAMA 2 doğrulama OTP'si (v6.126):sms · work-email — POST kod üretir+gönderir (kanal env'siz simülasyon), PUT kodu doğrular → Doctor.smsVerifiedAt/workEmailVerifiedAt. Self-auth (hedef doktor DAİMA oturumdan; IDOR yok) + rate-limit 5/10dk + audit. Kod sha256(kod+satırId) olarak saklanır, düz metin HİÇBİR yere yazılmaz
admin/doctors/[id]/clinic-phone
Klinik telefonu geri-arama teyidi (v6.126): koordinatör/ADMIN, HealthTürkiye'deki resmî tesis numarasından doktoru arayıp POST ile damgalar (CLINIC_PHONE_VERIFY audit) · DELETE geri alır. İnsan-işletimli — otomasyon bilinçli YOK
sponsor · survey
sponsor/click (v6.68 — rol kapılı tıklama sayacı → 302; URL DB'den, open-redirect yok) · survey/respond (v6.69 — DOCTOR-only tek yanıt, P2002→409, yanıtla birlikte agregat döner) · doctor/sponsor-consent (kişiselleştirme açık rızası — grant fail-closed / revoke derhâl; ConsentRecord SPONSOR_TARGETING/_REVOKE scope'ları) · doctor/hr-consent (v6.87 — İK iletişim onamı, aynı desen; HR_CONTACT/_REVOKE + Doctor.hrContactOptInAt; opt-in, hizmete şart değil) · doctor/complete-profile (v6.87 — OAuth kimlik tamamlama: ad/ünvan/branş/şehir/telefon[şifreli]/dil; doğrulama e-posta kaydıyla birebir)
none | preview | full
canCaseBeAccessedBy
full
lib/case-preview casePreviewDto
[HASTA]
doktor/vaka/[id]
GET api/cases/[id]
GET api/cases
Kabul
POST api/cases/[id]/accept
doctorId:null
updateMany
CASE_ACCEPT
CASE_VIEW
1C-b
Personel klinik içerik kapısı (K06 1C-b, v6.289 — 👤 karar A ikinci yarı, kapsam envanteri onaylı 2026-09-21):
caseAccessLevel
none | preview | logistics | full
logistics
none
canCaseBeAccessedBy
full
lib/case-logistics caseLogisticsDto
doktor/vaka/[id]
CaseLogisticsView
GET api/cases/[id] lojistik DTO (audit "lojistik görünüm"). Klinik uç allowlist'leri yalnız DOCTOR (documents/DICOM · analyze-docs ·
coding · labs · recommendations · ai/soap · ai/discharge · ai/suggest-procedures; appointment teklifi / tourism-outreach / clinical/duty
ADMIN'siz). canStartConsultation koordinatör/yönetici 403; /gorusme/[id] + WebRTC sinyal kapısı personele kapalı; /takip ve
/vaka/[caseId] personel dalı notFound. İkinci Görüş:SO_CLINICAL_STAFF = DOCTOR (atama daraltmalı); koordinatör/yönetici
soCaseListScope LOJİSTİK liste (route diagnosisSummary null süzer), /operasyon/ikinci-gorus kuyruğu ve inceleme paneli tanı
özetsiz + belge İÇERİK bağlantısız (tür/etiket kalır — eksik belge talebi akışı sürer); Etik Kurul SO listesi 403. Güven sayfası
"koordinatör ve acente lojistik bilgi görür, klinik kayıt değil" (copy.ts trustPage) artık kod kanıtlı. Destek ihtiyacı için MASTER
bürünme (audit'li) ayrı. Kapsam envanteri: vault output/1c-b-kapsam-envanteri-2026-09-21.md.
· AI kapısılib/ai-gate.requireAiTriage — triage/analyze · cases POST · free-care/apply · patient/tourism-request önünde:
403 AI_ROLE_NOT_ALLOWED (PATIENT|ADMIN dışı) · 429 (20/dk/kullanıcı ORTAK kova + 60/dk/IP) · 403 AI_CONSENT_REQUIRED (aktif
AI_TRIAGE v2, geri-alma duyarlı) · 413 (şikayet >4000 · yanıtlar JSON >4000 · süre >500; kırpma yok). Kapı reddederse LLM çağrılmaz.
· POST /api/cases yazım bütünlüğü: belge imzaları yazımdan/LLM'den ÖNCE doğrulanır (415'te vaka oluşmaz); vaka + belgeler tek
$transaction; işlem düşerse yüklenen blob'lar silinir. Idempotency anahtarı yok (migration — ayrı karar).
· Kayıt e-posta kapısılib/signup-email-gate.ts: üretimde (NODE_ENV/VERCEL_ENV production) RESEND_API_KEY yoksa signup* rotaları
hesap yazmadan 503 EMAIL_PROVIDER_MISSING + alarm email-provider-missing; dormant "doğrulanmış damgala" kolaylığı yalnız
geliştirme/test ya da ALLOW_UNVERIFIED_SIGNUP=1 (prova).
· Post-op durum: "Stabil" yalnız GÜNCEL ölçümde (lib/postop measurementState, STALE_AFTER_DAYS=3 — klinik onay bekleyen yer tutucu);
hasta takip listesi kapanışı detayla aynı kaynaktan (recoveryClosed, lib/postop-rows).
· ✅ K10 kapandı (v6.278, 2026-09-20): geri alınan rıza <KAPSAM>_REGRANT sayaç-sürümlü kayıtla yeniden verilir
(recordRevocableConsent; decideActive son olumlu olay); GET /api/consent/ai + AiConsentGate sunucudan aktif rızayı okur (H10).
· Doktor profili iddiaları (D04, v6.280):lib/doctor-profile üretilmiş okul/üyelik/yayın/yıl DOLGUSUNU yalnız DEMO profilde yazar
(isDemoDoctorAccount: bağlı User yok ya da *@air.test; lib/doctor-demo doctorIsDemo) — gerçek profilde yalnız DB alanları, boş alan
"Bilgi eklenmedi", akademik not yoksa gizli; "%X başarı" (tanım/dönem yok) ve "Sağlık Turizmi Yetki Belgesi" rozeti (belge tipi yok) TÜM
hasta yüzeylerinden kalktı; e-Devlet diploma rozeti yalnız diplomaVerifiedAt, "hesap yönetim onaylı" yalnız verified; hasta yorumları
yalnız demo profilde üretilir (gerçekte "henüz doğrulanmış değerlendirme yok"); /doktorlar/[id] demo rozeti "Demo profil · örnek içerik".
· Güven sayfası vaatleri (V03, v6.280) — /guven-ve-gizlilik, 9 dil (aura-landing/copy.ts trustPage): 04 doktor kartı yalnız DİPLOMA'yı
zorunlu anlatır (e-Devlet barkodlu mezun belgesi + yönetim incelemesi; uzmanlık belgesi/MMSS ihtiyari — REQUIRED_DOC_TYPES ile aynı),
02 rıza kartı işleme-bazlı (genel KVKK+koşullar · AI ön değerlendirme · AI tercüme · sağlık beyanı; geri alma Hesabım — REVOCABLE_SCOPES),
01 AB depolama / ABD AI işleme ayrı cümle (bkz. 08), 10 KVKK başvurusu platform içi forma bağlanır (reportCta → /kvkk-basvuru; "⚖️ Tüzel
kişilik" notu: unvan/adres şirket kurulunca). aura-landing-copy.test eski kalıpları ("Üç ayrı rıza", zorunlu MMSS, "Taslak") kilitler.
· Kuyruk sayaç sözlüğü (D02, v6.281): "Toplam · Bekleyen · Acil (4-5)" yerine kapsamı ALT YAZIDA açıklanmış dört sayaç — açık
(NEW/IN_REVIEW/IN_CONSULT) · işlem bekleyen (NEW + IN_REVIEW) · aktif acil (aciliyet ≥4 VE açık — tamamlanmış vaka SAYILMAZ) · arşiv
(DONE). Etiketler lib/doctor-home QUEUE_COUNTERS, where'ler lib/case-access queueCounterWhere (stat tıklaması = aynı filtre);
status= parametresi sözde durumları open/pending de kabul eder (statusFilterWhere; GET /api/cases de). SO rozeti kapsamını söyler.
· Finans hakediş sözlüğü (D05, lib/finance.ts): hakediş KULVAR + ücret sözleşmesiyle — telehealth = demo ücret − komisyon · ücretsiz
= 0 USD "gönüllü katkı" AYRI sayaç · sağlık turizmi = hakedişe girmez (pay mutabakatta, sayı görünür). "Simülasyon" etiketi büyük
toplamın yanında; dökümde hasta adı YOK — kimliksiz işlem no txRef (K02/K03); sorgu yalnız freeCare/tourismPlan çeker.
· Hasta vaka listesi (K09-hasta / H11, lib/patient-cases.ts):/vakalarim + /second-opinion/vakalarim ÜÇ GRUP (işlem gerekiyor ·
devam eden · tamamlanan; her dosya TEK grupta; sayılar sunucuda) + branş/tarih filtresi (?grup=&branch=&from=&to=) + KEYSET sayfalama
(?cursor=<ms>.<id>; createdAt+id çifti, iki model aynı imleçle birleştirilir — mergeKeysetPage) + kart başına tek "sıradaki adım"
(caseNextStep/soNextStep). Varsayılan sekme: işlem gerektiren varsa o. take:100 tavanı ve istemci sıralaması kalktı.
· Hasta yüzeyi (4A, v6.283): vaka merkezi bandı DURUM bazlı (lib/patient-cases caseHubBand; DONE'da "kuyruğa eklendi" yok) · SO video randevusu
ÜÇ EVRE (lib/appointment-window: kuruldu → −15 dk…+60 dk pencere → geçti; katıl yalnız pencerede; saat TSİ + tarayıcı dilimi farklıysa yerel
saat; "şimdi" lib/use-now useSyncExternalStore — render'da Date.now() yok) · /hesap tek dil (hasta dili) + "onam metni dili" rozeti;
vaka merkezi arayüzü hastanın GÜNCEL diline, kayıt dili ayrı alan · takip "Randevu iste" dürüst devre dışı (akış yok) · ön görüşme kapısı
sahte kart alanları yerine "Demo ile devam et — ücret alınmaz" (odak başlığa, autoFocus yok; Billing sözleşmesi PAID/PAYMENT aynı) · belge adımı
iki açık yol (şimdi yükle / eksik belgeyle beklemeye al; "opsiyoneldir" kalktı) · ücretsiz ray "Başvuru & Onay" (N/A sahne yok) · Onay
Kanıtı sade özet + "Teknik kanıt" açılır + sekmeler role göre (lib/consent-proof-scopes; hasta personel/Doctorium sekmesi görmez) ·
Erişim Kaydı son-30-gün özeti + LOGIN vb. teknik olaylar ayrı açılır bölüm (lib/access-log-view).
· Doktor yüzeyi (4B, v6.284): kuyruk durum rozeti mobilde de görünür · Header ikon-linklerine aria-label · SO görüş formu htmlFor/id +
gönderilmemiş görüşte beforeunload uyarısı (sunucu şifreli taslak = migration → todo) · profilde "Bağlı hesap" satırı + kapasite DÖNEMLİ
(lib/capacity-period: Türkiye takvim ayı; aşım etiketlenir, engellemez) · konsültasyon mahremiyet şeridi de-id diliyle ("görüntünün kendisi
kaldırılmaz"), "Özgün şikâyet (hasta dili)" / "TR çeviri (AI)" etiketleri, LOINC tablosu + FHIR bağlantısı açılır "teknik ayrıntı" · ücretsiz
konsol / nöbet durum etiketlerinde kulvar adı · finans turizm HELD/RELEASED/REFUNDED "eski ödeme modeli — tarihsel" + not.
Kök layout DB dayanıklılığı (v6.15) — src/app/layout.tsx: kök layout HER sayfada (vitrin dahil)
çalışır ve çerez varsa getCurrentUser() → DB okur. DB erişilemezse (Neon uyanması/kesinti) buradan
fırlayan hata DB sorgusu OLMAYAN statik landing'i bileerror.tsx'e düşürüyordu → oturum okuması
try/catch ile izole, hata yutulur ve misafir kabuk çizilir.
🔒 Bu FAIL-CLOSED'dır, fail-open değil:user = nullen az yetki demektir. Oturumu token'dan
"kurtarmak" (DB doğrulamasını atlayıp token'a güvenmek) fail-open olurdu — iptal edilmiş oturum
geçer + rol bayatlar (bkz. JWT iptali maddesi) ⇒ yapma. Korunan sayfa/API kendi
getCurrentUser/requireUser kapısında yine reddeder; yalnız vitrin kabuğu ayakta kalır.
⚠️ getCurrentUser'ın KENDİSİNE bu davranışı taşıma (17+ çağrı noktası; yaptırım orada olmalı).
🪤 Belirti aldatıcıdır: çerezsiz ziyaretçi getCurrentUser'da DB'ye hiç gitmez ⇒ hata yalnız giriş
yapmış kullanıcıda görünür ("bende çalışıyor"); runtime hata kümesinde users=1 bunun imzasıdır.
Kök neden ayrı: DATABASE_URL → connect_timeout=15 (bkz. DEPLOY.md Adım 1).
Hesap ve veri silme (v6.11) — lib/account-deletion.ts: ⚖️ "hepsini sil" YAPILMADI, bilinçli:
sağlık kaydı yasal saklamaya tabidir (KVKK m.7 → m.5/m.6) → düz bir silme düğmesi hukuka aykırı olurdu.
İki katman: kişisel veri gerçekten silinir (+ parola çöpe, sessionVersion++ → giriş imkânsız);
klinik kayıt HERKESE kapanır (deletionLockedAt) ve RETENTION_YEARS (20, tek sabit — v6.272: A06 madde 3.2 ile
NİHAİ) sonunda cron/purge-deletedfiziken imha eder. v6.272: silme KVKK m.11 kütüğüne otomatik işlenir
(KvkkApplication SILME/ANSWERED, ip yazılmaz); patientHealthHistory + tek kullanımlık token özetleri de boşaltılır.
ConsentRecord (dayanağın ispatı) + AuditLog (hash-zinciri;
satır silmek zinciri kırar) kasıtlı saklanır; User satırı rıza-ispat bağı için kabuk kalır.
⚠️ Kilit rol kontrolünden ÖNCE (ownership.ts en başta deletionLocked()): ADMIN/COORDINATOR/ETHICS
geniş dalları kilidi delemez — testle sabit (tests/unit/ownership), oraya dokunma.
⚠️ deletionLockedAtCaseRef/SoCaseRef'te ZORUNLU: yeni bir vaka sorgusu yazarken select'e
eklemeyi unutursan DERLEME PATLAR (kasıtlı — fail-open yerine compile-error).
🔌 Gerçek crypto-shred YOK ve bugünkü mimaride kurulamaz: DEK alanın içinde (crypto.ts envelope) →
imha edilebilir tek anahtar global KEK (= herkesin verisi). Hasta-bazlı DEK'e geçilirse (crypto.ts:17
KMS swap noktası) purge "anahtar satırını sil"e döner. ✅ Onam metni v6.19'da düzeltildi (v3,
hukukçu onaylı): "(crypto-shred)" vaadi çıktı, metin fiziken-imha gerçeğini söylüyor;
CONSENT_VERSION 2→3 = herkes /onam'da bir kez yeniden onaylar.
Veri ikametgâhı — işlem bölgesi fra1 (v6.10):vercel.json"regions": ["fra1"] (Frankfurt).
Neden: Neon veritabanı eu-central-1 (Frankfurt); Vercel varsayılanı ise iad1 (Washington DC)
idi → PHI AB'de saklanıyor ama her istekte ABD'de işleniyordu (şifre orada çözülür) = gereksiz
uluslararası aktarım + her sorgu Atlantik'i geçiyordu. fra1 ikisini aynı yere koyar: veri uçtan uca
AB'de + DB gecikmesi düşer. ⚠️ Bölgeyi değiştirmeden önce Neon bölgesini kontrol et — ikisi ayrı
düşerse hem gecikme hem aktarım yükü geri gelir. AB dışına taşımak KVKK/GDPR aktarım analizi gerektirir.
(Bölge dışı sağlayıcılar ayrı konu: AI çağrıları — bkz. AI veri-minimizasyonu.)
Doktor veri dürüstlüğü (v4.19): rating/successRate/experienceYears/jci nullable + default'sız
(uydurma pazarlama varsayılanı yok); verified default false; public profil /doktorlar/[id]
verified-kapılı; üretilmiş yorumlar "örnek değerlendirme" etiketli; eşleştirme skoru boş metriği
inactive sayar. GET /api/cases artık sayfalı zarf döner: {items,total,page,pageSize,totalPages}.
Vitrin iddia dürüstlüğü (v6.8) — HALKA AÇIK METİN YAZARKEN OKU: vitrinde yalnız üründe
kanıtlanabilir iddia bulunur. Kaldırıldı, geri EKLEME: akreditasyon rozetleri (JCI/ISO 9001/
TÜRSAB/TGA/KVKK — belgeli ilişki yok; 4'ü 3. taraf tescilli markası, KVKK ise bir kanun) · demo
metrikler (20k+/40+/4.9) · uydurma hasta yorumları. Kurallar: "uçtan uca / end-to-end şifreleme"
YAZMA (gerçek: TLS + Faz 1 envelope, sunucu KEK → "iletimde ve sunucuda şifreli") · "KVKK/GDPR
kapsamında korunur" gibi hukuki sonuç iddiası yerine "yükümlülüklerini destekleyecek
şekilde tasarlandı" · doktor için "akredite" YOK ("bağımsız"; klinik için "sağlık turizmi yetki
belgeli" = kayıt defterinden doğrulanabilir) · AI dili determinist olamaz ("doğru uzmana
yönlendirir" ✗ → "uygun branşı önerir") · ölçülmemiş hız/oran iddiası YOK ("dakikalar içinde" ✗)
· "güvenli video" değil "şifreli video" (WebRTC DTLS-SRTP) · dil sayısı SPEECH_LANG ile
eşleşmeli (10) ya da sayı verilmemeli. Güven bölümünün 6 kartı (copy.tstrust) kod kanıtlıdır
(consent.ts · crypto.ts · ownership.ts · /admin/doktor-onay · audit.ts · bookingagencySentAt kapısı) — madde eklemeden ÖNCE kod kanıtını göster.
⚠️ Görünür metin YETMEZ:meta/og/twitter/JSON-LD (app/page.tsx) aynı iddia sınıfıdır,
ayrı tara. 🪤 hero "Telehealth and Health Tourism, end to end" + layout.tsx "uçtan uca dijital
sağlık platformu" = hizmet sürekliliği, şifreleme iddiası DEĞİL → dokunma.
Güven ve Gizlilik sayfası (v6.12) — /guven-ve-gizlilik, iddia dürüstlüğünün ANA YÜZEYİ: yukarıdaki
kuralların uzun biçimi; 10 bölüm × 9 dil (copy.tstrustPage · components/aura/trust-safety.tsx).
Sayfanın değeri "neyi iddia etmiyoruz" kutularındadır (kullanıcı kararı) — 5 bölümde: uçtan uca
şifreleme değil (anahtar sunucuda, çünkü klinik özet/tercüme/doktor görünümü sunucuda işlem
gerektirir) · "akredite doktor" demiyoruz · denetim kaydı fail-safe sınırı · silme
crypto-shred değil, fiziken · ihbar adresi ⚖️ TASLAK (uydurma adres YAZMA). Bu kutular bir
istisna değil sayfanın omurgasıdır → sessizce kaldırma; madde eklemeden önce kod kanıtını göster.
⚠️ Sayfa bir Gizlilik Politikası DEĞİLDİR (o belge hâlâ yok) — yerine koyma. /trust buraya 308.
🪤 Letterform wordAfter tuzağı: AURA harf dilimlerinden sonraki ek/noktalama ~12px kopuk
çizilir ("AURA ." / "AURA 'da") → trustPage.wordAfter tüm dillerde boş, noktalama lineAfter'a.
📌 copy.ts'e çok-dilli bölüm eklerken: sectionsuniform tut, bölüme özgü parçaları kökte
tut (aiEmphasis/transferItems) → tests/unit/aura-landing-copyshape() imzası (dizide uzunluk
da imzada) 9 dilde birebir kalır; bölüm-özgü render key ile bağlanır, index ile DEĞİL.
/v2 hero + entry-paths (v6.14) — DOKUNMADAN ÖNCE OKU: sayfa 5 turluk kullanıcı geri
bildirimiyle ayarlandı; aşağıdakiler kullanıcı kararıdır, sessizce değiştirme.
· Video-arkalı kart mimarisi SABİT (kullanıcı: "video gömmesi çok iyi olmuş, sıra doğru"): aktif
kartın kulvar videosu arkada oynar — aktiflik hover + KLAVYE focus + mobilde IntersectionObserver
(hover tek keşif yolu olamaz); preload="none" → açılışta hiçbir video inmez; ekran dışında/sekme
gizliyken hepsi pause.
· 🪤 Kontrastı PERDE DEĞİL KART ZEMİNİ taşır (panel/90 aktif · /75 pasif + backdrop-blur-md).
Daha koyu gerekirse kart zeminini artır, perdeyi değil — düz perde videoyu boğar (v6.14'ün hatası:
night/65+/75 → "video tam seçilmiyor"). Hero skrimi alt-koyu/üst-açık gradyan (0.88→0.40→0.22),
entry perdesi /22.
· 🪤 Hero sahneli açılış (pin+scrub):end: "+=30%" = TOPLAM süre, adım BAŞINA DEĞİL
(v6.14.4'te adım×55+40 yazıldı = ~315vh → "3 kez kaydırmam gerekiyor"; 14× kısaltıldı). stagger
YOK (kullanıcı: "tek yeter") — geri eklenirse pin süresini de büyüt. scrub 0.4.
· ⚠️ A11y sözleşmesi — BOZMA:reduced-motion'da pin/scrub hiç kurulmaz (tüm metin görünür,
normal scroll) · metinler SSR'da DOM'da, gizleme yalnız mount sonrasıgsap.set ile ⇒ JS
yoksa/hata alırsa içerik görünür kalır (fail-open, SEO güvenli). Bu bilinçli scroll-jacking:
wireframe "avoid" diyor, kullanıcı kararıyla yapıldı.
· Marka bloğu (.aura-brand): AURA letterform + tam altında Braille (merkez farkı 0px).
🪤 wordAfter'a dil eki/noktalama yazma (letterform sonrası ~9-12px kopuk çizer → lineAfter'a).
🪤 Glow: "aynı efekt" ≠ aynı değer — aura-breathe blur'u (14/44/90px) letterform ölçeğine göre;
Braille noktası 5.38px (26× fark) → aynı blur görünmez. Braille'in kendi keyframe'i var
(aura-breathe-braille, 3/8/18). İkisinde de sürekli hafif ışıma + hover'da nefes.
/v2 nav (v6.16) — V2Nav neden kök AuraNav'dan AYRI: kök nav /ve/how-it-works
tarafından kullanılıyor; V2Nav'ın "Bakım" sekmesi #care çapasına gider ve o çapa yalnız
/v2'de var (entry-paths) ⇒ kök nav'ı düzenlemek canlı landing'e kırık link koyardı. v2/
klasörü zaten "taşıma anında köke geçer" deseniyle kurulu.
· Ne değişti: dört hizmet sekmesi (Telehealth · İkinci Görüş · Sağlık Turizmi · Ücretsiz Sağlık)
→ tek bakım mimarisi (Bakım · Nasıl Çalışır · Güven ve Gizlilik · Doktorlar İçin). Sayfa "tek
bakım yolculuğu, dört giriş kapısı" derken nav'ın dört ayrı hizmet sıralaması sayfayla
çelişiyordu. Sözlük copy.ts → v2.nav (9 dil); menu/closekök nav sözlüğünden yeniden
kullanılır (t.nav.menu — zaten 9 dilde çevrili, tekrar tanımlama).
· 🪤 nav.cta = hero.ctaPrimary — 9 dilde AYNI etiket (nav.tsx'in "aynı etiket = aynı
niyet" sözleşmesi: ikisi de /giris'e gidiyor). Brand paketinin nav çevirileri v6.14 hero
çevirilerinden ayrı kalemden gelmişti → EN dışında 7 dilde iki farklı etiket çıkmıştı
(TR "Bakımınıza başlayın" vs "Bakım yolculuğunu başlat"). Birini değiştirirsen diğerini de
değiştir. Taşma değil ses sorunuydu: 1024px'te en uzun etiket (TR 187px) ile link grubu
arasında 222px boşluk ölçüldü — uzunluk kısıt değil.
· Hero ikincil CTA → #how (v6.16): etiket "AURA nasıl çalışır?" diyor → 4 adımlık şeride
iner. Önce #care'e gidiyordu = etiketle hedef çelişiyordu.
· Doktorlar İçin → /kurumsal-giris (geçici): todo'daki /for-clinicians rotası gelince oraya
bağlanır. ⚠️ "Doktor" DEĞİL "Doktor" — v4.21 proje-geneli rename (brand paketi "Doktorlar İçin"
önermişti, düzeltildi).
· a11y: mobil panel Escape ile kapanır · dokunma hedefleri 44px (hamburger 36→44) ·
aria-controls/aria-expanded bağlı · çapa dışı hedefler <a> değil <Link> (client-side →
air_lang dil seçimi ve video durumu korunur).
how.tsx 2. adım ikonu (v6.16):SparklesDEĞİLClipboardCheck — yıldız-parıltı AI'yı
ürünün öznesi gibi gösteriyordu; metin zaten doğruydu (v6.8), ikon onunla çelişiyordu. Bölüm
/ve/v2'de ORTAK → değişiklik ikisini birden etkiler.
--aura-accent-stronger (v6.16) — accent'in METİN rolü: gece cyan-500 (= accent, koyu zeminde
9.5 zaten yeterli) · gündüz cyan-800 #0d6470 (beyazda 6.83). 🪤 ÖLÇÜLDÜ:--aura-accent
(#17919e) beyazda 3.76 = WCAG AA'nın (4.5) ALTINDA → gündüz şeridindeki mono üst etiketler ve
adım numaraları eşiği geçmiyordu. Kullanım kuralı: METİN olan accent → -stronger; zemin/border/
ring (bg-…/12, border-…/40) → düz --aura-accent (dekoratif, kontrast eşiği yok). Accent'in
kendisi DEĞİŞTİRİLMEDİ — marka turkuazı yüzeylerde aynı. Kapsam:.aura-light ortak → canlı /
landing'in gündüz şeridi de koyulaştı (kullanıcı onaylı). Gece bantlar hiç etkilenmez (ölçüldü:
9.51 sabit).
/v2 iddia bölümleri (v6.16 Faz 2) — v2/claim-section.tsx: AI sorumluluğu (#ai) +
Erişilebilirlik (#accessibility). TEK bileşen, iki besleme (aynı şekil: eyebrow/headline/intro +
4 madde + not) — sözlük copy.tsv2.ai / v2.accessibility, 9 dil.
· ⚠️ "Neyi iddia etmiyoruz" kutusu bölümün OMURGASI — sessizce kaldırma (/guven-ve-gizlilik ile
aynı kullanıcı kararı). AI kutusu: AI tanı koymaz/tedavi seçmez/klinik yargı üretmez, çıktı
endikatiftir. A11y kutusu: WCAG uyumluluk beyanı YOK (bağımsız denetimden geçilmedi) + Braille
GÖRSEL marka öğesidir, Braille cihazı/ekran okuyucu desteği DEĞİL.
· 🪤 Her madde KOD KANITLI (harita copy.tsv2.ai başlığında: ClinicalDecisionPanel ·
ai-consent · ai-minimize · langDir · reduced-motion · entry-paths klavye · hero fail-open).
Kanıtlanamayan madde GİRMEZ ([[public-claim-honesty]]).
· Bölüme girmeyenler (kasıtlı):sesle dikte — yalnız 3 hasta formunda (triyaj/SO/turizm), TÜM
yüzeylerde değil ⇒ landing'de genel vaat yanıltıcı olurdu (kullanıcı kararı 2026-07-16).
🪤 Turbopack CSS cache (v6.16): globals.css'e yeni bir değişken eklendiğinde dev server bunu
kısmi güncelleyebiliyor — :root tanımı geliyor ama aynı derlemedeki .aura-light override'ı
gelmiyor (aynı dosya, aynı commit). Belirti: token gündüzde gece değerini veriyor ama --aura-accent
doğru. Çözüm: .next sil + dev server yeniden başlat. Ölçüm yapmadan önce token'ın computed
değerini doğrula — yoksa "düzeltmem çalışmadı" diye kaynağı boşuna kurcalarsın.
v6.18 TAŞIMA (2026-07-16) — V2 = ANA SAYFA:/ artık V2Home render eder; /v2 →
permanentRedirect("/"). Geri dönüş: tag landing-eski-v5.9-son (eski bileşenler v6.19'da
SİLİNDİ — 724d601, −769 satır: landing/eski hero/kök nav/motion/client-only; geri dönüş yalnız
tag'ten. chapters.tsx küçültülmüş CANLI: how-it-works ChapterCta+ChapterData kullanır,
AuraChapters artık yok). V2Nav = SİTE GENELİ nav
(/, /how-it-works, /guven-ve-gizlilik, /for-clinicians) — kök AuraNav'ın /#ch-* çapaları yeni ana
sayfada karşılıksız (kullanma). Metadata/JSON-LD yeni konumlandırmada ("Care, without borders."; "end
to end" tamamen çıktı). Açık/koyu ritim (kullanıcı planı): çift-koyu açılış sonrası katı almaşık —
hero(K) entry(K) how(A) connected(K) doctors(A) trust(K) ai(A) accessibility(K) clinicians(A)
closing(K); koyu bölümler sarmalayıcısız (gece token miras), açıklar tekil .aura-light. Koyu kontrast
ÖLÇÜLDÜ (6.48–17.66 AA üstü). [lang] locale rotaları da V2Home (initialLang) + v2 metadata.
v6.17 sözleşmeleri (2026-07-16):
· /v2 bölüm sırası: hero → entry(#care) → how(#how) → connected → doctors → trust →
ai → accessibility → clinicians (+cta → /for-clinicians). Connected/Clinicians da
claim-section beslemesi — her madde kod kanıtlı, harita copy.ts ilgili blok başlığında.
· /for-clinicians: how-it-works sözleşmesi (indekslenir, sitemap 0.7, kendi aura nav/footer —
Header/SiteFooter gizleme listesinde). Sözlük v2.cliniciansiki yüzeyi besler (bölüm + sayfa).
Not kutusu: doğrulama = belge incelemesi, akreditasyon DEĞİL (v6.8).
· V05 + V06 (v6.291, 2026-09-21 — kontrol raporu Paket 5 başlangıcı, 👤 tablo onayı):/for-clinicians kapanışı doktor
başvurusuna gider (AuraClosingcta?: {label, href} prop'u — varsayılan hasta girişi /giris; sayfa v2.clinicians.cta.signup
→ /kayit, yeni sözlük anahtarı YOK); sentetik cta: /kayit. TR mikro metin: "ekle-only" → "yalnızca eklenen ve geriye dönük
değiştirilemeyen" · "Yargınız sizde kalsın." → "Klinik karar sizde." · "FHIR konuşan" → "FHIR standardında yapılandırılmış"
(diğer 8 dil "speaks FHIR" eğretilemesini korur; entegrasyon iması YOK — iddia disiplini). Toplu hekim→doktor ünlü uyumu kalıntıları
düzeltildi (doktorumuz/doktorlarımız, t() çiftleri birlikte) + bekçi testi turkce-unlu-uyumu-bekcisi.test.
· V04 (v6.294, 2026-09-21 — 👤 9 dil tablosu onaylı): how-it-works rehberlerinde ücret/demo sınırları HİZMET BAZINDA — görüşme
{consultFee} USD şikâyet öncesi (simülasyon) · ikinci görüş {soFee} USD peşin tek ödeme, yazılı rapor + video (simülasyon) · turizm
ödemesiz, fiyat görüşmede kesinleşir · ücretsiz kulvar ücret yok. Sözlükte TUTAR YAZILMAZ: yer tutucular render'da lib/aura-landing/fees.ts fillFees ile lib/billing CONSULT_FEE_USD / lib/second-opinion SO_FEE_USD'den dolar (tek kaynak; aura-landing-copy.test 9 dilde yer
tutucu ZORUNLU + literal "60/600 USD" YASAK; aura-landing-fees.test).
· V01 (v6.296, 2026-09-21 — 👤 karar A + demo rozeti; 9 dil tablosu onaylı): hero başlığı AYNI ("Care, without borders." — title/OG/
sentetik h1 değişmedi); alt açıklama hizmet bazlı (dört yol + "uygunluk, kapsam ve ücret seçtiğiniz hizmete göre açıklanır"); ana CTA
"Hizmet seçin" → #care (giriş kartları; hasta girişi nav + footer'da kalır), ikincil "Nasıl çalışır?" → #how; YENİ v2.hero.demo
rozeti ("MVP demo — gerçek ödeme alınmaz.", 9 dil, CTA'ların altında mono); page.tsx meta açıklaması EN alt açıklamanın kopyası;
[lang] rotaları sözlükten alır; sentetik /cta: #care; aura-landing-copy.test V01 kilidi.
· V02 (v6.297, 2026-09-21): footer "Keşfet" çapaları /#ch-consult · /#ch-tourism (v5 landing kalıntısı, ana sayfada KARŞILIKSIZ)
→ /#care-consult · /#care-tourism; giriş kartı kökü (EntryCard<article>) id="care-<key>" (4 kart). YENİ
tests/unit/landing-anchors.test.ts: kök-göreli href="/#x" (src geneli) + landing ağacındaki (home.tsx import zinciri) href="#x"
↔ landing id= eşliği (kart id'leri COPY anahtarlarından); /#ch-* geri gelemez. Sentetik beklenti değişmedi. Paket 5 TAMAM
(V02 · V04 · V05 · V06 · V01 🚪 A).
· Paket 6 kod tarafı (v6.299, 2026-09-21 — 👤 tasarım + 9 dil etiket onayı): hero'da görünür "Hareketi durdur / oynat" (sol-alt pill; AI
rozeti sağ-altta) — tercih lib/aura-landing/motion-pref.ts (air_hero_motion, useSyncExternalStore, SSR "on"; yalnız izleyici kolaylığı,
sunucuya gitmez); "off" → otomatik oynatma kurulmaz; reduced-motion/Save-Data'da otomatik oynatma zaten yok, düğmeden açık istek serbest ·
metin sütununa YEREL eliptik skrim + h1/alt açıklama text-shadow (genel skrim kalır) · rehber videosunda oynatma sonrası sağ-üst
"Duraklat / Devam et" (kullanıcı duraklattıysa görünürlük gözlemcisi yeniden başlatmaz) · 4 sözlük anahtarı × 9 dil (v2.hero.motionPause/ motionPlay, hiw.pause/resume). Medya işi (12–18 sn hero yeniden kesim + ürün demo videosu) 👤 todo — kod dokunulmadan VIDEOS kaynakları değişir.
· /doctorium V3 (v6.166→168, 2026-08-26 — "Apple estetiği" modernizasyon turu; V2'yi süpersede):
bileşenler components/aura/doctorium-v3/ — zebra YOK: hero + 12 bölüm (v6.262; 2026-08-26'da 14'tü) + header + footer tek açık
zemin (V3_LIGHT #fbfbfa; manifesto açık-panel bandı; koyu kutular yalnız ProductFrame ürün
pencereleri) · hero film14 video-zeminli (v1 DoctoriumBgVideo aynen; film13→film14
f809013 2026-08-27 — kullanıcı onaylı marka filmi, VO+müzik taşır) · ses aç/kapa düğmesi sağ
altta (v6.182; v6.180'de kaldırılmıştı, kullanıcı geri istedi — bottom-12, AI şeffaflık
rozetinin ÜSTÜNE istiflenir; yalnız video mount edildiyse render edilir → mobilde yok; autoplay
politikası gereği video daima sessiz başlar) · tipografi Inter tek aile (DoctoriumWordV3 wordmark Inter
semibold cv11/ss01; aura-display/mono v3 yüzeyinde yok, ürün pencereleri hariç) · Framer Motion
bölüm girişleri (FadeInUp 400ms, reduced-motion destekli) · düğme dili A · Yükselme
(ui/button.tsx cva + v3 CtaLink; 🪤 primary'de var(--dl-emerald) KULLANMA — koyu bölümde
nane çözülür, AA düşer) · "Bugün sizin için" yuvası = Doctorium Post tanıtımı. ⚠️ content.ts
v2 arşiviyle PAYLAŞIMLI → v3'e özel metin bölüm dosyasında LOKAL (Post/Identity/FinalCta).
Registry/veri/analytics sözleşmeleri V2'den aynen devralındı (aşağıda). v2 yedeği: tag
doctorium-landing-v2-son + /doctorium-v2 (noindex). Kaldırıldı (596c43b, 2026-08-28):
V3'ün font geçişi doğrulanınca paylaşılan bileşenler (ProductFrame/FeedPreview/
PersonalizationDemo/vb., 8 dosya) doctorium-v3/'e taşındı, /doctorium-v1 + /doctorium-v2
rotaları silindi — geri dönüş yalnız git tag'lerle (doctorium-landing-v1-son /
doctorium-landing-v2-son). Küre marka görselleri -v2 (kenar bake'li, public/brand/).
· v6.262 (2026-09-10, 👤 üç karar + küçük paket) — hero + 12 bölüm: Sorun (+Sektörel sütunu, satır bazlı canShow) · Manifesto ·
Nasıl çalışır (+Etkinlikleriniz = eski "Kontrol sizde") · Sağlık Hukuku 04 (registry testi sırayı kilitler: legal = personalize + 1) ·
Post · Akademik · Kongre (örnek pick.openDeadlineFirst — açık son günlü etkinlik önce) · İlaç & Cihaz · 09 Öğrenciler
(sections/Students.tsx: koral kulvar --dl-coral/--dl-coral-fill, küre + DoctoriumStudentLockup damgası; ProductFrame'de portalın
GERÇEK EduOpportunityRow + TusKpiStrip'i — CareerEduSections.tsx'ten ayrıştırıldı; veri landing-feed studentsProof: DB onaylı
kayıtlar, düşerse lib/edu-opportunities onaylı seed) · 10 Güven (eski Profesyonel alan + Güven: kimlik + 4 şeffaflık maddesi +
deneme paneli, çapa #guven) · Neden Doctorium · Başla (öğrenci student-outline düğmesi + deneme satırı). Deneme satırıTRIAL_LANDING_LINE (lib/doctorium-trial-copy.ts) yalnız isTrialEnabled() açıkken — ücret/ödeme kelimesi GEÇMEZ (👤). Kayıt defteri
+5 verified anahtar (sector.news · student.career_edu · student.tus · student.transition · membership.trial; cap2 kendi
damgasıyla). 🪤 Öğrenci kapsamı sarmalayıcısı: .theme-light ATA + .doctorium-scope[data-audience=student] ALT eleman. 🪤 Yeni
bölüm = SECTIONS + events.ts yerleşim + LandingEventBeacon haritası + registry testi; sıra/numara elle yazılmaz.
· /doctorium V2 — ARŞİV /doctorium-v2 (v6.136, 2026-08-23 — kullanıcının 7 parçalık "Landing Page V2" paketi): anlatı
"modül kataloğu"ndan "her doktor kendi Doctorium'unu oluşturur" kategorisine geçti (marka → ürün
"daha fazla bilgi değil, sizin için doğru bilgi" → günlük "bugün sizin için"; AI hero'da geçmez).
Kod: src/lib/doctorium-landing/ — capability registry (capabilities.ts: verified/partial/
unsupported; yalnız verified+partial render; EMA/TİTCK/ilgi alanı/kaynak seçimi/ülke/sıklık/AI
provenance unsupported → metinde GEÇMEZ) · typed copy content.ts ({Doctorium} → lockup; bölüm
requires) · routes.ts (giriş CTA'sı /doctorium/giris?next=/doktor/doctorium — proxy anonimi hasta
kapısına atar) · landing-feed.ts (gerçek personalFeedPage + 10 dk memo + fixture yedeği; anonim
GET /api/doctorium/landing-feed allowlist+rate-limit) · why.ts (kuraldan türetilmiş "Neden
görüyorum?"). Bileşenler components/aura/doctorium-v2/ — 14 bölüm; ProductFrame = --c-*
tema-takipli gerçek ürün penceresi içinde GERÇEK bileşenler (ArticleCardhrefFor · çıkarılan
LegalSearchBox [demo prop] · CongressList · AcademicSummaryBlock · lib/doc-status.tsstatusRozet) — sahte dashboard YOK. Analytics first-party agregat (LandingEvent günlük sayaç,
POST /api/landing-event; kimlik/IP/UA/URL/tercih YOK → onam gerekmez). v1 yedeği: tag
doctorium-landing-v1-son + /doctorium-v1 (noindex; kaldırıldı 596c43b, 2026-08-28 —
rota+doctorium-landing.tsx birlikte kalktı, izole+tek bağımlıydı). CTA kontrastı (kullanıcı kararı): dolgu #065f46, Doctor BEYAZ + ium NANE
#a7f3d0 (DoctoriumOnEmerald tek kaynak; eski #34d399+beyaz 1.92:1 AA altıydı). Sözleşme testi
tests/unit/doctorium-landing-registry.test.ts; /doctorium artık sentetik kontrol + a11y e2e'de.
· /doctorium v1 (v6.100–100.1, 2026-08-16 — ARTIK /doctorium-v1): Doctorium tanıtım landing'i — for-clinicians gibi
indekslenir + sitemap 0.7 + Header gizleme listesinde, ama V2Nav DEĞİL: kendi üst barı/footer'ı,
TR-only (components/aura/doctorium-landing.tsx). Almaşık koyu/açık ritim (v6.100.1 — ana
vitrin deseni): çift-koyu açılış (hero+güven) → olanaklar A → hukuk K → puanlar A → öğrenci K
(kutu bantta dikey ortalı) → final A → footer K; açık bölümler style={LIGHT} (.aura-light rol
değerleri; zümrüt metin karşılığı #047857, by-AURA wordmark'ı bölüme duyarlı light/dark PNG;
CTA dolgu butonları temadan bağımsız sabit zümrüt). Prizma hero (🪤 prism span'ine
display:block şart — inline'da yükseklik 0'a çöker; ışıma dönüş anında). Marka kuralları:
"Doctorium" her metinde lockup (Doctor beyaz + ium zümrüt, D büyük; zümrüt-zeminli CTA istisna),
"by AURA" imzasında AURA = gerçek wordmark PNG ve yalnız o tıklanır (→ /). Header'da
AURA↔Doctorium marka toggle'ı (DOCTOR/COORDINATOR; ⚠️ v6.103'te 2. nesle geçti — aşağıya
bak; nav'daki Doctorium sekmesi KALKTI) + Doctorium odak modu (portaldayken Doktor/Post-Op sekmeleri
ve menüde Profilim/Finans gizli) + Aşama-1 doktoru AURA'ya geçerken /doktor?from=doctorium →
baslangic?from=aura-gecis Aşama-2 uyarı ekranı (belge listesi + doğrulama şartı).
· v6.102 (2026-08-16):/doctorium/giris kapısı (DoctoriumGate, auth-gates.tsx — zümrüt dönen
sembol + lockup başlık + Doktor/Tıp Öğrencisi rolleri + Google/Apple/e-posta; noindex + Header
gizleme listesinde) · landing arka plan video zemini (DoctoriumBgVideo: hero koyu / final CTA
açık overlay; film2/film3 720p + gate2 kapı videosu). Braille — Doctorium'da KALDIRILDI
(2026-08-21, add6409, kullanıcı kararı):DoctoriumBraille bileşeni ve ⠙⠕⠉⠞⠕⠗⠊⠥⠍
dizesi koddan silindi; kapı başlığı ve landing footer'ı braille'siz. AURA tarafındaki
AuraBraille (⠁⠥⠗⠁, AuraLogo.tsx) DURUYOR. Doctorium'a braille geri EKLENMEZ.
· v6.103 (2026-08-16) — marka toggle'ı 2. NESİL, TEK KAYAN SEMBOL (v6.100'ün "iki logo yan
yana, aktif olan döner" nesli SÜPERSEDE): dönen AuraMarktektir, aktif markanın yuvasında
durur; toggle'da öbür yuvaya kayar ve rengi değişir (AURA turkuaz brand ↔ Doctorium zümrüt
emerald). Renk geçişi iki ton katmanının cross-fade'i — SVG gradyan id'leri prop-sabit
olduğundan CSS ile renk transition'lanamaz. Kayma ölçümlü left transition'ı: yuva konumları
useLayoutEffect + ResizeObserver ile ölçülür (AURA wordmark PNG genişliği yükleme/temaya göre
değişir → sabit px OLMAZ; ilk boyada left: auto→px atlar, bu yüzden ölçüm öncesi gizli).
motion-reduce'ta kayma kapalı; pasif taraf opacity-45. DoctoriumSidebar'da bant tepesindeki
lockup KALKTI (marka artık tek konumda: Header toggle'ı) — bant doğrudan zümrüt nabızla açılır.
· v6.103.1 (2026-08-16) — marka adı temizliği:PortamedLogo.tsx → AuraLogo.tsx (export
PortamedLogo → AuraLogo), PortamedArt.tsx → AuraArt.tsx; 26 dosyada import/JSX/yorum
süpürüldü. Projede "portamed" metni ve dosya adı kalmadı (git grep -i portamed = 0). Tek
bilinçli iz: PublicLocale.tsx'teki pm_locale localStorage anahtarı — eski tercihi
air_langa taşıyan GÖÇ kodu, silinirse o tarayıcılarda dil seçimi sıfırlanır. 🪤 Bu rename
sırasında git mv'nin stage'i paralel oturumun commit'ine karıştı → origin/main bir süre
build-kırık kaldı (deploy ERROR); ders: rename+süpürme+commit tek turda bitirilir.
· Braille kaldırıldı + giriş ekranları logosuz (2026-08-23, v6.138): kullanıcı kararı
"Braille'i kaldırıyoruz" → AuraBraille bileşeni, .aura-braille CSS'i ve aura-breathe-braille
keyframe'i SİLİNDİ (hero, footer lockup, kapılar braille'siz; geri eklenmez). Güven bölümündeki
"AURA altındaki Braille görsel marka öğesidir" cümlesi 9 dilde kaldırıldı (olmayan öğe hakkında
beyan kalmasın — iddia disiplini). Giriş ekranları: üstteki küre/lockup kaldırıldı, AURA bir kez
yazılır — "GLOBAL CARE" başlıktaki AURA'nın altında (WordHeadline globalCare → GlobalCareLine,
wordmark kutusuna hizalı); /doctorium/giris'teki zümrüt küre de kalktı. 🪤 em tuzağı:
font-size'daki em ebeveyne, margindaki em elemanın KENDİ puntosuna göre çözülür → em modunda üst
boşluk .2016/.323 = 0.624em (ilk denemede GLOBAL CARE AURA'ya yapıştı; Playwright ile 6,4px ölçüldü).
· Marka seti v2 — küre + vektör wordmark (2026-08-23, v6.137): sembol artık kullanıcının
holografik küresi (AuraMark/AuraSpinner; 4,6MB kaynak GIF → paketin SVG renk filtresi
karelere pişirilip hqdn3d ile temizlenerek alfa kanallı WebP 160px 352KB / 240px 717KB,
public/brand/; Doctorium = aynı karelerin hue −30° kaydırması, hedef "ium" #34d399). Küre
koyu disk (#0d0e10) üstünde çizilir → açık zeminde yıkanmaz, koyuda görünmez; nabız/hâle
paketin aura-logo.css'inden CSS'e taşındı (.aura-sphere); reduced-motion'da statik PNG'ye
düşer. Wordmark vektör (AuraWordSvg, 742B, HQ PNG'den ÖLÇÜLEREK kurulan 4 yol; IoU 0,976;
R gövdesiz, U kâsesi elips, yatay 56/dikey 61px) — PNG çifti, maske ve 137px harf dilimleri
(assets/letters, hero'da pikselleşiyordu) SİLİNDİ; tüm "AURA" yazımları (nav, header, hero,
kapılar, how/trust, ByAura, metin içi) tek kaynaktan. Tam lockup AuraLockup (küre + AURA +
GLOBAL CARE + braille; oranlar ölçülü: küre 2.65H, GLOBAL CARE .235H/.215H, harfler A-bacak
hizasında) footer + /giris + /kurumsal-giris'te; braille artık GLOBAL CARE'in altında (kural
güncellemesi). Favicon A · koyu disk + küre (favicon.ico turkuaz / icon-doctorium.ico
zümrüt, 16–128), apple-touch + PWA 192/512 B · yuvarlatılmış kare (maskable %80) —
scripts/gen-icons.py küreden üretir; ?v=2→3 (3 layout + manifest + sw), sw.js VERSION
v6→v7. JSON-LD logo → /icon-512.png?v=3. 🪤 Turbopack kısmi CSS önbelleği yeni .sınıfı
dev'de düşürdü → lockup alt yazı stili INLINE. 🪤 Next 16 ikinci next dev'i reddeder (kilit);
paralel oturumun sunucusu aynı ağacı HMR ile servis eder — doğrulama Playwright ile oradan.
· Öğrenci lockup'ı (üç katmanlı üyelik Faz B2 — logo; v6.251 U4, 2026-09-06 — v6.239'un ışık-telli webp
görselini SÜPERSEDE etti): kitle STUDENT olan hesapta Header marka bloğu küre (28 px) + "Doctorium" wordmark'ı
(Inter 600, −0,02em) + altında ince köşeli parantez içinde koral "STUDENT" (Inter 900, 0,4em) çizer — görsel varlık
değil gerçek metin (Header.tsxDoctoriumBrand({student}), stiller .dsl-*globals.css öğrenci paleti bloğunda).
Parantezlerin dış kenarı wordmark'ın MÜREKKEP sınırına hizalı (canvas ölçümü: D sol 0,0625em · m sağ 0,0366em; .dsl-st
kendi puntosu 0,4em olduğundan /0,4 ile çevrilir — em tuzağı); renk --audience-accent (header kromu daima gece →
#fb923c). Sekme başlığı generateMetadata ile "Doctorium Student" (doktor/doctorium/layout.tsx + page.tsx — page'in
absolute başlığı layout şablonunu ezer, ikisi de kitleye duyarlı). Favicon bilinçli DEĞİŞMEDİ (16 px'te üç harf okunmaz).
Mockup turları + kaynak HTML: vault doctorium-marka-arsivi/edu-stu-mockup-2026-09-05/ (sheet9→11, U4). LinkedIn kapak
slaytı 3 de aynı lockup'la yenilendi (linkedin_kapak_seti.py, doctorium-student-lockup-u4-beyaz-2x.png).
· PWA manifest + iOS/push ikonu MARKA-DUYARLI (Faz E, 2026-09-03, v6.207): doctorium.tr'nin manifest'i
"AURA Health" adı ve turkuaz ikonla sunuluyordu (QA 02.09 sızıntı ailesi). Statik public/manifest.webmanifest
SİLİNDİ → src/app/manifest.ts BRAND_MODE'a göre Doctorium/AURA manifest'i üretir (build-time, force-static;
Doctorium açıklaması LANDING_META ile tek kaynak). Doctorium ikon seti apple-touch-icon-doctorium.png ·
icon-doctorium-192/512.png (gen-icons.py, zümrüt küre + aynı B kalıbı, ?v=1); kök layout ikonları deploy'a,
üç Doctorium layout'unun iOS ikonu zümrüte; sw.jsv8 push ikonu/adı HOST'a göre (sw'de env yok).
Sözleşme testi tests/unit/pwa-brand.test.ts (statik manifest geri gelirse / ikon eksikse kırılır).
· PWA marka kabuğu (2026-08-19, 82c2b8f) — 🚀 CANLI: amblem 2026-07-14'te AuraMark'a
geçmişti ama React ağacının DIŞINDAKİ yüzeyler güncellenmemişti; ~2 ay boyunca çevrimdışı
sayfası, push bildirimi ikonu/badge'i, ana ekrana ekleme ve tarayıcı sekmesi eski camgöbeği
üçgen "A"yı gösterdi (favicon daha da eskiydi: 2026-06-04). icon-192/512 · apple-touch-icon ·
favicon.ico (16–256px) güncel amblemden yeniden üretildi — tek jeneratör
scripts/gen-icons.py (AuraLogo.tsx geometrisinden; amblem oranı kare kontrolünden
geçmezse durur). Rakip jeneratörler gen-icons.mjs (eski üçgeni üretiyordu) + extract-logo.py
(kaynağı eski logo dosyası) SİLİNDİ. manifest.webmanifest: "uçtan uca" çıkarıldı (iddia
disiplini — layout.tsx'ten çıkarılmıştı, manifest'te kalmıştı), ad/açıklama layout.tsx ile
hizalandı, theme_color #101010→#0d0e10 (viewport ile çelişiyordu), background_color
#ffffff→#0d0e10 (gece varsayılanda PWA açılış ekranı beyaz patlıyordu). OG/Twitter görseli
p-hero3→p-hero8 (canlı hero v-hero8 iken paylaşım kartı eski filmin karesini
gösteriyordu; 5 sayfa) + beyan edilen boyut 1280×720→1920×1080 (gerçek dosya). offline.html
gece temasına + marka turkuazı #28c8d8'e alındı. global-error.tsx renkleri sabitlendi —
bu bileşen kök layout'u ATLAR, var(--c-*) çözülmez, buton görünmez kalırdı.
🪤 sw.js VERSION v4→v5 ŞART: PRECACHE'teki dosya değişince artırılmazsa mevcut kullanıcı
eski kopyayı görmeye devam eder (cache adı VERSION'dan türer). Temizlik: ~74 MB süpersede varlık
(film2-12, v-hero3) + .gstack/qa-reports — hepsi önce doctorium-video-arsivi/3-eski-surumler'e
yedeklendi. 🪤 Ölü varlık taramasında şablon dizgisi kör noktadır:src={`/assets/${d.img}.jpg`}
gibi yollar basename aramasında görünmez — doc-*.jpg bu yüzden yanlışlıkla silinip geri alındı;
silmeden önce \$\{…\}\.(jpg|png|mp4|webp|svg) desenini ayrıca tara.
· Rotaya göre sekme ikonu (2026-08-19, c918a1b) — 🚀 CANLI: favicon bulunulan markaya göre
değişir — AURA turkuaz #28C8D8, Doctorium zümrüt #34d399; ikisi de marka renginde
dolu daire + tam siyah AuraMark. Eşleme: layout.tsx → /favicon.ico ·
doctorium/layout.tsx (YENİ, yalnız metadata) ve doktor/doctorium/layout.tsx (mevcut
auth+footer layout'una yalnız metadata eklendi) → /icon-doctorium.ico. Alt rotalar segment
mirasıyla kapsanır. 🪤 Dosya konvansiyonu ÇALIŞMADI:src/app/doctorium/icon.ico denendi —
dosya rota olarak servis edildi (HTTP 200) ama Next <link rel="icon"> BASMADI; kök
src/app/favicon.ico alt segment ikonunu bastırıyor. Çözüm: kök favicon.icosilindi,
ikonlar public/ altına alındı, bağlama metadata.icons ile açık yapıldı (segment merge'inde
en derin tanım kazanır). /favicon.ico public'ten servis edildiği için tarayıcının otomatik
isteği de 200 alır. 🪤 Dosya adı ROTAYI gösterir, rengi DEĞİL (icon-doctorium.ico).
🪤 Görsel kurguda 6 tur denendi (beyaz daire + renkli amblem → 2 kez koyulaştırma → dolu daire +
beyaz amblem → + ince siyah kontur → dolu daire + tam siyah amblem) ve renk eşlemesi bir kez
takas edilip geri alındı (Doctorium'un kimliği zümrüt); gerekçeler scripts/gen-icons.py
başlığında — geri dönme. PWA ikonları bu turda DEĞİŞMEDİ (koyu kare + marka gradyanı).
· Hero mobil kaynak:<source media="(max-width:767px)"> → src720 (848KB); masaüstü 1080p
kullanıcı kararı, dokunma. Save-Data → video hiç başlatılmaz. 🪤 WebM DENENDİ ve ATILDI:
VP9 çıktısı (1112KB) mevcut h264 720p'den BÜYÜK — kaynak zaten agresif sıkıştırılmış; eklemeden
önce ölç.
· "Bakım Yolculuğum" = hasta-yüzü ad; rota /vakalarim KALDI, klinik personelde "vaka"
KALIR. v6.20: hasta yüzünde tam rename tamamlandı — SO listesi "İkinci Görüş Yolculuğum"
(köprü "Bakım Yolculuğum"), "Başvuru No"/"Başvurunuz"/"Başvuruyu oluştur" vb.; vitrin TR "başvuru"
ailesi (7 dil zaten case/Fall/dossier). DeleteAccountPanel da v6.272'de "başvuru"ya geçti (A06 5.1 hizası) —
hasta yüzünde "vaka" KALMADI. /takip + /sikayet geri linki rol-duyarlı
(hasta → /vaka/[id], personel → /doktor/vaka/[id]).
· Locale rotaları /en…/bg (app/[lang]): ÇALIŞIR ama bilinçli noindex + sitemap dışı —
"/" hâlâ 9-dil-tek-URL kanoniği (v5.9.1). 📌 Kullanıcı kararı (2026-07-16): KAPALI KALIYOR —
Gizlilik Politikası + gerçek ödeme öncesi indeksleme erken; hukuki metinler nihaileşince yeniden
değerlendirilecek (robots satırı + sitemap + "/" canonical stratejisi birlikte). dynamicParams=false ŞART (kök segment — kaldırılırsa
/herhangi-şey bu rotaya düşer). LangProvider initialLang: URL dili kazanır, air_lang ezilmez.
Video posterleri (v6.14.5) — YENİ/YENİLENEN VİDEO EKLERKEN OKU: poster daima o videonun ilk
karesinden: ffmpeg -i <video> -frames:v 1 -q:v 2 <poster>.jpg. Ad-versiyonla (p-consult2.jpg)
— aynı URL'de içerik değiştirmek edge cache'te eskiyi sundurur. 🪤 4 kulvar posteri eski sürümden
kalmıştı (fark 23-46; hero 0.4 ve HIW 0.7-1.1 kontrol grubuydu) → preload="none" ile
görünür zıplama; poster ortak VIDEOS haritasından geldiği için hata canlı landing'de de vardı.
Ölç, göz kararı yapma: yeni poster ↔ ilk kare farkı < ~1.5 (JPEG payı); en-boy oranı tutmuyorsa
veya video posterden yeniyse şüphelen.
Design token mimarisi (v6.13) — RENK/ÖLÇEK DEĞİŞTİRMEDEN ÖNCE OKU:globals.css'te ÜÇ ayrı
sistem var, karıştırma: (1)--c-* + .theme-light/.theme-dark = sistem geneli (v6.1;
.logo-word-* toggle buna bağlı) · (2)--aura-* + .aura-light = landing/vitrin
(⚠️ landing gündüzü .theme-light DEĞİL .aura-light) · (3).aura-theme-* = kullanıcı
draft'ının getirmek istediği ikinci tema sistemi — ALINMADI, ekleme.
--aura-* iki KATMANDIR: ham palet (:root üstteki blok — cyan-50..900/night/deep-ink/
stone-*/durum renkleri/text/space/radius/shadow/duration/ease/content) = statik kaynak;
rol token'ları (--aura-bg/panel/surface/ink/grey/micro/accent/hairline) = tema değişkeni,
ham paletten değer alır. 🪤 Bileşende ham paleti DOĞRUDAN kullanma (var(--aura-cyan-500)) —
daima rol token'ı (var(--aura-accent)); yoksa o yüzey gündüz temasında sabit kalır = kırılır.
🪤 Yeni renk rolü eklerken gece :root + gündüz .aura-light'a İKİSİNE birden ekle.
Ölçek token'ları tanımlı ama bileşenlere uygulanmadı (mevcut değerler yerinde; taşıma ayrı tur).
⚠️ Draft'tan 2 kasıtlı sapma: stone-100#eff1ec (draft #eef1ec) · border-dark0.09
(draft 0.10) — sıfır-görsel-değişiklik için kod değerleri korundu.
📌 Token'a dokunan değişikliğin doğrulaması: bu ortamda screenshot alınamıyor → değişiklikten
ÖNCE computed-style baseline al, sonra karşılaştır (v6.13 böyle kanıtlandı: dev + prod sıfır diff).
Tipografi / Arapça-Farsça (v6.9) — YENİ YÜZEY EKLERKEN OKU: Inter Kiril kapsar (RU/KK/KY markalı;
subsets YALNIZ preload'u belirler, @font-face diğer subset'leri de içerir) ama hiçbir Latin
ailesi Arap alfabesini kapsamaz → Noto Sans Arabic:lang(ar)/:lang(fa) altında bağlıdır
(globals.css). 🪤 Genel font yığınına sıralamayla eklenemez: next/font her aileye gömdüğü
"<Aile> Fallback" face'inin unicode-range'i U+0-10FFFF'tir → sonra koyarsan "Inter Fallback"
(sistem fontu) Arapçayı kapar ve Noto hiç inmez, önce koyarsan "Noto … Fallback" Latin'i Inter'den
çalar; adjustFontFallback:false etkisiz. ⚠️ ar/fa çizen YENİ yüzeye lang niteliği vermeyi
UNUTMA (JourneyIntakeShell/landing verir; LANG_BCP47[dilAdı] → "ar-SA") — yoksa font sessizce
sistem fallback'ine düşer, tsc/build YAKALAMAZ.
Braille eşiği (v6.9):<AuraBraille height> — height*364/78 < 56px ise hiçbir şey çizmez
(marka kuralı: yeterli netlikle çizilemiyorsa Braille konmaz). Kullanılan iki yer height={12} (=56px).
Küçültmek Braille'i sessizce yok eder.
Ekran-dışı animasyon duraklatma (v6.9):AuraAnimPause (kök layout) tek global IntersectionObserver
ile .aura-sym-*/.aura-word'e .aura-anim-paused (animation-play-state: paused) uygular. Yeni
sürekli dekoratif animasyon eklersen sınıfını bu seçiciye ekle. AuraMark/AuraSpinner KASITLI
hook'suzdur (server-component uyumlu) → içine useEffect koyma; duraklatma dışarıdan uygulanır.
Hata sınırları (v4.17): kök error.tsx + global-error.tsx + not-found.tsx — 10 hasta
dilinde statik gömülü metin (lib/error-i18n.ts), çeviri zinciri/DB'ye bağımlı değil.
Object storage (Vercel Blob): PHI belgelerinin bytes'ı Blob'a yüklenmeden ÖNCE at-rest
şifrelenir (lib/storage.ts) → Blob yalnız ciphertext tutar; URL tahmin-edilemez + asla istemciye
sızdırılmaz (auth'lu rota proxy'ler). Token yoksa eski davranış (şifreli base64-in-DB).
AI veri-minimizasyonu (lib/ai-minimize.ts): SOAP/epikriz/paket AI çağrılarında hasta ADI
Anthropic'e GÖNDERİLMEZ ([HASTA] placeholder); çıktıda gerçek adla geri-yerleştirilir (doktor
görünümü korunur). Klinik içerik AI görevi için gönderilir (de-id sınırı: ad çıkar, semptom kalır).
Partner konsültasyon de-id (lib/ai-clinical.redactPersonNames): partnerin serbest-metnine
yazdığı kişi adları, talep KAYDEDİLMEDEN ÖNCE AI ile [ad]'a maskelenir (yapısal scrub e-posta/TC/
telefonu; bu katman sistemin bilmediği düz adları) → doktor havuzuna hasta kimliği sızmaz.
KVKK/GDPR: gerçek hasta verisi işlemeden önce veri işleme sözleşmeleri (DPA/SCC), AI sağlayıcı
aktarım güvenceleri ve uygun bölge (AB/TR) seçimi gerekir (bkz. vault wiki/kavramlar/).