- Bug 1: No fix needed - frontend already uses PUT for document updates - Bug 2: Changed folders API to use 'project' param (matches documents) - Bug 3: GET /folders now works without project filter (lists all folders) Changes: - folders.js: Accept 'project' instead of 'projectId', make it optional - folderService.js: Support listing all folders when projectId is null - api.js: Updated getFolders() to use 'project' param consistently
136 lines
4.6 KiB
JavaScript
136 lines
4.6 KiB
JavaScript
/**
|
|
* SimpleNote Web - Folders Routes
|
|
* CRUD + tree for folders
|
|
*/
|
|
|
|
import { Router } from 'express';
|
|
import { authMiddleware } from '../middleware/auth.js';
|
|
import { getFolderService } from '../services/folderService.js';
|
|
import { NotFoundError, ValidationError } from '../utils/errors.js';
|
|
|
|
const router = Router();
|
|
router.use(authMiddleware);
|
|
|
|
// GET /folders?project=X&parentId=Y - List folders (project is optional, matches documents API)
|
|
router.get('/', async (req, res) => {
|
|
try {
|
|
const { project, parentId } = req.query;
|
|
const folderService = getFolderService();
|
|
const folders = await folderService.getFolders(project || null, parentId || null);
|
|
res.json({ folders });
|
|
} catch (err) {
|
|
if (err instanceof ValidationError) {
|
|
return res.status(400).json({ error: err.message, code: err.code });
|
|
}
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error listing folders:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// POST /folders - Create folder
|
|
router.post('/', async (req, res) => {
|
|
try {
|
|
const { name, projectId, parentId } = req.body;
|
|
if (!name) {
|
|
throw new ValidationError('name is required');
|
|
}
|
|
if (!projectId) {
|
|
throw new ValidationError('projectId is required');
|
|
}
|
|
const folderService = getFolderService();
|
|
const folder = await folderService.createFolder({ name, projectId, parentId: parentId || null });
|
|
res.status(201).json(folder);
|
|
} catch (err) {
|
|
if (err instanceof ValidationError || err instanceof NotFoundError) {
|
|
const status = err instanceof ValidationError ? 400 : 404;
|
|
return res.status(status).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error creating folder:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// GET /folders/:id - Get folder contents
|
|
router.get('/:id', async (req, res) => {
|
|
try {
|
|
const folderService = getFolderService();
|
|
const folder = await folderService.getFolder(req.params.id);
|
|
res.json(folder);
|
|
} catch (err) {
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error getting folder:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// PUT /folders/:id - Update folder
|
|
router.put('/:id', async (req, res) => {
|
|
try {
|
|
const { name } = req.body;
|
|
const folderService = getFolderService();
|
|
const folder = await folderService.updateFolder(req.params.id, { name });
|
|
res.json(folder);
|
|
} catch (err) {
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
if (err instanceof ValidationError) {
|
|
return res.status(400).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error updating folder:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// DELETE /folders/:id - Delete folder
|
|
router.delete('/:id', async (req, res) => {
|
|
try {
|
|
const folderService = getFolderService();
|
|
const result = await folderService.deleteFolder(req.params.id);
|
|
res.json(result);
|
|
} catch (err) {
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error deleting folder:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// GET /folders/:id/documents - List documents in folder
|
|
router.get('/:id/documents', async (req, res) => {
|
|
try {
|
|
const folderService = getFolderService();
|
|
const result = await folderService.getFolderDocuments(req.params.id);
|
|
res.json(result);
|
|
} catch (err) {
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error listing folder documents:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
// GET /folders/:id/tree - Get full folder tree
|
|
router.get('/:id/tree', async (req, res) => {
|
|
try {
|
|
const folderService = getFolderService();
|
|
const tree = await folderService.getFolderTree(req.params.id);
|
|
res.json(tree);
|
|
} catch (err) {
|
|
if (err instanceof NotFoundError) {
|
|
return res.status(404).json({ error: err.message, code: err.code });
|
|
}
|
|
console.error('Error getting folder tree:', err);
|
|
res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
}
|
|
});
|
|
|
|
export default router;
|