diff --git a/config/database-postgres.js b/config/database-postgres.js index b14c76d..e700cf5 100644 --- a/config/database-postgres.js +++ b/config/database-postgres.js @@ -256,8 +256,20 @@ async function runQuery(sql, params = []) { const client = await pool.connect(); try { const result = await client.query(sql, params); + + // Si c'est un INSERT/UPDATE avec RETURNING, retourner la ligne complète + if (result.rows && result.rows.length > 0) { + logger.info(`[runQuery] Requête avec RETURNING - ID: ${result.rows[0].id}, rowCount: ${result.rowCount}`); + return { + ...result.rows[0], // Retourne toutes les colonnes de la première ligne + changes: result.rowCount + }; + } + + // Sinon, retourner juste le nombre de lignes affectées + logger.info(`[runQuery] Requête sans RETURNING - rowCount: ${result.rowCount}`); return { - id: result.rows[0]?.id || result.rowCount, + id: result.rowCount, changes: result.rowCount }; } catch (error) { diff --git a/routes/calendar.routes.js b/routes/calendar.routes.js index cba1eff..710616c 100644 --- a/routes/calendar.routes.js +++ b/routes/calendar.routes.js @@ -190,10 +190,12 @@ router.get('/oauth-callback', async (req, res) => { userId ]); } else { + logger.info(`[CREATE OAUTH TOKEN] Ajout nouveau token OAuth - user_id: ${userId}`); await runQuery(` INSERT INTO google_oauth_tokens (user_id, access_token, refresh_token, token_type, expiry_date, scope) VALUES ($1, $2, $3, $4, $5, $6) + RETURNING * `, [ userId, tokens.access_token, @@ -202,6 +204,7 @@ router.get('/oauth-callback', async (req, res) => { tokens.expiry_date || null, tokens.scope || SCOPES.join(' ') ]); + logger.info(`[CREATE OAUTH TOKEN] Token OAuth créé avec succès pour user_id: ${userId}`); } logger.info(`Tokens OAuth sauvegardés pour l'utilisateur ${userId}`); @@ -562,10 +565,12 @@ router.post('/sync', authenticateToken, async (req, res) => { ]); } else { // Créer un nouvel événement + logger.info(`[CREATE CALENDAR EVENT] Ajout événement - event_id: "${event.id}", title: "${event.summary || 'Sans titre'}"`); await runQuery(` INSERT INTO calendar_events (google_event_id, user_id, title, description, start_time, end_time, location, html_link, all_day) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + RETURNING * `, [ event.id, req.user.id, @@ -577,6 +582,7 @@ router.post('/sync', authenticateToken, async (req, res) => { event.htmlLink || '', isAllDay ]); + logger.info(`[CREATE CALENDAR EVENT] Événement créé avec succès - event_id: "${event.id}"`); } syncedCount++; } @@ -707,6 +713,7 @@ router.post('/events', authenticateToken, async (req, res) => { const itemEndUTC = itemIsAllDay ? itemEndRaw : new Date(itemEndRaw).toISOString(); // PostgreSQL : INSERT ... ON CONFLICT DO UPDATE (pas INSERT OR REPLACE) + logger.info(`[SYNC CALENDAR EVENT] Sync événement - event_id: "${item.id}"`); await runQuery(` INSERT INTO calendar_events (google_event_id, user_id, title, description, start_time, end_time, location, html_link, all_day, synced_at) @@ -720,6 +727,7 @@ router.post('/events', authenticateToken, async (req, res) => { html_link = EXCLUDED.html_link, all_day = EXCLUDED.all_day, synced_at = CURRENT_TIMESTAMP + RETURNING * `, [ item.id, req.user.id, diff --git a/routes/notes.routes.js b/routes/notes.routes.js index 4d7035c..11f807b 100644 --- a/routes/notes.routes.js +++ b/routes/notes.routes.js @@ -172,12 +172,15 @@ router.post('/', const { title, content } = req.body; + logger.info(`[CREATE NOTE] Début création - user_id: ${req.user.id}, title: "${title}"`); + const result = await runQuery(` INSERT INTO notes (user_id, title, content) VALUES ($1, $2, $3) + RETURNING * `, [req.user.id, title, content || '']); - logger.info(`Note créée: ${title} (ID: ${result.id}) par ${req.user.username}`); + logger.info(`[CREATE NOTE] Note créée avec succès - ID: ${result.id}, title: "${title}", user: ${req.user.username}`); res.status(201).json({ id: result.id, @@ -395,11 +398,16 @@ router.post('/:id/todos', const { text } = req.body; + logger.info(`[CREATE TODO] Ajout todo à note ${req.params.id}: "${text}"`); + const result = await runQuery(` INSERT INTO note_todos (note_id, text, position) VALUES ($1, $2, (SELECT COALESCE(MAX(position), FALSE) + 1 FROM note_todos WHERE note_id = $3)) + RETURNING * `, [req.params.id, text, req.params.id]); + logger.info(`[CREATE TODO] Todo créé - ID: ${result.id}, note_id: ${req.params.id}`); + await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.id]); res.status(201).json({ @@ -582,15 +590,18 @@ router.post('/:id/images', imageUpload.single('image'), async (req, res) => { } // Enregistrer l'image dans la base de données + logger.info(`[CREATE IMAGE] Ajout image à note ${req.params.id}: ${req.file.originalname}`); + const result = await runQuery(` INSERT INTO note_images (note_id, filename, original_name) VALUES ($1, $2, $3) + RETURNING * `, [req.params.id, req.file.filename, req.file.originalname]); // Mettre à jour la date de modification de la note await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.id]); - logger.info(`Image ajoutée à la note ${req.params.id}: ${req.file.filename}`); + logger.info(`[CREATE IMAGE] Image créée - ID: ${result.id}, filename: ${req.file.filename}, note_id: ${req.params.id}`); res.json({ message: 'Image ajoutée avec succès', @@ -716,15 +727,18 @@ router.post('/:id/files', fileUpload.single('file'), async (req, res) => { } // Enregistrer le fichier dans la base de données + logger.info(`[CREATE FILE] Ajout fichier à note ${req.params.id}: ${req.file.originalname}`); + const result = await runQuery(` INSERT INTO note_files (note_id, filename, original_name, file_size, mime_type) VALUES ($1, $2, $3, $4, $5) + RETURNING * `, [req.params.id, req.file.filename, req.file.originalname, req.file.size, req.file.mimetype]); // Mettre à jour la date de modification de la note await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.id]); - logger.info(`Fichier ajouté à la note ${req.params.id}: ${req.file.originalname}`); + logger.info(`[CREATE FILE] Fichier créé - ID: ${result.id}, filename: ${req.file.filename}, note_id: ${req.params.id}`); res.json({ message: 'Fichier ajouté avec succès', @@ -877,7 +891,12 @@ router.post('/:id/tags', async (req, res) => { return res.status(404).json({ error: 'Note non trouvée' }); } - const result = await runQuery('INSERT INTO note_tags (note_id, tag) VALUES ($1, $2)', [req.params.id, tag.trim().toLowerCase()]); + logger.info(`[CREATE TAG] Ajout tag à note ${req.params.id}: "${tag.trim().toLowerCase()}"`); + + const result = await runQuery('INSERT INTO note_tags (note_id, tag) VALUES ($1, $2) RETURNING *', [req.params.id, tag.trim().toLowerCase()]); + + logger.info(`[CREATE TAG] Tag créé - ID: ${result.id}, tag: "${result.tag}", note_id: ${req.params.id}`); + res.json({ id: result.id, tag: tag.trim().toLowerCase() }); } catch (error) { if (error.message && error.message.includes('UNIQUE constraint')) { diff --git a/routes/rss.routes.js b/routes/rss.routes.js index e24b413..e19daa9 100644 --- a/routes/rss.routes.js +++ b/routes/rss.routes.js @@ -47,13 +47,15 @@ router.post('/feeds', requireAdmin, async (req, res) => { try { const feed = await parser.parseURL(url); + logger.info(`[CREATE RSS FEED] Ajout flux - url: "${url}", title: "${feed.title || url}"`); + // Ajouter le flux const result = await runQuery( - 'INSERT INTO rss_feeds (url, title, description, enabled) VALUES ($1, $2, $3, TRUE)', + 'INSERT INTO rss_feeds (url, title, description, enabled) VALUES ($1, $2, $3, TRUE) RETURNING *', [url, feed.title || url, feed.description || ''] ); - logger.info(`✅ Flux ajouté: ${feed.title}`); + logger.info(`[CREATE RSS FEED] Flux créé avec succès - ID: ${result.id}, title: "${feed.title}"`); // Déclencher un fetch immédiat setTimeout(() => { @@ -250,11 +252,15 @@ Résumé (100 mots max):`; const summary = response.data.choices[0].message.content; + logger.info(`[CREATE RSS SUMMARY] Ajout résumé - article: "${article.title}", model: "${selectedModel}"`); + await runQuery( - 'INSERT INTO rss_summaries (summary, model, articles_count, feed_title, created_at) VALUES (?, ?, ?, ?, datetime("now"))', + 'INSERT INTO rss_summaries (summary, model, articles_count, feed_title, created_at) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP) RETURNING *', [`**${article.title}**\n\n${summary}\n\n🔗 [Lire l'article](${article.link})`, selectedModel, 1, article.feed_title] ); + logger.info(`[CREATE RSS SUMMARY] Résumé créé avec succès`); + return { article_id: article.id, title: article.title, diff --git a/routes/settings.routes.js b/routes/settings.routes.js index b957662..bf0175f 100644 --- a/routes/settings.routes.js +++ b/routes/settings.routes.js @@ -52,10 +52,12 @@ router.put('/', async (req, res) => { [value, key] ); } else { + logger.info(`[CREATE SETTING] Ajout nouveau paramètre - key: "${key}"`); await runQuery( - 'INSERT INTO settings (key, value) VALUES ($1, $2)', + 'INSERT INTO settings (key, value) VALUES ($1, $2) RETURNING *', [key, value] ); + logger.info(`[CREATE SETTING] Paramètre créé avec succès - key: "${key}"`); } } @@ -102,14 +104,15 @@ router.put('/:key', async (req, res) => { 'UPDATE settings SET value = $1, updated_at = CURRENT_TIMESTAMP WHERE key = $2', [value, req.params.key] ); + logger.info(`Paramètre mis à jour: ${req.params.key}`); } else { + logger.info(`[CREATE SETTING] Ajout nouveau paramètre - key: "${req.params.key}"`); await runQuery( - 'INSERT INTO settings (key, value) VALUES ($1, $2)', + 'INSERT INTO settings (key, value) VALUES ($1, $2) RETURNING *', [req.params.key, value] ); + logger.info(`[CREATE SETTING] Paramètre créé avec succès - key: "${req.params.key}"`); } - - logger.info(`Paramètre mis à jour: ${req.params.key}`); res.json({ key: req.params.key, value }); } catch (error) { logger.error('Erreur lors de la mise à jour du paramètre:', error); diff --git a/routes/todos.routes.js b/routes/todos.routes.js index f669cd6..82a77ac 100644 --- a/routes/todos.routes.js +++ b/routes/todos.routes.js @@ -45,12 +45,15 @@ router.post('/', const { text } = req.body; + logger.info(`[CREATE GLOBAL TODO] Début création - user_id: ${req.user.id}, text: "${text}"`); + const result = await runQuery(` INSERT INTO global_todos (user_id, text) VALUES ($1, $2) + RETURNING * `, [req.user.id, text]); - logger.info(`Todo global créé (ID: ${result.id}) par ${req.user.username}`); + logger.info(`[CREATE GLOBAL TODO] Todo global créé avec succès - ID: ${result.id}, user: ${req.user.username}`); res.status(201).json({ id: result.id, diff --git a/routes/users.routes.js b/routes/users.routes.js index c0b6d88..836f459 100644 --- a/routes/users.routes.js +++ b/routes/users.routes.js @@ -56,13 +56,15 @@ router.post('/', // Hasher le mot de passe const passwordHash = await bcrypt.hash(password, 12); + logger.info(`[CREATE USER] Début création - username: "${username}", is_admin: ${is_admin ? 1 : 0}`); + // Créer l'utilisateur const result = await runQuery( - 'INSERT INTO users (username, password_hash, is_admin) VALUES ($1, $2, $3)', + 'INSERT INTO users (username, password_hash, is_admin) VALUES ($1, $2, $3) RETURNING *', [username, passwordHash, is_admin ? 1 : 0] ); - logger.info(`Utilisateur créé: ${username} (ID: ${result.id})`); + logger.info(`[CREATE USER] Utilisateur créé avec succès - ID: ${result.id}, username: "${username}"`); res.status(201).json({ id: result.id,