fix(backend): fix trackEvent call signature and route registration tests

- auth.ts: type requireWriter param as { headers: { authorization?: string } } instead of unknown
- notes/routes.ts: fix 3 trackEvent calls from object form to positional args (event, userId, properties)
- workspaces/routes.ts: fix 1 trackEvent call from object form to positional args
- 5 route registration tests: add missing delete mock to app object for Phase 2 DELETE endpoints
This commit is contained in:
saravanakumardb1 2026-03-31 01:00:32 -07:00
parent 83f4953870
commit 6acd1a70d4
8 changed files with 15 additions and 5 deletions

View File

@ -20,7 +20,7 @@ export { extractAuth, requireRole };
* Convenience: require the caller to have at least 'editor' or 'admin' role. * Convenience: require the caller to have at least 'editor' or 'admin' role.
* Use on write routes (POST/PATCH/DELETE) that need role enforcement. * Use on write routes (POST/PATCH/DELETE) that need role enforcement.
*/ */
export async function requireWriter(req: unknown) { export async function requireWriter(req: { headers: { authorization?: string } }) {
const payload = await extractAuth(req); const payload = await extractAuth(req);
const role = (payload as { role?: string }).role; const role = (payload as { role?: string }).role;
if (role !== 'editor' && role !== 'admin' && role !== 'owner') { if (role !== 'editor' && role !== 'admin' && role !== 'owner') {

View File

@ -24,6 +24,7 @@ describe('noteArtifactRoutes', () => {
get: vi.fn(), get: vi.fn(),
post: vi.fn(), post: vi.fn(),
patch: vi.fn(), patch: vi.fn(),
delete: vi.fn(),
}; };
await noteArtifactRoutes(app as never); await noteArtifactRoutes(app as never);
@ -31,5 +32,6 @@ describe('noteArtifactRoutes', () => {
expect(app.get).toHaveBeenCalledTimes(1); expect(app.get).toHaveBeenCalledTimes(1);
expect(app.post).toHaveBeenCalledTimes(1); expect(app.post).toHaveBeenCalledTimes(1);
expect(app.patch).toHaveBeenCalledTimes(1); expect(app.patch).toHaveBeenCalledTimes(1);
expect(app.delete).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -21,11 +21,13 @@ describe('noteRelationshipRoutes', () => {
const app = { const app = {
get: vi.fn(), get: vi.fn(),
post: vi.fn(), post: vi.fn(),
delete: vi.fn(),
}; };
await noteRelationshipRoutes(app as never); await noteRelationshipRoutes(app as never);
expect(app.get).toHaveBeenCalledTimes(1); expect(app.get).toHaveBeenCalledTimes(1);
expect(app.post).toHaveBeenCalledTimes(1); expect(app.post).toHaveBeenCalledTimes(1);
expect(app.delete).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -24,6 +24,7 @@ describe('noteTaskRoutes', () => {
get: vi.fn(), get: vi.fn(),
post: vi.fn(), post: vi.fn(),
patch: vi.fn(), patch: vi.fn(),
delete: vi.fn(),
}; };
await noteTaskRoutes(app as never); await noteTaskRoutes(app as never);
@ -31,5 +32,6 @@ describe('noteTaskRoutes', () => {
expect(app.get).toHaveBeenCalledTimes(1); expect(app.get).toHaveBeenCalledTimes(1);
expect(app.post).toHaveBeenCalledTimes(1); expect(app.post).toHaveBeenCalledTimes(1);
expect(app.patch).toHaveBeenCalledTimes(1); expect(app.patch).toHaveBeenCalledTimes(1);
expect(app.delete).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -36,6 +36,7 @@ describe('noteRoutes', () => {
get: vi.fn(), get: vi.fn(),
post: vi.fn(), post: vi.fn(),
patch: vi.fn(), patch: vi.fn(),
delete: vi.fn(),
}; };
await noteRoutes(app as never); await noteRoutes(app as never);
@ -43,5 +44,6 @@ describe('noteRoutes', () => {
expect(app.get).toHaveBeenCalledTimes(4); expect(app.get).toHaveBeenCalledTimes(4);
expect(app.post).toHaveBeenCalledTimes(4); expect(app.post).toHaveBeenCalledTimes(4);
expect(app.patch).toHaveBeenCalledTimes(1); expect(app.patch).toHaveBeenCalledTimes(1);
expect(app.delete).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -89,7 +89,7 @@ export async function noteRoutes(app: RouteApp) {
}; };
const created = await repo.createNote(doc); const created = await repo.createNote(doc);
trackEvent({ event: 'note.created', userId: auth.sub, properties: { noteId: created.id, workspaceId: created.workspaceId } }); trackEvent('note.created', auth.sub, { noteId: created.id, workspaceId: created.workspaceId });
reply.code(201); reply.code(201);
return created; return created;
}); });
@ -125,7 +125,7 @@ export async function noteRoutes(app: RouteApp) {
throw new NotFoundError('Note not found'); throw new NotFoundError('Note not found');
} }
trackEvent({ event: 'note.updated', userId: auth.sub, properties: { noteId: id, workspaceId } }); trackEvent('note.updated', auth.sub, { noteId: id, workspaceId });
return updated; return updated;
}); });
@ -180,7 +180,7 @@ export async function noteRoutes(app: RouteApp) {
throw new NotFoundError('Note not found'); throw new NotFoundError('Note not found');
} }
trackEvent({ event: 'note.archived', userId: auth.sub, properties: { noteId: id, workspaceId } }); trackEvent('note.archived', auth.sub, { noteId: id, workspaceId });
return updated; return updated;
}); });

View File

@ -27,6 +27,7 @@ describe('workspaceRoutes', () => {
get: vi.fn(), get: vi.fn(),
post: vi.fn(), post: vi.fn(),
patch: vi.fn(), patch: vi.fn(),
delete: vi.fn(),
}; };
await workspaceRoutes(app as never); await workspaceRoutes(app as never);
@ -34,5 +35,6 @@ describe('workspaceRoutes', () => {
expect(app.get).toHaveBeenCalledTimes(3); expect(app.get).toHaveBeenCalledTimes(3);
expect(app.post).toHaveBeenCalledTimes(1); expect(app.post).toHaveBeenCalledTimes(1);
expect(app.patch).toHaveBeenCalledTimes(1); expect(app.patch).toHaveBeenCalledTimes(1);
expect(app.delete).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -73,7 +73,7 @@ export async function workspaceRoutes(app: FastifyInstance) {
}; };
const created = await repo.createWorkspace(doc); const created = await repo.createWorkspace(doc);
trackEvent({ event: 'workspace.created', userId: auth.sub, properties: { workspaceId: created.id } }); trackEvent('workspace.created', auth.sub, { workspaceId: created.id });
reply.code(201); reply.code(201);
return created; return created;
}); });