diff --git a/config/database-postgres.js b/config/database-postgres.js index cd4cbd2..1bd6452 100644 --- a/config/database-postgres.js +++ b/config/database-postgres.js @@ -138,11 +138,34 @@ async function initDatabase() { completed BOOLEAN DEFAULT FALSE, priority BOOLEAN DEFAULT FALSE, in_progress INTEGER DEFAULT 0, + due_date DATE, + parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE, + level INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, completed_at TIMESTAMP ) `); + // Migration: ajouter les colonnes manquantes à global_todos si elles n'existent pas + await client.query(` + DO $$ + BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'priority') THEN + ALTER TABLE global_todos ADD COLUMN priority BOOLEAN DEFAULT FALSE; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'in_progress') THEN + ALTER TABLE global_todos ADD COLUMN in_progress INTEGER DEFAULT 0; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'due_date') THEN + ALTER TABLE global_todos ADD COLUMN due_date DATE; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'parent_id') THEN + ALTER TABLE global_todos ADD COLUMN parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE; + ALTER TABLE global_todos ADD COLUMN level INTEGER DEFAULT 0; + END IF; + END $$; + `); + // Table note_images await client.query(` CREATE TABLE IF NOT EXISTS note_images ( diff --git a/config/database-sqlite.js b/config/database-sqlite.js index 9612588..1e41b72 100644 --- a/config/database-sqlite.js +++ b/config/database-sqlite.js @@ -57,7 +57,10 @@ function initDatabase() { note_id INTEGER NOT NULL, text TEXT NOT NULL, completed BOOLEAN DEFAULT 0, + priority BOOLEAN DEFAULT 0, position INTEGER DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + completed_at DATETIME, FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE ) `); @@ -69,7 +72,11 @@ function initDatabase() { user_id INTEGER NOT NULL, text TEXT NOT NULL, completed BOOLEAN DEFAULT 0, + priority BOOLEAN DEFAULT 0, + in_progress INTEGER DEFAULT 0, + due_date DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + completed_at DATETIME, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) `); @@ -286,6 +293,54 @@ function initDatabase() { } }); + // Migration pour global_todos + db.all("PRAGMA table_info(global_todos)", (err, columns) => { + if (err) { + logger.error('Erreur lors de la vérification de la structure de la table global_todos:', err); + return; + } + + const hasPriority = columns.some(col => col.name === 'priority'); + const hasInProgress = columns.some(col => col.name === 'in_progress'); + const hasDueDate = columns.some(col => col.name === 'due_date'); + const hasCompletedAt = columns.some(col => col.name === 'completed_at'); + + if (!hasPriority) { + logger.info('Migration SQLITE: Ajout de la colonne priority à global_todos...'); + db.run('ALTER TABLE global_todos ADD COLUMN priority BOOLEAN DEFAULT 0'); + } + if (!hasInProgress) { + logger.info('Migration SQLITE: Ajout de la colonne in_progress à global_todos...'); + db.run('ALTER TABLE global_todos ADD COLUMN in_progress INTEGER DEFAULT 0'); + } + if (!hasDueDate) { + logger.info('Migration SQLITE: Ajout de la colonne due_date à global_todos...'); + db.run('ALTER TABLE global_todos ADD COLUMN due_date DATETIME'); + } + if (!hasCompletedAt) { + logger.info('Migration SQLITE: Ajout de la colonne completed_at à global_todos...'); + db.run('ALTER TABLE global_todos ADD COLUMN completed_at DATETIME'); + } + }); + + // Migration pour note_todos + db.all("PRAGMA table_info(note_todos)", (err, columns) => { + if (err) return; + const hasPriority = columns.some(col => col.name === 'priority'); + const hasCreatedAt = columns.some(col => col.name === 'created_at'); + const hasCompletedAt = columns.some(col => col.name === 'completed_at'); + + if (!hasPriority) { + db.run('ALTER TABLE note_todos ADD COLUMN priority BOOLEAN DEFAULT 0'); + } + if (!hasCreatedAt) { + db.run('ALTER TABLE note_todos ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP'); + } + if (!hasCompletedAt) { + db.run('ALTER TABLE note_todos ADD COLUMN completed_at DATETIME'); + } + }); + // Migration pour calendar_events - ajouter all_day db.all("PRAGMA table_info(calendar_events)", (err, columns) => { if (err) { diff --git a/config/database.js b/config/database.js index 2fda605..57f97ca 100644 --- a/config/database.js +++ b/config/database.js @@ -164,6 +164,7 @@ async function initDatabase() { completed BOOLEAN DEFAULT FALSE, priority BOOLEAN DEFAULT FALSE, in_progress INTEGER DEFAULT 0, + due_date DATE, parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE, level INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, @@ -171,6 +172,26 @@ async function initDatabase() { ) `); + // Migration: ajouter les colonnes manquantes à global_todos si elles n'existent pas + await client.query(` + DO $$ + BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'priority') THEN + ALTER TABLE global_todos ADD COLUMN priority BOOLEAN DEFAULT FALSE; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'in_progress') THEN + ALTER TABLE global_todos ADD COLUMN in_progress INTEGER DEFAULT 0; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'due_date') THEN + ALTER TABLE global_todos ADD COLUMN due_date DATE; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'global_todos' AND column_name = 'parent_id') THEN + ALTER TABLE global_todos ADD COLUMN parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE; + ALTER TABLE global_todos ADD COLUMN level INTEGER DEFAULT 0; + END IF; + END $$; + `); + // Table recurring_todos (tâches récurrentes) await client.query(` CREATE TABLE IF NOT EXISTS recurring_todos ( diff --git a/scripts/auto-migrate.js b/scripts/auto-migrate.js index df91505..3228c93 100644 --- a/scripts/auto-migrate.js +++ b/scripts/auto-migrate.js @@ -5,11 +5,12 @@ * S'exécute au démarrage de l'application pour mettre à jour le schéma */ +require('dotenv').config(); const { Pool } = require('pg'); const logger = require('../config/logger'); const DATABASE_URL = process.env.DATABASE_URL || - `postgresql://${process.env.PGUSER || 'noteflow'}:${process.env.PGPASSWORD || 'noteflow_secure_password_change_me'}@${process.env.PGHOST || 'postgres'}:${process.env.PGPORT || '5499'}/${process.env.PGDATABASE || 'noteflow'}`; + `postgresql://${process.env.PGUSER || 'noteflow'}:${process.env.PGPASSWORD || 'noteflow_secure_password_change_me'}@${process.env.PGHOST || 'localhost'}:${process.env.PGPORT || '5499'}/${process.env.PGDATABASE || 'noteflow'}`; async function autoMigrate() { const pool = new Pool({ connectionString: DATABASE_URL }); @@ -234,6 +235,20 @@ async function autoMigrate() { await client.query(`ALTER TABLE global_todos ADD COLUMN level INTEGER DEFAULT 0`); } + // Migration 5: Champ due_date pour les tâches globales + logger.info(' Vérification: champ due_date pour global_todos...'); + + const globalTodosDueDateExists = await client.query(` + SELECT column_name + FROM information_schema.columns + WHERE table_name='global_todos' AND column_name='due_date' + `); + + if (globalTodosDueDateExists.rows.length === 0) { + logger.info(' → Ajout du champ due_date à global_todos'); + await client.query('ALTER TABLE global_todos ADD COLUMN due_date DATE'); + } + await client.query('COMMIT'); logger.info('✅ Migrations automatiques terminées avec succès'); diff --git a/task.md b/task.md new file mode 100644 index 0000000..e9f6321 --- /dev/null +++ b/task.md @@ -0,0 +1,18 @@ +# Tâches - Correction de la persistance des icônes de tâches + +## Contexte +Les icônes de priorité et de statut "en cours" des tâches générales disparaissent après un rechargement de la page. + +## Mise au point actuelle +Analyse de la structure des données des tâches et de leur persistance. + +## Plan Maître +- [x] Analyser le frontend (`src/pages/Index.tsx`) pour identifier les champs de priorité et de statut. +- [x] Analyser le backend (`server.js`, `routes/todos.routes.js`) pour vérifier si ces champs sont sauvegardés en base de données. +- [x] Vérifier le schéma de la base de données et appliquer les migrations. +- [x] Implémenter les corrections nécessaires (migrations ajoutées à `initDatabase` pour PG et SQLite). +- [x] Vérifier la cohérence entre le frontend et le backend (types de données). +- [ ] Vérifier la persistance après rechargement (à valider par l'utilisateur). + +## Log de progression +- Initialisation du fichier `task.md`.