Augustin 750e2c4fe8 Add conception-assistant web application with journal management
- Express server with routes for index and API endpoints
- CRUD operations for markdown journals via REST API
- Modular view components (header, main, footer, page)
- UUID-based file management system for journals
- Content-editable journal editor with AI assistant features
- Package.json with express and uuid dependencies
- Basic project structure with assets, config, tests, views directories

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 16:17:28 +02:00

187 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const router = express.Router();
const fs = require('fs');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
function modifMd(id, modifications) {
if (id === undefined) throw new Error('id obligatoire');
if (!Array.isArray(modifications) || modifications.length === 0) throw new Error('modifications requises');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
const map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) throw new Error('Fichier markdown inexistant');
let lignes = fs.readFileSync(mdPath, 'utf8').split('\n');
modifications = modifications.slice().sort((a, b) => a.debut - b.debut);
let offset = 0;
for (let m of modifications) {
let debut = m.debut + offset;
let fin = m.fin + offset;
const remplacement = Array.isArray(m.contenu) ? m.contenu : m.contenu.split('\n');
if (debut < 0 || fin >= lignes.length || debut > fin)
throw new Error('Plage invalide (début/fin) pour une modification');
const avant = lignes.slice(0, debut);
const apres = lignes.slice(fin + 1);
lignes = [...avant, ...remplacement, ...apres];
offset += remplacement.length - (fin - debut + 1);
}
const nouveau = lignes.join('\n');
fs.writeFileSync(mdPath, nouveau, { encoding: 'utf8', flag: 'w' });
return { id, uuid, path: mdPath, modifications };
}
function createMd(markdownContent = "# Titre\nContenu...") {
const uuid = uuidv4();
const dataDir = path.resolve(__dirname, '../data');
const mdPath = path.join(dataDir, `${uuid}.md`);
const mapPath = path.join(dataDir, 'uuid_map.json');
fs.writeFileSync(mdPath, markdownContent, { encoding: 'utf8', flag: 'w' });
let map = {};
if (fs.existsSync(mapPath)) {
map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
}
let id = Object.keys(map).at(-1);
if (id == undefined){
map[0] = uuid;
} else {
id = +id+1
map[id] = uuid;
}
fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8');
return { id, uuid, path: mdPath, markdownContent};
}
function readMd(id = undefined) {
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
let map = {};
if (fs.existsSync(mapPath)) {
map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
}
if (id !== undefined) {
const uuid = map[id];
if (!uuid) {
throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
}
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) {
throw new Error(`Le fichier ${mdPath} nexiste pas`);
}
const markdownContent = fs.readFileSync(mdPath, 'utf8');
return [{ id, uuid, path: mdPath, markdownContent }];
} else {
const results = [];
for (const [curId, uuid] of Object.entries(map)) {
const mdPath = path.join(dataDir, `${uuid}.md`);
if (fs.existsSync(mdPath)) {
const markdownContent = fs.readFileSync(mdPath, 'utf8');
results.push({ id: curId, uuid, path: mdPath, markdownContent });
}
}
return results;
}
}
function modifMd(id, newMarkdownContent) {
if (id === undefined) throw new Error('id obligatoire');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
let map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) throw new Error('Le fichier markdown nexiste pas');
fs.writeFileSync(mdPath, newMarkdownContent, { encoding: 'utf8', flag: 'w' });
return { id, uuid, path: mdPath, newMarkdownContent };
}
function deteMd(id) {
if (id === undefined) throw new Error('id obligatoire');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
let map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (fs.existsSync(mdPath)) fs.unlinkSync(mdPath);
delete map[id];
fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8');
return { id, deleted: true };
}
// GET /api/journals - Récupérer tous les journaux
router.get('/journals', (req, res) => {
res.json({
success: true,
data: readMd()
});
});
// POST /api/journals - Créer un nouveau journal
router.post('/journals', (req, res) => {
const { content } = req.body;
res.status(201).json({
success: true,
data: createMd(content)
});
});
// GET /api/journals/:id - Récupérer un journal spécifique
router.get('/journals/:id', (req, res) => {
const { id } = req.params;
res.json({
success: true,
data: readMd(id)
});
});
// PUT /api/journals/:id - Mettre à jour un journal
router.put('/journals/:id', (req, res) => {
const { id } = req.params;
const { start, end, content } = req.body;
res.json({
success: true,
data: modifMd(id, {start, end, content})
});
});
// DELETE /api/journals/:id - Supprimer un journal
router.delete('/journals/:id', (req, res) => {
const { id } = req.params;
res.json({
success: true,
data: deteMd(id)
});
});
module.exports = router;