diff --git a/apps/web/src/app/api/pages/reorder/__tests__/route.test.ts b/apps/web/src/app/api/pages/reorder/__tests__/route.test.ts index c59f51911..949571d8d 100644 --- a/apps/web/src/app/api/pages/reorder/__tests__/route.test.ts +++ b/apps/web/src/app/api/pages/reorder/__tests__/route.test.ts @@ -161,16 +161,40 @@ describe('PATCH /api/pages/reorder', () => { expect(pageReorderService.reorderPage).not.toHaveBeenCalled(); }); - it('returns 400 for negative position values', async () => { + it('accepts negative position values (for fractional positioning)', async () => { const response = await PATCH(createRequest({ pageId: mockPageId, newParentId: null, newPosition: -1, })); - const body = await response.json(); + + expect(response.status).toBe(200); + expect(pageReorderService.reorderPage).toHaveBeenCalledWith( + expect.objectContaining({ newPosition: -1 }) + ); + }); + + it('accepts fractional position values (for between-item positioning)', async () => { + const response = await PATCH(createRequest({ + pageId: mockPageId, + newParentId: null, + newPosition: 2.5, + })); + + expect(response.status).toBe(200); + expect(pageReorderService.reorderPage).toHaveBeenCalledWith( + expect.objectContaining({ newPosition: 2.5 }) + ); + }); + + it('returns 400 for non-finite position values', async () => { + const response = await PATCH(createRequest({ + pageId: mockPageId, + newParentId: null, + newPosition: Infinity, + })); expect(response.status).toBe(400); - expect(body.error).toMatch(/position|non-negative/i); expect(pageReorderService.reorderPage).not.toHaveBeenCalled(); }); diff --git a/apps/web/src/app/api/pages/reorder/route.ts b/apps/web/src/app/api/pages/reorder/route.ts index bf2805963..ba7b229f4 100644 --- a/apps/web/src/app/api/pages/reorder/route.ts +++ b/apps/web/src/app/api/pages/reorder/route.ts @@ -10,7 +10,7 @@ const AUTH_OPTIONS = { allow: ['jwt', 'mcp'] as const, requireCSRF: true }; const reorderSchema = z.object({ pageId: z.string(), newParentId: z.string().nullable(), - newPosition: z.number().int().gte(0, 'Position must be a non-negative integer'), + newPosition: z.number().finite(), }); export async function PATCH(request: Request) {