16 Commits
Author SHA1 Message Date
Mustafa Yildiz 9cd4ccf298 fix: dilekçe kataloğunu tek, DB-destekli kaynağa birleştir (Faz 3.5)
Gerçek bir sessiz veri kalitesi hatası bulundu: laawos-backend'deki dilekçe
kataloğu (petitionKnowledge.ts, 18 tür) ile laawos/Drafting.tsx ekranının
GERÇEKTEN kullandığı frontend kataloğu (petitionController.ts, 79 tür)
birbirinden bağımsız iki ayrı kopyaydı. Drafting.tsx backend'in
/drafting/catalog endpoint'ini hiç çağırmıyordu — kullanıcı ekrandaki 79
türden backend'in bilmediği 61'ini seçtiğinde, AI'ya hiçbir özel talimat/
zorunlu unsur listesi gitmiyordu (resolvePetitionContext sessizce boş
addon dönüyordu).

Yeni petitionCatalogService.ts, frontend'deki daha zengin 79'luk kataloğu
tek doğru kaynak olarak Supabase'e (sql/24_petition_types.sql, laawos
reposunda) taşıyor — 5dk cache + Supabase okunamazsa/migration henüz
çalıştırılmamışsa FALLBACK_PETITION_TYPES'a (programatik olarak birebir
çıkarılmış) düşme garantisi. getPetitionById/resolvePetitionContext artık
async ve bu servisi kullanıyor. Kategoriler (10 adet) kodda sabit kaldı.

