docs(i18n): update master plan and add v2 phase 0/1 smoke tests
This commit is contained in:
@@ -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ı iç
|
||||
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.
|
||||
Reference in New Issue
Block a user