feat: Implement database initialization with custom timestamp parsers and add priority, in_progress, due_date, parent_id, and level columns to the global_todos table.

This commit is contained in:
Michael committed 2026-03-25 11:14:56 +01:00
1 parent 56b257421c
commit 3f64e061e0
5 files changed
+133 -1

No files matched your search

+23
View File
@@ -138,11 +138,34 @@ async function initDatabase() {
completed BOOLEAN DEFAULT FALSE, completed BOOLEAN DEFAULT FALSE,
priority BOOLEAN DEFAULT FALSE, priority BOOLEAN DEFAULT FALSE,
in_progress INTEGER DEFAULT 0, 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, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at 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 // Table note_images
await client.query(` await client.query(`
CREATE TABLE IF NOT EXISTS note_images ( CREATE TABLE IF NOT EXISTS note_images (
+55
View File
@@ -57,7 +57,10 @@ function initDatabase() {
note_id INTEGER NOT NULL, note_id INTEGER NOT NULL,
text TEXT NOT NULL, text TEXT NOT NULL,
completed BOOLEAN DEFAULT 0, completed BOOLEAN DEFAULT 0,
priority BOOLEAN DEFAULT 0,
position INTEGER 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 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE
) )
`); `);
@@ -69,7 +72,11 @@ function initDatabase() {
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
text TEXT NOT NULL, text TEXT NOT NULL,
completed BOOLEAN DEFAULT 0, completed BOOLEAN DEFAULT 0,
priority BOOLEAN DEFAULT 0,
in_progress INTEGER DEFAULT 0,
due_date DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
completed_at DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE 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 // Migration pour calendar_events - ajouter all_day
db.all("PRAGMA table_info(calendar_events)", (err, columns) => { db.all("PRAGMA table_info(calendar_events)", (err, columns) => {
if (err) { if (err) {
+21
View File
@@ -164,6 +164,7 @@ async function initDatabase() {
completed BOOLEAN DEFAULT FALSE, completed BOOLEAN DEFAULT FALSE,
priority BOOLEAN DEFAULT FALSE, priority BOOLEAN DEFAULT FALSE,
in_progress INTEGER DEFAULT 0, in_progress INTEGER DEFAULT 0,
due_date DATE,
parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE, parent_id INTEGER REFERENCES global_todos(id) ON DELETE CASCADE,
level INTEGER DEFAULT 0, level INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 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) // Table recurring_todos (tâches récurrentes)
await client.query(` await client.query(`
CREATE TABLE IF NOT EXISTS recurring_todos ( CREATE TABLE IF NOT EXISTS recurring_todos (
+16 -1
View File
@@ -5,11 +5,12 @@
* S'exécute au démarrage de l'application pour mettre à jour le schéma * S'exécute au démarrage de l'application pour mettre à jour le schéma
*/ */
require('dotenv').config();
const { Pool } = require('pg'); const { Pool } = require('pg');
const logger = require('../config/logger'); const logger = require('../config/logger');
const DATABASE_URL = process.env.DATABASE_URL || 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() { async function autoMigrate() {
const pool = new Pool({ connectionString: DATABASE_URL }); 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`); 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'); await client.query('COMMIT');
logger.info('✅ Migrations automatiques terminées avec succès'); logger.info('✅ Migrations automatiques terminées avec succès');
+18
View File
@@ -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`.