Files
neta/docs/self-hosted-redesign/i18n-phase-9-release-readiness.md

230 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: I18n Faz 9 — Hardening, Migrasyon ve Release Readiness
description: Çok dilli sistemin self-host production yayınına hazır olduğunu gösteren migration, backup, API, Dokploy ve operasyon raporu.
phase: 9
status: completed
last_updated: 2026-07-19
---
# I18n Faz 9 — Hardening, migrasyon ve release readiness
Faz-9, çok dilli sistemin production self-host kurulumunda güvenli şekilde
yayınlanabilmesi için migration, backup/restore, import, mobil API ve operasyon
kapılarını kapatır.
## Sonuç
Çok dilli sistem release adayıdır.
- Yeni kurulumda `tr` ve `en` aktif gelir, default locale `tr` olur.
- Eski Türkçe kolonlar `content_translations` içine `tr` locale'iyle backfill
edilir.
- Backfill tekrar çalışan migration'da duplicate üretmez.
- `fr` custom locale, content translation, backup ve restore zincirinde korunur.
- API v1 localization sözleşmesi additive ve eski mobil client'larla uyumludur.
- Runtime Supabase bağımlılığı veya Supabase env kullanımı geri gelmemiştir.
- Built-in kataloglar standalone server bundle içinde bulunur.
## Release kapıları
### Migration
`pnpm i18n:phase9-hardening` şu migration senaryolarını gerçek temp SQLite DB
üzerinde çalıştırır:
1. Boş DB migration.
2. Boş DB üzerinde ikinci migration çalıştırması.
3. 00000007 arası eski schema üzerinde production-benzeri Türkçe veri.
4. 0008 i18n migration'ı sonrası Türkçe backfill doğrulaması.
5. Aynı DB üzerinde tekrar migration ve idempotent count kontrolü.
Backfill doğrulanan alanlar:
- `project.name`
- `project.description`
- `task.title`
- `planning_section.title`
- `branding.portalWelcome`
### Backup ve restore
Hardening smoke, production-benzeri DB'ye `fr` custom locale ve Fransızca proje
çevirisi ekler, backup alır ve ayrı bir data directory içine restore eder.
Restore sonrası:
- `instance_locales.fr` aktif kalır.
- `content_translations` içindeki Fransızca çeviri korunur.
- `foreign_key_check` temiz döner.
Restore failure prosedürü de test edilir: checksum'u bozulan backup restore
edilmez ve mevcut hedef DB korunur.
### Supabase import uyumu
Faz-9, Supabase import aracının Faz-8 smoke kapsamını release blocker kabul eder.
`phase8:import-smoke` şu davranışları doğrular:
- dry-run DB'yi değiştirmez;
- apply import kayıtları taşır;
- `--allow-existing` idempotent upsert yapar;
- invalid enum, eksik foreign key ve unsafe storage path reddedilir;
- pre-import backup restore ile rollback provası yapılır.
Import aracı Supabase SDK kullanmaz; offline `neta-supabase-export` bundle'ını
okur.
## Dokploy / Docker operasyon notu
Dokploy'da `/app/data` kalıcı volume olmalıdır. Bu volume şunları taşır:
- `neta.db`
- `uploads/`
- `backups/`
- `tmp/`
Production deploy öncesi:
```bash
pnpm db:backup -- --retention-count 14
```
Restore provası production volume üstüne değil, ayrı geçici hedefe yapılmalıdır:
```bash
pnpm db:restore -- \
--from /app/data/backups/neta-TIMESTAMP \
--target /tmp/neta-restore-rehearsal \
--force
```
Translation tabloları `neta.db` içinde olduğu için backup/restore kapsamında
otomatik korunur:
- `instance_locales`
- `instance_i18n_settings`
- `instance_ui_translations`
- `content_translations`
- `clients.portal_locale`
- `portal_invitations.locale`
- `user_preferences.language`
## Self-host default locale
Yeni kurulumda default locale `tr` olur. Owner Ayarlar üzerinden varsayılan dili
aktif başka bir locale'e alabilir. Default locale yalnız `active` locale olabilir;
draft veya archived locale default yapılamaz.
Mobil istemciler instance dil bilgisini şu endpoint'lerden keşfeder:
- `GET /.well-known/neta`
- `GET /api/v1/meta`
- `GET /api/v1/me`
## Dil ekleme ve import/export rehberi
Owner akışı:
1. Ayarlar → Diller ve çeviriler bölümünden yeni locale ekle.
2. Locale'i önce `draft` olarak tut.
3. UI çeviri eksiklerini tamamla veya JSON import ile yükle.
4. İçerik formlarındaki locale tab'larında proje/görev/portal metinlerini gir.
5. Portal'a hazır olduğunda locale'i `active` yap.
6. Gerekirse varsayılan locale'i değiştir.
Import/export:
- UI çeviri export paketi `neta-i18n` formatındadır.
- Import yalnız owner scope ile çalışır.
- Built-in locale'ler silinmez veya archived yapılamaz.
- Bozuk namespace/key/value import'u validation ile reddedilir.
## Portal müşterisine dil atama
Müşteri portal dili iki noktada belirlenir:
1. Portal daveti oluştururken seçilen locale.
2. Müşteri detayındaki portal dili ayarı.
Davet kabul edildiğinde:
- `clients.portal_locale` set edilir;
- client user preference dili aynı locale'e alınır;
- davet kabulü sonrası login ekranı davet locale'iyle açılır.
## Mobil API localization sözleşmesi
Mobil taraf locale'i şu sırayla çözmelidir:
1. Explicit query: `/api/v1/me?locale=en`
2. Better Auth session preference
3. Client portal locale
4. `Accept-Language`
5. Instance default locale
Unsupported explicit locale için server:
```json
{
"ok": false,
"error": {
"code": "UNSUPPORTED_LOCALE",
"message": "Unsupported locale.",
"details": {
"messageKey": "validation.unsupportedLocale"
}
}
}
```
Client kullanıcıya gösterilecek metni kendi catalog'undan `messageKey` ile
çözmelidir; program akışı stabil `code` alanına bağlanmalıdır.
## Gözlem ve performans
Faz-9 smoke seviyesi performans kapıları:
- Dashboard ve portal listeleri batch content resolver kullanır; N+1 translation
sorgusu release riski kabul edilir.
- Missing translation durumunda raw key production kullanıcı arayüzüne düşmemeli;
fallback chain kullanılmalıdır.
- Catalog version, UI translation mutation'larında artar ve mobil meta cache
invalidation için kullanılabilir.
- Hassas içerik loglanmamalıdır; missing translation log'u key/locale seviyesinde
kalmalıdır.
## Verification
Çalıştırılan komutlar:
```bash
pnpm phase-i18n:boundary
pnpm i18n:phase9-hardening
pnpm i18n:phase8-smoke
pnpm i18n:phase7-smoke
pnpm i18n:phase5-smoke
pnpm i18n:phase3-smoke
pnpm i18n:phase2-smoke
pnpm i18n:phase1-smoke
pnpm phase8:import-smoke
pnpm typecheck
pnpm build
pnpm phase9:smoke
git diff --check
```
`phase9:smoke` local listener açtığı için sandbox içinde `EPERM` alabilir; bu
durumda izinli çalıştırılmalıdır.
## Release uyarısı
Bu rapor teknik release readiness sağlar. Gerçek production cutover için ortam
sahibi yine şu dış adımları yürütmelidir:
- production backup;
- maintenance/read-only penceresi;
- final Supabase export/import;
- gerçek satır ve dosya checksum karşılaştırması;
- owner/client kabul smoke'u;
- DNS/reverse proxy geçişi;
- rollback retention penceresi.