49 KiB
title, description, status, current_phase, last_updated
| title | description | status | current_phase | last_updated |
|---|---|---|---|---|
| Neta Çok Dilli Sistem ve Yerelleştirme Ana Planı | Self-host edilen Neta instance'larında yönetilebilir arayüz dilleri, çok dilli içerik formları, müşteri portalı dili ve mobil API uyumu için faz bazlı uygulama planı. | completed | completed | 2026-07-19 |
Neta Çok Dilli Sistem ve Yerelleştirme Ana Planı
1. Belgenin amacı
Bu plan, Neta'yı yalnızca Türkçe metinler gösteren bir uygulamadan, self-host eden kişinin yönetebildiği çok dilli bir platforma dönüştürür.
Hedef sistemde:
- Türkçe (
tr) ve İngilizce (en) ilk kurulumda hazır ve aktif gelir. - Instance sahibi Ayarlar sayfasından yeni bir dil ekleyebilir.
- Eklenen dil için sidebar, sayfa başlıkları, butonlar, durumlar, formlar, doğrulama mesajları, auth ekranları ve müşteri portalı metinleri çevrilebilir.
- Çevrilebilir iş içerikleri, aynı form içinde dil sekmeleriyle girilebilir.
- Müşteri portal daveti oluşturulurken müşterinin dili seçilir.
- Davet ekranı dahil olmak üzere müşteri portalı seçilen dilde açılır.
- Tarih, saat, sayı ve para gösterimleri seçili locale'e göre biçimlendirilir.
- Web ile aynı dil ve içerik modeli gelecekteki React Native istemcisi tarafından API üzerinden kullanılabilir.
- Yeni bir dil eklemek yeni bir deployment veya kod değişikliği gerektirmez.
Bu belge implementasyon sırasını, veri modelini, fallback davranışını, UI sözleşmelerini, migrasyon stratejisini, güvenlik sınırlarını ve test kapılarını tanımlar.
2. Mevcut sistem inceleme özeti
Codebase incelemesinde çok dillilik açısından aşağıdaki mevcut durum tespit edildi:
user_preferences.languagealanı bulunuyor ve varsayılanıtr.- Aynı alanda SQLite check constraint yalnızca
trveendeğerlerine izin veriyor. - Preference service şu anda yalnızca
colorModedöndürüyor; dil tercihini runtime'a taşımıyor. - Root layout içindeki
<html lang="tr">sabit. - Sidebar konfigürasyonları Türkçe başlıkları doğrudan taşıyor.
- Dashboard, ayarlar, auth ve portal ekranlarında kullanıcıya gösterilen metinler bileşenlerin içine gömülü.
- Tarih ve para gösterimlerinde
tr-TRvedate-fns/locale/trdoğrudan kullanılıyor. - Müşteri daveti oluşturulurken locale seçilmiyor veya davete kaydedilmiyor.
clients,app_profilesveportal_invitationsüzerinde portal dili alanı yok.- Proje, görev ve planlama alanlarının başlık/açıklamaları tek sütunda tutuluyor.
- Mobil discovery ve
/api/v1/metasözleşmesinde desteklenen diller ilan edilmiyor. - Arayüz metni içerme ihtimali bulunan yaklaşık 141 TypeScript/TSX dosyası var.
Bu nedenle yalnızca bir çeviri kütüphanesi eklemek yeterli değildir. Arayüz yerelleştirmesi, kullanıcı içeriği çevirileri, portal locale çözümleme ve API sözleşmesi birlikte ele alınmalıdır.
3. Temel kavramlar
Bu projede iki farklı veri türü birbirinden kesin olarak ayrılacaktır.
3.1. Arayüz çevirisi
Uygulamanın kendisine ait metinlerdir:
- Sidebar grup ve menü adları
- Sayfa başlıkları
- Buton, tab ve dialog metinleri
- Form label ve placeholder'ları
- Boş durum ve onay mesajları
- Toast ve kullanıcıya gösterilen hata metinleri
- Durum, öncelik ve kategori label'ları
- Login, kayıt ve davet ekranları
- Müşteri portalındaki sistem metinleri
Bu metinler stabil anahtarlarla çağrılır:
t("navigation.projects")
t("projects.form.name.label")
t("status.project.completed")
Türkçe ve İngilizce kaynak katalogları kod içinde sürümlenir. Instance sahibinin yaptığı değişiklikler ve sonradan eklenen diller SQLite içinde saklanır.
3.2. İçerik çevirisi
Freelancer'ın oluşturduğu ve müşteriye gösterilebilecek iş verileridir:
- Proje adı ve açıklaması
- Proje kapak görseli alt metni
- Proje planlama bölümü başlığı ve içeriği
- Müşteriye açık görev başlığı ve açıklaması
- Portal karşılama ve footer metinleri
- İleride teklif, sözleşme ve benzeri portal içerikleri
Bu içerikler formdaki locale tab'larıyla girilir ve content_translations
tablosunda saklanır.
3.3. Çevrilmeyecek alanlar
Her form alanını dil başına çoğaltmak doğru değildir. Aşağıdaki alanlar ortak kalır:
- Tarih ve saat
- Tutar, para birimi ve vergi
- Durum, öncelik ve kategori enum değerleri
- Müşteri/proje ilişkileri
- İlerleme yüzdesi
- E-posta, telefon ve URL
- Dosya ve görselin kendisi
- Teknik ID'ler
Bu alanların değerleri ortak tutulur; kullanıcıya gösterilen label'ları arayüz sözlüğünden çevrilir.
3.4. Yazıldığı dilde kalacak içerikler
İletişim niteliğindeki kayıtlar otomatik olarak çoğaltılmayacaktır:
- Müşterinin yazdığı revizyon talebi
- Chat mesajları
- Freelancer'ın özel günlüğü
- Müşteri aktivite notları
Bu içeriklerde gerekirse sourceLocale metadata'sı saklanabilir; metnin kendisi
yazıldığı dilde gösterilir. Otomatik çeviri ayrı ve opsiyonel bir ürün özelliğidir.
4. Kilitlenecek ürün kararları
Faz 0 tamamlanırken aşağıdaki kararlar ADR ile kesinleştirilecektir. Bu planın önerilen varsayımları şöyledir:
- Türkçe ve İngilizce silinemez built-in diller olacak.
- İlk migration sonrasında instance varsayılan dili Türkçe olacak.
- Yeni eklenen dil önce
draft, ardındanactivedurumuna alınacak. - Eksik çeviri halinde sayfada çeviri anahtarı değil fallback metni gösterilecek.
- Yeni locale için instance sahibi
trveyaenfallback dili seçecek. - Portal için kritik çevirileri tamamlanmayan dil müşteri dili olarak yayınlanamayacak.
- Dashboard ve portal route'larına
/tr,/engibi URL prefix'i eklenmeyecek. - Locale; kullanıcı tercihi, davet kaydı ve güvenli cookie üzerinden çözümlenecek.
- Arayüz çeviri sistemi için ağır bir runtime bağımlılığı eklenmeyecek; mevcut
Intl, React ve SQLite temelli küçük bir Neta i18n katmanı yazılacak. - İlk sürümde makine çevirisi zorunlu olmayacak.
- Çeviri paketi JSON olarak içe ve dışa aktarılabilecek.
- İçerik formlarında yalnızca çevrilebilir metin alanları locale tab'ları içinde olacak.
- Instance varsayılan dilindeki zorunlu alanlar boş bırakılamayacak.
- Built-in Türkçe ve İngilizce katalogları release sırasında yüzde 100 tamamlanmış olmak zorunda olacak.
5. Hedef mimari
Kod ile gelen anahtar kataloğu
├── tr katalog
└── en katalog
|
v
SQLite locale kayıtları + instance çeviri override'ları
|
v
Locale resolver
├── Auth öncesi: davet / cookie / instance default
├── Freelancer: user preference / instance default
└── Client: user preference / client portal locale / instance default
|
v
Translator
├── Server Components
├── Server Actions / hata kodları
├── Client Components provider
└── API locale context
|
+--------------------------+
| |
v v
Arayüz sözlüğü İçerik translation resolver
sidebar, label, hata project/task/planning/branding
5.1. Önerilen klasör yapısı
lib/i18n/
types.ts
keys.ts
catalog.ts
format.ts
locales/
tr/
common.ts
auth.ts
navigation.ts
dashboard.ts
clients.ts
projects.ts
tasks.ts
calendar.ts
finance.ts
journal.ts
chat.ts
settings.ts
portal.ts
validation.ts
en/
...
server/i18n/
locale.ts
resolver.ts
translator.ts
catalog.ts
service.ts
content.ts
validation.ts
server/repositories/
i18n.ts
content-translations.ts
components/i18n/
i18n-provider.tsx
locale-tabs.tsx
localized-fields.tsx
translation-status.tsx
5.2. Namespace standardı
Katalog tek ve devasa bir JSON dosyası olmayacaktır. Anahtarlar modül bazında namespace'lere ayrılır:
| Namespace | Kapsam |
|---|---|
common |
Kaydet, sil, düzenle, iptal, loading, boş durumlar |
auth |
Login, register, davet, şifre ve auth hataları |
navigation |
Freelancer ve portal sidebar |
dashboard |
Freelancer dashboard |
clients |
Müşteri liste/detay/form |
projects |
Proje liste/detay/form/planlama |
tasks |
Görev liste/kanban/form |
calendar |
Takvim ve etkinlik |
finance |
Finans, analiz ve işlem formu |
journal |
Günlük ekranı |
chat |
AI sohbet ekranı |
settings |
Ayarlar ve dil yönetimi |
portal |
Müşteri portalı |
status |
Domain status/priority/type label'ları |
validation |
Form, action ve kullanıcıya açık hata metinleri |
Her anahtar anlamlı ve stabil olmalıdır. Türkçe cümle anahtar olarak kullanılmamalıdır.
6. Locale çözümleme sözleşmesi
6.1. Locale formatı
- Locale kodları BCP 47 formatında kabul edilir:
tr,en,fr,de,pt-BR,zh-CN. - Girdi
Intl.getCanonicalLocales()ile normalize edilir. - Aynı locale farklı harf biçimleriyle ikinci kez eklenemez.
- Locale kaydında gösterim adı, native ad ve yön (
ltr/rtl) tutulur. - Maksimum locale kodu ve metin uzunlukları merkezi Zod schema ile doğrulanır.
6.2. Freelancer locale önceliği
- Giriş yapan kullanıcının
user_preferences.languagedeğeri - Güvenli ve aktif bir
neta_localecookie değeri - Instance varsayılan locale'i
- Son güvenlik fallback'i olarak
tr
6.3. Müşteri portalı locale önceliği
- Müşteri hesabının
user_preferences.languagedeğeri - İlgili
clients.portal_localedeğeri - Instance varsayılan locale'i
- Son güvenlik fallback'i olarak
tr
6.4. Davet ve auth öncesi locale önceliği
- Portal davetinin
localesnapshot'ı - Aktif
neta_localecookie değeri - Instance varsayılan locale'i
- Son güvenlik fallback'i olarak
tr
Accept-Language yalnızca public login ekranında, header'daki locale instance
üzerinde aktifse düşük öncelikli ilk ziyaret ipucu olarak kullanılabilir. Müşteri
davetinin seçilmiş dilini değiştiremez.
6.5. Çeviri fallback zinciri
Örnek seçili locale fr-CA ise:
fr-CA override
-> fr override
-> locale kaydında seçilen fallback (en veya tr)
-> built-in en
-> kontrollü missing-translation metni
Production ekranında projects.form.name.label gibi ham anahtarlar
gösterilmeyecektir. Development ve test ortamında missing key loglanacaktır.
6.6. HTML ve formatlama
- Root layout içindeki
langaktif locale'e göre üretilecek. - Root layout içindeki
dir, locale kaydındakiltrveyartldeğerinden üretilecek. - Tarih/saat
Intl.DateTimeFormat(locale, options)ile biçimlendirilecek. - Para ve sayı
Intl.NumberFormat(locale, options)ile biçimlendirilecek. date-fnsgereken yerlerde locale mapping merkezi helper üzerinden seçilecek.- Timezone tercihi locale'den bağımsız kalacak.
- Para birimi tercihi locale'den bağımsız kalacak.
7. Hedef veri modeli
Tablo ve kolon adları implementasyon sırasında Drizzle naming standardına göre kesinleştirilir.
7.1. instance_locales
Instance üzerinde yönetilebilen dil listesidir.
| Alan | Amaç |
|---|---|
code |
Canonical BCP 47 locale, primary key |
display_name |
Ayarlar ekranındaki yönetim adı |
native_name |
Dilin kendi dilindeki adı |
direction |
ltr veya rtl |
fallback_locale |
Eksik anahtarların düşeceği aktif locale |
status |
draft, active, archived |
is_builtin |
Türkçe ve İngilizce koruması |
sort_order |
Form tab sırası |
created_at |
Oluşturulma zamanı |
updated_at |
Güncellenme zamanı |
Kurallar:
trveenmigration ile eklenir.- Built-in locale silinemez veya arşivlenemez.
- Varsayılan veya müşteri tarafından kullanılan locale doğrudan silinemez.
- Locale silmek yerine arşivleme tercih edilir.
fallback_locale, kaydın kendisi olamaz ve döngü oluşturamaz.
7.2. instance_i18n_settings
Tek instance'a ait global dil ayarlarıdır.
| Alan | Amaç |
|---|---|
id |
Sabit default kaydı |
owner_user_id |
Instance sahibi |
default_locale |
Yeni kullanıcılar ve genel fallback |
catalog_version |
Cache invalidation için artan sürüm |
updated_by_user_id |
Son değiştiren owner |
updated_at |
Son değişiklik |
İlk migration default_locale=tr olarak seed eder.
7.3. instance_ui_translations
Built-in katalog override'larını ve sonradan eklenen locale metinlerini saklar.
| Alan | Amaç |
|---|---|
id |
Teknik kimlik |
locale |
instance_locales.code ilişkisi |
namespace |
Katalog namespace'i |
translation_key |
Stabil anahtar |
value |
Çevrilmiş düz metin |
updated_by_user_id |
Değişikliği yapan owner |
created_at |
Oluşturulma zamanı |
updated_at |
Güncellenme zamanı |
Unique constraint:
(locale, namespace, translation_key)
Built-in Türkçe ve İngilizce metinler kodda kalır. Bu tablo yalnızca değiştirilen değerleri ve custom locale değerlerini taşır; böylece her katalog sürümünde binlerce seed satırı oluşturulmaz.
7.4. content_translations
Portalda gösterilebilen domain içeriklerini normalize biçimde saklar.
| Alan | Amaç |
|---|---|
id |
Teknik kimlik |
owner_user_id |
Authorization scope |
entity_type |
project, task, planning_section, branding vb. |
entity_id |
İlgili domain kaydı |
field |
name, title, description, content, cover_image_alt vb. |
locale |
İçeriğin locale'i |
value |
Çevrilmiş metin |
created_at |
Oluşturulma zamanı |
updated_at |
Güncellenme zamanı |
Unique constraint:
(owner_user_id, entity_type, entity_id, field, locale)
Polymorphic entity_id nedeniyle DB seviyesinde her domain tablosuna foreign key
kurulamaz. Bütün erişim merkezi ContentTranslationService üzerinden yapılır:
- Geçerli entity ve çevrilebilir alan registry üzerinden doğrulanır.
- Owner scope zorunludur.
- Domain kaydı silinirken çeviri kayıtları aynı transaction içinde silinir.
- Portal actor yalnızca kendisine açık kaynakların resolved metnini okuyabilir.
- Portal actor ham çeviri setini veya başka locale içeriklerini değiştiremez.
7.5. Mevcut tablo değişiklikleri
user_preferences.languageüzerindeki sabitin ('tr', 'en')constraint'i kaldırılır.- Bu alan yalnızca instance üzerinde aktif locale değerlerini service katmanında kabul eder.
clients.portal_localealanı eklenir.portal_invitations.localealanı eklenir.- Davet kabul transaction'ında client locale ve yeni kullanıcının preference locale'i birlikte yazılır.
- Gerekirse mevcut
owner_user_idadlı preference kolonu şema kırmadan korunur; kod tarafında bunun tüm auth kullanıcıları için preference sahibi anlamına geldiği belgelenir.
7.6. Eski içerik kolonları
projects.name, projects.description, tasks.title gibi mevcut kolonlar ilk
sürümde kaldırılmayacaktır.
- Migration mevcut değerleri Türkçe translation kayıtlarına backfill eder.
- Yeni create/update akışı varsayılan locale değerini hem eski kolona hem
content_translationstablosuna transaction içinde yazar. - Eski kolonlar geriye uyumluluk ve güvenli rollback projection'ı olur.
- Portal ve yeni API okuma akışları locale-aware resolver kullanır.
- Bu kolonların tamamen kaldırılması ayrı bir major veri modeli kararıdır.
8. Çevrilebilir domain alanları
8.1. İlk zorunlu kapsam
| Entity | Çevrilebilir alanlar | Portal etkisi |
|---|---|---|
project |
name, description, coverImageAlt |
Proje liste ve detay |
projectPlanningSection |
title, content |
Proje planlama içeriği |
task |
title, description |
Yalnız müşteriye açık görevler |
branding |
portalWelcomeText, portalFooterText |
Portal shell/dashboard |
8.2. İkinci kapsam
| Entity | Çevrilebilir alanlar | Not |
|---|---|---|
proposal |
title, description |
Portalda yayınlandığında zorunlu |
contract |
title, content |
Portalda yayınlandığında zorunlu |
invoice |
Açıklama/not alanı eklenirse | Mevcut şemada metin alanı yok |
calendarEvent |
title, description |
Portal görünürlüğü eklenirse |
8.3. Çevrilmeyecek domain alanları
- Client adı ve firma adı kimlik verisidir; locale tab'ına girmez.
- Finans açıklaması owner-only olduğu sürece tek dilde kalır.
- Günlük notları ve AI chat içerikleri tek dilde kalır.
- Müşteri aktivite başlığı/içeriği owner-only olduğu sürece tek dilde kalır.
- Revizyon talebi müşterinin yazdığı dilde saklanır.
Bu kapsam ileride portal görünürlüğü değiştiğinde registry üzerinden genişletilebilir.
9. Çok dilli form UX sözleşmesi
Formlar Poyraz UI Tabs bileşeniyle ortak bir LocalizedFields bileşimi
kullanacaktır.
Örnek proje formu:
[ Türkçe ✓ ] [ English ! ] [ Français ✓ ]
Proje adı
[ Marka web sitesi ]
Açıklama
[ ... ]
------------------------------------------------
Tür, müşteri, durum, tarih, bütçe, para birimi
Kurallar:
- Aktif diller instance
sort_orderdeğerine göre tab olarak gösterilir. - Varsayılan dil ilk tab olur ve “Varsayılan” işareti taşır.
- Eksik zorunlu alan bulunan tab uyarı noktası taşır.
- Dolu tab görsel tamamlanma işareti taşır.
- Tab değiştirmek form state'ini kaybettirmez.
- Input ID'leri locale ile ayrıştırılır.
- Form field adları merkezi parser'ın okuyacağı stabil yapıda olur:
translations.tr.name,translations.en.namegibi. - Zorunlu alan doğrulaması varsayılan locale için yapılır.
- Müşteriye açık içerik kaydedilirken hedef portal locale'de eksik alan varsa kullanıcıya fallback uygulanacağı açıkça gösterilir.
- Dil ekleme veya arşivleme açık bir formu bozmaz; form açılırken locale snapshot'ı alınır.
- Mobil ve dar ekranlarda tab listesi yatay kayabilir; formun tamamı yatay scroll oluşturmaz.
- Screen reader için tab, panel, label ve validation ilişkileri korunur.
10. Dil yönetimi UX sözleşmesi
Ayarlar sayfasına Diller ve çeviriler bölümü eklenir.
10.1. Dil listesi
Her dil satırında:
- Native ad ve locale kodu
- Built-in/custom bilgisi
- Draft/active/archived durumu
- Genel çeviri tamamlanma yüzdesi
- Portal kritik çeviri tamamlanma yüzdesi
- Varsayılan dil işareti
- Düzenle, dışa aktar, aktif et/arşivle aksiyonları
10.2. Dil ekleme
Dil ekleme dialog'unda:
- Locale kodu
- Görünen ad
- Native ad
- Yazı yönü
- Fallback dili
yer alır. Yeni dil draft oluşturulur ve henüz müşterilere atanamaz.
10.3. Çeviri editörü
- Namespace filtresi
- Anahtar veya kaynak metin arama
- Yalnız eksik çevirileri gösterme
- Türkçe ve İngilizce referans metinlerini yan yana görme
- Hedef locale input'u
- Tek alan kaydetme ve toplu kaydetme
- Fallback'ten gelen değer ile gerçek override ayrımını görme
- Değeri sıfırlayarak built-in/fallback metnine dönme
- Portal için kritik anahtar filtresi
10.4. JSON içe/dışa aktarma
Önerilen format:
{
"schemaVersion": 1,
"locale": "fr",
"fallbackLocale": "en",
"catalogVersion": 1,
"translations": {
"common.save": "Enregistrer",
"navigation.projects": "Projets"
}
}
İçe aktarma:
- Owner yetkisi gerektirir.
- Dosya boyutu ve entry sayısı sınırlandırılır.
- Bilinmeyen key'ler raporlanır ve varsayılan olarak yazılmaz.
- Geçersiz veya tehlikeli anahtarlar reddedilir.
- Mevcut değerlerin üzerine yazma için açık onay gerekir.
- Import özeti ekleme/değiştirme/atlama sayılarıyla gösterilir.
11. Portal dili ve davet akışı
Yeni davet akışı:
- Freelancer müşteri detayında “Portal hesabı aç” dialog'unu açar.
- E-posta ile birlikte
Portal diliseçer. - Dropdown yalnızca aktif ve portal kritik çevirileri hazır dilleri gösterir.
- Seçim
portal_invitations.localealanına snapshot olarak yazılır. - Aynı seçim
clients.portal_localealanına kaydedilir. - Müşteri davet linkini açtığında hesap oluşturma ekranı bu dilde görünür.
- Davet kabul transaction'ı Better Auth user, profile, client bağlantısı ve
user_preferences.languagekaydını atomik oluşturur. - Müşteri login olduğunda portal aynı locale ile açılır.
- Freelancer daha sonra müşteri detayından portal dilini değiştirebilir.
- Dil arşivlenecekse bu dili kullanan müşteriler için yeni locale seçilmeden işlem tamamlanmaz.
Davet yenilendiğinde yeni davet seçilen son locale'i taşır. Eski davet revoke edilirken locale audit metadata'sına eklenir.
12. API ve mobil istemci sözleşmesi
Çok dillilik yalnızca web UI davranışı olmayacaktır.
12.1. Discovery ve metadata
/api/v1/meta additive olarak aşağıdaki bilgileri döndürür:
{
"localization": {
"defaultLocale": "tr",
"supportedLocales": [
{
"code": "tr",
"nativeName": "Türkçe",
"direction": "ltr"
},
{
"code": "en",
"nativeName": "English",
"direction": "ltr"
}
]
}
}
Capability listesine aşağıdaki kayıt eklenir:
{
"id": "instance.localization",
"version": 1,
"status": "available",
"access": "public"
}
12.2. Kullanıcı bilgisi
GET /api/v1/me:
- Çözülmüş
preferences.languagedeğerini döndürür. - Client rolünde
portalLocalebilgisini döndürür. - Locale'in arşivlenmesi gibi edge case'lerde çözülmüş fallback locale'i döndürür.
12.3. Gelecek resource endpoint'leri
Accept-Languagedestekler.- Gerekirse açık
?locale=frparametresi destekler. - Client actor yalnızca kendi atanmış/izin verilen locale görünümünü alır.
- Freelancer actor isterse
includeTranslations=trueile bütün edit setini alır. - Varsayılan resource response resolved metni döndürür.
- Mutation sözleşmesi
translations: { locale: { field: value } }yapısını kullanır. - Bilinmeyen locale için stabil
UNSUPPORTED_LOCALEhata kodu döner. - API'nin
error.codealanı stabil kalır;error.messageseçili locale'de üretilebilir.
12.4. Cache sözleşmesi
- Public meta cache'i dil listesi değişince revalidate edilir.
- Locale bağımlı public yanıtlar
Vary: Accept-Languagetaşır. - Authenticated resource yanıtları
private, no-storekalır. - Mobil istemci katalog sürümünü saklayabilir; değiştiğinde ilgili locale sözlüğünü yeniler.
13. Güvenlik ve veri bütünlüğü
- Locale ve çeviri yönetimi yalnızca freelancer/owner rolüne açıktır.
- UI translation değerleri varsayılan olarak düz metin render edilir.
- Çeviri editörü key üzerinden key dışı kod veya HTML çalıştırmaz.
- Rich text gerekirse ayrı sanitize edilmiş alan tipi olarak tasarlanır.
- Interpolation yalnızca tanımlı değişkenlere izin verir.
- Kullanıcı tarafından girilen
{{...}}token'ları katalog şemasına göre doğrulanır. - Her çeviri değeri için maksimum uzunluk tanımlanır.
- JSON import için byte ve entry limiti uygulanır.
__proto__,constructor, path traversal benzeri key'ler reddedilir.- Fallback döngüleri service katmanında engellenir.
- Aktif kullanımda olan locale hard delete edilemez.
- İçerik çevirileri her read/write işleminde owner ve actor scope'u ile sınırlandırılır.
- Client başka müşteriye ait translation kayıtlarını enumerate edemez.
- Davet locale'i sadece aynı owner'ın aktif locale listesinden seçilebilir.
- Locale değişiklikleri auth audit veya ayrı settings audit kaydına yazılır.
14. Performans ve cache yaklaşımı
- Built-in
tr/enkatalogları statik import ile gelir. - DB yalnızca override ve custom locale değerlerini taşır.
- Server translator, request başına resolved dictionary oluşturur.
- Client layout'a yalnız ihtiyaç duyduğu namespace'leri alır.
- Tüm katalog her sayfada browser'a gönderilmez.
catalog_versionher locale/translation mutation'ında transaction içinde artırılır.- Cache anahtarı
locale + namespace set + catalogVersionolur. - Dil değişikliğinde ilgili layout ve metadata revalidate edilir.
- İçerik resolver liste sorgularında N+1 oluşturmaz; entity ID listesi ve locale zinciri için tek toplu sorgu kullanır.
- Portal proje/görev listelerinde translation join/batch ölçümü yapılır.
- SQLite index'leri locale ve entity lookup'larına göre eklenir.
15. Faz bazlı uygulama planı
Faz 0 — Envanter, ADR ve test fixture'ları
Amaç: Kod yazmadan önce kapsamı ve davranış sözleşmelerini kilitlemek.
Görevler
- Kullanıcıya görünen sabit metinlerin dosya ve namespace envanterini çıkar.
- Freelancer ve portal sayfalarını ayrı migration listelerine ayır.
- Tüm sabit
tr-TR,<html lang="tr">vedate-fns/locale/trkullanımlarını kaydet. - Çevrilebilir domain alan registry'sini kesinleştir.
- UI çevirisi ile domain içerik çevirisi ayrımını ADR olarak yaz.
- Locale çözümleme önceliğini ADR olarak yaz.
- Route prefix kullanılmaması kararını kaydet.
- Custom runtime i18n katmanı kararını ve bağımlılık etkisini kaydet.
- Türkçe mevcut veri fixture'ı hazırla.
- İngilizce ve eksik Fransızca katalog fixture'ı hazırla.
- Freelancer, Türkçe client ve İngilizce client auth fixture'ları hazırla.
- RTL davranışı için test locale'i belirle.
- Baseline build, typecheck ve ilgili smoke sonuçlarını kaydet.
Faz 0 çıktıları
- Faz 0 ADR seti
- Faz 0 i18n envanteri
- Faz 0 fixture planı
- Faz 0 migration ve geri dönüş sözleşmesi
- Faz 0 baseline sonuçları
Çıkış kriteri
- Katalog anahtar standardı onaylandı.
- İlk çevrilebilir entity/field listesi onaylandı.
- Fallback ve portal yayın kuralları tartışmasız hale geldi.
- Migrasyon öncesi geri dönüş ve backup adımları yazıldı.
Faz 1 — Locale veri modeli ve service katmanı
Amaç: Dil yönetiminin güvenli SQLite temelini oluşturmak.
Görevler
instance_localesDrizzle şemasını ekle.instance_i18n_settingsDrizzle şemasını ekle.instance_ui_translationsDrizzle şemasını ekle.content_translationsDrizzle şemasını ekle.clients.portal_localealanını ekle.portal_invitations.localealanını ekle.user_preferences.languagesabit check constraint'ini kaldır.- Gerekli unique constraint ve index'leri ekle.
- Türkçe ve İngilizce locale seed'lerini migration içine ekle.
- Instance varsayılan dilini
trolarak seed et. - Mevcut preference kayıtlarını doğrula ve normalize et.
- Locale CRUD repository ve service katmanını yaz.
- Locale ekleme, aktif etme, arşivleme ve default değiştirme validasyonlarını yaz.
- Fallback döngüsü ve referanslı locale korumasını uygula.
- Owner/client negatif authorization testlerini yaz.
- Backup/restore smoke testine yeni tabloları dahil et.
Faz 1 çıktıları
- Faz 1 locale veri modeli ve service raporu
server/db/schema/i18n.tsserver/repositories/i18n.tsserver/i18n/service.tsserver/db/migrations/0008_wild_mercury.sqlscripts/i18n-phase1-smoke.mjsscripts/i18n-phase1-smoke.ts
Çıkış kriteri
- Mevcut veritabanı kayıpsız migrate oluyor.
- Yeni instance
trveenile açılıyor. - Geçersiz locale ve fallback döngüsü DB'ye yazılamıyor.
- Aktif kullanılan locale yanlışlıkla silinemiyor.
- Mevcut login, dashboard ve portal akışları değişmeden çalışıyor.
Faz 2 — Çeviri runtime'ı ve built-in kataloglar
Amaç: Server ve client component'lerde ortak, typed ve fallback destekli çeviri altyapısını kurmak.
Görevler
- Katalog key/namespace tiplerini tanımla.
- Built-in Türkçe katalogları mevcut metinlerden çıkar.
- İngilizce katalogları eksiksiz hazırla.
- Server-side
createTranslator(locale, namespaces)helper'ını yaz. - Client
I18nProviderveuseTranslationshook'unu yaz. - Interpolation formatını ve doğrulamasını uygula.
- Basit çoğul kurallarını
Intl.PluralRulesile uygula. - DB override + built-in + fallback merge sırasını uygula.
- Locale resolver'ı cookie/session/instance kaynaklarına bağla.
neta_localecookie lifecycle'ını ekle.- Root layout
langvedirdeğerlerini dinamik yap. - Ortak tarih, saat, para ve sayı formatter'larını yaz.
- Missing key development log'u ve production fallback davranışını uygula.
- Namespace bazlı cache ve
catalog_versioninvalidation'ını uygula. - Türkçe/İngilizce katalog parity testini yaz.
Faz 2 çıktıları
- Faz 2 çeviri runtime raporu
lib/i18n/*locales/tr/*locales/en/*components/i18n/i18n-provider.tsxserver/i18n/catalog.tsserver/i18n/locale.tsserver/i18n/resolver.tsserver/i18n/translator.tsserver/i18n/runtime.tsapp/api/i18n/locale/route.tsscripts/i18n-phase2-smoke.mjsscripts/i18n-phase2-smoke.ts
Çıkış kriteri
- Aynı component Türkçe ve İngilizce render edilebiliyor.
- Custom locale override deployment olmadan okunabiliyor.
- Eksik Fransızca anahtar belirlenen fallback ile gösteriliyor.
<html lang>ve<html dir>locale'e göre doğru.- Client hydration mismatch oluşmuyor.
- Built-in katalog key setleri yüzde 100 eşleşiyor.
Faz 3 — Ayarlar: dil ve çeviri yönetimi
Amaç: Instance sahibinin kod değiştirmeden dil ekleyip yönetebilmesini sağlamak.
Görevler
- Ayarlar sidebar'ına
Diller ve çevirilerbölümü ekle. - Dil listesi ve tamamlanma kartlarını Poyraz UI ile oluştur.
- Yeni dil ekleme dialog'unu ekle.
- Default locale değiştirme akışını ekle.
- Giriş yapan freelancer için kişisel arayüz dili seçicisini ekle ve
user_preferences.languagealanına bağla. - Draft/active/archive lifecycle'ını ekle.
- Namespace ve eksik anahtar filtreli çeviri editörünü ekle.
- Türkçe/İngilizce referans metinlerini editörde göster.
- Tekil ve toplu çeviri kaydetme action'larını yaz.
- Built-in override'ı sıfırlama aksiyonunu ekle.
- Genel ve portal kritik tamamlanma yüzdesini hesapla.
- JSON export endpoint/action'ını yaz.
- Güvenli JSON import preview ve commit akışını yaz.
- Çeviri değişikliklerinde layout/meta/cache revalidation uygula.
- Ayarlar mutation'larını audit et.
- Yetkisiz client erişimi için negatif test ekle.
Faz 3 çıktıları
- Faz 3 ayarlar dil ve çeviri yönetimi raporu
app/(dashboard)/settings/page.tsxapp/(dashboard)/settings/actions.tsserver/i18n/service.tsserver/repositories/i18n.tsserver/settings/preferences.tsscripts/i18n-phase3-smoke.mjsscripts/i18n-phase3-smoke.ts
Çıkış kriteri
- Owner Ayarlar'dan
frekleyebiliyor. - Fransızca bir sidebar metni girilip sayfa yenilemeden sonra kullanılabiliyor.
- Eksik metinler editörde bulunabiliyor.
- JSON export/import round-trip veri kaybetmiyor.
- Client dil yönetimi endpoint/action'larına erişemiyor.
Faz 4 — Freelancer arayüzünün sayfa sayfa taşınması
Amaç: Owner uygulamasındaki bütün sistem metinlerini katalog üzerinden göstermek.
Ortak bileşenler
- App shell, skip link ve mobil menü
- Sidebar grup ve menüleri
- Hesap dropdown'ı ve çıkış
- Page header, stat card ve empty/error state
- Status badge ve confirmation dialog
- Toast, pending button ve genel validation mesajları
- Metadata description ve erişilebilirlik label'ları
Sayfalar
- Login
- İlk admin kaydı
- Dashboard
- Takvim
- Analizler
- Müşteriler listesi
- Müşteri detayı ve portal daveti
- Projeler listesi
- Proje detayı
- Görevler
- Finans
- Günlük
- AI sohbet
- Teklifler
- Faturalar
- Abonelikler
- Ayarlar
Formatlama ve hata sözleşmesi
- Tüm sabit
tr-TRkullanımını locale-aware formatter'a taşı. - Tüm sabit
date-fnsTürkçe locale importlarını merkezi mapping'e taşı. - Enum değerlerini çevirmeden, yalnız gösterim label'larını çevir.
- Server action'larda kullanıcıya gösterilen string yerine stabil hata kodu döndürmeye başla.
- Hata kodlarını
validationnamespace'i üzerinden kullanıcı locale'inde göster. - AI endpoint teknik hata detaylarını korurken UI mesajlarını locale-aware yap.
Faz 4 çıktıları
- Faz 4 freelancer UI migration raporu
- Faz 4 kalan hardcoded metin raporu
components/layout/app-shell.tsxcomponents/layout/dashboard-shell.tsxconfig/sidebar.tsapp/(dashboard)/layout.tsxapp/(dashboard)/dashboard-client.tsxlib/i18n/browser.tslib/i18n/date-fns.tsscripts/i18n-phase4-boundary.mjs
Çıkış kriteri
- Freelancer UI Türkçe ve İngilizce eksiksiz kullanılabiliyor.
- Sidebar ve tüm header'lar seçili dilde.
- Dialog, toast, empty state ve form doğrulamaları seçili dilde.
- Tarih, sayı ve para formatları seçili locale'e uyuyor.
- Hardcoded kullanıcı metni boundary kontrolü kalan istisnaları raporluyor.
Faz 5 — Çok dilli domain içerikleri ve form tab'ları
Amaç: Freelancer'ın müşteriye gösterilecek içeriği aktif dillerde girebilmesini sağlamak.
Altyapı
- Çevrilebilir entity/field registry'sini kodla.
ContentTranslationServiceve repository batch sorgularını yaz.- Locale fallback'li content resolver'ı yaz.
- Create/update/delete transaction entegrasyonunu yaz.
LocalizedFieldsveLocaleTabsortak bileşenlerini yaz.- FormData translation parser ve Zod doğrulamasını yaz.
- Eksik tab göstergesi ve default locale zorunluluğunu ekle.
- Mevcut Türkçe içeriği
trkayıtlarına idempotent backfill et. - Eski temel kolon ile varsayılan locale projection'ını transaction içinde senkron tut.
Formlar
- Proje oluşturma formu: ad, açıklama, görsel alt metni
- Proje düzenleme formu: ad, açıklama, görsel alt metni
- Planlama alanı oluşturma/düzenleme: başlık ve içerik
- Görev oluşturma/düzenleme: başlık ve açıklama
- Proje detayından görev ekleme: başlık ve açıklama
- Genel ayarlar: portal karşılama ve footer metni
- İkinci kapsam aktifse teklif ve sözleşme formları — bu fazda aktif kapsam dışı bırakıldı.
Okuma akışları
- Freelancer liste/detayında kendi locale'ine resolved metin göster.
- Edit formlarında tüm locale değerlerini batch yükle.
- Arama davranışını tanımla: ilk sürümde aktif owner locale + temel kolon.
- AI context üretirken source/default locale davranışını belirle.
- İçerik silinince translation kayıtlarını aynı transaction'da sil.
Çıkış kriteri
- Proje adı Türkçe, İngilizce ve Fransızca ayrı kaydedilebiliyor.
- Tab değişimi girilmiş değeri kaybettirmiyor.
- Varsayılan dil başlığı boş proje oluşturulamıyor.
- Aynı proje seçili locale'e göre farklı resolved başlık döndürüyor.
- Locale translation query'leri liste ekranında N+1 oluşturmuyor.
- Eski veriler migration sonrasında Türkçe olarak görünmeye devam ediyor.
Faz 5 çıktıları
- Faz 5 çok dilli domain içerikleri raporu
lib/i18n/content.tsserver/i18n/content.tscomponents/i18n/localized-fields.tsxapp/(dashboard)/projects/actions.tsapp/(dashboard)/tasks/actions.tsapp/(dashboard)/projects/page.tsxapp/(dashboard)/projects/[id]/page.tsxapp/(dashboard)/tasks/page.tsxscripts/i18n-phase5-smoke.mjsscripts/i18n-phase5-smoke.ts
Faz 6 — Müşteri portal dili ve davet akışı
Amaç: Müşterinin ilk davet ekranından itibaren kendisine atanmış dili görmesini sağlamak.
Davet
- Portal hesabı açma dialog'una dil dropdown'u ekle.
- Yalnız portal-ready aktif dilleri seçilebilir yap.
- Compatibility
/api/create-client-useradapter'ına locale ekle. /api/portal-invitationssözleşmesine locale ekle.- Invitation schema ve service validasyonuna locale ekle.
- Locale'i invitation ve client kaydına transaction içinde yaz.
- Davet preview response'una güvenli locale bilgisini ekle.
- Davet sayfasını invitation locale'i ile render et.
- Davet kabulünde
user_preferences.languagekaydını oluştur. - Invitation audit metadata'sına locale ekle.
Portal shell ve sayfalar
- Portal sidebar
- Portal hesap dropdown'ı ve çıkış
- Portal dashboard
- Portal projeler listesi
- Portal proje detayı
- Portal public görev listesi
- Portal revizyon listesi
- Revizyon oluşturma formu
- Portal progress ve empty state'ler
- Portal tarih, sayı ve durum label'ları
İçerik çözümleme
- Proje ve planlama içeriklerini client locale'inde resolve et.
- Public görevleri client locale'inde resolve et.
- Eksik içerikte belirlenen fallback zincirini uygula.
- Revizyon talebini yazıldığı dilde sakla.
- Client başka locale'lerin edit setine erişemediğini test et.
Yönetim
- Müşteri detayında mevcut portal dilini göster.
- Portal dili değiştirme aksiyonu ekle.
- Locale arşivleme öncesi etkilenen müşteri sayısını göster.
- Client locale değişikliğinde aktif session'ın sonraki request'te yeni dili kullanmasını sağla.
Çıkış kriteri
- İngilizce seçilen davet linki İngilizce açılıyor.
- Hesap kabulü sonrasında portal İngilizce kalıyor.
- Fransızca client, Fransızca proje içeriğini görüyor.
- Eksik Fransızca içerik güvenli fallback ile gösteriliyor.
- Türkçe client davranışında regression yok.
- Başka müşterinin locale veya çeviri verisi sızmıyor.
Faz 6 çıktıları
- Faz 6 müşteri portal dili ve davet akışı raporu
server/auth/invitations.tsapp/api/create-client-user/route.tsapp/api/portal-invitations/route.tsapp/api/portal-clients/[clientId]/locale/route.tsapp/invite/[token]/page.tsxapp/portal/layout.tsxcomponents/layout/portal-shell.tsxconfig/portal-sidebar.tsapp/portal/page.tsxapp/portal/projects/page.tsxapp/portal/projects/[id]/page.tsxapp/portal/tasks/page.tsxapp/portal/revisions/page.tsx
Faz 7 — Auth, hata, bildirim ve erişilebilirlik bütünlüğü
Amaç: Ana sayfalar dışında kalan uç metinleri ve locale edge case'lerini tamamlamak.
Görevler
- Login ekranında aktif diller arasında seçim sun.
- İlk admin kurulumunda instance default locale davranışını tamamla.
- Forgot/reset password ekranlarını kataloglaştır.
- 404, error boundary ve maintenance metinlerini kataloglaştır.
- Server action redirect query mesajlarını stabil hata kodlarına taşı.
- Toast tekrarlarını engelleyen mevcut akışları locale değişiminde doğrula.
- Erişilebilirlik label,
aria-label, tooltip ve screen-reader metinlerini kataloglaştır. - Interpolation ve plural örneklerini tüm built-in locale'lerde test et.
- RTL smoke testi yap; desteklenmeyen layout noktalarını raporla ve düzelt.
- Locale değiştirme kontrolünün focus ve klavye davranışını test et.
- Bildirim/e-posta sistemi eklendiğinde kullanacağı locale sözleşmesini belgeye bağla.
Çıkış kriteri
- Auth öncesi ve sonrası locale geçişi tutarlı.
- Kullanıcıya görünen server hata mesajları Türkçe'ye gömülü değil.
- Erişilebilirlik metinleri de seçili locale'de.
- RTL locale temel shell ve formları kullanılamaz hale getirmiyor.
Faz 8 — API v1 ve mobil hazırlık
Amaç: Aynı dil modelini gelecekteki React Native istemcisi için stabil bir sözleşmeye dönüştürmek.
Görevler
instance.localizationcapability kaydını ekle./api/v1/metalocalization alanlarını ekle./.well-known/netaiçin gerekli additive locale bilgisini değerlendir./api/v1/mepreference language ve portal locale alanlarını ekle.Accept-Languageparser ve locale negotiation helper'ını yaz.- Gelecek resource endpoint'leri için localized response contract'ı ekle.
- Owner mutation contract'ında
translationsshape'ini standartlaştır. UNSUPPORTED_LOCALEhata kodunu API response mapping'e ekle.- Client'ın unknown locale/capability değerlerini güvenli ele almasını belgeye ekle.
- Meta cache revalidation ve absolute URL davranışını test et.
- API contract fixture'larını
tr,en,friçin ekle. - Phase 9 mobile smoke testlerini localization alanlarıyla genişlet.
Faz 8 çıktıları
- Faz 8 API v1 ve mobil hazırlık raporu
server/api/v1/localization.tsserver/api/v1/contracts.tsscripts/i18n-phase8-smoke.mjsscripts/i18n-phase8-smoke.tsapp/api/v1/me/route.tsscripts/phase9-api-boundary.mjsdocs/self-hosted-redesign/i18n-phase-8-fixtures/
Çıkış kriteri
- Mobil istemci instance'ın desteklediği dilleri keşfedebiliyor.
/mekullanıcının çözülmüş dilini döndürüyor.- Eski v1 client'lar additive alanlar nedeniyle kırılmıyor.
- Locale seçimi server authorization sınırını aşmıyor.
Faz 9 — Hardening, migrasyon ve release
Amaç: Çok dilli özelliği self-host production kurulumu için güvenli şekilde yayınlamak.
Migrasyon
- Release öncesi otomatik backup zorunluluğunu belgeye ekle.
- Boş DB migration testi yap.
- Mevcut production benzeri Türkçe DB migration testi yap.
- Tekrar çalışan idempotent backfill testi yap.
- Migration failure sonrası eski sürüme dönüş prosedürünü test et.
- Backup/restore sonrasında locale ve çeviri bütünlüğünü doğrula.
- Supabase import aracının yeni locale default'larını doğru oluşturduğunu test et.
Otomasyon
phase-i18n:boundaryscript'i ekle.- Hardcoded kullanıcı metni istisna listesini minimumda tut.
- Built-in katalog parity ve interpolation değişken testlerini CI'a ekle.
- Locale service authorization testlerini CI'a ekle.
- Content translation transaction testlerini CI'a ekle.
- Portal davet locale E2E testini CI'a ekle.
- Build, typecheck, lint ve mevcut phase smoke testlerini çalıştır.
- Docker standalone image içinde built-in katalogların bulunduğunu doğrula.
Performans ve gözlem
- Freelancer dashboard render süresini önce/sonra ölç.
- Portal proje listesi query sayısını önce/sonra ölç.
- Custom katalog yükleme boyutunu ölç.
- Missing translation sayacını logla; hassas içerik loglama.
- Catalog version/cache invalidation yarış koşullarını test et.
Dokümantasyon
- Self-host kurulum dokümanına default locale ayarını ekle.
- Dil ekleme ve çeviri import/export rehberi yaz.
- Portal müşterisine dil atama rehberi yaz.
- Mobil API localization sözleşmesini güncelle.
- Backup/restore dokümanına translation tablolarını ekle.
- Release note ve upgrade uyarısını yaz.
Çıkış kriteri
- Türkçe ve İngilizce kataloglar yüzde 100 tamamlandı.
- Fransızca custom locale uçtan uca smoke testi geçti.
- Davet öncesi, davet, login ve portal locale zinciri doğrulandı.
- Mevcut Türkçe veri kaybı veya görünüm regression'ı yok.
- Docker/Dokploy persistent volume backup-restore testi geçti.
- Mobil v1 sözleşmesi geriye uyumlu.
- Release readiness raporu yazıldı.
16. Test matrisi
| Senaryo | Beklenen sonuç |
|---|---|
| Yeni kurulum | tr ve en aktif, default tr |
| Mevcut DB upgrade | Eski içerik Türkçe translation olarak backfill |
| Owner dili İngilizce | Freelancer UI ve formatlar İngilizce |
| Eksik Fransızca UI key | Tanımlı fallback metni, ham key değil |
| Fransızca proje içeriği | Fransızca client Fransızca metni görür |
| Eksik Fransızca proje alanı | Default içerik fallback'i gösterilir |
| İngilizce portal daveti | Davet kabul sayfası İngilizce |
| Davet kabulü | Client preference dili invitation locale olur |
| Client tekrar login | Portal dili korunur |
| Locale arşivleme | Referanslı client varsa yönlendirme istenir |
| Translation import | Preview sonrası geçerli key'ler yazılır |
| Zararlı import key'i | Validation ile reddedilir |
| Client translation endpoint'i | 403/404 ile reddedilir |
| Başka client projesi | Locale değişse de erişilemez |
| RTL test locale'i | dir=rtl, shell ve form kullanılabilir |
| Backup/restore | Locale, overrides ve içerik çevirileri korunur |
| Eski mobil client | Yeni additive meta alanlarını yok sayarak çalışır |
17. Riskler ve azaltma yaklaşımı
17.1. Hardcoded metin kaçakları
Risk: Bazı toast, tooltip veya empty state metinleri Türkçe kalabilir.
Azaltma:
- Namespace bazlı sayfa checklist'i
- Boundary script
- Türkçe karakter/string taraması
- İngilizce E2E ekran gezintisi
17.2. Client/server locale uyuşmazlığı
Risk: Server Türkçe, client İngilizce render ederek hydration hatası oluşturabilir.
Azaltma:
- Locale'i layout server tarafında bir kez çözmek
- Client provider'a resolved locale ve namespace snapshot vermek
- İlk render öncesi browser dilini bağımsız yeniden seçmemek
17.3. Translation sorgularında N+1
Risk: Liste ekranlarında her proje için ayrı query çalışabilir.
Azaltma:
- Batch resolver
- Composite index
- Query-count smoke testi
17.4. Eksik müşteri çevirisi
Risk: Müşteri portalı kısmen farklı dillerde görünebilir.
Azaltma:
- Portal kritik namespace kapsamı
- Publish readiness yüzdesi
- Davet dropdown'unda yalnız portal-ready locale
- İçerik alanlarında eksik tab uyarısı
- Belirgin ve deterministik fallback
17.5. Eski kolon ve translation tablosu ayrışması
Risk: Bir write yalnız tablolardan birini günceller.
Azaltma:
- Tek service mutation noktası
- Transaction
- Repository'ye doğrudan UI erişimini boundary testiyle engelleme
- Tutarlılık kontrol script'i
17.6. Custom çeviride XSS veya bozuk interpolation
Risk: Owner'ın girdiği metin HTML veya sahte placeholder ile render'ı bozabilir.
Azaltma:
- Düz metin varsayımı
- Placeholder schema doğrulaması
- HTML render etmeme
- Import limitleri ve güvenli key parser
18. Önerilen commit parçalama stratejisi
Her faz kendi içinde rollback edilebilir küçük commit'lere ayrılmalıdır:
- Şema, migration ve repository
- Service, validation ve test
- Ortak UI/runtime altyapısı
- Sayfa/form entegrasyonları
- Dokümantasyon ve phase checklist güncellemesi
Şema migration'ı ile onu kullanan runtime kodu ayrı deploy'larda uyumsuz hale gelmemelidir. Gerekirse expand/migrate/contract sırası izlenir.
19. Genel tamamlanma checklist'i
- Faz 0 — Envanter, ADR ve fixture
- Faz 1 — Locale veri modeli ve service
- Faz 2 — Runtime ve built-in kataloglar
- Faz 3 — Dil/çeviri yönetimi
- Faz 4 — Freelancer UI migration
- Faz 5 — Çok dilli içerik ve form tab'ları
- Faz 6 — Portal dili ve davet
- Faz 7 — Auth/hata/a11y bütünlüğü
- Faz 8 — API ve mobil hazırlık
- Faz 9 — Hardening ve release
20. Nihai definition of done
Bu özellik aşağıdaki maddelerin tamamı sağlanmadan bitmiş sayılmaz:
- Türkçe ve İngilizce yeni kurulumda hazır gelir.
- Owner Ayarlar'dan üçüncü bir dil ekleyebilir.
- Owner custom dilde bütün sistem metinlerini düzenleyebilir.
- Sidebar, başlıklar, butonlar, formlar, durumlar ve hatalar seçili dilde gösterilir.
- Tarih, saat, sayı ve para locale'e göre biçimlenir.
- Çevrilebilir formlarda aktif diller tab olarak görünür.
- Proje ve müşteriye açık görev içerikleri dil başına saklanır.
- Portal davetinde müşteri dili seçilir.
- Davet kabul ekranı seçilen dilde açılır.
- Müşteri her login sonrasında portalı atanmış dilde görür.
- Portal içerikleri müşteri locale'ine göre çözülür.
- Eksik çeviri davranışı deterministik ve güvenlidir.
- Client authorization locale parametresiyle aşılamaz.
- Mobil metadata desteklenen dilleri ilan eder.
- Backup/restore bütün custom dilleri ve çevirileri korur.
- Mevcut Türkçe veriler migration sırasında kaybolmaz.
- Build, typecheck, lint, i18n boundary ve E2E smoke testleri geçer.