fix: resolve API inconsistencies found by Mokoto
- 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
This commit is contained in:
@@ -171,10 +171,12 @@ class ApiClient {
|
||||
}
|
||||
|
||||
// ===== Folders =====
|
||||
getFolders(projectId, parentId = null) {
|
||||
const params = new URLSearchParams({ projectId });
|
||||
getFolders(project = null, parentId = null) {
|
||||
const params = new URLSearchParams();
|
||||
if (project) params.append('project', project);
|
||||
if (parentId) params.append('parentId', parentId);
|
||||
return this.get(`/folders?${params.toString()}`);
|
||||
const query = params.toString();
|
||||
return this.get(`/folders${query ? '?' + query : ''}`);
|
||||
}
|
||||
|
||||
getFolder(id) {
|
||||
|
||||
@@ -11,15 +11,12 @@ import { NotFoundError, ValidationError } from '../utils/errors.js';
|
||||
const router = Router();
|
||||
router.use(authMiddleware);
|
||||
|
||||
// GET /folders?projectId=X&parentId=Y - List folders
|
||||
// GET /folders?project=X&parentId=Y - List folders (project is optional, matches documents API)
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const { projectId, parentId } = req.query;
|
||||
if (!projectId) {
|
||||
throw new ValidationError('projectId query parameter is required');
|
||||
}
|
||||
const { project, parentId } = req.query;
|
||||
const folderService = getFolderService();
|
||||
const folders = await folderService.getFolders(projectId, parentId || null);
|
||||
const folders = await folderService.getFolders(project || null, parentId || null);
|
||||
res.json({ folders });
|
||||
} catch (err) {
|
||||
if (err instanceof ValidationError) {
|
||||
|
||||
@@ -157,12 +157,14 @@ export class FolderService {
|
||||
}
|
||||
}
|
||||
|
||||
async getFolders(projectId, parentId = null) {
|
||||
// Verify project exists
|
||||
async getFolders(projectId = null, parentId = null) {
|
||||
const folders = [];
|
||||
|
||||
// If projectId is provided, verify it exists
|
||||
if (projectId) {
|
||||
const projectService = getProjectService(this.dataRoot);
|
||||
await projectService.getProject(projectId);
|
||||
|
||||
const folders = [];
|
||||
}
|
||||
|
||||
if (parentId) {
|
||||
// Get folders within a specific parent
|
||||
@@ -187,8 +189,8 @@ export class FolderService {
|
||||
folderCount: this._countSubFolders(join(entryPath, 'sub-folders')),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Get root folders of the project
|
||||
} else if (projectId) {
|
||||
// Get root folders of a specific project
|
||||
const rootFoldersPath = this._projectFoldersPath(projectId);
|
||||
if (!pathExists(rootFoldersPath)) {
|
||||
return folders;
|
||||
@@ -208,6 +210,35 @@ export class FolderService {
|
||||
folderCount: this._countSubFolders(join(entryPath, 'sub-folders')),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// No projectId provided - list folders from all projects
|
||||
if (!pathExists(this.projectsPath)) {
|
||||
return folders;
|
||||
}
|
||||
|
||||
const projectEntries = listDir(this.projectsPath);
|
||||
for (const projectEntry of projectEntries) {
|
||||
const projectPath = join(this.projectsPath, projectEntry);
|
||||
if (!isDirectory(projectPath)) continue;
|
||||
|
||||
const rootFoldersPath = join(projectPath, FOLDERS_DIR);
|
||||
if (!pathExists(rootFoldersPath)) continue;
|
||||
|
||||
const entries = listDir(rootFoldersPath);
|
||||
for (const entry of entries) {
|
||||
const entryPath = join(rootFoldersPath, entry);
|
||||
if (!isDirectory(entryPath)) continue;
|
||||
|
||||
const meta = readJSON(join(entryPath, FOLDER_META_FILE));
|
||||
if (!meta) continue;
|
||||
|
||||
folders.push({
|
||||
...meta,
|
||||
documentCount: this._countDocuments(join(entryPath, 'documents')),
|
||||
folderCount: this._countSubFolders(join(entryPath, 'sub-folders')),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return folders;
|
||||
|
||||
Reference in New Issue
Block a user