# MIGRACE — Svatba v kostce na nový server

Tento balík obsahuje **kompletní systém svatbavkostce.cz** připravený k nasazení
na nový (silnější) server. Soubory (fotky/videa od hostů) zůstávají na starém
serveru jako úložiště na `https://files.svatbavkostce.cz`; tento server převezme
**všechno ostatní**: marketingový web, aplikaci, autentizaci, databázi a REST API.

---

## 🚀 Jak spustit migraci (zkopíruj tento pokyn Claude Code na novém serveru)

> **Předpoklad:** balík je rozbalený do `./svk-migration/` (viz „Stažení a rozbalení").

```
Jsi seniorní DevOps inženýr. V adresáři ./svk-migration/ je kompletní balík pro
migraci systému „Svatba v kostce" na tento server. Přečti si MIGRATION.md a proveď
CELOU migraci podle něj: nainstaluj závislosti, naimportuj databázi, vygeneruj nové
secrets, nasaď backend služby (PostgREST, GoTrue), postav a nasaď aplikaci i
marketingový web, nastav reverzní proxy s HTTPS, a napoj Storage na existující
files.svatbavkostce.cz. Po každém kroku ověř, že funguje, a nic na serveru
nerozbij. Domény: svatbavkostce.cz (marketing), app.svatbavkostce.cz (aplikace),
api-svk.svatbavkostce.cz (backend). Na konci proveď end-to-end test registrace a
přihlášení a napiš mi souhrn + co musím dořešit ručně (DNS, přepnutí files.).
```

Claude Code pak projde kroky níže. **Nejdřív si ale přečti sekci „⚠️ Co musíš
zajistit RUČNĚ"** — pár věcí (DNS, přesměrování `files.`) nejde udělat z tohoto
serveru.

---

## 📦 Obsah balíku

```
svk-migration/
├── MIGRATION.md                  # tento návod
├── database-full.sql             # kompletní dump DB (auth + public + storage struktura)
├── svatbavkostce-web/            # kompletní soubory webu
│   ├── index.html, app.js, vendor/   # marketingový web (statický)
│   └── app/                      # Next.js aplikace (zdroj, bez node_modules/.next)
│       ├── src/                  # celý zdrojový kód (moduly, AI asistentka…)
│       ├── supabase/migrations/  # SQL migrace (0001–0006)
│       ├── package.json
│       ├── ARCHITECTURE.md, DEPLOYMENT.md   # dokumentace architektury
│       └── .env.production.example
└── reference-configs/            # vzory systemd unitů, vhostů, config šablon
```

---

## 🏗️ Architektura po migraci

| Komponenta | Kde | Doména / port |
|---|---|---|
| Marketingový web (statický) | **nový server** | `svatbavkostce.cz` |
| Aplikace (Next.js SSG) | **nový server** | `app.svatbavkostce.cz` |
| GoTrue (Auth) | **nový server** | interní `:8056` → `api-svk…/auth/v1` |
| PostgREST (REST) | **nový server** | interní `:8055` → `api-svk…/rest/v1` |
| PostgreSQL (hlavní DB) | **nový server** | interní `:5432` |
| **Storage (fotky/videa)** | **STARÝ server** | `files.svatbavkostce.cz` |

**Klíč:** aplikace na novém serveru volá Storage na `files.svatbavkostce.cz`.
Storage tam **sdílí JWT secret** s tímto novým serverem, takže přijme tokeny
vydané zdejším GoTrue a odvodí oprávnění z tokenu (žádná synchronizace DB).

---

## 0. Stažení a rozbalení

```bash
# Balík je ke stažení z transfer domény:
curl -L -o svk-migration.tar.gz "https://svatbatransfer.m-portal.cz/svk-migration.tar.gz"
mkdir -p svk-migration && tar xzf svk-migration.tar.gz -C svk-migration --strip-components=1
cd svk-migration
```

---

## 1. Systémové závislosti

Zjisti architekturu (`uname -m`) — podle ní se stahují správné binárky.

```bash
# PostgreSQL 15+ (nebo použij existující)
apt-get update && apt-get install -y postgresql postgresql-contrib
# Node.js 20 (pro build aplikace)
node --version || (curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs)
# Web server (Apache s proxy moduly, nebo nginx)
apt-get install -y apache2 certbot python3-certbot-apache
a2enmod proxy proxy_http headers rewrite ssl
```

**Binárky PostgREST + GoTrue** (podle architektury — `aarch64` nebo `x86-64`):
```bash
mkdir -p /opt/svk-supabase/bin && cd /opt/svk-supabase/bin
ARCH=$(uname -m)   # aarch64 | x86_64
# PostgREST v14:
[ "$ARCH" = "aarch64" ] && PG=ubuntu-aarch64 || PG=linux-static-x86-64
curl -L "https://github.com/PostgREST/postgrest/releases/download/v14.14/postgrest-v14.14-${PG}.tar.xz" -o p.tar.xz
tar xf p.tar.xz && rm p.tar.xz && chmod +x postgrest
# GoTrue (Supabase auth) v2:
[ "$ARCH" = "aarch64" ] && GT=arm64 || GT=x86_64
curl -L "https://github.com/supabase/auth/releases/download/v2.192.0/auth-v2.192.0-${GT}.tar.gz" -o a.tar.gz
tar xzf a.tar.gz && rm a.tar.gz && chmod +x auth
cd -
```

---

## 2. Databáze

```bash
# Vytvoř DB
sudo -u postgres createdb svatba_v_kostce

# Naimportuj strukturu + data
sudo -u postgres psql -d svatba_v_kostce < database-full.sql
```

**Role a hesla (VYGENERUJ NOVÁ):**
```bash
# Vygeneruj silná hesla + JWT secret
mkdir -p /etc/svk-supabase && chmod 700 /etc/svk-supabase
JWT_SECRET=$(openssl rand -base64 48 | tr -d '\n')
DB_PASS=$(openssl rand -base64 24 | tr -d '/+=\n' | head -c 32)
GOTRUE_DB_PASS=$(openssl rand -base64 24 | tr -d '/+=\n' | head -c 32)
cat > /etc/svk-supabase/secrets.env <<EOF
JWT_SECRET=$JWT_SECRET
SVK_DB_PASS=$DB_PASS
SVK_GOTRUE_DB_PASS=$GOTRUE_DB_PASS
EOF
chmod 600 /etc/svk-supabase/secrets.env
source /etc/svk-supabase/secrets.env

# Supabase role model (standardní názvy — aplikace i migrace je očekávají)
sudo -u postgres psql -d svatba_v_kostce <<SQL
do \$\$ begin create role anon nologin noinherit; exception when duplicate_object then null; end \$\$;
do \$\$ begin create role authenticated nologin noinherit; exception when duplicate_object then null; end \$\$;
do \$\$ begin create role service_role nologin noinherit bypassrls; exception when duplicate_object then null; end \$\$;
do \$\$ begin create role authenticator noinherit login password '${DB_PASS}';
  exception when duplicate_object then alter role authenticator with password '${DB_PASS}'; end \$\$;
grant anon, authenticated, service_role to authenticator;
do \$\$ begin create role svk_auth_admin login password '${GOTRUE_DB_PASS}' createrole;
  exception when duplicate_object then alter role svk_auth_admin with password '${GOTRUE_DB_PASS}'; end \$\$;
-- auth schéma vlastní GoTrue admin, aby si mohl spravovat migrace
alter schema auth owner to svk_auth_admin;
grant all on all tables in schema auth to svk_auth_admin;
grant usage on schema auth, storage, public to anon, authenticated, service_role;
SQL
```

**API klíče (anon + service_role JWT):** vygeneruj HS256 JWT podepsané `JWT_SECRET`
s payloadem `{"role":"anon",...}` resp. `{"role":"service_role",...}`. Skript:
```bash
node -e '
const c=require("crypto"), s=process.env.JWT_SECRET;
const mk=r=>{const iat=Math.floor(Date.now()/1e3),p={role:r,iss:"svk",iat,exp:iat+3153600000};
const b=o=>Buffer.from(JSON.stringify(o)).toString("base64url");
const d=b({alg:"HS256",typ:"JWT"})+"."+b(p);
return d+"."+c.createHmac("sha256",s).update(d).digest("base64url")};
console.log("ANON_KEY="+mk("anon")); console.log("SERVICE_ROLE_KEY="+mk("service_role"));
' >> /etc/svk-supabase/secrets.env
source /etc/svk-supabase/secrets.env
```

---

## 3. Backend služby (PostgREST + GoTrue)

Vzory jsou v `reference-configs/`. Doplň do nich vygenerovaná hesla a nastav
domény tohoto serveru. Klíčové hodnoty:

**PostgREST** (`/etc/svk-supabase/postgrest.conf`):
```
db-uri = "postgres://authenticator:${SVK_DB_PASS}@127.0.0.1:5432/svatba_v_kostce"
db-schemas = "public,storage"
db-anon-role = "anon"
jwt-secret = "${JWT_SECRET}"
db-pool = 6
server-host = "127.0.0.1"
server-port = 8055
```

**GoTrue** (`/etc/svk-supabase/gotrue.env`) — DŮLEŽITÉ hodnoty:
```
GOTRUE_API_HOST=127.0.0.1
PORT=8056
API_EXTERNAL_URL=https://api-svk.svatbavkostce.cz
DATABASE_URL=postgres://svk_auth_admin:${SVK_GOTRUE_DB_PASS}@127.0.0.1:5432/svatba_v_kostce?search_path=auth
GOTRUE_DB_MIGRATIONS_PATH=/opt/svk-supabase/bin/migrations
GOTRUE_SITE_URL=https://app.svatbavkostce.cz
GOTRUE_URI_ALLOW_LIST=https://app.svatbavkostce.cz/**,https://app.svatbavkostce.cz/auth/callback,https://app.svatbavkostce.cz/reset-password,capacitor://localhost/**
GOTRUE_JWT_SECRET=${JWT_SECRET}
GOTRUE_JWT_EXP=3600
GOTRUE_MAILER_AUTOCONFIRM=false     # true jen pro první testy
# SMTP pro potvrzovací e-maily (doplň vlastní):
GOTRUE_SMTP_HOST=... GOTRUE_SMTP_PORT=587 GOTRUE_SMTP_USER=... GOTRUE_SMTP_PASS=...
GOTRUE_SMTP_SENDER_NAME=Svatba v kostce
GOTRUE_MAILER_EXTERNAL_HOSTS=api-svk.svatbavkostce.cz,app.svatbavkostce.cz
```

**systemd služby** (vzory `reference-configs/svk-*.service`) — použij je, ověř
cesty k binárkám, pak:
```bash
cp reference-configs/svk-postgrest.service reference-configs/svk-gotrue.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now svk-postgrest svk-gotrue
systemctl status svk-postgrest svk-gotrue   # obojí musí být active
```

> **Storage službu na tomto serveru NENASAZUJ** — zůstává na starém serveru.
> Zdejší DB má jen strukturu `storage.*` schématu (kvůli konzistenci migrací).

---

## 4. Reverzní proxy + HTTPS

Vytvoř 3 vhosty (vzory v `reference-configs/`):

- **`api-svk.svatbavkostce.cz`** → proxy na GoTrue (`:8056`) + PostgREST (`:8055`)
  + **Storage** (`/storage/v1/` → `https://files.svatbavkostce.cz/storage/v1/`).
  POZOR na CORS: řeš ho JEN v této proxy (viz `reference-configs/api-svk…-le-ssl.conf`
  — GoTrue u preflightu s `x-supabase-api-version` vynechá hlavičky, proto OPTIONS
  zkratuj na 204 z proxy a backend CORS hlavičky přepiš).
- **`app.svatbavkostce.cz`** → DocumentRoot = `.../app/out` (statický export),
  SPA fallback + `Cache-Control` (viz vzor).
- **`svatbavkostce.cz`** (+ www) → DocumentRoot = marketing (`index.html`, `app.js`),
  `index.html` `no-cache`, ostatní assety dlouhá cache (cache-busting je v `app.js?v=…`).

```bash
# Certifikáty (po nastavení DNS — viz sekce RUČNĚ):
certbot --apache -d svatbavkostce.cz -d www.svatbavkostce.cz
certbot --apache -d app.svatbavkostce.cz
certbot --apache -d api-svk.svatbavkostce.cz
```

---

## 5. Aplikace (Next.js) + marketing web

```bash
cd svatbavkostce-web/app
# .env s TVÝMI novými klíči:
cat > .env.production.example <<EOF
NEXT_PUBLIC_SUPABASE_URL=https://api-svk.svatbavkostce.cz
NEXT_PUBLIC_SUPABASE_ANON_KEY=${ANON_KEY}
EOF
cp .env.production.example .env.local

npm install
npm run build           # → out/ (statický export)

# nasazení: DocumentRoot app.svatbavkostce.cz míří na .../app/out
# marketing (index.html, app.js, vendor) nasaď jako DocumentRoot svatbavkostce.cz
```

Aplikace i migrace (`supabase/migrations/0001–0006`) už jsou v DB dumpu; pokud
bys stavěl DB od nuly bez dumpu, aplikuj je v pořadí a pak reloadni PostgREST cache.

---

## 6. Napojení na Storage (files.svatbavkostce.cz)

Aplikace ukládá dokumenty/fotky do bucketu `wedding-docs` na starém serveru.
Aby to fungovalo:

1. **Storage na starém serveru musí mít STEJNÝ `JWT_SECRET`** jako tento nový
   (viz `files.svatbavkostce.cz` setup na starém serveru — tam se secret nastaví
   podle tohoto nového). Předej si `JWT_SECRET` z `/etc/svk-supabase/secrets.env`
   bezpečně (ne přes balík!).
2. Proxy `api-svk…/storage/v1/` → `https://files.svatbavkostce.cz/storage/v1/`.
3. Aplikační Storage service volá `NEXT_PUBLIC_SUPABASE_URL/storage/v1` — funguje
   beze změny kódu.

---

## ⚠️ Co musíš zajistit RUČNĚ (nejde z tohoto serveru)

1. **DNS** — přesměruj A záznamy na IP nového serveru:
   - `svatbavkostce.cz`, `www.svatbavkostce.cz`, `app.svatbavkostce.cz`,
     `api-svk.svatbavkostce.cz` → **nová IP**.
   - `files.svatbavkostce.cz` → **zůstává na staré IP** (úložiště).
2. **JWT secret sdílení** — hodnotu `JWT_SECRET` z nového serveru nastav i do
   Storage na starém serveru (jinak Storage odmítne tokeny). Přenes ji bezpečně.
3. Po přepnutí DNS a ověření **vypni staré služby** na starém serveru (kromě
   Storage) a starý marketing/app.

---

## ✅ Ověření (na konci)

```bash
systemctl is-active svk-postgrest svk-gotrue     # active
curl -I https://api-svk.svatbavkostce.cz/health   # 200 (GoTrue)
curl -I https://app.svatbavkostce.cz/login/       # 200
curl -I https://svatbavkostce.cz/                 # 200
# registrace → potvrzení e-mailu → přihlášení → dashboard
```

Detaily architektury: `svatbavkostce-web/app/ARCHITECTURE.md` a `DEPLOYMENT.md`.
