Merge pull request #82 from R0m1k3/claude/update-rss-feeds-011CV6EZDsWAUqbRHZR1117Q

Claude/update rss feeds 011 cv6 ez ds wa uqb rhzr1117 q
This commit is contained in:
LogiFlow authored and GitHub committed 2025-11-14 10:52:02 +01:00
commit 860688b583
15 files changed
+314 -12

No files matched your search

+157
View File
@@ -0,0 +1,157 @@
# 🚨 RÉCUPÉRATION DES DONNÉES - Guide d'urgence
## 📋 Qu'est-ce qui s'est passé ?
Vos données ne sont **PAS perdues** ! Le problème était que:
1. Docker était configuré pour utiliser PostgreSQL (`DB_TYPE=postgres`)
2. Mais le code chargeait toujours SQLite
3. Résultat: une nouvelle base SQLite vide était créée
4. Vos vraies données sont restées dans la base SQLite d'origine
## ✅ Solution appliquée
Un système de **détection automatique** a été ajouté (`config/database-loader.js`) qui:
- Détecte `DB_TYPE=postgres` → charge PostgreSQL
- Détecte `DATABASE_URL=postgresql://` → charge PostgreSQL
- Sinon → charge SQLite
## 🔄 Deux options pour récupérer vos données
### Option 1: Utiliser SQLite (RAPIDE - recommandé pour l'instant)
**Revenir temporairement à SQLite le temps de tout vérifier:**
```bash
# 1. Arrêter les containers
docker-compose down
# 2. Modifier docker-compose.yml temporairement
# Commentez ces lignes dans la section notes-app > environment:
# - DATABASE_URL=postgresql://...
# - DB_TYPE=postgres
# 3. Relancer
docker-compose build notes-app
docker-compose up -d
```
Vos données réapparaîtront immédiatement car SQLite sera rechargé.
### Option 2: Migrer vers PostgreSQL (PROPRE - recommandé pour production)
**Migration complète de SQLite → PostgreSQL:**
```bash
# 1. Reconstruire avec le nouveau code
docker-compose build notes-app
# 2. Démarrer les containers
docker-compose up -d
# 3. Attendre 30 secondes que PostgreSQL démarre
sleep 30
# 4. Lancer la migration
bash scripts/run-migration.sh
```
Cette option copie toutes vos données de SQLite vers PostgreSQL.
## 🔍 Vérifier que tout fonctionne
### Après Option 1 (SQLite):
```bash
# Vérifier les données
docker exec notes-todo-app node -e "
const { getAll } = require('./config/database-loader');
getAll('SELECT COUNT(*) as count FROM notes').then(r => {
console.log('Notes:', r[0].count);
process.exit(0);
});
"
```
### Après Option 2 (PostgreSQL):
```bash
# Vérifier les données dans PostgreSQL
docker exec noteflow-postgres psql -U noteflow -d noteflow -p 5499 \
-c "SELECT COUNT(*) FROM notes;"
docker exec noteflow-postgres psql -U noteflow -d noteflow -p 5499 \
-c "SELECT COUNT(*) FROM rss_articles;"
```
## 🎯 Recommandation
**Pour l'instant:**
1. Utilisez **Option 1** (SQLite) pour récupérer immédiatement vos données
2. Vérifiez que tout fonctionne bien
3. Plus tard, quand vous êtes prêt, utilisez **Option 2** pour migrer vers PostgreSQL
## 📂 Où sont vos données ?
- **SQLite actuel:** `./data/notes.db` (vos vraies données sont ici)
- **PostgreSQL:** Container Docker `noteflow-postgres` (vide ou partiellement migré)
## ⚠️ Important
**NE SUPPRIMEZ PAS** le fichier `./data/notes.db` tant que vous n'avez pas:
1. Vérifié que tout fonctionne avec PostgreSQL
2. Confirmé que toutes vos données sont migrées
3. Testé l'application pendant plusieurs jours
## 🆘 En cas de problème
### Voir les logs
```bash
docker-compose logs notes-app | tail -50
```
### Identifier quelle base est utilisée
```bash
docker exec notes-todo-app node -e "
console.log('DB_TYPE:', process.env.DB_TYPE);
console.log('DATABASE_URL:', process.env.DATABASE_URL?.replace(/:[^:@]+@/, ':***@'));
"
```
### Forcer SQLite même avec Docker
```bash
docker exec -e DB_TYPE=sqlite notes-todo-app node server.js
```
## 📞 Debug rapide
```bash
# Compter les notes dans SQLite
docker exec notes-todo-app node -e "
const sqlite3 = require('sqlite3');
const db = new sqlite3.Database('./data/notes.db');
db.get('SELECT COUNT(*) as count FROM notes', (err, row) => {
console.log('Notes SQLite:', row.count);
db.close();
});
" 2>/dev/null
# Compter les notes dans PostgreSQL
docker exec noteflow-postgres psql -U noteflow -d noteflow -p 5499 -t \
-c "SELECT COUNT(*) FROM notes;" 2>/dev/null || echo "PostgreSQL non accessible"
```
## ✅ Checklist de récupération
- [ ] Containers redémarrés avec nouvelle configuration
- [ ] Base de données accessible (SQLite OU PostgreSQL)
- [ ] Notes visibles dans l'interface
- [ ] Tâches visibles
- [ ] Flux RSS configurés
- [ ] Événements calendrier présents
- [ ] Paramètres restaurés
---
**Date de création:** 2025-11-14
**Commit de correction:** 55a1809 - Fix: Chargement automatique SQLite/PostgreSQL
+22
View File
@@ -0,0 +1,22 @@
// Chargeur automatique de base de données (SQLite ou PostgreSQL)
const logger = require('./logger');
// Détecter le type de base de données
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
const DATABASE_URL = process.env.DATABASE_URL;
logger.info(`Configuration de base de données: ${DB_TYPE}`);
// Charger le module approprié
let databaseModule;
if (DB_TYPE === 'postgres' || DATABASE_URL?.startsWith('postgresql://')) {
logger.info('Chargement de la configuration PostgreSQL');
databaseModule = require('./database-postgres');
} else {
logger.info('Chargement de la configuration SQLite');
databaseModule = require('./database');
}
// Exporter toutes les fonctions du module chargé
module.exports = databaseModule;
+1 -1
View File
@@ -4,7 +4,7 @@ const router = express.Router();
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const { getOne } = require('../config/database'); const { getOne } = require('../config/database-loader');
const { generateToken, authenticateToken } = require('../middleware/auth'); const { generateToken, authenticateToken } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -2,7 +2,7 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { google } = require('googleapis'); const { google } = require('googleapis');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -6,7 +6,7 @@ const path = require('path');
const fs = require('fs'); const fs = require('fs');
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken } = require('../middleware/auth'); const { authenticateToken } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -2,7 +2,7 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const { getOne } = require('../config/database'); const { getOne } = require('../config/database-loader');
const logger = require('../config/logger'); const logger = require('../config/logger');
// Cache pour les modèles (rafraîchi toutes les heures) // Cache pour les modèles (rafraîchi toutes les heures)
+1 -1
View File
@@ -3,7 +3,7 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const Parser = require('rss-parser'); const Parser = require('rss-parser');
const axios = require('axios'); const axios = require('axios');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -3,7 +3,7 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const Parser = require('rss-parser'); const Parser = require('rss-parser');
const axios = require('axios'); const axios = require('axios');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -1,7 +1,7 @@
// Routes de gestion des paramètres // Routes de gestion des paramètres
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -3,7 +3,7 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken } = require('../middleware/auth'); const { authenticateToken } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+1 -1
View File
@@ -4,7 +4,7 @@ const router = express.Router();
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const { authenticateToken, requireAdmin } = require('../middleware/auth'); const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../config/logger'); const logger = require('../config/logger');
+123
View File
@@ -0,0 +1,123 @@
// Script de diagnostic - Vérifier où sont les données
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const { Pool } = require('pg');
console.log('\n🔍 DIAGNOSTIC DES DONNÉES\n');
console.log('═══════════════════════════════════════════\n');
// Variables d'environnement
console.log('📋 Configuration actuelle:');
console.log(' DB_TYPE:', process.env.DB_TYPE || '(non défini → SQLite)');
console.log(' DATABASE_URL:', process.env.DATABASE_URL ?
process.env.DATABASE_URL.replace(/:[^:@]+@/, ':***@') : '(non défini)');
console.log('');
// 1. Vérifier SQLite
const SQLITE_PATH = path.join(__dirname, '../data/notes.db');
console.log('📊 Données dans SQLite (' + SQLITE_PATH + '):');
const sqliteDb = new sqlite3.Database(SQLITE_PATH, async (err) => {
if (err) {
console.log(' ❌ Erreur connexion SQLite:', err.message);
checkPostgres();
return;
}
const tables = ['users', 'notes', 'global_todos', 'rss_feeds', 'rss_articles', 'calendar_events', 'settings'];
let completed = 0;
for (const table of tables) {
sqliteDb.get(`SELECT COUNT(*) as count FROM ${table}`, (err, row) => {
if (err) {
console.log(` • ${table}: ❌ ${err.message}`);
} else {
const icon = row.count > 0 ? '✅' : '⚪';
console.log(` ${icon} ${table.padEnd(20)} : ${row.count}`);
}
completed++;
if (completed === tables.length) {
sqliteDb.close(() => {
console.log('');
checkPostgres();
});
}
});
}
});
// 2. Vérifier PostgreSQL
async function checkPostgres() {
const DATABASE_URL = process.env.DATABASE_URL;
if (!DATABASE_URL || !DATABASE_URL.startsWith('postgresql://')) {
console.log('📊 PostgreSQL: Non configuré (DATABASE_URL manquant)\n');
showConclusion();
return;
}
console.log('📊 Données dans PostgreSQL:');
const pool = new Pool({
connectionString: DATABASE_URL,
max: 1,
connectionTimeoutMillis: 3000,
});
try {
const client = await pool.connect();
const tables = ['users', 'notes', 'global_todos', 'rss_feeds', 'rss_articles', 'calendar_events', 'settings'];
for (const table of tables) {
try {
const result = await client.query(`SELECT COUNT(*) as count FROM ${table}`);
const count = parseInt(result.rows[0].count);
const icon = count > 0 ? '✅' : '⚪';
console.log(` ${icon} ${table.padEnd(20)} : ${count}`);
} catch (err) {
console.log(` • ${table.padEnd(20)} : ❌ ${err.message.split('\n')[0]}`);
}
}
client.release();
await pool.end();
console.log('');
showConclusion();
} catch (error) {
console.log(' ❌ Connexion impossible:', error.message);
console.log('');
showConclusion();
}
}
function showConclusion() {
console.log('═══════════════════════════════════════════');
console.log('\n💡 CONCLUSION:\n');
const dbType = process.env.DB_TYPE || 'sqlite';
const hasDbUrl = process.env.DATABASE_URL?.startsWith('postgresql://');
if (dbType === 'postgres' || hasDbUrl) {
console.log(' L\'application est configurée pour PostgreSQL');
console.log(' ');
console.log(' ⚠️ Si PostgreSQL est vide et SQLite contient des données:');
console.log(' → Vos données sont dans SQLite');
console.log(' → Lancez la migration: bash scripts/run-migration.sh');
console.log(' ');
console.log(' ✅ Si PostgreSQL contient des données:');
console.log(' → Migration déjà effectuée');
console.log(' → Redémarrez: docker-compose restart notes-app');
} else {
console.log(' L\'application est configurée pour SQLite');
console.log(' ');
console.log(' ✅ Si SQLite contient des données:');
console.log(' → Tout est normal');
console.log(' → Vérifiez l\'interface web');
}
console.log('\n═══════════════════════════════════════════\n');
process.exit(0);
}
+1 -1
View File
@@ -7,7 +7,7 @@ const path = require('path');
const fs = require('fs'); const fs = require('fs');
const logger = require('./config/logger'); const logger = require('./config/logger');
const { initDatabase } = require('./config/database'); const { initDatabase } = require('./config/database-loader');
// Créer l'application Express // Créer l'application Express
const app = express(); const app = express();
+1 -1
View File
@@ -1,6 +1,6 @@
// Service RSS NOUVEAU - Architecture simple et robuste // Service RSS NOUVEAU - Architecture simple et robuste
const Parser = require('rss-parser'); const Parser = require('rss-parser');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const logger = require('../config/logger'); const logger = require('../config/logger');
const parser = new Parser({ const parser = new Parser({
+1 -1
View File
@@ -1,6 +1,6 @@
// Service RSS NOUVEAU - Architecture simple et robuste // Service RSS NOUVEAU - Architecture simple et robuste
const Parser = require('rss-parser'); const Parser = require('rss-parser');
const { getAll, getOne, runQuery } = require('../config/database'); const { getAll, getOne, runQuery } = require('../config/database-loader');
const logger = require('../config/logger'); const logger = require('../config/logger');
const parser = new Parser({ const parser = new Parser({