docs: add phased self-hosted redesign plan and checklist

This commit is contained in:
Poyraz
2026-07-10 22:07:50 +03:00
parent 57aab2932e
commit ae8fa1425c
9 changed files with 3786 additions and 0 deletions
@@ -0,0 +1,125 @@
---
title: Phase 1 Runtime, SQLite and Deploy Skeleton
description: Faz 1 kapsamında eklenen Next.js standalone, SQLite, Drizzle migration, health, Docker ve backup/restore kanıtları.
status: active
last_updated: 2026-07-10
---
# Phase 1 Runtime, SQLite and Deploy Skeleton
Bu dosya Faz 1 için uygulanan runtime iskeletini ve local doğrulama sonuçlarını kaydeder. Bu faz feature migration yapmaz; Supabase ve Poyraz UI runtime'ı henüz kaldırılmadı.
## Eklenen runtime yüzeyi
- `server/config.ts`: Zod ile server config parse eder, `DATA_DIR` ve `DATABASE_PATH` yollarını çözer.
- `server/db/client.ts`: `better-sqlite3` singleton connection, Drizzle client ve SQLite PRAGMA ayarlarını yönetir.
- `server/db/transaction.ts`: nested çağrılarda yeni transaction açmadan aynı connection üzerinde çalışan synchronous transaction helper.
- `server/db/health.ts`: readiness için data dir yazılabilirlik, `SELECT 1` ve migration table kontrolü.
- `server/db/schema/*`: Faz 1 runtime smoke tabloları.
- `server/db/migrations/*`: Drizzle tarafından üretilen ilk SQLite migration ve journal metadata.
- `app/api/health/live/route.ts`: process liveness endpoint'i.
- `app/api/health/ready/route.ts`: DB/data/migration readiness endpoint'i.
- `scripts/migrate.mjs`: production startup öncesi migration runner.
- `scripts/backup.mjs`: SQLite backup API kullanan backup POC.
- `scripts/restore.mjs`: overwrite guard içeren restore POC.
- `scripts/phase1-smoke.mjs`: migration, persistence, backup ve restore smoke.
- `Dockerfile`: multi-stage Next standalone image.
- `docker-compose.yml`: tek app service, named volume ve readiness healthcheck.
## Config davranışı
- `DATA_DIR` verilmezse development/test için `.data`, production için `/app/data` kullanılır.
- `DATABASE_PATH` verilmezse `DATA_DIR/neta.db` kullanılır.
- Relative path değerleri `process.cwd()` üzerinden absolute hale getirilir.
- Uygulama `data`, `uploads`, `backups` ve `tmp` dizinlerini kontrollü oluşturur.
- Secret değerler config validation çıktısına yazılmaz; mevcut config modülü boot sırasında değer dump etmez.
## SQLite davranışı
Connection açılırken uygulanan PRAGMA değerleri:
- `foreign_keys = ON`
- `journal_mode = WAL`
- `synchronous = NORMAL`
- `busy_timeout = 5000`
Connection `globalThis.__netaSqliteConnection` ile process içinde singleton tutulur. Development hot reload sırasında aynı process içinde duplicate connection oluşmaması hedeflenir.
## Migration davranışı
İlk migration:
- `server/db/migrations/0000_wise_reaper.sql`
- Tablolar: `runtime_checks`, `runtime_events`
- Journal: `server/db/migrations/meta/_journal.json`
Migration runner request sırasında çalışmaz. Docker startup komutu önce `node scripts/migrate.mjs`, sonra `node server.js` çalıştırır.
## Health endpoint sonuçları
Local dev server:
- Komut: `npm.cmd run dev -- --hostname 127.0.0.1 --port 3010`
- `/api/health/live`: HTTP 200, `{"status":"ok", ...}`
- `/api/health/ready`: HTTP 200, `dataDirWritable=true`, `databaseReachable=true`, `migrationsApplied=true`
Health response DB path, data path, schema path veya secret döndürmez.
## Doğrulama sonuçları
2026-07-10 local sonuçları:
| Komut | Sonuç | Not |
| --- | --- | --- |
| `npm.cmd run db:generate` | Başarılı | İlk Drizzle migration üretildi. |
| `npm.cmd run db:migrate` | Başarılı | `.data/neta.db` üzerine migration uygulandı. |
| `npm.cmd run db:migrate` ikinci çalıştırma | Başarılı | Aynı DB üzerinde idempotency smoke geçti. |
| `npm.cmd run phase1:smoke` | Başarılı | Temp data dir, migration, persistence, backup ve restore geçti. |
| `npm.cmd run typecheck` | Başarılı | TypeScript temiz. |
| `npm.cmd run build` | Başarılı | Next.js production build geçti, standalone output etkin. |
| `npm.cmd run lint` | Başarısız | Faz 0 baseline ile aynı 34 error, 25 warning; yeni Faz 1 dosyaları lint çıktısında görünmedi. |
| `docker compose build` | Başarısız | Docker Desktop/Linux engine çalışmıyor: daemon pipe bulunamadı. Docker smoke henüz doğrulanmadı. |
## Backup/restore POC
`scripts/backup.mjs`:
- SQLite `backup()` API kullanır.
- Backup klasörü `DATA_DIR/backups/neta-<timestamp>` altında oluşur.
- `neta.db`, `uploads/` kopyası ve `manifest.json` üretir.
- Manifest her dosya için byte ve SHA-256 içerir.
`scripts/restore.mjs`:
- `--from <backup-dir>` zorunlu.
- `--target <data-dir>` ile ayrı restore hedefi verilebilir.
- Var olan DB üzerine yazmak için `--force` gerekir.
Eksik kalan restore sertliği:
- Restore manifest checksum doğrulaması henüz uygulanmadı.
- Docker içinde native SQLite smoke henüz çalıştırılamadı.
## Docker durumu
Dockerfile kararları:
- `node:22-bookworm-slim`
- `npm ci`
- `next.config.ts` içinde `output: "standalone"`
- Runtime user: `nextjs`
- Persistent volume: `/app/data`
- Startup: migration, sonra standalone `server.js`
Compose kararları:
- Tek application service: `neta`
- Named volume: `neta-data:/app/data`
- Healthcheck: `/api/health/ready`
- Restart policy: `unless-stopped`
- Replica sayısı tanımlı değil; hedef single instance.
Docker doğrulaması açık istisna:
- Local Docker daemon çalışmadığı için `docker compose build`, `docker compose up`, native SQLite Linux runtime ve container restart persistence testleri yapılamadı.