Remplace les références obsolètes note.parsanet.org / notes.parsanet.org dans les guides de déploiement et l'exemple Docker. Co-authored-by: Cursor <cursoragent@cursor.com>
13 KiB
13 KiB
Plan de réparation production — 19 mai 2026
État actuel des problèmes
- Tables brainstorm manquantes en prod — les 7 tables n'existent pas en base
- Migration non enregistrée — le container a été build avec 17 migrations, la 18e (brainstorm) est dans le code mais pas dans l'image
- Redis fonctionne — le container redis tourne, mais il faut vérifier que memento-web a bien
REDIS_URL
Étape 1 : Créer les tables brainstorm en prod
Se connecter au serveur en root, puis :
docker exec -i memento-postgres psql -U memento -d memento <<'EOSQL'
-- ========================================
-- Tables brainstorm
-- ========================================
CREATE TABLE IF NOT EXISTS "BrainstormSession" (
"id" TEXT NOT NULL,
"seedIdea" TEXT NOT NULL,
"sourceNoteId" TEXT,
"contextNoteIds" TEXT,
"exportedNoteId" TEXT,
"userId" TEXT NOT NULL,
"inviteToken" TEXT,
"inviteExpiry" TIMESTAMP(3),
"liveblocksRoomId" TEXT,
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"guestCanEdit" BOOLEAN NOT NULL DEFAULT false,
"status" TEXT NOT NULL DEFAULT 'active',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "BrainstormSession_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormIdea" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"waveNumber" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT NOT NULL,
"connectionToSeed" TEXT,
"noveltyScore" INTEGER,
"parentIdeaId" TEXT,
"convertedToNoteId" TEXT,
"relatedNoteIds" TEXT,
"status" TEXT NOT NULL DEFAULT 'active',
"positionX" DOUBLE PRECISION,
"positionY" DOUBLE PRECISION,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"createdBy" TEXT,
"createdByType" TEXT DEFAULT 'ai',
CONSTRAINT "BrainstormIdea_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormNoteRef" (
"id" TEXT NOT NULL,
"ideaId" TEXT NOT NULL,
"noteId" TEXT,
"relation" TEXT NOT NULL,
"explanation" TEXT NOT NULL,
"verdict" TEXT NOT NULL DEFAULT 'unresolved',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"visibility" TEXT NOT NULL DEFAULT 'participants',
CONSTRAINT "BrainstormNoteRef_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormParticipant" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"role" TEXT NOT NULL DEFAULT 'viewer',
"joinedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BrainstormParticipant_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormActivity" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"userId" TEXT,
"action" TEXT NOT NULL,
"details" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BrainstormActivity_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormShare" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"sharedBy" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'pending',
"permission" TEXT NOT NULL DEFAULT 'editor',
"notifiedAt" TIMESTAMP(3),
"respondedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "BrainstormShare_pkey" PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "BrainstormSnapshot" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"activityId" TEXT,
"step" INTEGER NOT NULL,
"label" TEXT,
"ideaGraph" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BrainstormSnapshot_pkey" PRIMARY KEY ("id")
);
-- ========================================
-- Index uniques
-- ========================================
CREATE UNIQUE INDEX IF NOT EXISTS "BrainstormSession_inviteToken_key" ON "BrainstormSession"("inviteToken");
CREATE UNIQUE INDEX IF NOT EXISTS "BrainstormParticipant_sessionId_userId_key" ON "BrainstormParticipant"("sessionId", "userId");
CREATE UNIQUE INDEX IF NOT EXISTS "BrainstormShare_sessionId_userId_key" ON "BrainstormShare"("sessionId", "userId");
-- ========================================
-- Index de performance
-- ========================================
CREATE INDEX IF NOT EXISTS "BrainstormSession_userId_idx" ON "BrainstormSession"("userId");
CREATE INDEX IF NOT EXISTS "BrainstormSession_userId_createdAt_idx" ON "BrainstormSession"("userId", "createdAt");
CREATE INDEX IF NOT EXISTS "BrainstormSession_inviteToken_idx" ON "BrainstormSession"("inviteToken");
CREATE INDEX IF NOT EXISTS "BrainstormSession_isPublic_idx" ON "BrainstormSession"("isPublic");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_sessionId_idx" ON "BrainstormIdea"("sessionId");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_waveNumber_idx" ON "BrainstormIdea"("waveNumber");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_status_idx" ON "BrainstormIdea"("status");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_parentIdeaId_idx" ON "BrainstormIdea"("parentIdeaId");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_sessionId_status_idx" ON "BrainstormIdea"("sessionId", "status");
CREATE INDEX IF NOT EXISTS "BrainstormIdea_sessionId_waveNumber_createdAt_idx" ON "BrainstormIdea"("sessionId", "waveNumber", "createdAt");
CREATE INDEX IF NOT EXISTS "BrainstormNoteRef_ideaId_idx" ON "BrainstormNoteRef"("ideaId");
CREATE INDEX IF NOT EXISTS "BrainstormNoteRef_noteId_idx" ON "BrainstormNoteRef"("noteId");
CREATE INDEX IF NOT EXISTS "BrainstormParticipant_sessionId_idx" ON "BrainstormParticipant"("sessionId");
CREATE INDEX IF NOT EXISTS "BrainstormParticipant_userId_idx" ON "BrainstormParticipant"("userId");
CREATE INDEX IF NOT EXISTS "BrainstormActivity_sessionId_createdAt_idx" ON "BrainstormActivity"("sessionId", "createdAt");
CREATE INDEX IF NOT EXISTS "BrainstormShare_userId_idx" ON "BrainstormShare"("userId");
CREATE INDEX IF NOT EXISTS "BrainstormShare_status_idx" ON "BrainstormShare"("status");
CREATE INDEX IF NOT EXISTS "BrainstormSnapshot_sessionId_step_idx" ON "BrainstormSnapshot"("sessionId", "step");
CREATE INDEX IF NOT EXISTS "BrainstormSnapshot_sessionId_createdAt_idx" ON "BrainstormSnapshot"("sessionId", "createdAt");
-- ========================================
-- Clés étrangères
-- ========================================
DO $$ BEGIN
ALTER TABLE "BrainstormSession" ADD CONSTRAINT "BrainstormSession_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormSession" ADD CONSTRAINT "BrainstormSession_sourceNoteId_fkey" FOREIGN KEY ("sourceNoteId") REFERENCES "Note"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormSession" ADD CONSTRAINT "BrainstormSession_exportedNoteId_fkey" FOREIGN KEY ("exportedNoteId") REFERENCES "Note"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormIdea" ADD CONSTRAINT "BrainstormIdea_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "BrainstormSession"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormIdea" ADD CONSTRAINT "BrainstormIdea_parentIdeaId_fkey" FOREIGN KEY ("parentIdeaId") REFERENCES "BrainstormIdea"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormIdea" ADD CONSTRAINT "BrainstormIdea_convertedToNoteId_fkey" FOREIGN KEY ("convertedToNoteId") REFERENCES "Note"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormNoteRef" ADD CONSTRAINT "BrainstormNoteRef_ideaId_fkey" FOREIGN KEY ("ideaId") REFERENCES "BrainstormIdea"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormNoteRef" ADD CONSTRAINT "BrainstormNoteRef_noteId_fkey" FOREIGN KEY ("noteId") REFERENCES "Note"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormParticipant" ADD CONSTRAINT "BrainstormParticipant_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "BrainstormSession"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormParticipant" ADD CONSTRAINT "BrainstormParticipant_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormActivity" ADD CONSTRAINT "BrainstormActivity_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "BrainstormSession"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormActivity" ADD CONSTRAINT "BrainstormActivity_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormShare" ADD CONSTRAINT "BrainstormShare_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "BrainstormSession"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormShare" ADD CONSTRAINT "BrainstormShare_sharedBy_fkey" FOREIGN KEY ("sharedBy") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormShare" ADD CONSTRAINT "BrainstormShare_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
DO $$ BEGIN
ALTER TABLE "BrainstormSnapshot" ADD CONSTRAINT "BrainstormSnapshot_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "BrainstormSession"("id") ON DELETE CASCADE ON UPDATE CASCADE;
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
-- ========================================
-- Enregistrer la migration dans Prisma
-- ========================================
INSERT INTO "_prisma_migrations" (id, checksum, migration_name, logs, started_at, finished_at, applied_steps_count)
VALUES (
gen_random_uuid(),
'manual-creation-20260519',
'20260519120000_add_brainstorm_tables',
NULL,
now(),
now(),
1
) ON CONFLICT DO NOTHING;
EOSQL
Étape 2 : Vérifier que les tables sont créées
docker exec memento-postgres psql -U memento -d memento -c "SELECT tablename FROM pg_tables WHERE schemaname='public' AND tablename LIKE '%rainstorm%' ORDER BY tablename;"
Résultat attendu : 7 lignes (BrainstormActivity, BrainstormIdea, BrainstormNoteRef, BrainstormParticipant, BrainstormSession, BrainstormShare, BrainstormSnapshot)
Étape 3 : Vérifier les migrations enregistrées
docker exec memento-postgres psql -U memento -d memento -c "SELECT migration_name FROM _prisma_migrations ORDER BY started_at DESC LIMIT 3;"
Résultat attendu : la migration 20260519120000_add_brainstorm_tables doit apparaître.
Étape 4 : Vérifier Redis
docker ps | grep redis
docker exec memento-redis redis-cli ping
Résultat attendu : PONG
Vérifier que memento-web a bien la variable REDIS_URL :
docker exec memento-web env | grep REDIS
Résultat attendu : REDIS_URL=redis://redis:6379
Si vide, il faut recréer le container :
docker compose up -d --force-recreate memento-note
Étape 5 : Redémarrer l'app
docker compose restart memento-note
Étape 6 : Vérifier les logs
sleep 10
docker logs memento-web --tail 30 2>&1 | grep -i -E "error|redis|brainstorm"
Résultat attendu :
- Aucune erreur
BrainstormSession does not exist - Aucune erreur
redis ECONNREFUSED [redis] Connecteddoit apparaître
Étape 7 : Tester le brainstorm
- Ouvrir https://memento-note.com/brainstorm
- Taper une idée et cliquer le bouton +
- Vérifier que les 9 idées apparaissent sur le canvas
Si l'étape 1 échoue
Copier le message d'erreur exact. Les causes possibles :
- Permission denied → il faut être root (
sudo -iavant) - duplicate_object → tables déjà créées partiellement, aller à l'étape 2 pour vérifier
- Column exists → certaines colonnes existent déjà, les
IF NOT EXISTSgèrent ça
Si le brainstorm charge indéfiniment
Vérifier les logs en temps réel :
docker logs memento-web -f --tail 50 2>&1 &
Puis lancer un brainstorm et regarder les logs. Copier le message d'erreur exact.