diff --git a/config/database.js b/config/database.js index b14c76d..780f3cf 100644 --- a/config/database.js +++ b/config/database.js @@ -168,8 +168,8 @@ async function initDatabase() { user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, title TEXT NOT NULL, description TEXT, - start_time TIMESTAMP NOT NULL, - end_time TIMESTAMP NOT NULL, + start_time TIMESTAMPTZ NOT NULL, + end_time TIMESTAMPTZ NOT NULL, location TEXT, color_id TEXT, html_link TEXT, diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 2d027f6..b30abcc 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -75,6 +75,10 @@ else echo "✅ PostgreSQL contient déjà des données ($HAS_DATA utilisateurs)" fi +echo "" +echo "🔄 Migration des timezones du calendrier..." +node scripts/migrate-calendar-timezone.js 2>/dev/null || echo " ℹ️ Migration timezone déjà effectuée ou non nécessaire" + echo "" echo "========================================" echo "🚀 Démarrage du serveur NoteFlow..." diff --git a/migrations/002_calendar_timestamptz.sql b/migrations/002_calendar_timestamptz.sql new file mode 100644 index 0000000..3bf4dda --- /dev/null +++ b/migrations/002_calendar_timestamptz.sql @@ -0,0 +1,24 @@ +-- Migration: Convertir calendar_events TIMESTAMP → TIMESTAMPTZ +-- Pour corriger le décalage horaire de 1h dans l'affichage + +BEGIN; + +-- Convertir start_time de TIMESTAMP à TIMESTAMPTZ +ALTER TABLE calendar_events + ALTER COLUMN start_time TYPE TIMESTAMPTZ + USING start_time AT TIME ZONE 'UTC'; + +-- Convertir end_time de TIMESTAMP à TIMESTAMPTZ +ALTER TABLE calendar_events + ALTER COLUMN end_time TYPE TIMESTAMPTZ + USING end_time AT TIME ZONE 'UTC'; + +COMMIT; + +-- Vérification +SELECT + column_name, + data_type +FROM information_schema.columns +WHERE table_name = 'calendar_events' + AND column_name IN ('start_time', 'end_time'); diff --git a/routes/calendar.routes.js b/routes/calendar.routes.js index b30c180..6251028 100644 --- a/routes/calendar.routes.js +++ b/routes/calendar.routes.js @@ -430,7 +430,7 @@ router.post('/sync', authenticateToken, async (req, res) => { endTime, event.location || '', event.htmlLink || '', - isAllDay ? 1 : 0, + isAllDay, existing.id ]); } else { @@ -448,7 +448,7 @@ router.post('/sync', authenticateToken, async (req, res) => { endTime, event.location || '', event.htmlLink || '', - isAllDay ? 1 : 0 + isAllDay ]); } syncedCount++; diff --git a/scripts/migrate-calendar-timezone.js b/scripts/migrate-calendar-timezone.js new file mode 100755 index 0000000..c87517d --- /dev/null +++ b/scripts/migrate-calendar-timezone.js @@ -0,0 +1,97 @@ +#!/usr/bin/env node + +// Migration: Convertir calendar_events TIMESTAMP → TIMESTAMPTZ +const { Pool } = require('pg'); + +const DATABASE_URL = process.env.DATABASE_URL; + +if (!DATABASE_URL) { + console.error('❌ DATABASE_URL non définie'); + process.exit(1); +} + +async function migrate() { + const pool = new Pool({ connectionString: DATABASE_URL }); + + try { + console.log('\n🔄 Migration: calendar_events TIMESTAMP → TIMESTAMPTZ\n'); + + const client = await pool.connect(); + + // Vérifier le type actuel + const check = await client.query(` + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'calendar_events' + AND column_name IN ('start_time', 'end_time') + `); + + console.log('📊 Types actuels:'); + check.rows.forEach(row => { + console.log(` ${row.column_name}: ${row.data_type}`); + }); + + // Si déjà TIMESTAMPTZ, skip + const alreadyMigrated = check.rows.every(row => + row.data_type.includes('timestamp with time zone') || + row.data_type === 'timestamptz' + ); + + if (alreadyMigrated) { + console.log('\n✅ Migration déjà effectuée, rien à faire'); + client.release(); + await pool.end(); + return; + } + + console.log('\n🔄 Conversion en cours...'); + + await client.query('BEGIN'); + + // Convertir start_time + await client.query(` + ALTER TABLE calendar_events + ALTER COLUMN start_time TYPE TIMESTAMPTZ + USING start_time AT TIME ZONE 'UTC' + `); + console.log(' ✅ start_time → TIMESTAMPTZ'); + + // Convertir end_time + await client.query(` + ALTER TABLE calendar_events + ALTER COLUMN end_time TYPE TIMESTAMPTZ + USING end_time AT TIME ZONE 'UTC' + `); + console.log(' ✅ end_time → TIMESTAMPTZ'); + + await client.query('COMMIT'); + + // Vérifier après migration + const verify = await client.query(` + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'calendar_events' + AND column_name IN ('start_time', 'end_time') + `); + + console.log('\n📊 Types après migration:'); + verify.rows.forEach(row => { + console.log(` ${row.column_name}: ${row.data_type}`); + }); + + console.log('\n✅ Migration terminée avec succès!'); + console.log(''); + console.log('📝 Note: Resynchronisez vos événements Google Calendar'); + console.log(' pour appliquer le nouveau format de timezone.'); + console.log(''); + + client.release(); + await pool.end(); + + } catch (error) { + console.error('\n❌ Erreur lors de la migration:', error.message); + process.exit(1); + } +} + +migrate();