Gerçek testle doğrulandı: "Kira Tespit / Kira Uyarlama Dava Dilekçesi"
(TBK m. 344) — eskiden backend'in 18'lik listesinde olmayan, artık doğru
şekilde zengin systemPromptAddon üretiyor.
2026-08-30 13:36:57 +03:00
Mustafa Yildiz b689b0f8fc feat: dinamik AI prompt yönetimi (ai_prompts tablosu + promptService)
20 AI system prompt'unu (chat/analiz/dilekçe/içtihat) koddan Supabase'e
taşıyan promptService.ts eklendi — artık bir prompt metnini değiştirmek
için redeploy gerekmiyor, admin panelden Supabase'e yazılıp 5dk içinde
devreye giriyor (bkz. laawos/docs/DINAMIK_PROMPT_MIMARISI_VE_YONETIMI.md,
laawos/sql/23_ai_prompts.sql — Supabase Studio'da elle çalıştırılmalı).

Canlı kullanıcı olduğu için davranış değişikliği YOK: promptService'in
fallback metinleri bugünkü hardcoded prompt'ların birebir kopyası
(programatik script ile karakter karakter doğrulandı), Supabase migration
çalıştırılmadan/erişilemezken sistem bugünkü gibi çalışmaya devam ediyor.
Bilinçli olarak dokunulmayanlar: model seçimi (tek global AI_MODEL env),
temperature (hiç gönderilmiyor), max_tokens (call-site'a göre değişiyor)
— hiçbiri gerçek AI çağrısına yansıtılmıyor, sadece prompt METNİ dinamik.

chat_intern iki farklı promptun (canlı sohbet vs. anlık soru-cevap) aynı
chat_mode='intern' etiketini paylaştığı görüldüğü için chat_intern_live
ve chat_intern_qa olarak ayrıştırıldı. Ayrıca kodda var olup dokümanda
listelenmeyen doc_strategy, doc_mediation, legislation_keywords, chat_title
ve chat_thread_general de tabloya eklendi.
2026-08-30 12:25:10 +03:00
Mustafa Yildiz dd7fccdd0c feat(drafting): centralize petition knowledge, CMK/HMK procedural rules, and prompt resolver on backend 2026-08-22 19:20:35 +03:00
Mustafa YildizandClaude Sonnet 5 ab20d88422 feat: documents/analyses/drafts Postgres yazmalarını geçiş bayrağının arkasına al
Yerel-öncelikli veri mimarisi (Faz 3) — registerLocalDocument, case.
controller.ts'in 6 fonksiyonu (5 analiz + Dijital Stajyer) ve drafting.
controller.ts'in generateDraft/generateAngarya'sı artık PERSIST_TO_
POSTGRES ortam değişkenine göre davranıyor.

Bayrak varsayılan olarak true (mevcut davranış birebir korunuyor) —
kod deploy'u gerçek davranışı DEĞİŞTİRMİYOR. Kullanıcı gerçek veriyle
Faz 1/2'yi (yerel SQLite'a çift yazma + istekten metin kabul etme) test
edip güvendiğinde, PERSIST_TO_POSTGRES=false ayarıyla (kod değişikliği
gerekmeden) yazmalar durur; geri dönüş de aynı şekilde anlık.

case_events ve chat_messages kapsam dışı, dokunulmadı. Angarya taslakları
için bilinen bir sınırlama var: Faz 1'de yerel dual-write eklenmediğinden,
bayrak kapatıldığında bu taslaklar hiçbir yerde kalıcı olmayacak.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 00:31:59 +03:00
Mustafa Yildiz a5946eeb4a feat: Dava Özeti, Çelişki Avcısı ve Dilekçe Taslağı'na mevzuat entegrasyonu
mevzuat-etl'in doldurduğu Supabase mevzuat/mevzuat_madde tablolarından
(aynı proje) ilgili kanun maddelerini bulup analiz/taslak üretiminden önce
prompt'a ekliyor. Bulma: önce dava metnindeki açık atıfları regex ile yakala
(TCK m.141, 5237 sayılı Kanun'un 141. maddesi gibi, tur-agnostik), boşsa
precedent.controller.ts'deki AI-keyword-sıkıştırma + tam-metin arama
desenine düşer. Hiçbir zaman exception fırlatmaz, mevzuat bulunamazsa analiz
normal devam eder.

Dilekçe Taslağı (generateDraft) farklı ele alınıyor — çıktısı JSON değil düz
metin ve aynen dilekçe belgesi olarak kullanılıyor, bu yüzden referans
bloğu ayrıca işaretlenip sistem promptuna "kopyalama, sadece atıf yap"
talimatı eklendi. generateAngarya (Süre Tutum/Mazeret/Vekaletname) bilerek
dışarıda bırakıldı — hukuki tartışma içermeyen idari dilekçeler.

Tasarım: mevzuat-etl/docs/superpowers/specs/2026-08-17-laawos-mevzuat-entegrasyonu-design.md

Not: drafts.used_legislation (jsonb) sütunu Supabase Studio'dan elle eklendi.
2026-08-17 00:46:26 +03:00
Mustafa Yildiz 66a3960d90 fix: Ollama KEEP_ALIVE=-1 ve AbortError mesaj netliği, callAiModelRaw'a opsiyonel timeoutMs
KEEP_ALIVE '30m' -> -1: GPU'da bolca boş VRAM var, modeli sürekli bellekte
tutmanın maliyeti yok, 30dk sınırı gereksiz soğuk-başlangıç gecikmelerine
sebep oluyordu (bkz. 2026-08-14 log: 44GB boş / 17.5GB kullanılan).
2026-08-17 00:46:10 +03:00
mstfyldz a6c1eabaad fix: default OCR prompt to markdown output
Kullanıcı OCR sonuçlarının markdown formatında gelmesini istedi — test
edildi (gerçek çok sayfalı taranmış evrakta doğrulandı), tablo/başlık
yapısını doğru yakalıyor.
2026-08-11 10:28:19 +03:00
mstfyldz 97ec7cd7f8 feat: DeepSeek-OCR endpoint + GPU request queue for AI calls
Mizan ve DeepSeek-OCR aynı self-hosted GPU'yu paylaşıyor; backend'de hiçbir
eşzamanlılık sınırı yoktu, yoğun anlarda istekler Ollama kuyruğunda 90sn'yi
aşıp sessizce "başarısız" görünüyordu. aiQueue.ts, GPU'ya giden istek sayısını
sınırlayıp fazlasını backend'de bekletiyor.

Yeni POST /documents/ocr-image, tek bir görseli DeepSeek-OCR ile metne
çeviriyor (Electron tarafındaki çok sayfalı TIFF/taranmış PDF işleme
adımının kullanacağı uç, ayrı bir PR'da bağlanacak).
2026-08-11 10:12:33 +03:00
mstfyldzandClaude Sonnet 5 ce6fa9deae feat: Google Drive restore endpoints (Faz 3)
GET /api/google-drive/backup-files: kullanıcının senkronize
edilmiş dosyalarının listesi (PRD §28 "N dosya bulundu"). GET
/download: bir dosyayı Drive'dan proxy'leyip ham baytları döner —
istenen drive_file_id'nin gerçekten bu kullanıcıya ait olduğu
önce doğrulanıyor (PRD §39, başka kullanıcının backup'ı sızmasın).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 04:24:56 +03:00
mstfyldzandClaude Sonnet 5 313d5b72ef feat: Google Drive backup upload endpoint (Faz 2 — backend half)
POST /api/google-drive/upload: Electron'un backupQueue'sunun
gönderdiği tek dosyayı alıp Google'ın resumable upload session'ıyla
Drive'a yazıyor (mevcutsa aynı drive_file_id'yi PATCH ederek yeni
sürüm olarak, PRD Test 4). Dava başlığı = Drive'daki alt klasör adı
(lokal yapı korunuyor). GET /backup-status: Ayarlar > Yedekleme
paneli için toplam dosya/boyut/son senkron özeti.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 04:14:27 +03:00
mstfyldzandClaude Sonnet 5 328aef91bd feat: Google Drive backup OAuth (Faz 1 — backend)
PRD "AyrisLegal Google Drive Backup & Recovery" kapsamında sadece
backend altyapısı: OAuth connect/callback/status/disconnect/refresh
uç noktaları, AES-256-GCM token şifreleme (tokenCrypto.ts), tek
kullanımlık CSRF state (oauthState.ts), drive.file scope ile
AyrisLegal/Davalar klasör oluşturma (googleDriveClient.ts). Electron
tarafı (dosya tarama/kuyruk/UI) ayrı bir aşamada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 03:51:02 +03:00
mstfyldzandClaude Sonnet 5 029402a620 fix: raise num_predict for interactive chat to stop mid-sentence cutoffs
800 token sınırı çok düşüktü — çok bölümlü hukuki cevaplar (kira feshi,
tazminat hesabı gibi) bu sınıra çarpıp cümlenin ortasında kesiliyordu.
Varsayılan ve chatMessage/sendThreadMessage'ın kullandığı num_predict
2048'e çıkarıldı. Ayrıca Ollama done_reason:"length" döndürdüğünde
(yanıt sınıra çarpıp kesildiğinde) sunucu loglarına uyarı yazılıyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 00:35:00 +03:00
mstfyldzandClaude Sonnet 5 bcc78ce304 perf: switch all AI calls to native Ollama endpoint, add streaming + keep_alive
Tüm AI çağrıları artık ortak lib/aiClient.ts üzerinden gidiyor:
- /v1/chat/completions yerine native /api/chat (think:false burada
  güvenilir çalışıyor)
- keep_alive:30m ile model her istekte bellekten atılıp soğuk
  başlamıyor
- num_predict ile öngörülemez uzunlukta üretime üst sınır
- İnteraktif sohbet uç noktaları (chatMessage, sendThreadMessage)
  artık SSE ile token token akıtıyor
- Dosya sohbetinde varsayılan olarak belgenin tam metni değil analiz
  özeti gönderiliyor; tam metin sadece kullanıcı açıkça isterse
  eklenir

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 00:21:49 +03:00
mstfyldzandClaude Sonnet 5 c939dcf564 feat: iddianame-first case summary + remove hardcoded AI endpoint
- summarizeCase: if an iddianame is among the case's documents, run a
  narrow first-pass analysis on it alone (isnatEdilenSuc, iddiaOzeti,
  onemliTarihler), then feed that as context into the general
  case-wide evaluation instead of treating every document equally.
- ANALYSIS_SYSTEM_PROMPT no longer asks the AI to guess "taraflar" -
  that now comes from real UYAP data (cases.parties) instead.
- Removed the hardcoded RunPod proxy URL fallback from every call
  site (document/chat/precedent controllers + lib/openai.ts) - it was
  a real infra endpoint checked into source. New lib/aiConfig.ts
  throws if RUNPOD_API_BASE_URL isn't set rather than silently
  falling back to it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-09 20:00:06 +03:00
mstfyldzandClaude Sonnet 5 99d4d770d5 feat: add POST /api/cases/parties to store UYAP taraf bilgileri
The UYAP extension now captures the davaci/davali/sanik + vekil data
from the "Taraf Bilgileri" tab and sends it once per case. This
endpoint finds/creates the matching case by title (same lookup used
by registerLocalDocument, now shared via lib/caseLookup.ts) and stores
it in a new cases.parties column - a much more reliable source for
the case detail screen's "Taraflar" info than the AI's own guess from
OCR'd document text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-09 19:29:53 +03:00
mstfyldz df70520ede Initial commit 2026-08-08 17:19:28 +03:00