mirror of
https://github.com/R0m1k3/noteflow.git
synced 2026-10-11 17:29:37 +02:00
Fix: Conversion SQL SQLite → PostgreSQL
Correction de TOUTES les requêtes SQL pour PostgreSQL: 1. Paramètres: ? → $1, $2, $3... - 234 conversions automatiques - auth.routes.js: WHERE username = $1 - Tous les routes et services corrigés 2. Booléens: 0/1 → TRUE/FALSE - WHERE enabled = 1 → WHERE enabled = TRUE - WHERE completed = 0 → WHERE completed = FALSE - rss-scheduler.js ligne 154: corrigé ERREURS RÉSOLUES: - ✅ "syntax error at end of input" (auth login) - ✅ "operator does not exist: boolean = integer" (RSS) Script: scripts/convert-sql-to-postgres.js - Conversion automatique intelligente - Gère WHERE, INSERT, UPDATE, DELETE, SELECT - Remplace ? par $N selon ordre - Convertit booléens 0/1 → TRUE/FALSE Fichiers modifiés: - routes/*.js (9 fichiers) - services/*.js (2 fichiers) - 234 requêtes SQL corrigées La connexion et les flux RSS devraient maintenant fonctionner.
This commit is contained in:
12 files changed
+235
-134
No files matched your search
@@ -29,7 +29,7 @@ router.post('/login',
|
|||||||
|
|
||||||
// Rechercher l'utilisateur
|
// Rechercher l'utilisateur
|
||||||
const user = await getOne(
|
const user = await getOne(
|
||||||
'SELECT id, username, password_hash, is_admin FROM users WHERE username = ?',
|
'SELECT id, username, password_hash, is_admin FROM users WHERE username = $1',
|
||||||
[username]
|
[username]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ router.post('/logout', authenticateToken, (req, res) => {
|
|||||||
router.get('/me', authenticateToken, async (req, res) => {
|
router.get('/me', authenticateToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const user = await getOne(
|
const user = await getOne(
|
||||||
'SELECT id, username, is_admin, created_at FROM users WHERE id = ?',
|
'SELECT id, username, is_admin, created_at FROM users WHERE id = $1',
|
||||||
[req.user.id]
|
[req.user.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+25
-25
@@ -172,14 +172,14 @@ router.get('/oauth-callback', async (req, res) => {
|
|||||||
const { tokens } = await oauth2Client.getToken(code);
|
const { tokens } = await oauth2Client.getToken(code);
|
||||||
|
|
||||||
// Sauvegarder les tokens dans la base de données
|
// Sauvegarder les tokens dans la base de données
|
||||||
const existing = await getOne('SELECT id FROM google_oauth_tokens WHERE user_id = ?', [userId]);
|
const existing = await getOne('SELECT id FROM google_oauth_tokens WHERE user_id = $1', [userId]);
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
await runQuery(`
|
await runQuery(`
|
||||||
UPDATE google_oauth_tokens
|
UPDATE google_oauth_tokens
|
||||||
SET access_token = ?, refresh_token = COALESCE(?, refresh_token),
|
SET access_token = $1, refresh_token = COALESCE($2, refresh_token),
|
||||||
token_type = ?, expiry_date = ?, scope = ?, updated_at = CURRENT_TIMESTAMP
|
token_type = $3, expiry_date = $4, scope = $5, updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE user_id = ?
|
WHERE user_id = $6
|
||||||
`, [
|
`, [
|
||||||
tokens.access_token,
|
tokens.access_token,
|
||||||
tokens.refresh_token,
|
tokens.refresh_token,
|
||||||
@@ -192,7 +192,7 @@ router.get('/oauth-callback', async (req, res) => {
|
|||||||
await runQuery(`
|
await runQuery(`
|
||||||
INSERT INTO google_oauth_tokens
|
INSERT INTO google_oauth_tokens
|
||||||
(user_id, access_token, refresh_token, token_type, expiry_date, scope)
|
(user_id, access_token, refresh_token, token_type, expiry_date, scope)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
`, [
|
`, [
|
||||||
userId,
|
userId,
|
||||||
tokens.access_token,
|
tokens.access_token,
|
||||||
@@ -267,7 +267,7 @@ router.get('/auth-status', authenticateToken, async (req, res) => {
|
|||||||
} else {
|
} else {
|
||||||
// OAuth2
|
// OAuth2
|
||||||
const tokens = await getOne(
|
const tokens = await getOne(
|
||||||
'SELECT access_token, expiry_date FROM google_oauth_tokens WHERE user_id = ?',
|
'SELECT access_token, expiry_date FROM google_oauth_tokens WHERE user_id = $1',
|
||||||
[req.user.id]
|
[req.user.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ router.get('/auth-status', authenticateToken, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
async function getValidTokens(userId) {
|
async function getValidTokens(userId) {
|
||||||
const tokenData = await getOne(
|
const tokenData = await getOne(
|
||||||
'SELECT * FROM google_oauth_tokens WHERE user_id = ?',
|
'SELECT * FROM google_oauth_tokens WHERE user_id = $1',
|
||||||
[userId]
|
[userId]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -317,8 +317,8 @@ async function getValidTokens(userId) {
|
|||||||
// Mettre à jour les tokens dans la base de données
|
// Mettre à jour les tokens dans la base de données
|
||||||
await runQuery(`
|
await runQuery(`
|
||||||
UPDATE google_oauth_tokens
|
UPDATE google_oauth_tokens
|
||||||
SET access_token = ?, expiry_date = ?, updated_at = CURRENT_TIMESTAMP
|
SET access_token = $1, expiry_date = $2, updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE user_id = ?
|
WHERE user_id = $3
|
||||||
`, [credentials.access_token, credentials.expiry_date, userId]);
|
`, [credentials.access_token, credentials.expiry_date, userId]);
|
||||||
|
|
||||||
oauth2Client.setCredentials(credentials);
|
oauth2Client.setCredentials(credentials);
|
||||||
@@ -347,9 +347,9 @@ router.get('/events', authenticateToken, async (req, res) => {
|
|||||||
id, google_event_id, title, description,
|
id, google_event_id, title, description,
|
||||||
start_time, end_time, location, html_link
|
start_time, end_time, location, html_link
|
||||||
FROM calendar_events
|
FROM calendar_events
|
||||||
WHERE user_id = ? AND start_time >= ?
|
WHERE user_id = $1 AND start_time >= $2
|
||||||
ORDER BY start_time ASC
|
ORDER BY start_time ASC
|
||||||
LIMIT ?
|
LIMIT $3
|
||||||
`, [req.user.id, now, limit]);
|
`, [req.user.id, now, limit]);
|
||||||
|
|
||||||
res.json(events || []);
|
res.json(events || []);
|
||||||
@@ -412,7 +412,7 @@ router.post('/sync', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Vérifier si l'événement existe déjà
|
// Vérifier si l'événement existe déjà
|
||||||
const existing = await getOne(
|
const existing = await getOne(
|
||||||
'SELECT id FROM calendar_events WHERE google_event_id = ? AND user_id = ?',
|
'SELECT id FROM calendar_events WHERE google_event_id = $1 AND user_id = $2',
|
||||||
[event.id, req.user.id]
|
[event.id, req.user.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -420,9 +420,9 @@ router.post('/sync', authenticateToken, async (req, res) => {
|
|||||||
// Mettre à jour l'événement existant
|
// Mettre à jour l'événement existant
|
||||||
await runQuery(`
|
await runQuery(`
|
||||||
UPDATE calendar_events
|
UPDATE calendar_events
|
||||||
SET title = ?, description = ?, start_time = ?, end_time = ?,
|
SET title = $1, description = $2, start_time = $3, end_time = $4,
|
||||||
location = ?, html_link = ?, all_day = ?, synced_at = CURRENT_TIMESTAMP
|
location = $5, html_link = $6, all_day = $7, synced_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = ?
|
WHERE id = $8
|
||||||
`, [
|
`, [
|
||||||
event.summary || 'Sans titre',
|
event.summary || 'Sans titre',
|
||||||
event.description || '',
|
event.description || '',
|
||||||
@@ -438,7 +438,7 @@ router.post('/sync', authenticateToken, async (req, res) => {
|
|||||||
await runQuery(`
|
await runQuery(`
|
||||||
INSERT INTO calendar_events
|
INSERT INTO calendar_events
|
||||||
(google_event_id, user_id, title, description, start_time, end_time, location, html_link, all_day)
|
(google_event_id, user_id, title, description, start_time, end_time, location, html_link, all_day)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
`, [
|
`, [
|
||||||
event.id,
|
event.id,
|
||||||
req.user.id,
|
req.user.id,
|
||||||
@@ -485,7 +485,7 @@ router.post('/sync', authenticateToken, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.post('/disconnect', authenticateToken, async (req, res) => {
|
router.post('/disconnect', authenticateToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await runQuery('DELETE FROM google_oauth_tokens WHERE user_id = ?', [req.user.id]);
|
await runQuery('DELETE FROM google_oauth_tokens WHERE user_id = $1', [req.user.id]);
|
||||||
logger.info(`Tokens OAuth supprimés pour l'utilisateur ${req.user.username}`);
|
logger.info(`Tokens OAuth supprimés pour l'utilisateur ${req.user.username}`);
|
||||||
|
|
||||||
res.json({ message: 'Déconnecté avec succès' });
|
res.json({ message: 'Déconnecté avec succès' });
|
||||||
@@ -553,7 +553,7 @@ router.post('/events', authenticateToken, async (req, res) => {
|
|||||||
const response = await calendar.events.insert({
|
const response = await calendar.events.insert({
|
||||||
calendarId: calendarId,
|
calendarId: calendarId,
|
||||||
resource: event,
|
resource: event,
|
||||||
sendUpdates: attendees && attendees.length > 0 ? 'all' : 'none'
|
sendUpdates: attendees && attendees.length > 0 $1 'all' : 'none'
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info(`Événement créé: ${response.data.id} pour l'utilisateur ${req.user.username}`);
|
logger.info(`Événement créé: ${response.data.id} pour l'utilisateur ${req.user.username}`);
|
||||||
@@ -626,7 +626,7 @@ router.put('/events/:id', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Récupérer l'événement existant depuis la DB
|
// Récupérer l'événement existant depuis la DB
|
||||||
const dbEvent = await getOne(
|
const dbEvent = await getOne(
|
||||||
'SELECT google_event_id FROM calendar_events WHERE id = ? AND user_id = ?',
|
'SELECT google_event_id FROM calendar_events WHERE id = $1 AND user_id = $2',
|
||||||
[req.params.id, req.user.id]
|
[req.params.id, req.user.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -674,7 +674,7 @@ router.put('/events/:id', authenticateToken, async (req, res) => {
|
|||||||
calendarId: calendarId,
|
calendarId: calendarId,
|
||||||
eventId: dbEvent.google_event_id,
|
eventId: dbEvent.google_event_id,
|
||||||
resource: event,
|
resource: event,
|
||||||
sendUpdates: attendees && attendees.length > 0 ? 'all' : 'none'
|
sendUpdates: attendees && attendees.length > 0 $1 'all' : 'none'
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info(`Événement mis à jour: ${response.data.id} pour l'utilisateur ${req.user.username}`);
|
logger.info(`Événement mis à jour: ${response.data.id} pour l'utilisateur ${req.user.username}`);
|
||||||
@@ -683,9 +683,9 @@ router.put('/events/:id', authenticateToken, async (req, res) => {
|
|||||||
const isAllDay = !startDateTime.includes('T') && !endDateTime.includes('T');
|
const isAllDay = !startDateTime.includes('T') && !endDateTime.includes('T');
|
||||||
await runQuery(`
|
await runQuery(`
|
||||||
UPDATE calendar_events
|
UPDATE calendar_events
|
||||||
SET title = ?, description = ?, start_time = ?, end_time = ?,
|
SET title = $1, description = $2, start_time = $3, end_time = $4,
|
||||||
location = ?, html_link = ?, all_day = ?, synced_at = CURRENT_TIMESTAMP
|
location = $5, html_link = $6, all_day = $7, synced_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = ?
|
WHERE id = $8
|
||||||
`, [
|
`, [
|
||||||
title,
|
title,
|
||||||
description || null,
|
description || null,
|
||||||
@@ -719,7 +719,7 @@ router.put('/events/:id', authenticateToken, async (req, res) => {
|
|||||||
router.delete('/events/:id', authenticateToken, async (req, res) => {
|
router.delete('/events/:id', authenticateToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const event = await getOne(
|
const event = await getOne(
|
||||||
'SELECT id FROM calendar_events WHERE id = ? AND user_id = ?',
|
'SELECT id FROM calendar_events WHERE id = $1 AND user_id = $2',
|
||||||
[req.params.id, req.user.id]
|
[req.params.id, req.user.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -727,7 +727,7 @@ router.delete('/events/:id', authenticateToken, async (req, res) => {
|
|||||||
return res.status(404).json({ error: 'Événement non trouvé' });
|
return res.status(404).json({ error: 'Événement non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('DELETE FROM calendar_events WHERE id = ?', [req.params.id]);
|
await runQuery('DELETE FROM calendar_events WHERE id = $1', [req.params.id]);
|
||||||
|
|
||||||
logger.info(`Événement ${req.params.id} supprimé`);
|
logger.info(`Événement ${req.params.id} supprimé`);
|
||||||
|
|
||||||
|
|||||||
+54
-54
@@ -52,9 +52,9 @@ router.get('/', async (req, res) => {
|
|||||||
n.id, n.title, n.content, n.image_filename, n.archived, n.priority,
|
n.id, n.title, n.content, n.image_filename, n.archived, n.priority,
|
||||||
n.created_at, n.updated_at,
|
n.created_at, n.updated_at,
|
||||||
(SELECT COUNT(*) FROM note_todos WHERE note_id = n.id) as todos_count,
|
(SELECT COUNT(*) FROM note_todos WHERE note_id = n.id) as todos_count,
|
||||||
(SELECT COUNT(*) FROM note_todos WHERE note_id = n.id AND completed = 1) as todos_completed
|
(SELECT COUNT(*) FROM note_todos WHERE note_id = n.id AND completed = TRUE) as todos_completed
|
||||||
FROM notes n
|
FROM notes n
|
||||||
WHERE n.user_id = ? AND n.archived = ?
|
WHERE n.user_id = $1 AND n.archived = $2
|
||||||
ORDER BY n.priority DESC, n.updated_at DESC
|
ORDER BY n.priority DESC, n.updated_at DESC
|
||||||
`, [req.user.id, archivedFilter]);
|
`, [req.user.id, archivedFilter]);
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ router.get('/', async (req, res) => {
|
|||||||
const todos = await getAll(`
|
const todos = await getAll(`
|
||||||
SELECT id, text, completed, position
|
SELECT id, text, completed, position
|
||||||
FROM note_todos
|
FROM note_todos
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY position ASC, id ASC
|
ORDER BY position ASC, id ASC
|
||||||
`, [note.id]);
|
`, [note.id]);
|
||||||
note.todos = todos || [];
|
note.todos = todos || [];
|
||||||
@@ -71,7 +71,7 @@ router.get('/', async (req, res) => {
|
|||||||
const images = await getAll(`
|
const images = await getAll(`
|
||||||
SELECT id, filename, original_name, created_at
|
SELECT id, filename, original_name, created_at
|
||||||
FROM note_images
|
FROM note_images
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [note.id]);
|
`, [note.id]);
|
||||||
note.images = images || [];
|
note.images = images || [];
|
||||||
@@ -79,7 +79,7 @@ router.get('/', async (req, res) => {
|
|||||||
const files = await getAll(`
|
const files = await getAll(`
|
||||||
SELECT id, filename, original_name, file_size, mime_type, created_at
|
SELECT id, filename, original_name, file_size, mime_type, created_at
|
||||||
FROM note_files
|
FROM note_files
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [note.id]);
|
`, [note.id]);
|
||||||
note.files = files || [];
|
note.files = files || [];
|
||||||
@@ -88,7 +88,7 @@ router.get('/', async (req, res) => {
|
|||||||
const tags = await getAll(`
|
const tags = await getAll(`
|
||||||
SELECT id, tag as name
|
SELECT id, tag as name
|
||||||
FROM note_tags
|
FROM note_tags
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY tag ASC
|
ORDER BY tag ASC
|
||||||
`, [note.id]);
|
`, [note.id]);
|
||||||
note.tags = tags || [];
|
note.tags = tags || [];
|
||||||
@@ -110,7 +110,7 @@ router.get('/:id', async (req, res) => {
|
|||||||
const note = await getOne(`
|
const note = await getOne(`
|
||||||
SELECT id, title, content, image_filename, created_at, updated_at
|
SELECT id, title, content, image_filename, created_at, updated_at
|
||||||
FROM notes
|
FROM notes
|
||||||
WHERE id = ? AND user_id = ?
|
WHERE id = $1 AND user_id = $2
|
||||||
`, [req.params.id, req.user.id]);
|
`, [req.params.id, req.user.id]);
|
||||||
|
|
||||||
if (!note) {
|
if (!note) {
|
||||||
@@ -121,7 +121,7 @@ router.get('/:id', async (req, res) => {
|
|||||||
const todos = await getAll(`
|
const todos = await getAll(`
|
||||||
SELECT id, text, completed, position
|
SELECT id, text, completed, position
|
||||||
FROM note_todos
|
FROM note_todos
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY position, id
|
ORDER BY position, id
|
||||||
`, [req.params.id]);
|
`, [req.params.id]);
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ router.get('/:id', async (req, res) => {
|
|||||||
const images = await getAll(`
|
const images = await getAll(`
|
||||||
SELECT id, filename, original_name, created_at
|
SELECT id, filename, original_name, created_at
|
||||||
FROM note_images
|
FROM note_images
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [req.params.id]);
|
`, [req.params.id]);
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ router.get('/:id', async (req, res) => {
|
|||||||
const files = await getAll(`
|
const files = await getAll(`
|
||||||
SELECT id, filename, original_name, file_size, mime_type, created_at
|
SELECT id, filename, original_name, file_size, mime_type, created_at
|
||||||
FROM note_files
|
FROM note_files
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [req.params.id]);
|
`, [req.params.id]);
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ router.post('/',
|
|||||||
|
|
||||||
const result = await runQuery(`
|
const result = await runQuery(`
|
||||||
INSERT INTO notes (user_id, title, content)
|
INSERT INTO notes (user_id, title, content)
|
||||||
VALUES (?, ?, ?)
|
VALUES ($1, $2, $3)
|
||||||
`, [req.user.id, title, content || '']);
|
`, [req.user.id, title, content || '']);
|
||||||
|
|
||||||
logger.info(`Note créée: ${title} (ID: ${result.id}) par ${req.user.username}`);
|
logger.info(`Note créée: ${title} (ID: ${result.id}) par ${req.user.username}`);
|
||||||
@@ -207,7 +207,7 @@ router.put('/:id',
|
|||||||
const { title, content } = req.body;
|
const { title, content } = req.body;
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -248,13 +248,13 @@ router.put('/:id/archive', async (req, res) => {
|
|||||||
const { archived } = req.body;
|
const { archived } = req.body;
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE notes SET archived = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
'UPDATE notes SET archived = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
|
||||||
[archived ? 1 : 0, req.params.id]
|
[archived ? 1 : 0, req.params.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ router.put('/:id/archive', async (req, res) => {
|
|||||||
router.delete('/:id', async (req, res) => {
|
router.delete('/:id', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ router.delete('/:id', async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('DELETE FROM notes WHERE id = ?', [req.params.id]);
|
await runQuery('DELETE FROM notes WHERE id = $1', [req.params.id]);
|
||||||
|
|
||||||
logger.info(`Note supprimée (ID: ${req.params.id}) par ${req.user.username}`);
|
logger.info(`Note supprimée (ID: ${req.params.id}) par ${req.user.username}`);
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ router.post('/:id/image', upload.single('image'), async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
// Supprimer le fichier uploadé
|
// Supprimer le fichier uploadé
|
||||||
fs.unlinkSync(req.file.path);
|
fs.unlinkSync(req.file.path);
|
||||||
@@ -324,7 +324,7 @@ router.post('/:id/image', upload.single('image'), async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mettre à jour la note avec le nouveau fichier
|
// Mettre à jour la note avec le nouveau fichier
|
||||||
await runQuery('UPDATE notes SET image_filename = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.file.filename, req.params.id]);
|
await runQuery('UPDATE notes SET image_filename = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2', [req.file.filename, req.params.id]);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
message: 'Image ajoutée avec succès',
|
message: 'Image ajoutée avec succès',
|
||||||
@@ -346,7 +346,7 @@ router.post('/:id/image', upload.single('image'), async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.delete('/:id/image', async (req, res) => {
|
router.delete('/:id/image', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id, image_filename FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -361,7 +361,7 @@ router.delete('/:id/image', async (req, res) => {
|
|||||||
fs.unlinkSync(imagePath);
|
fs.unlinkSync(imagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('UPDATE notes SET image_filename = NULL, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.params.id]);
|
await runQuery('UPDATE notes SET image_filename = NULL, updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.id]);
|
||||||
|
|
||||||
res.json({ message: 'Image supprimée avec succès' });
|
res.json({ message: 'Image supprimée avec succès' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -384,7 +384,7 @@ router.post('/:id/todos',
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -393,10 +393,10 @@ router.post('/:id/todos',
|
|||||||
|
|
||||||
const result = await runQuery(`
|
const result = await runQuery(`
|
||||||
INSERT INTO note_todos (note_id, text, position)
|
INSERT INTO note_todos (note_id, text, position)
|
||||||
VALUES (?, ?, (SELECT COALESCE(MAX(position), 0) + 1 FROM note_todos WHERE note_id = ?))
|
VALUES ($1, $2, (SELECT COALESCE(MAX(position), FALSE) + 1 FROM note_todos WHERE note_id = $3))
|
||||||
`, [req.params.id, text, req.params.id]);
|
`, [req.params.id, text, req.params.id]);
|
||||||
|
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.params.id]);
|
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.id]);
|
||||||
|
|
||||||
res.status(201).json({
|
res.status(201).json({
|
||||||
id: result.id,
|
id: result.id,
|
||||||
@@ -430,7 +430,7 @@ router.put('/todos/:todoId',
|
|||||||
SELECT nt.id, nt.note_id
|
SELECT nt.id, nt.note_id
|
||||||
FROM note_todos nt
|
FROM note_todos nt
|
||||||
JOIN notes n ON nt.note_id = n.id
|
JOIN notes n ON nt.note_id = n.id
|
||||||
WHERE nt.id = ? AND n.user_id = ?
|
WHERE nt.id = $1 AND n.user_id = $2
|
||||||
`, [req.params.todoId, req.user.id]);
|
`, [req.params.todoId, req.user.id]);
|
||||||
|
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
@@ -456,7 +456,7 @@ router.put('/todos/:todoId',
|
|||||||
if (updates.length > 0) {
|
if (updates.length > 0) {
|
||||||
params.push(req.params.todoId);
|
params.push(req.params.todoId);
|
||||||
await runQuery(`UPDATE note_todos SET ${updates.join(', ')} WHERE id = ?`, params);
|
await runQuery(`UPDATE note_todos SET ${updates.join(', ')} WHERE id = ?`, params);
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [todo.note_id]);
|
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [todo.note_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ message: 'Todo modifié avec succès' });
|
res.json({ message: 'Todo modifié avec succès' });
|
||||||
@@ -478,15 +478,15 @@ router.delete('/todos/:todoId', async (req, res) => {
|
|||||||
SELECT nt.id, nt.note_id
|
SELECT nt.id, nt.note_id
|
||||||
FROM note_todos nt
|
FROM note_todos nt
|
||||||
JOIN notes n ON nt.note_id = n.id
|
JOIN notes n ON nt.note_id = n.id
|
||||||
WHERE nt.id = ? AND n.user_id = ?
|
WHERE nt.id = $1 AND n.user_id = $2
|
||||||
`, [req.params.todoId, req.user.id]);
|
`, [req.params.todoId, req.user.id]);
|
||||||
|
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
return res.status(404).json({ error: 'Todo non trouvé' });
|
return res.status(404).json({ error: 'Todo non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('DELETE FROM note_todos WHERE id = ?', [req.params.todoId]);
|
await runQuery('DELETE FROM note_todos WHERE id = $1', [req.params.todoId]);
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [todo.note_id]);
|
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [todo.note_id]);
|
||||||
|
|
||||||
res.json({ message: 'Todo supprimé avec succès' });
|
res.json({ message: 'Todo supprimé avec succès' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -511,7 +511,7 @@ const searchNotes = async (req, res) => {
|
|||||||
const notes = await getAll(`
|
const notes = await getAll(`
|
||||||
SELECT id, title, content, image_filename, created_at, updated_at
|
SELECT id, title, content, image_filename, created_at, updated_at
|
||||||
FROM notes
|
FROM notes
|
||||||
WHERE user_id = ? AND (title LIKE ? OR content LIKE ?)
|
WHERE user_id = $1 AND (title LIKE $2 OR content LIKE $3)
|
||||||
ORDER BY updated_at DESC
|
ORDER BY updated_at DESC
|
||||||
LIMIT 50
|
LIMIT 50
|
||||||
`, [req.user.id, searchTerm, searchTerm]);
|
`, [req.user.id, searchTerm, searchTerm]);
|
||||||
@@ -565,7 +565,7 @@ router.post('/:id/images', imageUpload.single('image'), async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
// Supprimer le fichier uploadé
|
// Supprimer le fichier uploadé
|
||||||
fs.unlinkSync(req.file.path);
|
fs.unlinkSync(req.file.path);
|
||||||
@@ -575,11 +575,11 @@ router.post('/:id/images', imageUpload.single('image'), async (req, res) => {
|
|||||||
// Enregistrer l'image dans la base de données
|
// Enregistrer l'image dans la base de données
|
||||||
const result = await runQuery(`
|
const result = await runQuery(`
|
||||||
INSERT INTO note_images (note_id, filename, original_name)
|
INSERT INTO note_images (note_id, filename, original_name)
|
||||||
VALUES (?, ?, ?)
|
VALUES ($1, $2, $3)
|
||||||
`, [req.params.id, req.file.filename, req.file.originalname]);
|
`, [req.params.id, req.file.filename, req.file.originalname]);
|
||||||
|
|
||||||
// Mettre à jour la date de modification de la note
|
// Mettre à jour la date de modification de la note
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.params.id]);
|
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(`Image ajoutée à la note ${req.params.id}: ${req.file.filename}`);
|
||||||
|
|
||||||
@@ -607,7 +607,7 @@ router.post('/:id/images', imageUpload.single('image'), async (req, res) => {
|
|||||||
router.get('/:id/images', async (req, res) => {
|
router.get('/:id/images', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -615,7 +615,7 @@ router.get('/:id/images', async (req, res) => {
|
|||||||
const images = await getAll(`
|
const images = await getAll(`
|
||||||
SELECT id, filename, original_name, created_at
|
SELECT id, filename, original_name, created_at
|
||||||
FROM note_images
|
FROM note_images
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [req.params.id]);
|
`, [req.params.id]);
|
||||||
|
|
||||||
@@ -637,7 +637,7 @@ router.delete('/:noteId/images/:imageId', async (req, res) => {
|
|||||||
SELECT ni.id, ni.filename, ni.note_id
|
SELECT ni.id, ni.filename, ni.note_id
|
||||||
FROM note_images ni
|
FROM note_images ni
|
||||||
JOIN notes n ON ni.note_id = n.id
|
JOIN notes n ON ni.note_id = n.id
|
||||||
WHERE ni.id = ? AND ni.note_id = ? AND n.user_id = ?
|
WHERE ni.id = $1 AND ni.note_id = $2 AND n.user_id = $3
|
||||||
`, [req.params.imageId, req.params.noteId, req.user.id]);
|
`, [req.params.imageId, req.params.noteId, req.user.id]);
|
||||||
|
|
||||||
if (!image) {
|
if (!image) {
|
||||||
@@ -651,10 +651,10 @@ router.delete('/:noteId/images/:imageId', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Supprimer l'entrée de la base de données
|
// Supprimer l'entrée de la base de données
|
||||||
await runQuery('DELETE FROM note_images WHERE id = ?', [req.params.imageId]);
|
await runQuery('DELETE FROM note_images WHERE id = $1', [req.params.imageId]);
|
||||||
|
|
||||||
// Mettre à jour la date de modification de la note
|
// Mettre à jour la date de modification de la note
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.params.noteId]);
|
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [req.params.noteId]);
|
||||||
|
|
||||||
logger.info(`Image ${image.filename} supprimée de la note ${req.params.noteId}`);
|
logger.info(`Image ${image.filename} supprimée de la note ${req.params.noteId}`);
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ router.post('/:id/files', fileUpload.single('file'), async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
// Supprimer le fichier uploadé
|
// Supprimer le fichier uploadé
|
||||||
fs.unlinkSync(req.file.path);
|
fs.unlinkSync(req.file.path);
|
||||||
@@ -709,11 +709,11 @@ router.post('/:id/files', fileUpload.single('file'), async (req, res) => {
|
|||||||
// Enregistrer le fichier dans la base de données
|
// Enregistrer le fichier dans la base de données
|
||||||
const result = await runQuery(`
|
const result = await runQuery(`
|
||||||
INSERT INTO note_files (note_id, filename, original_name, file_size, mime_type)
|
INSERT INTO note_files (note_id, filename, original_name, file_size, mime_type)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
`, [req.params.id, req.file.filename, req.file.originalname, req.file.size, req.file.mimetype]);
|
`, [req.params.id, req.file.filename, req.file.originalname, req.file.size, req.file.mimetype]);
|
||||||
|
|
||||||
// Mettre à jour la date de modification de la note
|
// Mettre à jour la date de modification de la note
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [req.params.id]);
|
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(`Fichier ajouté à la note ${req.params.id}: ${req.file.originalname}`);
|
||||||
|
|
||||||
@@ -743,7 +743,7 @@ router.post('/:id/files', fileUpload.single('file'), async (req, res) => {
|
|||||||
router.get('/:id/files', async (req, res) => {
|
router.get('/:id/files', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
@@ -751,7 +751,7 @@ router.get('/:id/files', async (req, res) => {
|
|||||||
const files = await getAll(`
|
const files = await getAll(`
|
||||||
SELECT id, filename, original_name, file_size, mime_type, created_at
|
SELECT id, filename, original_name, file_size, mime_type, created_at
|
||||||
FROM note_files
|
FROM note_files
|
||||||
WHERE note_id = ?
|
WHERE note_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [req.params.id]);
|
`, [req.params.id]);
|
||||||
|
|
||||||
@@ -773,7 +773,7 @@ router.get('/files/:fileId/download', async (req, res) => {
|
|||||||
SELECT nf.id, nf.filename, nf.original_name, nf.mime_type
|
SELECT nf.id, nf.filename, nf.original_name, nf.mime_type
|
||||||
FROM note_files nf
|
FROM note_files nf
|
||||||
JOIN notes n ON nf.note_id = n.id
|
JOIN notes n ON nf.note_id = n.id
|
||||||
WHERE nf.id = ? AND n.user_id = ?
|
WHERE nf.id = $1 AND n.user_id = $2
|
||||||
`, [req.params.fileId, req.user.id]);
|
`, [req.params.fileId, req.user.id]);
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@@ -803,7 +803,7 @@ router.delete('/files/:fileId', async (req, res) => {
|
|||||||
SELECT nf.id, nf.note_id, nf.filename
|
SELECT nf.id, nf.note_id, nf.filename
|
||||||
FROM note_files nf
|
FROM note_files nf
|
||||||
JOIN notes n ON nf.note_id = n.id
|
JOIN notes n ON nf.note_id = n.id
|
||||||
WHERE nf.id = ? AND n.user_id = ?
|
WHERE nf.id = $1 AND n.user_id = $2
|
||||||
`, [req.params.fileId, req.user.id]);
|
`, [req.params.fileId, req.user.id]);
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@@ -817,10 +817,10 @@ router.delete('/files/:fileId', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Supprimer de la base de données
|
// Supprimer de la base de données
|
||||||
await runQuery('DELETE FROM note_files WHERE id = ?', [req.params.fileId]);
|
await runQuery('DELETE FROM note_files WHERE id = $1', [req.params.fileId]);
|
||||||
|
|
||||||
// Mettre à jour la date de modification de la note
|
// Mettre à jour la date de modification de la note
|
||||||
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [file.note_id]);
|
await runQuery('UPDATE notes SET updated_at = CURRENT_TIMESTAMP WHERE id = $1', [file.note_id]);
|
||||||
|
|
||||||
logger.info(`Fichier supprimé: ${file.filename}`);
|
logger.info(`Fichier supprimé: ${file.filename}`);
|
||||||
|
|
||||||
@@ -839,12 +839,12 @@ router.delete('/files/:fileId', async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.get('/:id/tags', async (req, res) => {
|
router.get('/:id/tags', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags = await getAll('SELECT id, tag FROM note_tags WHERE note_id = ? ORDER BY tag ASC', [req.params.id]);
|
const tags = await getAll('SELECT id, tag FROM note_tags WHERE note_id = $1 ORDER BY tag ASC', [req.params.id]);
|
||||||
res.json(tags || []);
|
res.json(tags || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Erreur lors de la récupération des tags:', error);
|
logger.error('Erreur lors de la récupération des tags:', error);
|
||||||
@@ -863,12 +863,12 @@ router.post('/:id/tags', async (req, res) => {
|
|||||||
return res.status(400).json({ error: 'Tag invalide' });
|
return res.status(400).json({ error: 'Tag invalide' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await runQuery('INSERT INTO note_tags (note_id, tag) VALUES (?, ?)', [req.params.id, tag.trim().toLowerCase()]);
|
const result = await runQuery('INSERT INTO note_tags (note_id, tag) VALUES ($1, $2)', [req.params.id, tag.trim().toLowerCase()]);
|
||||||
res.json({ id: result.id, tag: tag.trim().toLowerCase() });
|
res.json({ id: result.id, tag: tag.trim().toLowerCase() });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.message && error.message.includes('UNIQUE constraint')) {
|
if (error.message && error.message.includes('UNIQUE constraint')) {
|
||||||
@@ -888,14 +888,14 @@ router.delete('/:noteId/tags/:tagId', async (req, res) => {
|
|||||||
const tag = await getOne(`
|
const tag = await getOne(`
|
||||||
SELECT nt.id FROM note_tags nt
|
SELECT nt.id FROM note_tags nt
|
||||||
JOIN notes n ON nt.note_id = n.id
|
JOIN notes n ON nt.note_id = n.id
|
||||||
WHERE nt.id = ? AND nt.note_id = ? AND n.user_id = ?
|
WHERE nt.id = $1 AND nt.note_id = $2 AND n.user_id = $3
|
||||||
`, [req.params.tagId, req.params.noteId, req.user.id]);
|
`, [req.params.tagId, req.params.noteId, req.user.id]);
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
return res.status(404).json({ error: 'Tag non trouvé' });
|
return res.status(404).json({ error: 'Tag non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('DELETE FROM note_tags WHERE id = ?', [req.params.tagId]);
|
await runQuery('DELETE FROM note_tags WHERE id = $1', [req.params.tagId]);
|
||||||
res.json({ message: 'Tag supprimé' });
|
res.json({ message: 'Tag supprimé' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Erreur lors de la suppression du tag:', error);
|
logger.error('Erreur lors de la suppression du tag:', error);
|
||||||
@@ -912,12 +912,12 @@ router.patch('/:id/priority', async (req, res) => {
|
|||||||
const { priority } = req.body;
|
const { priority } = req.body;
|
||||||
|
|
||||||
// Vérifier que la note appartient à l'utilisateur
|
// Vérifier que la note appartient à l'utilisateur
|
||||||
const note = await getOne('SELECT id FROM notes WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const note = await getOne('SELECT id FROM notes WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!note) {
|
if (!note) {
|
||||||
return res.status(404).json({ error: 'Note non trouvée' });
|
return res.status(404).json({ error: 'Note non trouvée' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('UPDATE notes SET priority = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [priority ? 1 : 0, req.params.id]);
|
await runQuery('UPDATE notes SET priority = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2', [priority ? 1 : 0, req.params.id]);
|
||||||
|
|
||||||
logger.info(`Priorité de la note ${req.params.id} modifiée: ${priority}`);
|
logger.info(`Priorité de la note ${req.params.id} modifiée: ${priority}`);
|
||||||
res.json({ message: 'Priorité modifiée avec succès', priority });
|
res.json({ message: 'Priorité modifiée avec succès', priority });
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ router.get('/models', authenticateToken, async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer la clé API depuis les paramètres
|
// Récupérer la clé API depuis les paramètres
|
||||||
const setting = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_api_key']);
|
const setting = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_api_key']);
|
||||||
|
|
||||||
if (!setting || !setting.value) {
|
if (!setting || !setting.value) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
@@ -90,7 +90,7 @@ router.post('/refresh-models', authenticateToken, requireAdmin, async (req, res)
|
|||||||
modelsCacheTime = 0;
|
modelsCacheTime = 0;
|
||||||
|
|
||||||
// Rediriger vers la route GET pour récupérer les modèles
|
// Rediriger vers la route GET pour récupérer les modèles
|
||||||
const setting = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_api_key']);
|
const setting = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_api_key']);
|
||||||
|
|
||||||
if (!setting || !setting.value) {
|
if (!setting || !setting.value) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
@@ -150,7 +150,7 @@ router.post('/chat', authenticateToken, async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer la clé API
|
// Récupérer la clé API
|
||||||
const setting = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_api_key']);
|
const setting = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_api_key']);
|
||||||
|
|
||||||
if (!setting || !setting.value) {
|
if (!setting || !setting.value) {
|
||||||
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ router.post('/feeds', requireAdmin, async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si existe déjà
|
// Vérifier si existe déjà
|
||||||
const existing = await getOne('SELECT id FROM rss_feeds WHERE url = ?', [url]);
|
const existing = await getOne('SELECT id FROM rss_feeds WHERE url = $1', [url]);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
return res.status(409).json({ error: 'Ce flux existe déjà' });
|
return res.status(409).json({ error: 'Ce flux existe déjà' });
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ router.post('/feeds', requireAdmin, async (req, res) => {
|
|||||||
|
|
||||||
// Ajouter le flux
|
// Ajouter le flux
|
||||||
const result = await runQuery(
|
const result = await runQuery(
|
||||||
'INSERT INTO rss_feeds (url, title, description, enabled) VALUES (?, ?, ?, 1)',
|
'INSERT INTO rss_feeds (url, title, description, enabled) VALUES ($1, $2, $3, TRUE)',
|
||||||
[url, feed.title || url, feed.description || '']
|
[url, feed.title || url, feed.description || '']
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ router.put('/feeds/:id', requireAdmin, async (req, res) => {
|
|||||||
const { enabled } = req.body;
|
const { enabled } = req.body;
|
||||||
|
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE rss_feeds SET enabled = ? WHERE id = ?',
|
'UPDATE rss_feeds SET enabled = $1 WHERE id = $2',
|
||||||
[enabled ? 1 : 0, req.params.id]
|
[enabled ? 1 : 0, req.params.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ router.put('/feeds/:id', requireAdmin, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.delete('/feeds/:id', requireAdmin, async (req, res) => {
|
router.delete('/feeds/:id', requireAdmin, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await runQuery('DELETE FROM rss_feeds WHERE id = ?', [req.params.id]);
|
await runQuery('DELETE FROM rss_feeds WHERE id = $1', [req.params.id]);
|
||||||
logger.info(`Flux supprimé: ${req.params.id}`);
|
logger.info(`Flux supprimé: ${req.params.id}`);
|
||||||
res.json({ message: 'Flux supprimé' });
|
res.json({ message: 'Flux supprimé' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -136,7 +136,7 @@ router.get('/articles', async (req, res) => {
|
|||||||
LEFT JOIN rss_feeds f ON a.feed_id = f.id
|
LEFT JOIN rss_feeds f ON a.feed_id = f.id
|
||||||
WHERE a.pub_date IS NOT NULL
|
WHERE a.pub_date IS NOT NULL
|
||||||
ORDER BY a.pub_date DESC
|
ORDER BY a.pub_date DESC
|
||||||
LIMIT ?
|
LIMIT $1
|
||||||
`, [limit]);
|
`, [limit]);
|
||||||
|
|
||||||
logger.debug(`Articles récupérés: ${articles?.length || 0}`);
|
logger.debug(`Articles récupérés: ${articles?.length || 0}`);
|
||||||
@@ -194,8 +194,8 @@ router.post('/fetch', requireAdmin, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.post('/summarize', async (req, res) => {
|
router.post('/summarize', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const apiKey = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_api_key']);
|
const apiKey = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_api_key']);
|
||||||
const model = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_model']);
|
const model = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_model']);
|
||||||
|
|
||||||
if (!apiKey || !apiKey.value) {
|
if (!apiKey || !apiKey.value) {
|
||||||
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ router.post('/feeds', requireAdmin, async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si existe déjà
|
// Vérifier si existe déjà
|
||||||
const existing = await getOne('SELECT id FROM rss_feeds WHERE url = ?', [url]);
|
const existing = await getOne('SELECT id FROM rss_feeds WHERE url = $1', [url]);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
return res.status(409).json({ error: 'Ce flux existe déjà' });
|
return res.status(409).json({ error: 'Ce flux existe déjà' });
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ router.post('/feeds', requireAdmin, async (req, res) => {
|
|||||||
|
|
||||||
// Ajouter le flux
|
// Ajouter le flux
|
||||||
const result = await runQuery(
|
const result = await runQuery(
|
||||||
'INSERT INTO rss_feeds (url, title, description, enabled) VALUES (?, ?, ?, 1)',
|
'INSERT INTO rss_feeds (url, title, description, enabled) VALUES ($1, $2, $3, TRUE)',
|
||||||
[url, feed.title || url, feed.description || '']
|
[url, feed.title || url, feed.description || '']
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ router.put('/feeds/:id', requireAdmin, async (req, res) => {
|
|||||||
const { enabled } = req.body;
|
const { enabled } = req.body;
|
||||||
|
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE rss_feeds SET enabled = ? WHERE id = ?',
|
'UPDATE rss_feeds SET enabled = $1 WHERE id = $2',
|
||||||
[enabled ? 1 : 0, req.params.id]
|
[enabled ? 1 : 0, req.params.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ router.put('/feeds/:id', requireAdmin, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.delete('/feeds/:id', requireAdmin, async (req, res) => {
|
router.delete('/feeds/:id', requireAdmin, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await runQuery('DELETE FROM rss_feeds WHERE id = ?', [req.params.id]);
|
await runQuery('DELETE FROM rss_feeds WHERE id = $1', [req.params.id]);
|
||||||
logger.info(`Flux supprimé: ${req.params.id}`);
|
logger.info(`Flux supprimé: ${req.params.id}`);
|
||||||
res.json({ message: 'Flux supprimé' });
|
res.json({ message: 'Flux supprimé' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -136,7 +136,7 @@ router.get('/articles', async (req, res) => {
|
|||||||
LEFT JOIN rss_feeds f ON a.feed_id = f.id
|
LEFT JOIN rss_feeds f ON a.feed_id = f.id
|
||||||
WHERE a.pub_date IS NOT NULL
|
WHERE a.pub_date IS NOT NULL
|
||||||
ORDER BY a.pub_date DESC
|
ORDER BY a.pub_date DESC
|
||||||
LIMIT ?
|
LIMIT $1
|
||||||
`, [limit]);
|
`, [limit]);
|
||||||
|
|
||||||
logger.debug(`Articles récupérés: ${articles?.length || 0}`);
|
logger.debug(`Articles récupérés: ${articles?.length || 0}`);
|
||||||
@@ -194,8 +194,8 @@ router.post('/fetch', requireAdmin, async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.post('/summarize', async (req, res) => {
|
router.post('/summarize', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const apiKey = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_api_key']);
|
const apiKey = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_api_key']);
|
||||||
const model = await getOne('SELECT value FROM settings WHERE key = ?', ['openrouter_model']);
|
const model = await getOne('SELECT value FROM settings WHERE key = $1', ['openrouter_model']);
|
||||||
|
|
||||||
if (!apiKey || !apiKey.value) {
|
if (!apiKey || !apiKey.value) {
|
||||||
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
return res.status(400).json({ error: 'Clé API OpenRouter non configurée' });
|
||||||
|
|||||||
@@ -44,16 +44,16 @@ router.put('/', async (req, res) => {
|
|||||||
if (value === undefined || value === null) continue;
|
if (value === undefined || value === null) continue;
|
||||||
|
|
||||||
// Vérifier si le paramètre existe
|
// Vérifier si le paramètre existe
|
||||||
const existing = await getOne('SELECT id FROM settings WHERE key = ?', [key]);
|
const existing = await getOne('SELECT id FROM settings WHERE key = $1', [key]);
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?',
|
'UPDATE settings SET value = $1, updated_at = CURRENT_TIMESTAMP WHERE key = $2',
|
||||||
[value, key]
|
[value, key]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'INSERT INTO settings (key, value) VALUES (?, ?)',
|
'INSERT INTO settings (key, value) VALUES ($1, $2)',
|
||||||
[key, value]
|
[key, value]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ router.put('/', async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.get('/:key', async (req, res) => {
|
router.get('/:key', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const setting = await getOne('SELECT value FROM settings WHERE key = ?', [req.params.key]);
|
const setting = await getOne('SELECT value FROM settings WHERE key = $1', [req.params.key]);
|
||||||
|
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
return res.status(404).json({ error: 'Paramètre non trouvé' });
|
return res.status(404).json({ error: 'Paramètre non trouvé' });
|
||||||
@@ -95,16 +95,16 @@ router.put('/:key', async (req, res) => {
|
|||||||
const { value } = req.body;
|
const { value } = req.body;
|
||||||
|
|
||||||
// Vérifier si le paramètre existe
|
// Vérifier si le paramètre existe
|
||||||
const existing = await getOne('SELECT id FROM settings WHERE key = ?', [req.params.key]);
|
const existing = await getOne('SELECT id FROM settings WHERE key = $1', [req.params.key]);
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?',
|
'UPDATE settings SET value = $1, updated_at = CURRENT_TIMESTAMP WHERE key = $2',
|
||||||
[value, req.params.key]
|
[value, req.params.key]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'INSERT INTO settings (key, value) VALUES (?, ?)',
|
'INSERT INTO settings (key, value) VALUES ($1, $2)',
|
||||||
[req.params.key, value]
|
[req.params.key, value]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ router.put('/:key', async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
router.delete('/:key', async (req, res) => {
|
router.delete('/:key', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await runQuery('DELETE FROM settings WHERE key = ?', [req.params.key]);
|
await runQuery('DELETE FROM settings WHERE key = $1', [req.params.key]);
|
||||||
|
|
||||||
logger.info(`Paramètre supprimé: ${req.params.key}`);
|
logger.info(`Paramètre supprimé: ${req.params.key}`);
|
||||||
res.json({ message: 'Paramètre supprimé avec succès' });
|
res.json({ message: 'Paramètre supprimé avec succès' });
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ router.get('/', async (req, res) => {
|
|||||||
const todos = await getAll(`
|
const todos = await getAll(`
|
||||||
SELECT id, text, completed, created_at
|
SELECT id, text, completed, created_at
|
||||||
FROM global_todos
|
FROM global_todos
|
||||||
WHERE user_id = ?
|
WHERE user_id = $1
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
`, [req.user.id]);
|
`, [req.user.id]);
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ router.post('/',
|
|||||||
|
|
||||||
const result = await runQuery(`
|
const result = await runQuery(`
|
||||||
INSERT INTO global_todos (user_id, text)
|
INSERT INTO global_todos (user_id, text)
|
||||||
VALUES (?, ?)
|
VALUES ($1, $2)
|
||||||
`, [req.user.id, text]);
|
`, [req.user.id, text]);
|
||||||
|
|
||||||
logger.info(`Todo global créé (ID: ${result.id}) par ${req.user.username}`);
|
logger.info(`Todo global créé (ID: ${result.id}) par ${req.user.username}`);
|
||||||
@@ -84,7 +84,7 @@ router.put('/:id',
|
|||||||
const { text, completed } = req.body;
|
const { text, completed } = req.body;
|
||||||
|
|
||||||
// Vérifier que le todo appartient à l'utilisateur
|
// Vérifier que le todo appartient à l'utilisateur
|
||||||
const todo = await getOne('SELECT id FROM global_todos WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const todo = await getOne('SELECT id FROM global_todos WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
return res.status(404).json({ error: 'Todo non trouvé' });
|
return res.status(404).json({ error: 'Todo non trouvé' });
|
||||||
}
|
}
|
||||||
@@ -121,13 +121,13 @@ router.put('/:id',
|
|||||||
router.patch('/:id/toggle', async (req, res) => {
|
router.patch('/:id/toggle', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Vérifier que le todo appartient à l'utilisateur
|
// Vérifier que le todo appartient à l'utilisateur
|
||||||
const todo = await getOne('SELECT id, completed FROM global_todos WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const todo = await getOne('SELECT id, completed FROM global_todos WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
return res.status(404).json({ error: 'Todo non trouvé' });
|
return res.status(404).json({ error: 'Todo non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const newCompleted = todo.completed ? 0 : 1;
|
const newCompleted = todo.completed ? 0 : 1;
|
||||||
await runQuery('UPDATE global_todos SET completed = ? WHERE id = ?', [newCompleted, req.params.id]);
|
await runQuery('UPDATE global_todos SET completed = $1 WHERE id = $2', [newCompleted, req.params.id]);
|
||||||
|
|
||||||
logger.info(`Todo global ${newCompleted ? 'complété' : 'réouvert'} (ID: ${req.params.id}) par ${req.user.username}`);
|
logger.info(`Todo global ${newCompleted ? 'complété' : 'réouvert'} (ID: ${req.params.id}) par ${req.user.username}`);
|
||||||
|
|
||||||
@@ -145,12 +145,12 @@ router.patch('/:id/toggle', async (req, res) => {
|
|||||||
router.delete('/:id', async (req, res) => {
|
router.delete('/:id', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Vérifier que le todo appartient à l'utilisateur
|
// Vérifier que le todo appartient à l'utilisateur
|
||||||
const todo = await getOne('SELECT id FROM global_todos WHERE id = ? AND user_id = ?', [req.params.id, req.user.id]);
|
const todo = await getOne('SELECT id FROM global_todos WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]);
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
return res.status(404).json({ error: 'Todo non trouvé' });
|
return res.status(404).json({ error: 'Todo non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await runQuery('DELETE FROM global_todos WHERE id = ?', [req.params.id]);
|
await runQuery('DELETE FROM global_todos WHERE id = $1', [req.params.id]);
|
||||||
|
|
||||||
logger.info(`Todo global supprimé (ID: ${req.params.id}) par ${req.user.username}`);
|
logger.info(`Todo global supprimé (ID: ${req.params.id}) par ${req.user.username}`);
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ router.post('/',
|
|||||||
const { username, password, is_admin } = req.body;
|
const { username, password, is_admin } = req.body;
|
||||||
|
|
||||||
// Vérifier si l'utilisateur existe déjà
|
// Vérifier si l'utilisateur existe déjà
|
||||||
const existingUser = await getOne('SELECT id FROM users WHERE username = ?', [username]);
|
const existingUser = await getOne('SELECT id FROM users WHERE username = $1', [username]);
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
return res.status(400).json({ error: 'Ce nom d\'utilisateur existe déjà' });
|
return res.status(400).json({ error: 'Ce nom d\'utilisateur existe déjà' });
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ router.post('/',
|
|||||||
|
|
||||||
// Créer l'utilisateur
|
// Créer l'utilisateur
|
||||||
const result = await runQuery(
|
const result = await runQuery(
|
||||||
'INSERT INTO users (username, password_hash, is_admin) VALUES (?, ?, ?)',
|
'INSERT INTO users (username, password_hash, is_admin) VALUES ($1, $2, $3)',
|
||||||
[username, passwordHash, is_admin ? 1 : 0]
|
[username, passwordHash, is_admin ? 1 : 0]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ router.put('/:id',
|
|||||||
const { password, is_admin } = req.body;
|
const { password, is_admin } = req.body;
|
||||||
|
|
||||||
// Vérifier que l'utilisateur existe
|
// Vérifier que l'utilisateur existe
|
||||||
const user = await getOne('SELECT id, username FROM users WHERE id = ?', [userId]);
|
const user = await getOne('SELECT id, username FROM users WHERE id = $1', [userId]);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(404).json({ error: 'Utilisateur non trouvé' });
|
return res.status(404).json({ error: 'Utilisateur non trouvé' });
|
||||||
}
|
}
|
||||||
@@ -104,12 +104,12 @@ router.put('/:id',
|
|||||||
// Mettre à jour le mot de passe si fourni
|
// Mettre à jour le mot de passe si fourni
|
||||||
if (password) {
|
if (password) {
|
||||||
const passwordHash = await bcrypt.hash(password, 12);
|
const passwordHash = await bcrypt.hash(password, 12);
|
||||||
await runQuery('UPDATE users SET password_hash = ? WHERE id = ?', [passwordHash, userId]);
|
await runQuery('UPDATE users SET password_hash = $1 WHERE id = $2', [passwordHash, userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mettre à jour le statut admin si fourni
|
// Mettre à jour le statut admin si fourni
|
||||||
if (typeof is_admin !== 'undefined') {
|
if (typeof is_admin !== 'undefined') {
|
||||||
await runQuery('UPDATE users SET is_admin = ? WHERE id = ?', [is_admin ? 1 : 0, userId]);
|
await runQuery('UPDATE users SET is_admin = $1 WHERE id = $2', [is_admin ? 1 : 0, userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Utilisateur modifié: ${user.username} (ID: ${userId})`);
|
logger.info(`Utilisateur modifié: ${user.username} (ID: ${userId})`);
|
||||||
@@ -136,13 +136,13 @@ router.delete('/:id', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier que l'utilisateur existe
|
// Vérifier que l'utilisateur existe
|
||||||
const user = await getOne('SELECT id, username FROM users WHERE id = ?', [userId]);
|
const user = await getOne('SELECT id, username FROM users WHERE id = $1', [userId]);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(404).json({ error: 'Utilisateur non trouvé' });
|
return res.status(404).json({ error: 'Utilisateur non trouvé' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supprimer l'utilisateur (les notes et todos seront supprimés en cascade)
|
// Supprimer l'utilisateur (les notes et todos seront supprimés en cascade)
|
||||||
await runQuery('DELETE FROM users WHERE id = ?', [userId]);
|
await runQuery('DELETE FROM users WHERE id = $1', [userId]);
|
||||||
|
|
||||||
logger.info(`Utilisateur supprimé: ${user.username} (ID: ${userId})`);
|
logger.info(`Utilisateur supprimé: ${user.username} (ID: ${userId})`);
|
||||||
|
|
||||||
|
|||||||
Executable
+101
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Script de conversion SQLite → PostgreSQL pour les requêtes SQL
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
console.log('🔄 Conversion des requêtes SQLite → PostgreSQL\n');
|
||||||
|
|
||||||
|
// Fichiers à convertir
|
||||||
|
const files = [
|
||||||
|
'routes/auth.routes.js',
|
||||||
|
'routes/calendar.routes.js',
|
||||||
|
'routes/notes.routes.js',
|
||||||
|
'routes/openrouter.routes.js',
|
||||||
|
'routes/rss.routes.js',
|
||||||
|
'routes/rss.routes-v2.js',
|
||||||
|
'routes/settings.routes.js',
|
||||||
|
'routes/todos.routes.js',
|
||||||
|
'routes/users.routes.js',
|
||||||
|
'services/rss-scheduler.js',
|
||||||
|
'services/rss-scheduler-v2.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
let totalChanges = 0;
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const filePath = path.join(__dirname, '..', file);
|
||||||
|
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
console.log(`⏭️ ${file} n'existe pas, skip`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = fs.readFileSync(filePath, 'utf8');
|
||||||
|
let changes = 0;
|
||||||
|
|
||||||
|
// 1. Convertir les paramètres ? vers $1, $2, $3...
|
||||||
|
// Chercher toutes les requêtes SQL entre quotes
|
||||||
|
content = content.replace(/(["'`])([^"'`]*?\bWHERE\b[^"'`]*?)(\1)/gi, (match, quote, sql, endQuote) => {
|
||||||
|
let newSql = sql;
|
||||||
|
let paramCount = 0;
|
||||||
|
|
||||||
|
// Remplacer chaque ? par $N
|
||||||
|
newSql = newSql.replace(/\?/g, () => {
|
||||||
|
paramCount++;
|
||||||
|
return `$${paramCount}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (paramCount > 0) {
|
||||||
|
changes += paramCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quote + newSql + endQuote;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Gérer aussi les requêtes INSERT, UPDATE, DELETE
|
||||||
|
content = content.replace(/(["'`])([^"'`]*?\b(?:INSERT|UPDATE|DELETE|SELECT)\b[^"'`]*?)(\1)/gi, (match, quote, sql, endQuote) => {
|
||||||
|
if (sql.includes('$')) return match; // Déjà converti
|
||||||
|
|
||||||
|
let newSql = sql;
|
||||||
|
let paramCount = 0;
|
||||||
|
|
||||||
|
// Remplacer chaque ? par $N
|
||||||
|
newSql = newSql.replace(/\?/g, () => {
|
||||||
|
paramCount++;
|
||||||
|
return `$${paramCount}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (paramCount > 0) {
|
||||||
|
changes += paramCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quote + newSql + endQuote;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. Convertir les booléens 0/1 vers TRUE/FALSE
|
||||||
|
// enabled = 1 → enabled = TRUE
|
||||||
|
content = content.replace(/\bWHERE\s+(\w+)\s*=\s*1\b/gi, 'WHERE $1 = TRUE');
|
||||||
|
content = content.replace(/\bWHERE\s+(\w+)\s*=\s*0\b/gi, 'WHERE $1 = FALSE');
|
||||||
|
content = content.replace(/\bAND\s+(\w+)\s*=\s*1\b/gi, 'AND $1 = TRUE');
|
||||||
|
content = content.replace(/\bAND\s+(\w+)\s*=\s*0\b/gi, 'AND $1 = FALSE');
|
||||||
|
content = content.replace(/\bOR\s+(\w+)\s*=\s*1\b/gi, 'OR $1 = TRUE');
|
||||||
|
content = content.replace(/\bOR\s+(\w+)\s*=\s*0\b/gi, 'OR $1 = FALSE');
|
||||||
|
|
||||||
|
// 3. Convertir DEFAULT dans les INSERT
|
||||||
|
content = content.replace(/,\s*0\s*\)/g, ', FALSE)'); // Avant la fin de VALUES
|
||||||
|
content = content.replace(/,\s*1\s*\)/g, ', TRUE)');
|
||||||
|
content = content.replace(/VALUES\s*\(\s*1\s*,/gi, 'VALUES (TRUE,');
|
||||||
|
content = content.replace(/VALUES\s*\(\s*0\s*,/gi, 'VALUES (FALSE,');
|
||||||
|
|
||||||
|
if (changes > 0) {
|
||||||
|
fs.writeFileSync(filePath, content, 'utf8');
|
||||||
|
console.log(`✅ ${file}: ${changes} changements`);
|
||||||
|
totalChanges += changes;
|
||||||
|
} else {
|
||||||
|
console.log(`⚪ ${file}: aucun changement`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\n✅ Total: ${totalChanges} conversions effectuées`);
|
||||||
|
console.log('\n📝 Vérifiez manuellement si nécessaire et testez!');
|
||||||
@@ -37,7 +37,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
|
|
||||||
// Mettre à jour les infos du flux
|
// Mettre à jour les infos du flux
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE rss_feeds SET title = ?, description = ?, last_fetched_at = CURRENT_TIMESTAMP WHERE id = ?',
|
'UPDATE rss_feeds SET title = $1, description = $2, last_fetched_at = CURRENT_TIMESTAMP WHERE id = $3',
|
||||||
[parsedFeed.title || feed.url, parsedFeed.description || '', feed.id]
|
[parsedFeed.title || feed.url, parsedFeed.description || '', feed.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
// Vérifier si l'article existe UNIQUEMENT par lien
|
// Vérifier si l'article existe UNIQUEMENT par lien
|
||||||
// Simple et fiable
|
// Simple et fiable
|
||||||
const existing = await getOne(
|
const existing = await getOne(
|
||||||
'SELECT id FROM rss_articles WHERE link = ?',
|
'SELECT id FROM rss_articles WHERE link = $1',
|
||||||
[item.link]
|
[item.link]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
// Nouvel article - l'ajouter
|
// Nouvel article - l'ajouter
|
||||||
await runQuery(
|
await runQuery(
|
||||||
`INSERT INTO rss_articles (feed_id, title, link, description, pub_date, content)
|
`INSERT INTO rss_articles (feed_id, title, link, description, pub_date, content)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||||
[
|
[
|
||||||
feed.id,
|
feed.id,
|
||||||
item.title.trim(),
|
item.title.trim(),
|
||||||
@@ -105,7 +105,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
|
|
||||||
// Nettoyer les vieux articles (garder les N derniers)
|
// Nettoyer les vieux articles (garder les N derniers)
|
||||||
const articlesCount = await getOne(
|
const articlesCount = await getOne(
|
||||||
'SELECT COUNT(*) as count FROM rss_articles WHERE feed_id = ?',
|
'SELECT COUNT(*) as count FROM rss_articles WHERE feed_id = $1',
|
||||||
[feed.id]
|
[feed.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -115,9 +115,9 @@ async function fetchSingleFeed(feed) {
|
|||||||
DELETE FROM rss_articles
|
DELETE FROM rss_articles
|
||||||
WHERE id IN (
|
WHERE id IN (
|
||||||
SELECT id FROM rss_articles
|
SELECT id FROM rss_articles
|
||||||
WHERE feed_id = ?
|
WHERE feed_id = $1
|
||||||
ORDER BY pub_date ASC
|
ORDER BY pub_date ASC
|
||||||
LIMIT ?
|
LIMIT $2
|
||||||
)
|
)
|
||||||
`, [feed.id, toDelete]);
|
`, [feed.id, toDelete]);
|
||||||
logger.debug(` 🗑️ ${toDelete} anciens articles supprimés`);
|
logger.debug(` 🗑️ ${toDelete} anciens articles supprimés`);
|
||||||
@@ -151,7 +151,7 @@ async function fetchAllFeeds() {
|
|||||||
logger.info('🔄 === Début mise à jour RSS ===');
|
logger.info('🔄 === Début mise à jour RSS ===');
|
||||||
|
|
||||||
// Récupérer tous les flux activés
|
// Récupérer tous les flux activés
|
||||||
const feeds = await getAll('SELECT * FROM rss_feeds WHERE enabled = 1');
|
const feeds = await getAll('SELECT * FROM rss_feeds WHERE enabled = TRUE');
|
||||||
|
|
||||||
if (!feeds || feeds.length === 0) {
|
if (!feeds || feeds.length === 0) {
|
||||||
logger.info('⚠️ Aucun flux RSS activé');
|
logger.info('⚠️ Aucun flux RSS activé');
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
|
|
||||||
// Mettre à jour les infos du flux
|
// Mettre à jour les infos du flux
|
||||||
await runQuery(
|
await runQuery(
|
||||||
'UPDATE rss_feeds SET title = ?, description = ?, last_fetched_at = CURRENT_TIMESTAMP WHERE id = ?',
|
'UPDATE rss_feeds SET title = $1, description = $2, last_fetched_at = CURRENT_TIMESTAMP WHERE id = $3',
|
||||||
[parsedFeed.title || feed.url, parsedFeed.description || '', feed.id]
|
[parsedFeed.title || feed.url, parsedFeed.description || '', feed.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
// Vérifier si l'article existe UNIQUEMENT par lien
|
// Vérifier si l'article existe UNIQUEMENT par lien
|
||||||
// Simple et fiable
|
// Simple et fiable
|
||||||
const existing = await getOne(
|
const existing = await getOne(
|
||||||
'SELECT id FROM rss_articles WHERE link = ?',
|
'SELECT id FROM rss_articles WHERE link = $1',
|
||||||
[item.link]
|
[item.link]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
// Nouvel article - l'ajouter
|
// Nouvel article - l'ajouter
|
||||||
await runQuery(
|
await runQuery(
|
||||||
`INSERT INTO rss_articles (feed_id, title, link, description, pub_date, content)
|
`INSERT INTO rss_articles (feed_id, title, link, description, pub_date, content)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||||
[
|
[
|
||||||
feed.id,
|
feed.id,
|
||||||
item.title.trim(),
|
item.title.trim(),
|
||||||
@@ -105,7 +105,7 @@ async function fetchSingleFeed(feed) {
|
|||||||
|
|
||||||
// Nettoyer les vieux articles (garder les N derniers)
|
// Nettoyer les vieux articles (garder les N derniers)
|
||||||
const articlesCount = await getOne(
|
const articlesCount = await getOne(
|
||||||
'SELECT COUNT(*) as count FROM rss_articles WHERE feed_id = ?',
|
'SELECT COUNT(*) as count FROM rss_articles WHERE feed_id = $1',
|
||||||
[feed.id]
|
[feed.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -115,9 +115,9 @@ async function fetchSingleFeed(feed) {
|
|||||||
DELETE FROM rss_articles
|
DELETE FROM rss_articles
|
||||||
WHERE id IN (
|
WHERE id IN (
|
||||||
SELECT id FROM rss_articles
|
SELECT id FROM rss_articles
|
||||||
WHERE feed_id = ?
|
WHERE feed_id = $1
|
||||||
ORDER BY pub_date ASC
|
ORDER BY pub_date ASC
|
||||||
LIMIT ?
|
LIMIT $2
|
||||||
)
|
)
|
||||||
`, [feed.id, toDelete]);
|
`, [feed.id, toDelete]);
|
||||||
logger.debug(` 🗑️ ${toDelete} anciens articles supprimés`);
|
logger.debug(` 🗑️ ${toDelete} anciens articles supprimés`);
|
||||||
@@ -151,7 +151,7 @@ async function fetchAllFeeds() {
|
|||||||
logger.info('🔄 === Début mise à jour RSS ===');
|
logger.info('🔄 === Début mise à jour RSS ===');
|
||||||
|
|
||||||
// Récupérer tous les flux activés
|
// Récupérer tous les flux activés
|
||||||
const feeds = await getAll('SELECT * FROM rss_feeds WHERE enabled = 1');
|
const feeds = await getAll('SELECT * FROM rss_feeds WHERE enabled = TRUE');
|
||||||
|
|
||||||
if (!feeds || feeds.length === 0) {
|
if (!feeds || feeds.length === 0) {
|
||||||
logger.info('⚠️ Aucun flux RSS activé');
|
logger.info('⚠️ Aucun flux RSS activé');
|
||||||
|
|||||||
Reference in new issue
Block a user