L-GEVITY is het platform waar jij jouw huidige en toekomstige gezondheid kunt meten en verbeteren met gerichte leefstijlaanpassingen op basis van bloedwaarden, fitnesstests, biomarkers en slimme algor
The CPAP sleep-data platform: understandable nightly summaries, therapy charts, and your data in the tools you already use. The Mule and Miner bridges your machine to SleepHQ, OSCAR, or your dashboard
8h +1★ 104Health
Site preview image
Do you operate this project?
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Organization repository · verify with a repository file
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
🚀 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/).