diff --git a/docs/self-hosted-redesign/neta-react-native-mobile-master-plan.md b/docs/self-hosted-redesign/neta-react-native-mobile-master-plan.md new file mode 100644 index 0000000..7662b38 --- /dev/null +++ b/docs/self-hosted-redesign/neta-react-native-mobile-master-plan.md @@ -0,0 +1,1696 @@ +--- +title: Neta React Native Mobil Uygulama Ana Planı +description: Domain ile self-hosted Neta instance'larına bağlanan freelancer ve müşteri mobil uygulaması için ürün, API, mimari, ekran ve yayın planı. +status: planned +current_phase: "phase-0" +last_updated: 2026-07-25 +owners: + - mobile + - backend-api + - product +related_documents: + - phase-9-mobile-api.md + - adr-0018-device-pairing.md + - neta-multilingual-i18n-master-plan.md + - neta-self-hosted-v3-master-plan.md +--- + +# Neta React Native Mobil Uygulama Ana Planı + +## 1. Neta nedir? + +Neta; freelancer'ların ve küçük stüdyoların kendi iş süreçlerini tek bir +self-hosted sistemden yönetebildiği, aynı zamanda müşterilerine ayrı portal hesabı +açabildiği bir iş ve iletişim platformudur. + +Freelancer tarafında Neta'nın ana sorumlulukları: + +- Müşteri ve müşteri ilişkilerini yönetmek. +- Proje, proje planı, görev, ilerleme ve revizyon süreçlerini takip etmek. +- Takvim, finans, günlük ve analiz verilerini tek yerde toplamak. +- Teklif, fatura, sözleşme ve abonelik gibi ticari kayıtları yönetmek. +- Yapay zekâ destekli sohbet, proje risk analizi ve finans analizi sunmak. +- Workspace adı, light/dark logo, favicon, renkler, görünüm, dil ve AI + sağlayıcısı gibi instance ayarlarını self-host eden kişinin yönetmesini sağlamak. +- Türkçe ve İngilizce ile başlamak; yeni dillerin ve domain içerik + çevirilerinin admin tarafından eklenebilmesini sağlamak. + +Müşteri portalı tarafında Neta'nın ana sorumlulukları: + +- Müşterinin kendisiyle paylaşılan projeleri ve ilerlemeyi görmesi. +- Public olarak paylaşılan görevleri takip etmesi. +- Proje planını ve proje detayını kendi dilinde incelemesi. +- Revizyon hakkını görmesi ve yeni revizyon talebi oluşturması. +- Profil, şifre, tema ve adminin aktif ettiği diller arasında kendi tercihini + yönetmesi. + +Mobil uygulama ayrı bir SaaS backend'e bağlanmayacaktır. Her kullanıcı, +kendisinin veya hizmet aldığı freelancer'ın self-host ettiği Neta domain'ine +bağlanır. Dolayısıyla mobil uygulama genel bir Neta istemcisidir; veri sahibi, +kimlik sağlayıcısı ve iş mantığı girilen domain'deki Neta instance'ıdır. + +## 2. Mobil ürün vizyonu + +Temel akış: + +```text +Uygulama açılır + -> Kullanıcı Neta domain'ini girer + -> Instance discovery ve güvenlik kontrolü yapılır + -> Workspace markası, tema, diller ve yetenekler yüklenir + -> Kullanıcı email/şifre ile giriş yapar + -> /api/v1/me kullanıcı rolünü döndürür + -> Freelancer ise yönetim uygulaması açılır + -> Client ise müşteri portalı açılır +``` + +Tek bir iOS/Android uygulama paketi iki rolü de destekleyecektir. Aynı domain +ekranı, aynı auth altyapısı ve aynı API client kullanılır; authenticated shell +ve izin verilen ekranlar role/capability ile ayrılır. + +### 2.1. Birinci sürüm hedefi + +Birinci üretim sürümünde: + +- iOS ve Android desteklenecek. +- Domain discovery, email/şifre girişi, güvenli oturum ve çıkış olacak. +- Freelancer için dashboard, müşteriler, projeler, görevler, takvim, finans, + günlük, analiz, AI sohbet ve temel ayarlar bulunacak. +- Müşteri için portal dashboard, projeler, proje detayı, görevler, + revizyonlar ve kişisel ayarlar bulunacak. +- Instance branding, light/dark tema ve instance tarafından yönetilen diller + mobilde uygulanacak. +- Dinamik içerik formları aktif diller kadar tab/panel sunacak. +- Read cache bulunacak; internet olmadan yapılan mutation ilk sürümde sessizce + kuyruğa alınmayacak. +- Tek aktif instance ile başlanacak; veri modeli birden fazla kayıtlı instance'a + geçişi engellemeyecek. + +### 2.2. İlk sürüm dışında kalabilecekler + +- Tam offline mutation ve çakışma çözümü. +- Apple/Google sosyal giriş. +- Tablet için tamamen ayrı bilgi mimarisi; responsive two-pane destek yeterli. +- Müşteri ile freelancer arasında gerçek zamanlı genel mesajlaşma; mevcut AI + sohbetiyle karıştırılmayacak. +- Her self-hosted instance için ayrı App Store binary/white-label build. +- Background sync ile sınırsız veri indirme. + +## 3. Mevcut codebase incelemesi ve mobil hazırlık durumu + +Web uygulaması Next.js 16, React 19, Better Auth, SQLite, better-sqlite3 ve +Drizzle ORM üzerindedir. Supabase uygulama runtime'ından çıkarılmıştır. +Domain iş kuralları `DomainService` ve owner/client scope kontrolleri içinde +toplandığı için aynı servislerin REST API route'larından tekrar kullanılması +mümkündür. + +### 3.1. Bugün hazır olan mobil sözleşmeler + +| Endpoint | Durum | Mobilde kullanımı | +| --- | --- | --- | +| `GET /.well-known/neta` | Hazır | Domain discovery, instance ID, API linkleri, diller ve capability | +| `GET /api/v1/meta` | Hazır | Workspace, branding, minimum client sürümü ve capability | +| `GET /api/v1/health` | Hazır | Instance readiness kontrolü | +| `GET /api/v1/me` | Hazır | User, role, client bağı, tercih ve locale sonucu | +| `PATCH /api/v1/me/preferences` | Hazır | Kullanıcı dil ve tema tercihi | +| `GET /api/v1/localization/catalog` | Hazır | Instance tarafından özelleştirilen UI katalogları | +| `/api/auth/*` | Web için hazır | Better Auth native entegrasyonu ve multi-domain testi gerekli | +| `POST /api/files` | Web API olarak hazır | v1 envelope, absolute URL ve mobil upload kontratı gerekli | +| `GET /api/files/:id` | Hazır | Yetkili dosya görüntüleme; native auth testi gerekli | + +### 3.2. Mobil için henüz eksik backend yüzeyi + +Müşteri, proje, görev, takvim, finans, günlük ve business işlemlerinin +çoğu Server Action veya doğrudan server component veri yüklemesi kullanıyor. +Mobil uygulama Server Action çağırmayacak. Bunlar `/api/v1` altında kaynak +API'lerine dönüştürülmelidir. + +Mevcut `DomainService` şu alanları destekliyor ve yeni API route'ları bu katmanı +kullanmalıdır: + +- Clients ve client activities. +- Projects, planning sections, project tasks ve revisions. +- Tasks. +- Calendar events. +- Finance transactions. +- Journal entries. +- Chat sessions ve messages. +- Dashboard ve analytics hesapları. +- Proposals, contracts, invoices ve subscriptions. + +### 3.3. Mevcut auth kararındaki açık nokta + +`phase-9-mobile-api.md` bugün Better Auth cookie session'ını ilan ediyor; +`adr-0018-device-pairing.md` ise owner cihazları için opaque access/refresh token +pairing modelini kabul edilmiş fakat uygulanmamış karar olarak tutuyor. + +Güncel Better Auth, Expo istemcisi için `@better-auth/expo` ile cookie'leri +`expo-secure-store` içinde saklayan resmi bir native akış sunuyor. Hızlı MVP +için en kısa yol budur; fakat mevcut ADR sessizce geçersiz sayılamaz. + +Faz 0'da zorunlu karar: + +1. Multi-domain runtime base URL ile Better Auth Expo entegrasyon spike'ı yapılır. +2. Cookie izolasyonu, revoke, şifre değişikliği, disabled user ve restore + davranışı test edilir. +3. Sonuç yeterliyse ADR-0018, resmi native secure-cookie modelini ilk sürüm + olarak kabul edecek biçimde revize edilir; device pairing ikinci güvenlik modu + olur. +4. Sonuç yeterli değilse ADR-0018 aynen uygulanır ve owner mobil girişi pairing + tamamlanmadan production'a çıkmaz. +5. Client portal oturumu için de ayrı lifecycle kararı kayda geçirilir. + +Bu planın geri kalanı hızlı MVP için resmi Better Auth Expo secure-cookie +entegrasyonunu varsayar; Faz 0 kalite kapısı bu varsayımı onaylamak zorundadır. + +## 4. Temel mimari kararlar + +### 4.1. React Native dağıtımı + +Tercih edilen başlangıç: + +- Expo tabanlı React Native. +- Expo Router ile typed file-based routing. +- TypeScript strict mode. +- iOS ve Android için development build; Expo Go yalnız ilk UI spike'larında. +- EAS Build kolay yol olarak desteklenir; local Xcode/Gradle build zorunlu fallback + olarak belgelenir. Self-host backend kullanmak EAS'e bağımlı değildir. + +Expo Router yeni Expo projeleri için resmi öneridir ve typed route, deep link ve +native stack/tab yapısı sağlar. Kaynaklar: + +- [Expo Router introduction](https://docs.expo.dev/router/introduction/) +- [Expo authentication and protected routes](https://docs.expo.dev/router/advanced/authentication/) +- [Better Auth Expo integration](https://better-auth.com/docs/integrations/expo) +- [Expo local data storage guidance](https://docs.expo.dev/develop/user-interface/store-data/) + +Sürüm numaraları plana sabitlenmeyecek. Mobil uygulama bootstrap edildiği gün +stabil Expo SDK ve onunla uyumlu React Native sürümü seçilip lockfile'a +sabitlenecektir; canary/beta sürüm production tabanı olmayacaktır. + +### 4.2. Repository yerleşimi + +Mevcut Next.js kökünü taşımak ilk mobil fazda gereksiz risk yaratır. Önerilen +kademeli workspace yapısı: + +```text +neta/ + app/ # mevcut Next.js web uygulaması + server/ # mevcut backend/domain katmanı + mobile/ # Expo React Native uygulaması + src/app/ # Expo Router route'ları + src/features/ # dikey feature modülleri + src/components/ # mobil ortak UI + src/lib/ # API, auth, i18n, theme, storage + assets/ + app.config.ts + eas.json + package.json + packages/ + api-contracts/ # transport-safe tip/schema ve API contract'ları + design-tokens/ # DOM bağımsız semantik tokenlar + pnpm-workspace.yaml +``` + +Kurallar: + +- Web uygulaması ilk aşamada `apps/web` altına taşınmayacak. +- `server-only`, Next.js, Drizzle veya better-sqlite3 mobil bundle'a import + edilmeyecek. +- Paylaşılan paketlerde yalnız JSON-safe tipler, Zod şemaları, enumlar ve saf + yardımcılar bulunacak. +- API contract paketinin runtime bağımlılığı minimum tutulacak. + +### 4.3. Poyraz UI ve mobil tasarım sistemi + +Mevcut `poyraz-ui` React, Tailwind, Radix ve web DOM odaklıdır; React Native +içinde doğrudan kullanılamaz. Mobilde tasarım dili korunacak, web component +implementasyonu taşınmayacaktır. + +Mobil UI yaklaşımı: + +- `packages/design-tokens`: renk rolleri, spacing, radius, typography ve shadow + değerleri. +- `mobile/src/components/ui`: `Button`, `TextField`, `SelectSheet`, `Card`, + `StatCard`, `Badge`, `Tabs`, `SegmentedControl`, `Dialog`, `BottomSheet`, + `Toast`, `EmptyState`, `Skeleton`, `Screen`, `Header` gibi Neta primitives. +- Başlangıçta React Native `StyleSheet` ve semantik tokenlar kullanılacak; + yalnız gerçek ihtiyaç varsa yeni styling dependency eklenecek. +- Web'deki `default`, `secondary` ve `shine` davranışı native press/animation + diliyle yeniden yorumlanacak. Hover mobil kontrat değildir; pressed, focused, + disabled ve loading state'leri tanımlanacak. +- Light/dark kontrastı ve dynamic primary/accent renkleri aynı semantik rollerle + uygulanacak. + +### 4.4. İstemci katmanları + +```text +Screen / Route + -> Feature hook + -> Query veya mutation + -> Instance-bound API client + -> /api/v1 + -> auth/actor + -> DomainService + -> repository / SQLite +``` + +Ekranlar ham `fetch` çağrısı yapmaz. Her istek aktif instance kaydından türetilen +API client üzerinden gider. + +### 4.5. İstemci state sınırı + +- Server state: TanStack Query. +- Küçük local UI state: React state/reducer. +- Aktif instance, onboarding ve public metadata: küçük bir external store veya + context; büyük global state kütüphanesi ilk günden eklenmez. +- Token/cookie: SecureStore ve Better Auth native adapter. +- Secret olmayan instance listesi, katalog cache metadata'sı ve query cache: + AsyncStorage veya seçilen kalıcı cache adapter. +- Form state: Basit formlarda controlled input; çok dilli/büyük formlarda + React Hook Form ve ortak Zod şemaları. + +## 5. Domain bağlantısı ve instance discovery + +### 5.1. Domain giriş ekranı + +Alanlar ve davranış: + +- Tek input: `neta.example.com` veya `https://neta.example.com`. +- Kullanıcı protokol yazmazsa production'da `https://` eklenir. +- Path, query, fragment ve URL credential reddedilir. +- Domain normalize edilince ekranda son origin gösterilir. +- `Bağlan` aksiyonu loading, timeout ve tekrar dene durumuna sahiptir. +- Son başarılı instance, oturum yoksa hızlı seçim kartı olarak gösterilebilir. +- QR ile instance URL okuma ikinci iterasyonda eklenebilir; QR içeriği yine aynı + validasyondan geçer. + +### 5.2. Discovery state machine + +```text +idle + -> normalizing + -> discovering + -> validating-discovery + -> checking-health + -> loading-meta + -> loading-public-catalog + -> ready-for-auth + +Her adım -> recoverable-error | incompatible | unhealthy | tls-error +``` + +Sıralama: + +1. Origin normalize edilir. +2. `GET /.well-known/neta` en fazla tanımlı timeout ile çağrılır. +3. En fazla üç redirect izlenir; HTTPS'ten HTTP'ye downgrade reddedilir. +4. `protocol === "neta"` ve desteklenen `discoveryVersion` doğrulanır. +5. Discovery içindeki API URL'lerinin aynı güvenilir origin'de kaldığı + doğrulanır. +6. `GET /api/v1/health` ile DB/migration readiness kontrol edilir. +7. `GET /api/v1/meta` alınır; `instance.id === discovery.instanceId` + doğrulanır. +8. Mobil client sürümü `minimumSupportedVersion` ile karşılaştırılır. +9. Platform ve gerekli capability kontrol edilir. +10. Branding ve public localization catalog yüklenir. +11. Secret olmayan instance metadata'sı yerel kayda yazılır. +12. Auth ekranı workspace logosu ve adıyla açılır. + +Temel mobil uyumluluğu `capabilities` string listesinde `mobile-v1` ile ilan +edilir. Sürüm, durum ve rol/erişim detayları ayrı `capabilityDetails` listesinden +okunur; `planned` kayıtlar kullanılabilir feature olarak değerlendirilmez. + +### 5.3. HTTP geliştirme politikası + +- Production binary remote HTTP origin'e credential göndermez. +- `localhost`, `127.0.0.1`, Android emulator `10.0.2.2` ve açıkça tanımlanmış + LAN development adresleri yalnız development build'de kullanılabilir. +- TLS sertifika hatası için `yine de devam et` butonu production'da bulunmaz. +- Instance origin değişirse credential otomatik taşınmaz. +- Aynı origin daha sonra farklı `instanceId` döndürürse restore/yeni instance + uyarısı verilir ve eski session silinir. + +### 5.4. Yerel instance kaydı + +```ts +type StoredInstance = { + origin: string; + instanceId: string; + apiBaseUrl: string; + workspaceName: string; + lightLogoUrl: string | null; + darkLogoUrl: string | null; + faviconUrl: string | null; + discoveryVersion: number; + apiVersion: string; + catalogVersion: number; + lastConnectedAt: string; +}; +``` + +Secret storage key'leri `instanceId` ile namespace edilir. Aynı kullanıcının +farklı Neta kurulumlarındaki cookie veya tokenları birbirine karışmaz. + +## 6. Authentication ve oturum yönetimi + +### 6.1. Login akışı + +1. Instance discovery tamamlanır. +2. Runtime `baseURL = instance.origin` olan Better Auth native client oluşturulur. +3. Kullanıcı email ve şifre girer. +4. Better Auth `signIn.email` akışı kullanılır. +5. Native cookie/session materyali SecureStore'da instance'a özel prefix ile tutulur. +6. `GET /api/v1/me` çağrılır. +7. `role=freelancer` owner shell'e, `role=client` portal shell'e gider. +8. `disabled`, eksik client bağı veya süresi geçmiş session 401 olarak temizlenir. + +Login ekranında dil seçici olmayacak. Public auth ekranı instance default locale +ile gelir. Girişten sonra `/me.localization.resolvedLocale` kullanılır. + +### 6.2. Server tarafında gerekli auth değişiklikleri + +- `@better-auth/expo` server plugin'i eklenir. +- `neta://` production scheme trusted origin allowlist'e eklenir. +- Development `exp://` wildcard'ları yalnız development config'de açılır. +- Native login, logout, session refresh, password change ve cookie propagation + gerçek cihazda test edilir. +- CORS/header davranışı reverse proxy arkasında test edilir; native client + geldi diye web origin kontrolleri gevşetilmez. +- Auth audit event'lerine `client: mobile`, platform ve app version gibi hassas + olmayan alanlar eklenebilir. +- Rate limit login ve password endpoint'lerinde korunur. + +### 6.3. Session davranışı + +- App foreground'a geldiğinde session tamamen her render'da değil, stale süresi + dolmuşsa kontrol edilir. +- Her authenticated 401 sonrası tek bir session yenileme/doğrulama denemesi yapılır. +- Yenileme başarısızsa query cache temizlenir ve login ekranına gidilir. +- Logout server'a gönderilir; başarısız olsa bile cihazdaki session materyali + güvenli biçimde temizlenir ve kullanıcı bilgilendirilir. +- Şifre değişikliğinde server politikasına göre mevcut/tüm session'lar revoke edilir. +- App switcher snapshot'larında hassas finans ve profil verisi gizlenebilir. + +### 6.4. Register ve invitation + +- Mobil uygulamadan ilk self-host admin hesabı oluşturmak v1 hedefi değildir; + instance ilk kurulumu web üzerinden tamamlanır. +- Portal müşterisi davet linkini mobilde açtığında universal link ile app'e + gelebilir. +- Davet kabul akışı ilk sürümde güvenli web ekranına yönlendirilebilir; tam + native kabul daha sonraki fazda API sözleşmesiyle eklenir. +- Password reset linkleri deep link ile mobile dönebilir; ilk iterasyonda web + fallback her zaman korunur. + +## 7. API v1 genel sözleşmesi + +### 7.1. Ortak yanıt + +Başarı: + +```json +{ + "ok": true, + "data": {} +} +``` + +Hata: + +```json +{ + "ok": false, + "error": { + "code": "VALIDATION_ERROR", + "message": "Debug/fallback message", + "details": { + "messageKey": "validation.project.nameRequired", + "fieldErrors": { + "name": ["validation.required"] + } + } + } +} +``` + +Mobil mantık `message` string'ine bağlanmaz. Akış `code`, alan hataları +`fieldErrors`, kullanıcı metni `messageKey` ile çözülür. + +### 7.2. Ortak request header'ları + +- `Authorization` veya Better Auth native session header/cookie'si. +- `Accept: application/json`. +- `Accept-Language: `. +- `X-Neta-Client: mobile`. +- `X-Neta-Client-Version: `. +- `X-Neta-Platform: ios|android`. +- Mutation'larda `Idempotency-Key` desteklenmesi önerilir. + +### 7.3. Listeleme sözleşmesi + +Yeni liste endpoint'leri baştan cursor pagination ile tasarlanır: + +```http +GET /api/v1/projects?cursor=opaque&limit=30&status=active&search=neta +``` + +```json +{ + "ok": true, + "data": { + "items": [], + "pageInfo": { + "nextCursor": null, + "hasNextPage": false + } + } +} +``` + +- `limit` default 30, maksimum 100. +- Cursor opaque'tir; client DB ID/timestamp birleşimini varsaymaz. +- Filtre ve sort allowlist ile doğrulanır. +- Search normalize edilir ve maksimum uzunluğa sahiptir. + +### 7.4. Tarih, para ve ID + +- Timestamp: UTC ISO-8601. +- Yalnız takvim günü ifade eden alan: `YYYY-MM-DD`. +- Para: integer minor unit + ISO 4217 currency. +- Yüzde: integer 0–100 veya sözleşmede belirtilen basis point. +- ID: opaque string; client UUID olduğunu varsaymaz. +- Kullanıcı timezone'u `/me/preferences` içinde döner ve görsel formatlamada + kullanılır. + +### 7.5. Lokalize resource sözleşmesi + +Detay yanıtı: + +```json +{ + "resource": {}, + "localized": {}, + "locale": "en", + "fallbackChain": ["en", "tr"] +} +``` + +Owner edit formu `resource` ve tüm `translations` verisini alır. Portal/read-only +ekran normalde `localized` alanını kullanır. Owner mutation: + +```json +{ + "status": "active", + "translations": { + "tr": { "name": "Neta Mobil", "description": "..." }, + "en": { "name": "Neta Mobile", "description": "..." } + } +} +``` + +### 7.6. Eşzamanlı güncelleme + +- Update response `updatedAt` veya açık `version` alanı döndürür. +- Client mutation son bilinen version'ı gönderir. +- Eski kayda yazma `409 CONFLICT` döndürür. +- Mobil form kullanıcıya `Sunucudaki değişikliği yükle` ve kontrollü yeniden + uygulama seçeneği sunar; sessiz overwrite yapmaz. + +## 8. Endpoint envanteri + +Bu bölüm hedef API'yi tanımlar. `Hazır` olmayan endpoint'ler, ilgili ekran +yazılmadan önce backend fazında tamamlanacaktır. + +### 8.1. Public, discovery ve localization + +| Method | Endpoint | Amaç | Durum | +| --- | --- | --- | --- | +| GET | `/.well-known/neta` | Instance discovery | Hazır | +| GET | `/api/v1/meta` | Marka, sürüm, capability | Hazır | +| GET | `/api/v1/health` | Readiness | Hazır | +| GET | `/api/v1/localization/catalog` | UI katalog indirme | Hazır | + +### 8.2. Session ve kullanıcı + +| Method | Endpoint | Rol | Amaç | +| --- | --- | --- | --- | +| POST | `/api/auth/sign-in/email` | Public | Better Auth login | +| POST | `/api/auth/sign-out` | Session | Logout | +| GET | `/api/v1/me` | Session | Rol, profil, tercih, locale | +| PATCH | `/api/v1/me/preferences` | Owner/client | Dil, tema, timezone ve desteklenen tercih alanları | +| PATCH | `/api/v1/me/profile` | Owner/client | Display name ve avatar metadata | +| POST | `/api/v1/me/password` | Owner/client | Şifre değiştirme | +| GET | `/api/v1/me/sessions` | Owner/client | Aktif cihaz/session listesi; auth modeli kararına bağlı | +| DELETE | `/api/v1/me/sessions/:id` | Owner/client | Session revoke; auth modeli kararına bağlı | + +### 8.3. Owner dashboard ve analytics + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/dashboard?range=month` | Stat kartları, finans/mood trendi, son projeler/müşteriler | +| GET | `/api/v1/analytics?range=month` | Gelir-gider, proje, görev ve performans analizleri | + +Dashboard toplu response vermelidir; mobil ilk açılışta 8–10 ayrı request +atılmamalıdır. + +### 8.4. Clients + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/clients` | Liste, search, status ve pipeline filtreleri | +| POST | `/api/v1/clients` | Çok dilli müşteri oluşturma | +| GET | `/api/v1/clients/:id` | Detay, ilişkiler ve portal durumu | +| PATCH | `/api/v1/clients/:id` | Bilgi, durum, pipeline ve çeviri güncelleme | +| DELETE | `/api/v1/clients/:id` | Archive/delete politikasına göre kaldırma | +| GET | `/api/v1/clients/:id/activities` | Not, arama, toplantı, email aktiviteleri | +| POST | `/api/v1/clients/:id/activities` | Aktivite ekleme | +| POST | `/api/v1/clients/:id/portal-invitations` | Portal hesabı/daveti ve default locale | +| PATCH | `/api/v1/clients/:id/portal-locale` | Admin tarafından başlangıç dilini güncelleme | + +### 8.5. Projects, plan, revisions ve assets + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/projects` | Liste, filtre, search | +| POST | `/api/v1/projects` | Proje ve localized alanlar oluşturma | +| GET | `/api/v1/projects/:id` | Detay, müşteri, ilerleme, çeviriler | +| PATCH | `/api/v1/projects/:id` | Proje güncelleme ve tamamlama | +| DELETE | `/api/v1/projects/:id` | Proje kaldırma | +| GET | `/api/v1/projects/:id/planning-sections` | Plan bölümleri | +| POST | `/api/v1/projects/:id/planning-sections` | Plan bölümü ekleme | +| PATCH | `/api/v1/projects/:id/planning-sections/:sectionId` | Plan güncelleme/sıralama | +| DELETE | `/api/v1/projects/:id/planning-sections/:sectionId` | Plan bölümü silme | +| GET | `/api/v1/projects/:id/revisions` | Owner revizyon listesi ve allowance | +| PATCH | `/api/v1/projects/:id/revisions/:revisionId` | Revizyon durumu | +| GET | `/api/v1/projects/:id/assets` | Proje dosyaları | +| POST | `/api/v1/projects/:id/assets` | Multipart dosya yükleme | +| DELETE | `/api/v1/projects/:id/assets/:assetId` | Proje dosyası silme | + +### 8.6. Tasks + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/tasks` | Liste; status, priority, project, client ve tarih filtresi | +| POST | `/api/v1/tasks` | Localized görev oluşturma | +| GET | `/api/v1/tasks/:id` | Görev detayı | +| PATCH | `/api/v1/tasks/:id` | Alan/status güncelleme | +| DELETE | `/api/v1/tasks/:id` | Görev silme | +| POST | `/api/v1/tasks/:id/complete` | Idempotent tamamlama kısayolu | + +Drag/drop mutation tek tek tüm task objesini değil `{status, position?}` +patch'ini göndermelidir. Mevcut schema kalıcı task sırası tutmuyorsa mobilde +görsel sıra değiştirme ilk sürümde server sırası vaadi vermemelidir. + +### 8.7. Calendar + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/calendar/events?from=&to=` | Aralık bazlı etkinlik listesi | +| POST | `/api/v1/calendar/events` | Etkinlik oluşturma | +| GET | `/api/v1/calendar/events/:id` | Etkinlik detayı | +| PATCH | `/api/v1/calendar/events/:id` | Etkinlik güncelleme | +| DELETE | `/api/v1/calendar/events/:id` | Etkinlik silme | + +Calendar API sınırsız tüm kayıtları döndürmez. Aylık görünüm bir +önceki ve sonraki görünen haftayı kapsayan date range ister. + +### 8.8. Finance + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/finance/summary?month=` | Gelir, gider, brüt, KDV tahmini, net, bekleyen | +| GET | `/api/v1/finance/transactions` | Cursor listesi ve filtreler | +| POST | `/api/v1/finance/transactions` | Gelir/gider oluşturma | +| GET | `/api/v1/finance/transactions/:id` | Detay | +| PATCH | `/api/v1/finance/transactions/:id` | Güncelleme | +| DELETE | `/api/v1/finance/transactions/:id` | Silme | +| POST | `/api/v1/finance/analysis` | AI finans analizi; stabil v1 error/stream kontratı | + +Vergi/KDV sonuçları hukuki/mali tavsiye olarak sunulmaz. Oran instance ayarına +taşınmadığı sürece UI hard-coded `%20` varsayımı yapmamalıdır. + +### 8.9. Journal + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/journal/entries?from=&to=` | Tarih aralığı günlükleri | +| PUT | `/api/v1/journal/entries/:date` | Gün bazında idempotent create/update | +| GET | `/api/v1/journal/entries/:id` | Detay | +| PATCH | `/api/v1/journal/entries/:id` | Tarih/içerik güncelleme | +| DELETE | `/api/v1/journal/entries/:id` | Silme | + +### 8.10. AI chat ve analizler + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/chat/sessions` | Sohbet listesi | +| POST | `/api/v1/chat/sessions` | Yeni sohbet | +| DELETE | `/api/v1/chat/sessions/:id` | Sohbeti silme | +| GET | `/api/v1/chat/sessions/:id/messages` | Mesaj geçmişi | +| POST | `/api/v1/chat/sessions/:id/messages` | Streaming AI mesajı | +| POST | `/api/v1/projects/:id/risk-analysis` | Proje risk analizi | + +- Mobil stream formatı AI SDK'nin web hook'una kapalı olmamalı; SSE veya açık + NDJSON kontratı belgelenmelidir. +- Abort/cancel desteklenir. +- `UPSTREAM_ERROR`, `UPSTREAM_TIMEOUT`, `SERVICE_UNAVAILABLE` ayrı gösterilir. +- API provider key ve model secret hiçbir response'a girmez. + +### 8.11. Business + +| Kaynak | Endpoint kökü | İşlemler | +| --- | --- | --- | +| Proposals | `/api/v1/business/proposals` | List, create, detail, update, delete | +| Contracts | `/api/v1/business/contracts` | List, create, detail, update, delete | +| Invoices | `/api/v1/business/invoices` | List, create, detail, update, delete | +| Subscriptions | `/api/v1/business/subscriptions` | List, create, detail, update, delete | + +Web'de bazı business ekranları diğer core ekranlar kadar tamamlanmış değil. +Mobil parity, backend/domain modeli olmayan görsel vaatler üretmemeli; önce web ve +API davranışının product acceptance kriteri yazılmalıdır. + +### 8.12. Owner settings + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET/PATCH | `/api/v1/settings/general` | Workspace, footer ve genel ayarlar | +| GET/PATCH | `/api/v1/settings/appearance` | Renkler, radius ve default tema | +| POST | `/api/v1/settings/appearance/assets` | Light logo, dark logo ve favicon upload | +| DELETE | `/api/v1/settings/appearance/assets/:kind` | Marka asset'i kaldırma | +| GET/PATCH | `/api/v1/settings/ai` | Provider/model/key yönetimi; key response'ta maskeli | +| GET | `/api/v1/settings/locales` | Dil listesi ve kullanım durumu | +| POST | `/api/v1/settings/locales` | Draft dil ekleme | +| GET/PATCH | `/api/v1/settings/locales/:code` | Dil metadata/lifecycle | +| GET/PUT | `/api/v1/settings/locales/:code/translations` | UI çeviri editörü | +| POST | `/api/v1/settings/locales/import` | Translation import | +| GET | `/api/v1/settings/locales/export` | Translation export | + +AI key mutation ayrı step-up auth veya mevcut şifre onayı gerektirebilir. +Mevcut key mobil cihaza geri döndürülmez. + +### 8.13. Portal API + +Portal endpoint'leri ayrı isim alanında olmalı ve `clientId` query/body'den +güven kaynağı olarak alınmamalıdır. Client scope session'dan türetilir. + +| Method | Endpoint | Amaç | +| --- | --- | --- | +| GET | `/api/v1/portal/dashboard` | Müşteri stats, projeler ve ilerleme | +| GET | `/api/v1/portal/projects` | Session client'ın projeleri | +| GET | `/api/v1/portal/projects/:id` | Localized proje, plan, public tasks, allowance ve revisions | +| GET | `/api/v1/portal/tasks` | Yalnız client'a public görevler | +| GET | `/api/v1/portal/revisions` | Müşterinin revizyonları | +| POST | `/api/v1/portal/projects/:id/revisions` | Kaynak locale ile revizyon talebi | +| GET/PATCH | `/api/v1/portal/profile` | Kendi profil bilgisi | + +Cross-client negatif testleri her endpoint için zorunludur. Portal client owner +endpoint'lerini capability görse bile çağıramaz. + +## 9. Mobil navigasyon ve route yapısı + +### 9.1. Expo Router taslağı + +```text +mobile/src/app/ + _layout.tsx + index.tsx # bootstrap kararı + (connection)/ + connect.tsx + checking.tsx + incompatible.tsx + (auth)/ + login.tsx + forgot-password.tsx + (owner)/ + _layout.tsx + (tabs)/ + index.tsx # dashboard + work.tsx # clients/projects/tasks hub + calendar.tsx + finance.tsx + more.tsx + analytics/index.tsx + clients/index.tsx + clients/[id].tsx + projects/index.tsx + projects/[id].tsx + tasks/index.tsx + journal/index.tsx + chat/index.tsx + chat/[id].tsx + business/proposals/index.tsx + business/contracts/index.tsx + business/invoices/index.tsx + business/subscriptions/index.tsx + settings/_layout.tsx + settings/general.tsx + settings/appearance.tsx + settings/profile.tsx + settings/security.tsx + settings/ai.tsx + settings/language.tsx + settings/languages/index.tsx + settings/languages/[code].tsx + settings/languages/[code]/translations.tsx + (portal)/ + _layout.tsx + (tabs)/ + index.tsx # portal dashboard + projects.tsx + tasks.tsx + revisions.tsx + settings.tsx + projects/[id].tsx + settings/profile.tsx + settings/security.tsx + settings/appearance.tsx + settings/language.tsx + (modals)/ + client-form.tsx + client-activity-form.tsx + portal-invitation.tsx + project-form.tsx + planning-section-form.tsx + task-form.tsx + calendar-event-form.tsx + finance-transaction-form.tsx + journal-entry-form.tsx + revision-request.tsx +``` + +Route grupları security boundary değildir. Her API request server tarafında actor +ve role kontrolünden geçer. + +### 9.2. Owner tab yapısı + +Telefon alt navigasyonu en fazla beş ana hedef taşır: + +1. Ana Sayfa +2. İşler: Müşteriler, projeler ve görevler hub'ı +3. Takvim +4. Finans +5. Daha Fazla: Analiz, günlük, AI, business ve ayarlar + +Müşteriler/projeler/görevler sık kullanılıyorsa `İşler` ekranında son +kayıtlar ve büyük hızlı aksiyonlar bulunur. Tablet'te side rail kullanılabilir. + +### 9.3. Portal tab yapısı + +1. Ana Sayfa +2. Projeler +3. Görevler +4. Revizyonlar +5. Ayarlar + +## 10. Ekran ve feature planı + +### 10.1. Ortak bootstrap ekranları + +#### Splash/bootstrap + +- Kayıtlı instance ve session var mı kontrol eder. +- Branding cache varsa doğru light/dark logo ile açılır. +- Session kararı tamamlanmadan owner veya portal ekranı flash etmez. +- Migration/restore nedeniyle instance ID değiştiğinde connect ekranına döner. + +#### Domain connect + +- Domain input, son instance, hata detayı ve retry. +- DNS bulunamadı, timeout, TLS, Neta değil, eski API, bakım ve min version + hataları ayrı kullanıcı mesajlarına sahiptir. + +#### Login + +- Instance logosu, workspace adı, email, şifre, şifreyi göster ve unuttum. +- Domain değiştir aksiyonu. +- Dil seçici yok; instance default catalog kullanılır. +- Rate limit ve disabled account hataları genel `hatalı istek` altında kaybolmaz. + +### 10.2. Owner dashboard + +- Range seçici: hafta/ay/yıl veya backend'in desteklediği mevcut range'ler. +- Net kazanç, aktif proje, tamamlanan görev ve ortalama mood stat kartları. +- Gelir/gider özeti. +- Mood ve enerji trendi. +- Son projeler ve son müşteriler. +- Pull-to-refresh ve cache timestamp. +- Boş veride ilk kayıt CTA'ları. +- Grafikler screen reader için metinsel özet de sunar. + +### 10.3. Analytics + +- Tarih aralığı seçimi. +- Gelir/gider/net trendi. +- Proje status dağılımı. +- Görev tamamlama ve performans. +- Proje bazlı gelir. +- Grafik tooltip'leri locale-aware para/tarih formatlar. +- Dar ekranda chart yatay taşmaz; gerekirse kart bazlı swipe kullanılır. + +### 10.4. Clients + +#### Liste + +- Search, status ve pipeline filtresi. +- Kart ve kompakt liste seçeneği; kanban ikinci iterasyon olabilir. +- Telefon/email kısayolları izin ve platform API'siyle açılır. +- Yeni müşteri FAB/header action. + +#### Oluşturma/düzenleme + +- Name, company, email, phone, website, status, pipeline, follow-up ve notes. +- Çevrilebilir alanlar aktif locale tab/picker'larında. +- Default locale zorunlu; diğer locale'ler eksik kaydedilebilir. + +#### Detay + +- Özet, iletişim, pipeline, portal hesabı durumu. +- Projeler ve finans ilişkileri. +- Aktivite timeline ve not ekleme. +- Portal daveti oluşturma; aktif dillerden client default locale seçimi. +- Archive/destructive aksiyon confirmation. + +### 10.5. Projects + +#### Liste + +- Search, status, type ve client filtresi. +- Progress, deadline, client ve budget özeti. +- Yeni proje formu; client project/side project ilişki kuralı. + +#### Proje detayı + +Native segmented tab: + +- Genel: description, status, tarih, budget ve progress. +- Plan: category bazlı planning sections; create/edit/delete/reorder. +- Görevler: proje task'ları, public flag ve hızlı status. +- Revizyonlar: talepler, allowance ve owner status update. +- Dosyalar: cover ve portal-visible proje assets. +- Ayarlar: manual/auto progress, revision quota, complete ve delete. + +Plan ve project edit formları aktif locale sayısı kadar dil paneli sunar. + +### 10.6. Tasks + +- Liste ve kanban segmented control. +- Status, priority, client, project ve tarih filtreleri. +- Task detail sheet/screen. +- Create/edit: title, description, status, priority, schedule, due time, + estimated/actual minute, project, client, public-to-client. +- Multilingual title/description. +- Swipe action yalnız açık undo veya confirmation politikasıyla kullanılır. +- Optimistic status update; hata durumunda rollback ve toast. + +### 10.7. Calendar + +- Month ve agenda görünümü. +- Gün seçilince etkinlik listesi. +- Etkinlik türü, başlangıç/bitiş, project/client/task ilişkisi. +- Native date/time picker. +- Locale, timezone ve daylight-saving doğru işlenir. +- Task deadlines ve finance events server tarafından event olarak dönüyorsa + source/read-only bilgisi açık olur; client sentetik duplicate üretmez. + +### 10.8. Finance + +- Ay seçici. +- Horizontal stat carousel: aylık gelir, gider, brüt, vergi/KDV, net, bekleyen. +- Scroll indicator görsel olarak gereksizse gizlenir; accessibility swipe korunur. +- Transaction search/filter, income/expense ve payment status. +- Create/edit: amount minor conversion, currency, date, category, status, + project/client ve localized description/category alanları. +- Silme confirmation. +- AI analysis sheet; loading, timeout, provider eksik ve retry. +- Finans verisi log/analytics payload'larında varsayılan olarak redacted olur. + +### 10.9. Journal + +- Tarih bazlı liste/takvim. +- Mood, energy, work satisfaction score. +- Mood label ve note için localized form. +- Aynı tarih için create/update tek idempotent akış. +- Günlük içeriği hassas kabul edilir; notification preview ve crash log'a girmez. + +### 10.10. AI chat + +- Session listesi, yeni sohbet, silme. +- Mesaj geçmişi ve streaming cevap. +- Klavye, safe area, auto-scroll ve uzun mesaj performansı. +- Stop generation ve retry. +- AI provider ayarlanmamışsa doğrudan ilgili ayar ekranına CTA. +- User mesajı kaynak locale ile saklanır; AI output otomatik domain çevirisi sayılmaz. + +### 10.11. Business + +- Teklifler: liste, create/edit, client/project, amount, status, validity. +- Sözleşmeler: liste, detail, content, proposal/client, status, signed date. +- Faturalar: liste, detail, invoice number, amount, tax, dates, payment status. +- Abonelikler: liste, create/edit, billing cycle, next billing date, status. +- PDF oluşturma/paylaşma backend tarafında gerçek feature olmadan mobilde + gösterilmez. + +### 10.12. Owner settings + +#### Genel + +- Workspace/firma/freelance adı. +- Portal footer ve server'da var olan genel metadata alanları. +- Değişiklik sonrası discovery/meta cache invalidate edilir. + +#### Görünüm + +- Primary/accent renk. +- Instance default color mode ve kişisel color mode ayrı anlatılır. +- Light logo, dark logo ve favicon image picker/upload. +- Upload crop/preview, boyut ve MIME hatası. +- Mobil app aktif temaya göre doğru logoyu anında yeniler. + +#### Profil + +- Display name, email read/edit politikası ve avatar. + +#### Güvenlik + +- Şifre değiştirme. +- Auth modeli destekliyorsa cihaz/session listesi ve revoke. + +#### AI + +- Gemini/OpenAI/Groq/Ollama provider, model ve yeni API key. +- Mevcut secret geri okunmaz; yalnız configured/masked state. + +#### Kişisel dil + +- Yalnız active instance dilleri. +- Değişiklik `/me/preferences` üzerinden kaydedilir. +- Catalog/query cache locale ile birlikte atomik değişir. + +#### Dil yönetimi + +- Dil listesi, default, status, fallback ve tamamlanma. +- Draft dil ekleme ve metadata. +- Translation editor mobilde namespace -> filtre -> key listesi olarak parçalanır. +- Büyük import/export dosyaları native share/file picker kullanır. +- Dil lifecycle gibi riskli owner ayarları step-up confirmation gerektirir. + +### 10.13. Portal dashboard + +- Aktif/tamamlanan proje, tamamlanan görev ve bekleyen revizyon statları. +- Proje progress kartları. +- Freelancer tarafından tanımlanan portal footer/branding. +- Yalnız session client'a ait veriler. + +### 10.14. Portal projects ve project detail + +- Project list: localized name/description, status, deadline ve progress. +- Project detail: genel, plan, public tasks ve revisions. +- Revision allowance ve `Revizyon talep et` formu. +- Revizyon description kullanıcının yazdığı dilde saklanır; `sourceLocale` + zorunlu gönderilir. +- Başka client project ID'si 404/forbidden ile korunur ve veri sızdırmaz. + +### 10.15. Portal tasks ve revisions + +- Yalnız `isPublicToClient=true` task'lar. +- Project adı, status, deadline ve description localized. +- Revizyon listesi, status, tarih, project bağı ve orijinal client mesajı. + +### 10.16. Portal settings + +- Profil. +- Şifre/güvenlik. +- Light/dark/system kişisel tercih. +- Adminin active yaptığı diller arasında dil tercihi. +- Adminin client için atadığı `clientDefaultLocale` bilgi olarak gösterilir; + kullanıcı tercihi bunu ezebilir. +- Portal kullanıcısı instance branding, AI veya dil kataloğu yönetemez. + +## 11. Localization mimarisi + +### 11.1. İki ayrı dil katmanı + +1. Uygulamanın domain bağlanmadan önceki metinleri: mobil binary içinde bundled + Türkçe/İngilizce `bootstrap` kataloğu. +2. Instance'a bağlandıktan sonraki metinler: Neta catalog endpoint'inden gelen, + admin tarafından override edilebilen katalog. + +Yeni `mobile` namespace'leri server katalog registry'sine eklenmelidir: + +```text +mobile-common +mobile-connection +mobile-auth +mobile-owner +mobile-portal +mobile-settings +mobile-errors +mobile-accessibility +``` + +Web ve mobil aynı anlamdaki status/validation key'lerini tekrar kullanabilir. +Layout'a özgü metinler mobil namespace'te kalır. Admin yeni dil eklediğinde mobil +namespace'leri de translation editor'da görür. + +### 11.2. Locale çözümü + +Public connect/login: + +```text +instanceDefaultLocale -> bundled tr +``` + +Owner: + +```text +userPreferenceLocale -> instanceDefaultLocale -> built-in tr +``` + +Portal: + +```text +userPreferenceLocale -> clientDefaultLocale -> instanceDefaultLocale -> built-in tr +``` + +Bu karar `/api/v1/me` ile gelir; mobil client kendi alternatif öncelik sırasını +icat etmez. + +### 11.3. Catalog cache + +- Cache key: `instanceId + locale + namespaceSet + catalogVersion`. +- Catalog version aynıysa cached messages kullanılır. +- Version değişince yeni catalog atomik indirilir; yarım katalog UI'a uygulanmaz. +- Missing key development'ta raporlanır, production'da fallback kullanılır. +- Raw key production UI'da görünmemesi release testidir. +- RTL locale aktif edilirse `I18nManager` restart gereksinimi kontrollü UX ile + uygulanır; sadece text-align değiştirmek yeterli kabul edilmez. + +### 11.4. Çok dilli domain formları + +- Active locale'ler server sırasıyla tab/segmented dropdown olur. +- Default locale ilk ve zorunludur. +- Tab badge eksik zorunlu alanı gösterir. +- Tarih, status, para, relation, checkbox ve file alanları dil tab'ları dışındadır. +- Metin alanları registry'deki entity/field tanımından gelir; ekranlar kendi + farklı translation payload formatını oluşturmaz. +- Server `UNSUPPORTED_LOCALE` döndürürse metadata/catalog yenilenir ve formdaki + artık aktif olmayan dil korunarak kullanıcıya gösterilir. + +## 12. Branding ve tema + +Mobil tema `GET /api/v1/meta` alanlarından oluşur: + +- `primaryColor` +- `accentColor` +- `defaultColorMode` +- `radiusScale` +- `lightLogoUrl` +- `darkLogoUrl` +- `iconUrl/faviconUrl` + +Kurallar: + +- Kullanıcının `/me.preferences.colorMode` değeri instance default'u ezer. +- `system`, cihaz renk modunu takip eder. +- Light mod light logo, dark mod dark logo kullanır. +- Bir logo eksikse diğeri fallback olabilir; kontrast garantisi olmadığı için + nötr workspace placeholder da hazır tutulur. +- Remote renklerden semantic token seti üretilirken minimum kontrast kontrolü + yapılır; okunmaz renk için güvenli foreground otomatik seçilir. +- App icon ve native splash her instance'a göre runtime değişmez. Bunlar genel + Neta markasıdır; instance favicon/logo uygulama içinde kullanılır. +- Remote SVG kullanılacaksa sanitizer/render desteği ayrı test edilir. MVP'de + backend'in kabul ettiği PNG/JPEG/WebP formatları tercih edilir. + +## 13. Veri cache, offline ve mutation davranışı + +### 13.1. Query key standardı + +```ts +[instanceId, role, locale, resource, filters] +``` + +Örnek: + +```ts +[instanceId, "freelancer", "tr", "projects", { status: "active" }] +``` + +Instance, rol veya locale değişince yanlış kullanıcı verisinin görünmesi bu +ayrımla engellenir. + +### 13.2. Cache politikası + +- Meta/catalog: version bazlı uzun cache. +- Dashboard/finance: kısa stale time. +- Detail/list: orta stale time ve foreground refresh. +- Chat messages: aktif session'da kısa cache/stream. +- Profile/security: no sensitive persistent cache veya alan bazlı redaction. +- Logout/instance switch: ilgili instance+user query cache temizlenir. + +### 13.3. Offline v1 + +- Son başarılı read verisi `Son güncelleme` bilgisiyle gösterilebilir. +- Mutation başlatılırken network yoksa form kaybolmaz; kullanıcıya bağlantı + gerektiği söylenir. +- Otomatik kalıcı mutation queue v1'de yoktur; duplicate finans kaydı/revizyon + gibi riskleri önler. +- Optimistic update yalnız task status gibi kolay rollback edilebilir işlemlerde. +- Create/delete finance, project ve revision server onayından önce kalıcı + başarılı gösterilmez. + +### 13.4. Gelecek offline queue gereksinimleri + +- Idempotency key. +- Mutation dependency graph. +- Conflict/version kontrolü. +- Kullanıcıya görünür pending/failed queue. +- Logout ve instance switch'te pending data kararı. +- Hassas payload'lar için encrypted local database. + +## 14. Hata yönetimi ve kullanıcı geri bildirimi + +| Kod/durum | Mobil davranış | +| --- | --- | +| `VALIDATION_ERROR` | Alan hataları formda, genel hata summary'de | +| `UNAUTHENTICATED` | Session temizle, login'e git, draft formu mümkünse koru | +| `FORBIDDEN` | Yetki ekranı; route'u gizlemek tek başına yeterli değil | +| `NOT_FOUND` | Detail not-found ve listeye dön | +| `CONFLICT` | Server state refresh ve conflict UI | +| `UNSUPPORTED_LOCALE` | Locale metadata/catalog refresh | +| `UPSTREAM_TIMEOUT` | AI için tekrar dene; core data mutation tekrar edilmez | +| `SERVICE_UNAVAILABLE` | Instance bakım/readiness mesajı | +| Network timeout | Offline banner ve kontrollü retry | +| TLS error | Credential göndermeden bağlantıyı durdur | +| API major incompatible | App update veya desteklenmeyen instance ekranı | + +Her error objesi internal URL, SQL, stack trace, token veya secret içermemelidir. + +## 15. Dosya ve medya yönetimi + +- Image picker permission yalnız aksiyon anında istenir. +- Dosya MIME, extension ve 5 MB server limiti upload öncesi gösterilir. +- Upload `multipart/form-data` olur; auth header/cookie korunur. +- Progress, cancel ve retry bulunur. +- Server response absolute veya instance-bound URL döndürmelidir; mobil client + farklı origin varsaymaz. +- Private/portal/public branding visibility kuralları server'da uygulanır. +- Portal-visible olmayan project asset client'a URL olarak bile dönmez. +- EXIF/location metadata temizleme politikası backend veya upload öncesi için + ayrı acceptance kriteridir. + +## 16. Güvenlik modeli + +### 16.1. Zorunlu kurallar + +- Remote instance için HTTPS. +- Session/token yalnız SecureStore/Keychain/Keystore destekli alanda. +- Password hiçbir local storage, log, crash report veya analytics event'ine girmez. +- API key mobilde geri okunabilir biçimde tutulmaz. +- Owner/client authorization her endpoint'te server actor'dan türetilir. +- Portal query'lerinden gelen `clientId` yetki kaynağı değildir. +- Loglar request/response body'yi varsayılan olarak kaydetmez. +- Clipboard'a kopyalanan hassas bilgiler minimize edilir. +- Jailbreak/root detection tek başına auth kontrolü sayılmaz. +- Certificate pinning self-host ve değişken domain modelinde varsayılan olamaz; + opsiyonel instance fingerprint/pin ancak ayrı tasarımla gelir. + +### 16.2. Threat cases + +- Kötü niyetli discovery belgesinin başka origin'e auth URL vermesi. +- DNS rebinding/redirect ile HTTPS downgrade. +- Aynı origin'in restore sonrası farklı instance ID döndürmesi. +- Shared device'da kullanıcı A cache'inin kullanıcı B'ye görünmesi. +- Client'ın başka client project/task ID'sini tahmin etmesi. +- Retry sonucu duplicate finance/revision oluşması. +- AI error/log içine provider secret sızması. +- Remote logo/file ile dev payload veya aşırı bellek kullanımı. + +## 17. Performans hedefleri + +- Warm start'ta cached shell/logo hemen; auth doğrulama arka planda. +- Discovery ve meta request'leri timeout/abort destekler. +- Dashboard tek aggregate endpoint kullanır. +- Listeler cursor pagination ve virtualized list kullanır. +- Chart library yalnız gerçek chart ekranlarında lazy load edilir. +- Remote image boyutları sınırlanır ve cache edilir. +- Locale catalog namespace bazlı indirilir. +- Project detail'in tüm tab verileri ilk render'da zorunlu değilse lazy query olur. +- Chat message listesi uzun session'larda virtualized olur. + +Ölçülecek metrikler: + +- Cold start -> connect/login shell. +- Warm start -> authenticated shell. +- Dashboard usable data time. +- P50/P95 API latency endpoint ailesi bazında. +- JS crash-free session. +- Auth/session failure oranı. +- Catalog ve branding cache hit oranı. + +Telemetry self-host ilkesine uygun opt-in olmalı; merkezi Neta sunucusuna içerik +gönderilmemelidir. + +## 18. Erişilebilirlik ve cihaz uyumu + +- Minimum 44x44 iOS / uygun Android touch target. +- Dynamic font ve text scaling. +- Sadece renkle durum anlatılmaz. +- Icon button'larda localized accessibility label. +- Form error summary screen reader tarafından okunur. +- Chart'lar metinsel summary sunar. +- Dark/light kontrast semantik token testinden geçer. +- Keyboard avoidance ve focus order test edilir. +- Safe area, notch ve Android navigation bar uyumu. +- RTL layout mirror testi. +- 14 inç web davranışı mobil acceptance değildir; telefon, küçük telefon + ve tablet ayrı screenshot testlerine girer. + +## 19. Test stratejisi + +### 19.1. Unit + +- URL normalize ve origin validation. +- Discovery/meta schema parse. +- SemVer minimum client kontrolü. +- Error mapping. +- Money/date/locale format. +- Theme token derivation ve foreground contrast. +- Translation fallback. +- Query key isolation. + +### 19.2. Contract/integration + +- Her `/api/v1` endpoint için request/response schema. +- API version header ve envelope. +- Owner/client pozitif ve negatif auth. +- Cursor pagination determinism. +- Localized resource ve translation mutation. +- Idempotency ve conflict. +- File visibility. +- AI timeout/error/stream. + +### 19.3. Mobil component + +- Loading, empty, error, content. +- Light/dark ve custom primary. +- TR/EN, uzun custom locale ve RTL. +- Form validation ve locale tab errors. +- Offline banner ve mutation guard. + +### 19.4. E2E + +En az iki gerçek self-host fixture: + +1. Default branding, TR default, freelancer. +2. Custom branding, EN veya custom locale, portal client. + +Kritik E2E senaryoları: + +- Domain -> discovery -> login -> owner dashboard. +- Domain -> login -> portal dashboard. +- Yanlış domain/TLS/API version. +- Session expiry ve logout. +- Client create -> portal invite locale. +- Project create with TR/EN -> client EN portal read. +- Task create/public -> portal task visibility. +- Revision request -> owner status update. +- Finance create/edit/delete. +- Theme/logo switch. +- Locale/catalog version switch. +- Cross-client project access negative. + +### 19.5. Release gate + +```text +mobile lint +mobile typecheck +mobile unit tests +API contract tests +i18n key parity + raw key scan +owner/client authorization negative tests +iOS build +Android build +smoke against packaged self-host instance +``` + +## 20. CI/CD ve yayın + +- PR: lint, typecheck, unit, API contract ve i18n gate. +- Main/nightly: iOS simulator ve Android emulator E2E. +- Release candidate: TestFlight + Play Internal Testing. +- Production: staged rollout ve crash-free takip. +- `NETA_MINIMUM_MOBILE_VERSION` yalnız gerçekten zorunlu protokol/güvenlik + durumunda yükseltilir. +- Mobil app version, native build number ve API contract version ayrıdır. +- OTA update kullanılırsa native runtime version ile uyumluluk korunur; native + module gerektiren değişiklik OTA ile zorlanmaz. +- Privacy policy; girilen domain, cihazda tutulan metadata, opsiyonel telemetry ve + crash reporting davranışını açıkça anlatır. + +## 21. Faz bazlı uygulama planı + +Bir faz, checklist ve acceptance kriterleri tamamlanmadan `completed` sayılmaz. +Backend endpoint'i olmayan mobil ekran mock data ile bitmiş işaretlenmez. + +### Faz 0 — Baseline, kararlar ve mobil API gap analizi + +- [ ] Mevcut web route, Server Action, DomainService ve schema envanteri snapshot'lanır. +- [ ] Owner ve portal ekran parity matrisi onaylanır. +- [ ] Expo stabil SDK/RN/Node/pnpm sürümleri seçilir. +- [ ] Better Auth Expo multi-domain spike gerçek cihazda yapılır. +- [ ] Cookie/session izolasyonu iki farklı instance ile test edilir. +- [ ] ADR-0018 secure-cookie veya device-pairing sonucuna göre revize edilir. +- [ ] Portal client auth lifecycle kararı yazılır. +- [ ] Poyraz UI web sınırı ve mobil token kontratı kaydedilir. +- [ ] API endpoint backlog'u issue/fazlarla eşleştirilir. +- [ ] MVP, parity ve post-v1 kapsamı product tarafından onaylanır. + +Tamamlanma kriteri: Auth ve repository mimarisi açık karar, spike kanıtı ve +güncellenmiş ADR ile sabittir. + +### Faz 1 — Workspace ve Expo temel uygulama + +- [ ] `mobile/` Expo Router TypeScript app oluşturulur. +- [ ] pnpm workspace mevcut web root'unu bozmadan kurulur. +- [ ] iOS ve Android development build alınır. +- [ ] Environment ve app config yapısı kurulur. +- [ ] Typed routes, protected route grupları ve error boundary kurulur. +- [ ] Lint, typecheck, unit test ve CI scriptleri eklenir. +- [ ] SecureStore ve non-secret storage adapter'ları ayrılır. +- [ ] Network state ve app lifecycle provider eklenir. + +### Faz 2 — Mobil design system ve tema + +- [ ] Shared semantik design token paketi oluşturulur. +- [ ] Light/dark/system theme provider yazılır. +- [ ] Dynamic primary/accent ve kontrast çözümü uygulanır. +- [ ] Temel UI primitives tamamlanır. +- [ ] Loading/empty/error/skeleton/toast pattern'leri sabitlenir. +- [ ] Phone/tablet safe-area ve typography kuralları yazılır. +- [ ] UI katalog key'leri `mobile-*` namespace'lerine eklenir. +- [ ] Light/dark ve TR/EN component screenshot testleri eklenir. + +### Faz 3 — Domain discovery ve instance bootstrap + +- [ ] Domain normalize/validation saf modülü yazılır. +- [ ] Discovery, health ve meta client'ları yazılır. +- [ ] Redirect/origin/TLS/min-version/capability kontrolleri uygulanır. +- [ ] Instance registry ve instanceId değişim davranışı uygulanır. +- [ ] Domain connect/checking/error/incompatible ekranları tamamlanır. +- [ ] Branding ve public catalog bootstrap edilir. +- [ ] Localhost/emulator development policy test edilir. + +### Faz 4 — Native auth, session ve role shell + +- [ ] Server Better Auth Expo plugin ve trusted origin değişiklikleri yapılır. +- [ ] Instance-bound native auth client factory yazılır. +- [ ] Secure storage prefix instanceId ile izole edilir. +- [ ] Login, logout, expiry ve foreground session kontrolü tamamlanır. +- [ ] `/api/v1/me` ile owner/client route kararı uygulanır. +- [ ] Owner ve portal navigation shell'leri tamamlanır. +- [ ] Disabled user, password change ve revoke testleri geçer. +- [ ] Auth audit ve rate limit regression testleri geçer. + +### Faz 5 — API contract paketi ve resource altyapısı + +- [ ] `packages/api-contracts` transport-safe hale getirilir. +- [ ] Envelope, error, pagination ve localized response şemaları eklenir. +- [ ] Instance-bound fetch client, timeout, abort ve request metadata eklenir. +- [ ] Query client, query key factory ve cache persistence kurulur. +- [ ] API route helper'ları actor/role/locale/pagination için ortaklaştırılır. +- [ ] Idempotency ve optimistic concurrency kararı uygulanır. +- [ ] API OpenAPI veya machine-readable contract üretimi kararlaştırılır. + +### Faz 6 — Owner dashboard ve analytics + +- [ ] Dashboard aggregate API yazılır ve owner scope testi eklenir. +- [ ] Analytics range API yazılır. +- [ ] Dashboard ekranı tüm states ile tamamlanır. +- [ ] Analytics ekranı ve accessible chart summary tamamlanır. +- [ ] Para/tarih/locale format testleri geçer. +- [ ] Request count ve P95 hedefi ölçülür. + +### Faz 7 — Clients dikey dilimi + +- [ ] Clients list/detail/create/update/archive API'leri yazılır. +- [ ] Activity ve portal invitation API'leri v1'e alınır. +- [ ] Client list/filter/search ekranı tamamlanır. +- [ ] Client multilingual form tamamlanır. +- [ ] Client detail/activity/portal locale akışı tamamlanır. +- [ ] Portal invite duplicate/conflict ve owner-only testleri geçer. + +### Faz 8 — Projects dikey dilimi + +- [ ] Projects CRUD/list/detail API'leri yazılır. +- [ ] Planning sections ve revision owner API'leri yazılır. +- [ ] Project list ve multilingual create/edit tamamlanır. +- [ ] Project detail tabları tamamlanır. +- [ ] Progress/revision quota/complete/delete akışları test edilir. +- [ ] Client-project relation ve cross-owner negatifleri geçer. + +### Faz 9 — Tasks dikey dilimi + +- [ ] Tasks CRUD/filter API'leri yazılır. +- [ ] List/kanban görünümü tamamlanır. +- [ ] Multilingual task form tamamlanır. +- [ ] Optimistic status/complete ve rollback tamamlanır. +- [ ] Project auto-progress regression testleri geçer. +- [ ] Portal visibility server testi geçer. + +### Faz 10 — Calendar dikey dilimi + +- [ ] Date-range event API'leri yazılır. +- [ ] Month/agenda ekranı tamamlanır. +- [ ] Multilingual event form ve native date picker tamamlanır. +- [ ] Timezone/DST/start-end validation testleri geçer. +- [ ] Project/client/task ownership negatifleri geçer. + +### Faz 11 — Finance dikey dilimi + +- [ ] Summary ve transaction CRUD API'leri yazılır. +- [ ] Stat carousel ve transaction list/filter tamamlanır. +- [ ] Multilingual finance form ve money conversion test edilir. +- [ ] AI finance analysis v1 endpoint/error kontratına alınır. +- [ ] Duplicate mutation/idempotency testi geçer. +- [ ] Hassas veri log redaction testi geçer. + +### Faz 12 — Journal dikey dilimi + +- [ ] Range ve idempotent date upsert API'leri yazılır. +- [ ] Journal list/calendar ekranı tamamlanır. +- [ ] Mood/energy/satisfaction ve multilingual note formu tamamlanır. +- [ ] Same-date conflict ve offline guard testleri geçer. +- [ ] Hassas content telemetry kontrolü geçer. + +### Faz 13 — AI chat ve project risk + +- [ ] Chat session/message API'leri v1'e taşınır. +- [ ] Native streaming protokolü belgelenir ve uygulanır. +- [ ] Session list/chat detail/composer tamamlanır. +- [ ] Cancel/retry/timeout/provider-missing UX tamamlanır. +- [ ] Project risk analysis mobil action'la entegre edilir. +- [ ] Secret/error leakage testleri geçer. + +### Faz 14 — Business modülleri + +- [ ] Proposals API ve mobil ekranları tamamlanır. +- [ ] Contracts API ve mobil ekranları tamamlanır. +- [ ] Invoices API ve mobil ekranları tamamlanır. +- [ ] Subscriptions API ve mobil ekranları tamamlanır. +- [ ] Money/status/date ve owner-scope testleri geçer. +- [ ] Web'de eksik kalan product davranışları ayrıca tamamlanır veya feature + capability ile planned tutulur. + +### Faz 15 — Owner profil, güvenlik ve instance ayarları + +- [ ] Me profile/password/session API'leri tamamlanır. +- [ ] General/appearance/AI settings API'leri tamamlanır. +- [ ] Profil ve güvenlik ekranları tamamlanır. +- [ ] Workspace ve appearance ekranları tamamlanır. +- [ ] Light/dark logo ve favicon upload/remove tamamlanır. +- [ ] AI provider/key formu secret-safe tamamlanır. +- [ ] Meta/discovery/cache invalidation testi geçer. + +### Faz 16 — Dil tercihi, dil yönetimi ve çok dilli formlar + +- [ ] `mobile-*` TR/EN katalog parity yüzde 100 olur. +- [ ] Catalog version/cache/fallback runtime tamamlanır. +- [ ] Owner kişisel dil ekranı tamamlanır. +- [ ] Locale list/create/detail/lifecycle API ve ekranları tamamlanır. +- [ ] Translation editor ve import/export tamamlanır. +- [ ] Tüm owner form entity'leri ortak localized form contract'ına geçer. +- [ ] Custom locale ve RTL E2E geçer. +- [ ] Production raw-key taraması sıfır sonuç verir. + +### Faz 17 — Portal API ve authorization hardening + +- [ ] Portal dashboard/projects/tasks/revisions API'leri yazılır. +- [ ] Portal profile API tamamlanır. +- [ ] Localized response/fallback portal kontratı uygulanır. +- [ ] Her endpoint için cross-client ve owner/client role negatifleri yazılır. +- [ ] Public task ve portal asset visibility testleri geçer. +- [ ] Revision allowance ve sourceLocale testleri geçer. + +### Faz 18 — Portal mobil ekranları + +- [ ] Portal dashboard tamamlanır. +- [ ] Project list ve project detail tabları tamamlanır. +- [ ] Public tasks tamamlanır. +- [ ] Revision list/create tamamlanır. +- [ ] Profile/security/appearance/language ayarları tamamlanır. +- [ ] Admin branding ve client locale davranışı E2E geçer. +- [ ] Owner route'ları portal bundle UI'ında görünmez ve API'de forbidden'dır. + +### Faz 19 — Dosya, medya, invitation ve deep link + +- [ ] File endpoint'leri v1 envelope ve absolute URL kontratına alınır. +- [ ] Avatar, light logo, dark logo, favicon, cover ve project asset upload tamamlanır. +- [ ] Upload progress/cancel/retry tamamlanır. +- [ ] Universal/app link kurulumu yapılır. +- [ ] Portal invitation ve password reset web fallback ile test edilir. +- [ ] File visibility/MIME/size/EXIF güvenlik testleri geçer. + +### Faz 20 — Offline read cache, performans ve accessibility + +- [ ] Query persistence hassasiyet matrisiyle etkinleştirilir. +- [ ] Offline banner, stale timestamp ve mutation guard tamamlanır. +- [ ] Liste virtualization ve image cache uygulanır. +- [ ] Cold/warm start ve dashboard performans budget'ları geçer. +- [ ] Dynamic type, screen reader, keyboard ve touch target audit geçer. +- [ ] Light/dark/custom color ve RTL accessibility testleri geçer. +- [ ] Küçük telefon ve tablet responsive testleri geçer. + +### Faz 21 — Bildirim altyapısı ve background davranışı + +- [ ] Bildirimlerin self-host backend ile nasıl gönderileceği için ADR yazılır. +- [ ] Expo push relay kullanımının privacy/self-host etkisi açıklanır. +- [ ] Device registration/revoke endpoint'leri tasarlanır. +- [ ] Görev deadline, revizyon ve proje update event kapsamı belirlenir. +- [ ] Notification deep link auth ve instance kontrolünden geçer. +- [ ] Hassas içerik lock-screen preview'da varsayılan olarak gösterilmez. + +Bu faz ilk store release için zorunlu olmayabilir; capability `planned` kaldığı +sürece UI da sunulmaz. + +### Faz 22 — Production hardening ve store release + +- [ ] Tüm release gate'ler CI'da geçer. +- [ ] Gerçek Dokploy/reverse-proxy self-host instance ile smoke geçer. +- [ ] iOS TestFlight ve Play Internal Testing kabulü tamamlanır. +- [ ] Privacy policy, support ve domain troubleshooting dokümanı yayınlanır. +- [ ] App Store/Play metadata ve screenshot'lar TR/EN hazırlanır. +- [ ] Crash/log redaction ve opt-in telemetry doğrulanır. +- [ ] Minimum mobile version ve API compatibility senaryosu test edilir. +- [ ] Rollback, staged rollout ve hotfix prosedürü yazılır. +- [ ] Owner ve portal E2E acceptance imzası alınır. + +### Faz 23 — Device pairing ve gelişmiş oturum yönetimi + +Bu fazın kapsamı Faz 0 auth kararına bağlıdır. Pairing production blocker +olarak kalırsa Faz 4'e çekilir. + +- [ ] Pairing code/challenge schema ve rate limit uygulanır. +- [ ] Exchange/access/refresh rotation uygulanır. +- [ ] SecureStore token family entegrasyonu tamamlanır. +- [ ] Device list/revoke UI tamamlanır. +- [ ] Refresh reuse -> family compromised akışı test edilir. +- [ ] Password change/disabled user/tüm cihazlardan çıkış revoke eder. +- [ ] Backup restore token epoch rotate eder. +- [ ] Raw token/secret log ve DB'de bulunmaz. + +## 22. Milestone ve hızlı teslim sırası + +### Milestone A — Bağlanabilir uygulama + +Faz 0–5: + +- Domain girilir. +- Neta instance tanınır. +- Marka/dil yüklenir. +- Kullanıcı giriş yapar. +- Rolüne uygun boş shell açılır. + +### Milestone B — Freelancer core MVP + +Faz 6–13: + +- Dashboard, analiz, müşteri, proje, görev, takvim, finans, günlük ve AI. +- Bu noktada mobil uygulama freelancer'ın günlük ana işlerini karşılar. + +### Milestone C — Tam owner yönetimi + +Faz 14–16: + +- Business ve tüm ayarlar. +- Instance branding/dil/AI yönetimi. +- Çok dilli içerik parity. + +### Milestone D — Müşteri portalı + +Faz 17–19: + +- Portal API hardening. +- Portal ekranları. +- Dosyalar, invitation ve deep link. + +### Milestone E — Store kalitesi + +Faz 20–23: + +- Offline read, performans, accessibility, opsiyonel notification. +- Production hardening ve gerekiyorsa pairing. + +## 23. Definition of Done + +Bir feature yalnız UI göründüğünde tamamlanmış sayılmaz. Her feature için: + +- [ ] API v1 contract ve stable error code var. +- [ ] Owner/client authorization server tarafında testli. +- [ ] Loading, empty, error, offline ve content state'leri var. +- [ ] Light/dark ve custom branding doğru. +- [ ] TR/EN ve custom locale fallback doğru. +- [ ] Dinamik metin alanlarında translation payload doğru. +- [ ] Accessibility label, focus ve touch target doğru. +- [ ] Query invalidation/cache isolation doğru. +- [ ] Mutation duplicate/conflict davranışı tanımlı. +- [ ] Secret/PII log redaction doğru. +- [ ] Unit + contract + en az bir E2E happy path geçiyor. +- [ ] Plan faz checklist'i ve ilgili teknik doküman güncel. + +## 24. Başlamadan önce cevaplanması gereken ürün kararları + +Bu sorular Faz 0'da cevaplanmalı; uygulama bootstrap'ını bloke etmek zorunda +değildir fakat ilgili feature fazını bloke eder: + +1. Tek aktif instance yeterli mi, yoksa ilk sürümde hızlı instance switch olacak mı? +2. Owner mobil login email/şifre mi, pairing mi, yoksa ikisi birden mi olacak? +3. Müşteri invitation kabulü ilk sürümde native mi web fallback mi olacak? +4. Business ekranları MVP mi, parity milestone'u mu? +5. Mobilde admin dil translation editor gerçekten gerekli mi, yoksa ilk sürümde + dil seçimi yeterli ve katalog yönetimi web-only olabilir mi? +6. Push notification ilk store release blocker mı? +7. Tablet ilk release acceptance kapsamında mı? +8. Self-host instance'lar için merkezi telemetry tamamen kapalı mı, opt-in mi? + +## 25. İlk uygulanacak teknik dilim + +En hızlı ve riski en erken azaltan ilk uygulama dilimi: + +```text +Faz 0 auth spike + -> mobile workspace bootstrap + -> domain connect + -> discovery/meta/health + -> instance branding + catalog + -> Better Auth native login + -> /api/v1/me + -> role-based owner/portal shell +``` + +Bu dilim tamamlandığında henüz bütün ekranlar yazılmamış olsa bile projenin +en kritik vaadi kanıtlanmış olur: tek bir React Native uygulaması, kullanıcının +girdiği herhangi bir uyumlu self-hosted Neta domain'ini güvenli biçimde tanır, +o instance'ın markasına ve diline bürünür, kullanıcıyı doğrular ve freelancer +veya müşteri deneyimine doğru yönlendirir.