fix(cases): show the real reason when Link Existing rejects a case

POST /api/cases/link passed a fixed 'Invalid request body' to parseBody, which replaced the
schema's own message, so a bad name and a bad folder path (a leading ~, a character a session
working directory cannot have) looked the same. Drop the override so the first validation
issue is returned.
This commit is contained in:
Devvyn committed 2026-10-10 13:50:04 +08:00
1 parent 3d59e59e37
commit 0ae679553b
3 files changed
+25 -1

No files matched your search

@@ -0,0 +1,5 @@
---
'aicodeman': patch
---
Link Existing now says what is wrong when it rejects a case. A bad name reports "Invalid case name format" and a bad folder path reports why (not absolute, a character a session folder cannot have, ...), instead of the same "Invalid request body" for both.
+1 -1
View File
@@ -1536,7 +1536,7 @@ export function registerCaseRoutes(app: FastifyInstance, ctx: EventPort & Config
// admin-only in multi-user mode (mirrors host CRUD + the admin-only GET listing).
const denied = adminOnly(req, reply);
if (denied) return denied;
const { name, path: folderPath } = parseBody(LinkCaseSchema, req.body, 'Invalid request body');
const { name, path: folderPath } = parseBody(LinkCaseSchema, req.body);
// Expand ~ to home directory
const expandedPath = folderPath.startsWith('~') ? join(homedir(), folderPath.slice(1)) : folderPath;
+19
View File
@@ -647,6 +647,25 @@ describe('case-routes', () => {
expect(body.success).toBe(false);
});
it('says which field is wrong instead of a generic message', async () => {
const badName = await harness.app.inject({
method: 'POST',
url: '/api/cases/link',
payload: { name: 'bad name!', path: '/home/user/project' },
});
expect(badName.statusCode).toBe(400);
expect(JSON.parse(badName.body).error).toBe('Invalid case name format');
// A leading `~` is expanded later in the route but fails the absolute-path rule first.
const badPath = await harness.app.inject({
method: 'POST',
url: '/api/cases/link',
payload: { name: 'my-project', path: '~/project' },
});
expect(badPath.statusCode).toBe(400);
expect(JSON.parse(badPath.body).error).toMatch(/^Invalid path:/);
});
it('returns not found when folder does not exist', async () => {
mockedExistsSync.mockReturnValue(false);