Files
kxkm_clown/docs/RUNBOOK_MIGRATION_V1_V2.md

4.9 KiB

Runbook — Migration V1 -> V2 Postgres

Date de reference : 2026-03-16 Contexte : passage du stockage flat-file JSON/JSONL (V1) vers Postgres (V2).


0. Pre-requis

Elément Valeur attendue
Node.js v22.x (node --version)
Postgres v15+ en local ou distant, base kxkm_clown_v2 creee
DATABASE_URL postgres://user:pass@localhost:5432/kxkm_clown_v2
Acces V1 répertoire data/ present avec les JSONL/JSON intacts
Services arretes API V1 et V2 stoppees avant migration
# Verification rapide pre-vol
node --version
psql "$DATABASE_URL" -c "SELECT version();"
ls data/personas.overrides.json data/persona-sources/ data/persona-feedback/ data/persona-proposals/ 2>/dev/null

1. Snapshot V1 (sauvegarde prealable)

BACKUP_DIR="backups/v1-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp -r data/ "$BACKUP_DIR/data"
echo "Snapshot V1 dans $BACKUP_DIR"

Conserver ce dossier jusqu'a validation complete de la migration.


2. Rehearsal — dry-run avec verbosite

# Lecture + transform sans insertion en base
node scripts/migrate-v1-to-v2.js --dry-run --verbose 2>&1 | tee /tmp/migrate-dry-run.log

Inspecter la sortie :

  • Chaque item doit afficher [DRY-RUN] would insert ...
  • Aucune erreur de parsing ni d'exception
  • Comptages personas, graphs, runs coherents avec ls data/

Si des erreurs apparaissent (JSONL corrompu, champ manquant), corriger les donnees source avant de continuer.


3. Baseline V1 avant migration

Lancer le parity-check avec l'API V1 active pour capturer l'etat de reference.

# V1 sur port 3333 (default), V2 pas encore lancee
node scripts/parity-check.js --v1-port 3333 2>&1 | tee /tmp/parity-baseline.log

Les checks V2 echoueront (SKIP/FAIL) — c'est normal. Conserver le log pour comparaison post-migration.


4. Migration reelle

export DATABASE_URL="postgres://user:pass@localhost:5432/kxkm_clown_v2"

node scripts/migrate-v1-to-v2.js --verbose 2>&1 | tee /tmp/migrate-real.log

Verifications immediates post-migration :

psql "$DATABASE_URL" -c "
  SELECT 'personas' AS tbl, count(*) FROM personas
  UNION ALL SELECT 'node_graphs', count(*) FROM node_graphs
  UNION ALL SELECT 'node_runs',   count(*) FROM node_runs
  UNION ALL SELECT 'sessions',    count(*) FROM sessions;
"

Les comptages doivent correspondre aux totaux affiches par le script.


5. Validation parity — V2 demarree

# Lancer l'API V2 (avec DATABASE_URL)
export NODE_ENV=production
export DATABASE_URL="postgres://user:pass@localhost:5432/kxkm_clown_v2"
node apps/api/dist/server.js &
V2_PID=$!
sleep 2

# Lancer le parity check
node scripts/parity-check.js --v1-port 3333 --v2-port 4180 2>&1 | tee /tmp/parity-post.log

grep -E "PASS|FAIL|WARN" /tmp/parity-post.log

Critere de succes : 0 FAIL, 0 WARN sur les checks personas/graphs/channels/API shapes.


6. Smoke test V2

npm run smoke:v2 2>&1 | tee /tmp/smoke-v2.log

22 tests sur 5 categories. Resultat attendu : 22/22 PASS.

En cas d'echec, consulter smoke-v2.js pour identifier le test exact avant de continuer.


7. Cutover

Une fois parity + smoke verts :

# 1. Couper V1
pkill -f "node server.js" || true

# 2. Variables d'environnement de prod
export NODE_ENV=production
export DATABASE_URL="postgres://user:pass@host:5432/kxkm_clown_v2"

# 3. Redemarrer V2 en production
kill $V2_PID 2>/dev/null || true
node apps/api/dist/server.js

Verification finale :

curl -s http://localhost:4180/api/v2/health | python3 -m json.tool
# Attendu : { "ok": true, "data": { "storage": "postgres", ... } }

8. Rollback — si anomalie detectee

Truncate (garder le schema, rejouer la migration)

node scripts/rollback-v2.js --truncate --yes

Puis reprendre depuis l'etape 2.

Drop complet (schema detruit)

node scripts/rollback-v2.js --yes

Puis restaurer V1 depuis le snapshot :

cp -r "$BACKUP_DIR/data" .
node server.js

Rollback selectif (table specifique)

node scripts/rollback-v2.js --tables personas --truncate --yes

9. Checklist avant fermeture

  • parity-baseline.log conserve dans ops/v2/outputs/lot-4-bascule/
  • parity-post.log conserve dans ops/v2/outputs/lot-4-bascule/
  • smoke-v2.log conserve dans ops/v2/outputs/lot-4-bascule/
  • Snapshot V1 archive dans backups/
  • ops/v2/state.json : lot-4-bascule -> done
  • Variables DATABASE_URL / NODE_ENV=production persistees
  • docs/PROJECT_MEMORY.md mis a jour (migration completee)

References

Fichier Role
scripts/migrate-v1-to-v2.js Migration personas/graphs/runs vers Postgres
scripts/parity-check.js 10 checks parite V1/V2
scripts/rollback-v2.js Drop/truncate tables avec confirmation
scripts/smoke-v2.js 22 tests smoke V2 (5 categories)
packages/storage/src/ Repos Postgres + runMigrations()
apps/api/src/app.ts Guard DATABASE_URL production