docs(i18n): update master plan and add v2 phase 0/1 smoke tests

This commit is contained in:
poyrazavsever
2026-07-20 10:25:40 +03:00
parent 0f2ff48376
commit 9365dfd215
15 changed files with 795 additions and 106 deletions
@@ -0,0 +1,72 @@
# I18n V2 Faz 0 — Mimari kararlar
Tarih: 2026-07-20
## ADR-001 — Locale bağlama göre çözülür
Tek bir genel resolver yerine dört açık bağlam kullanılır:
- Public auth: instance default
- Invitation: invitation snapshot, ardından instance default
- Freelancer: user preference, ardından instance default
- Portal: user preference, client portal default, instance default
Public auth locale çözümünde cookie ve `Accept-Language` kullanılmaz. Locale
cookie'si dil değiştirme ve resolver akışından kaldırılır; authenticated tercih
veritabanından, public dil instance ayarından çözülür.
## ADR-002 — Kişisel tercih ve yönetim ayarı ayrıdır
`user_preferences.language`, `clients.portal_locale` ve
`instance_i18n_settings.default_locale` aynı kavram değildir:
- User preference kişinin açık seçimidir.
- Client portal locale adminin müşteri için belirlediği başlangıç/default dildir.
- Instance default public yüzeylerin ve fallback zincirinin dilidir.
Bu değerler farklı action/service fonksiyonlarıyla değiştirilir.
## ADR-003 — Ayarlar gerçek alt rotalara ayrılır
Component state ile değişen tek ayarlar ekranı kullanılmaz. `/settings/*`
altındaki her bölüm gerçek bir route olur. Ortak layout başlık, kalıcı
navigasyon, loading ve error sınırını sağlar. Her sonraki settings fazı kendi veri
yükleme ve mutation sınırını ayırır.
## ADR-004 — Sayfa tamamlanma birimi
Bir sayfa yalnız title çevrildiğinde tamamlanmış sayılmaz. Header, form, dialog,
toast, validation, loading/error/empty state, accessibility metni ve locale
formatlama aynı sayfa fazının kapsamındadır.
## ADR-005 — Dinamik metin ve iletişim içeriği ayrıdır
Proje, görev, takvim, finans ve benzeri yönetilen kayıtların çevrilebilir metin
alanları locale tab'larıyla saklanır. Chat mesajı ve revizyon talebi gibi bir
kişinin yazdığı iletişim metni çoğaltılmaz; kaynak dili korunur.
## ADR-006 — V1'den korunan parçalar
Korunacak:
- `instance_locales`
- `instance_i18n_settings`
- `instance_ui_translations`
- `content_translations`
- Built-in TR/EN katalog ve fallback temeli
- Locale-aware `Intl` helper'ları
Düzeltilecek:
- Resolver öncelikleri
- Preference doğrulaması
- Settings bilgi mimarisi
- Katalog kapsamı
- Translation registry kapsamı
- Sayfa bazlı payload sınırı
Sonraki fazlarda kaldırılabilecek:
- Auth sayfalarına bağlı locale select yüzeyi
- Eski monolit settings composition
- Katalog içindeki tamamlanmamış genel namespace yapısı
@@ -0,0 +1,43 @@
# I18n V2 Faz 0 — Baseline ve regression kapıları
Tarih: 2026-07-20
## Çalıştırılan kontroller
| Kontrol | Sonuç |
| --- | --- |
| `pnpm i18n:v2-page-audit` | Başarılı |
| `pnpm i18n:v2-phase1-smoke` | Başarılı |
| `pnpm typecheck` | Başarılı |
| `pnpm lint` | Başarılı, uyarı yok |
| `pnpm build` | Başarılı, 37 static/dynamic sayfa üretildi |
Sayfa audit'i mevcut ve Faz 2 ile eklenen toplam 31 route girişini doğruladı.
Türkçe karakter içeren 46 hard-coded aday dosya baseline olarak kaydedildi.
## Otomatik regression sözleşmesi
`i18n:v2-page-audit` şu kuralları korur:
- Plan kapsamındaki route dosyaları bulunmalıdır.
- Login, register, forgot-password ve reset-password public resolver kullanmalıdır.
- Auth sayfaları `LocaleSelectForm` kullanmamalıdır.
- Public locale otoritesi `LOCALE_COOKIE` bağımlılığı taşımamalıdır.
- Dört bağlama özel resolver export edilmelidir.
- Settings route navigasyonu pathname-aware ve desktop'ta sticky olmalıdır.
- Hard-coded Türkçe karakter adaylarının en yüksek kaynakları raporlanmalıdır.
`i18n:v2-phase1-smoke` şu öncelikleri doğrular:
- Public -> instance default
- Freelancer -> personal preference -> instance default
- Portal -> personal preference -> client default -> instance default
- Invitation -> invitation snapshot -> instance default
- Archived locale seçilemez.
- Geçersiz default güvenli fallback'e düşer.
- RTL direction locale kaydından korunur.
## Faz 0 çıkış notu
Bu baseline hard-coded metinleri çözmez. Her sayfa kendi fazında audit listesinden
çıkarılacak ve release aşamasında sıfır kullanıcı metni hedefi uygulanacaktır.
@@ -0,0 +1,53 @@
{
"schemaVersion": 1,
"instance": {
"defaultLocale": "tr",
"locales": [
{ "code": "tr", "status": "active", "fallbackLocale": null, "direction": "ltr" },
{ "code": "en", "status": "active", "fallbackLocale": "tr", "direction": "ltr" },
{ "code": "fr", "status": "draft", "fallbackLocale": "en", "direction": "ltr" },
{ "code": "ar", "status": "test", "fallbackLocale": "en", "direction": "rtl" }
]
},
"actors": {
"freelancerTr": { "role": "freelancer", "preference": "tr" },
"freelancerEn": { "role": "freelancer", "preference": "en" },
"clientAdminDefaultFr": {
"role": "client",
"preference": null,
"clientPortalLocale": "fr",
"expectedLocaleWhileFrIsDraft": "tr"
},
"clientPersonalEn": {
"role": "client",
"preference": "en",
"clientPortalLocale": "tr",
"expectedLocale": "en"
}
},
"content": {
"project": {
"id": "fixture-project",
"legacy": { "name": "Marka sitesi", "description": "Türkçe açıklama" },
"translations": {
"tr": { "name": "Marka sitesi", "description": "Türkçe açıklama" },
"en": { "name": "Brand website", "description": "English description" },
"fr": { "name": "Site de marque" }
}
},
"financeTransaction": {
"id": "fixture-finance",
"amountMinor": 125000,
"currency": "TRY",
"translations": {
"tr": { "category": "Yazılım", "description": "Proje ödemesi" },
"en": { "category": "Software", "description": "Project payment" }
}
}
},
"invitation": {
"locale": "en",
"expectedPublicAuthLocale": "tr",
"expectedInvitationLocale": "en"
}
}
@@ -0,0 +1,103 @@
# I18n V2 Faz 0 — Sayfa ve içerik envanteri
## Sayfa envanteri
| Yüzey | Route | Ana dosya | Plan fazı |
| --- | --- | --- | --- |
| Dashboard | `/` | `app/(dashboard)/dashboard-client.tsx` | 19 |
| Analizler | `/analytics` | `analytics-client.tsx` | 20 |
| Takvim | `/calendar` | `calendar-client.tsx` | 21 |
| Müşteriler | `/clients` | `clients-client.tsx` | 22 |
| Müşteri detay | `/clients/[id]` | `client-detail-client.tsx` | 23 |
| Projeler | `/projects` | `projects-client.tsx` | 24 |
| Proje detay | `/projects/[id]` | `project-detail-client.tsx` | 25 |
| Görevler | `/tasks` | `tasks-client.tsx` | 26 |
| Finans | `/finance` | `finance-client.tsx` | 27 |
| Günlük | `/journal` | `journal-client.tsx` | 28 |
| Sohbet | `/chat` | `app/(dashboard)/chat/page.tsx` | 29 |
| Teklifler | `/business/proposals` | `proposals-client.tsx` | 30 |
| Faturalar | `/business/invoices` | `invoices-client.tsx` | 31 |
| Abonelikler | `/business/subscriptions` | `subscriptions-client.tsx` | 32 |
| Login | `/login` | `app/login/page.tsx` | 14 |
| İlk kayıt | `/register` | `app/register/page.tsx` | 15 |
| Şifremi unuttum | `/forgot-password` | ilgili `page.tsx` | 16 |
| Şifre sıfırlama | `/reset-password` | ilgili `page.tsx` | 17 |
| Portal daveti | `/invite/[token]` | ilgili `page.tsx` | 38 |
| Portal dashboard | `/portal` | ilgili `page.tsx` | 39 |
| Portal projeler | `/portal/projects` | ilgili `page.tsx` | 40 |
| Portal proje detay | `/portal/projects/[id]` | ilgili client/page | 41 |
| Portal görevler | `/portal/tasks` | ilgili `page.tsx` | 42 |
| Portal revizyonlar | `/portal/revisions` | ilgili `page.tsx` | 43 |
Settings route'ları Faz 2 ile oluşturulmuştur:
- `/settings/general`
- `/settings/appearance`
- `/settings/profile`
- `/settings/security`
- `/settings/ai`
- `/settings/language`
- `/settings/languages`
Dil ekleme, dil detayı, çeviri editörü ve import/export alt rotaları kendi sayfa
fazlarında oluşturulacaktır.
## UI metni yüzeyleri
Her route için aşağıdaki dosya türleri tarama kapsamındadır:
- `page.tsx`, client composition ve local component'ler
- `actions.ts` ve kullanıcıya dönen domain/API hataları
- `loading.tsx`, `error.tsx`, `not-found.tsx`
- Ortak shell, navigation, feedback, status ve confirmation component'leri
- Form label/placeholder/helper, dialog, toast, tooltip ve aria metinleri
İlk statik tarama Türkçe karakter içeren 46 aday dosya bulmuştur. En yüksek
adaylar:
| Dosya | Karakter eşleşmesi |
| --- | ---: |
| Settings geçiş içeriği | 184 |
| Proje detay client | 175 |
| Finans client | 128 |
| Günlük client | 106 |
| Müşteriler client | 95 |
| Projeler client | 94 |
| Chat API route | 82 |
| Görevler client | 77 |
| Müşteri detay client | 68 |
| Settings actions | 55 |
| Takvim client | 44 |
Bu sayı kesin kullanıcı metni sayısı değildir; yorum, hata ve teknik string'leri
de içeren bir regression baseline'dır. Her sayfa fazında adaylar sınıflandırılıp
kullanıcıya açık hard-coded metin sayısı sıfıra indirilir.
## Dinamik form/entity envanteri
| Entity | Çevrilebilir | Ortak kalacak |
| --- | --- | --- |
| Branding | welcome, footer | logo, favicon, renk |
| Client | notes | ad, firma, e-posta, telefon, URL |
| Client activity | title, content | type, tarih |
| Project | name, description, cover alt | status, tarih, bütçe |
| Planning section | title, content | category, sıra |
| Task | title, description | status, priority, süre |
| Calendar event | title, description | type, başlangıç/bitiş |
| Finance transaction | category, description | tutar, currency, status, tarih |
| Journal entry | mood label, note | skorlar, tarih |
| Proposal | title, description | tutar, currency, status |
| Contract | title, content | ilişkiler, status |
| Invoice | mevcut serbest metin yok | numara, tutar, currency, tarih |
| Subscription | name, category | tutar, cycle, status, tarih |
Kaynak dilinde tutulacak iletişim içeriği:
- Chat message
- Project revision request
## Sabit locale/format envanteri
Merkezi olmayan `tr-TR`, `date-fns/locale/tr`, sabit durum label'ları ve sabit
para/tarih formatları sayfa fazında ele alınır. Yeni kullanım yalnız
`lib/i18n/format.ts` ve merkezi date-fns locale mapping üzerinden yapılabilir.