chat.controller.ts'teki dosya-bağlamı toplama mantığı (belgeler + analiz
özeti + geçmiş mesajlar) buildCaseChatContext() olarak paylaşılan hale
getirildi — mevcut SSE sohbeti (chatMessage) davranış değişmeden bunu
kullanıyor, yeni POST /api/whatsapp/message uç noktası da aynı motoru
tek-seferlik (non-streaming) çağırıyor.
Kimlik doğrulama farklı: bu uç nokta bir Supabase oturumu taşımıyor
(n8n'den gelen anonim WhatsApp mesajı), X-Webhook-Secret ile korunuyor.
Telefon → hesap eşleştirmesi profiles.phone üzerinden, hangi dava
dosyasıyla konuşulduğu whatsapp_sessions'ta tutuluyor (bkz. laawos
sql/20_whatsapp_integration.sql).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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).
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>
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>
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>
- Yeni POST /api/documents/extract-text: dosyayı hiçbir yere
kaydetmeden sadece metnini çıkarıp döner (chat ataç özelliği için)
- chatMessage ve sendThreadMessage artık body'de attachments
({filename,text}[]) kabul ediyor; AI bağlamına ekleniyor, kayıtlı
mesaja da "[Ek dosya(lar): ...]" notu düşülüyor
- chatMessage ayrıca document_ids kabul ediyor — dosya sohbetinde
kullanıcının bu mesajda özellikle işaret ettiği mevcut belge(ler)
AI'ye vurgulanıyor
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sohbet/Asistan sayfasındaki genel sohbetler artık kalıcı: yeni
chat_threads/thread_messages tabloları (cases ile ilişkisiz) ile
sendThreadMessage endpoint'i eklendi. Eski caseId==='general'
(kalıcı olmayan) dalı kaldırıldı, AI çağrısı ortak callAiChat
yardımcısına taşındı.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Belge Şablonları uploads now also get extracted_text (same OCR/office
pipeline as documents), and a new POST /api/drafting/generate builds
a real AI draft from the case's actual data (title, UYAP parties,
latest Dosya Özeti) — if the lawyer picks one of their own templates,
its extracted text is passed as a style/format reference only (the
prompt explicitly forbids copying the template's old case facts).
Dilekçe Hazırlama no longer fakes a draft with setTimeout.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Belge Şablonları now stores real files: POST /api/templates/upload
(multer -> Supabase Storage under templates/<user>/, then a templates
row), GET /api/templates/:id/download-url (short-lived signed URL),
and DELETE /api/templates/:id. Mounted at /api/templates.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
POST /api/cases/:caseId/summarize combines extracted text from all of
a case's documents and runs the existing AI analysis prompt, storing
the result as a case-level analysis (document_id: null). Powers the
"Özet Hazırla" button on the case detail screen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Accepts pre-extracted text (no raw file) from the AyrisLegal Electron
app's local OCR pipeline, matches/creates a case by title, and runs
the existing AI analysis flow. Also fixes a bug in uploadDocument:
officeparser@7.x's parseOffice() now returns a result object with
.toText() instead of a plain string, which was breaking PDF/DOCX
manual uploads.
Takes the user's described situation plus the top search results and
asks the AI model for a short legal assessment. Auth-protected since
it's a paid AI call.
POST /api/cases lets the frontend actually create a new dava dosyası
(no working "Yeni Dosya" flow existed before). chatMessage now
generates a short title from a case's first message (like Claude/
ChatGPT auto-titling) and renames the case, returned as `newTitle`.
Chat panel's trash icon should remove the whole case (not just clear
its chat history) — documents/analyses/chat_messages cascade-delete
via the existing ON DELETE CASCADE foreign keys.
Frontend's chat history trash icon was calling this endpoint but it
didn't exist yet, causing a JSON-parse error on the default 404 page.
Also renames the LegalOS health-check message to AyrisLegal.