3.7 KiB
3.7 KiB
Faz 6 — Müşteri portalı backend geçişi
Tarih: 2026-07-16
Kapsam
Bu faz, mevcut portal görsel yapısını koruyarak tüm portal veri okumalarını ve revizyon mutation akışını Supabase'ten Better Auth + SQLite + domain service katmanına taşır.
Taşınan route'lar:
/portal/portal/projects/portal/projects/:id/portal/tasks/portal/revisions- portal layout/session/branding adapter'ı
- proje detayındaki revizyon talebi Server Action'ı
Veri sözleşmeleri
| Portal alanı | Yeni kaynak |
|---|---|
| Client kimliği | Better Auth session + iki yönlü app_profiles.client_id / clients.auth_user_id bağı |
| Proje listesi ve detayı | client-scoped DomainService.listProjects/getProject |
| Public görevler | DomainService.listTasks; is_public_to_client = true repository filtresi |
| Planning section | client project scope doğrulamasından sonra listPlanningSections |
| Revizyon geçmişi | project/client scoped revision repository |
| Revizyon talebi | actor-derived client, aktif proje ve kota kontrolüyle BEGIN IMMEDIATE transaction |
| Proje dosyaları | authenticated local file route; yalnızca portal visibility |
| Marka verisi | server-rendered local branding service |
Yetkilendirme
- Portal actor yalnızca
requirePortalBackend()tarafından Better Auth session'dan üretilir. - Browser'dan
clientId, owner ID veya auth user ID alınmaz. - Client proje repository sorguları
projects.client_id,clients.idveclients.auth_user_idbağını birlikte doğrular. - Spoofed
authUserId + clientIdactor kombinasyonu proje, görev, revizyon ve dosya erişiminde reddedilir. - Project detail, planning, public task ve revision sorguları foreign project için
NOT_FOUNDdavranışı verir. - Private veya başka client'a ait project asset portal tarafından okunamaz.
- Revision action yalnızca
projectIdve açıklama alır; client kimliği session actor'dan türetilir.
Revizyon kotası
Portal detay adapter'ı toplam kotayı değil server-side hesaplanan kalan hakkı gösterir:
used = rejected olmayan revision kayıtları
remaining = max(project.revision_quota - used, 0)
canRequest = project active && remaining > 0
Talep anındaki nihai kontrol UI sonucuna güvenmez. Service transaction içinde client-project eşleşmesini, proje durumunu ve kullanılmış kotayı yeniden hesaplar. Başarısız insert kota tüketmez.
Dosya ve branding
- Portal-visible proje dosyası client session ile okunabilir.
- Private proje dosyası aynı project client'ı tarafından dahi okunamaz.
- Başka client'a ait portal-visible dosya
NOT_FOUNDdöner. - Client/file scope kontrolünde
clients.auth_user_idbağı ayrıca doğrulanır. - Portal layout application name ve logoları local branding service'ten server-side render eder.
Doğrulama
pnpm phase6:portal-boundary: sekiz portal runtime dosyasında Supabase import/env/erişimi olmadığını ve tüm server adapter'ların session-derived portal actor kullandığını doğrular.pnpm phase2:domain-smoke: cross-client, spoofed actor, private task, foreign planning/revision, inactive project ve kota negatiflerini doğrular.pnpm phase3:storage-smoke: portal/private/foreign/spoofed file authorization'ını doğrular.pnpm phase6:smoke: Better Auth client cookie ile beş portal route'unu SSR eder; local branding, public/private task ayrımı, planning ve revision geçmişini doğrular; foreign project route'unun 404 olduğunu kontrol eder.pnpm typecheck: başarılı.- Faz 6 dosyalarında hedefli ESLint: başarılı.
pnpm build: başarılı.git diff --check: başarılı.
Portal tasarımı ve UX revizyonu Faz 10'a; chat/AI ve business backend'i Faz 7'ye bırakılmıştır.