.agents/skills/api-endpoint/SKILL.md
Scaffold a complete new API endpoint for the WealthWise Express API. Triggers when asked to "add an endpoint", "create a route", "build an API for <entity>", or scaffold any new REST resource end-to-end. Does not trigger for frontend-only tasks.
npx skillsauth add hoangsonww/WealthWise-Finance-Tracker api-endpointInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Scaffold a complete new API endpoint for the WealthWise API following all project conventions.
The entity/resource name is provided in the task prompt.
Create all four layers in this exact order:
packages/shared-types/src/schemas/<entity>.schema.tsimport { z } from 'zod';
export const Create<Entity>Schema = z.object({
// entity-specific fields with validation
});
export const Update<Entity>Schema = Create<Entity>Schema.partial();
export const <Entity>ResponseSchema = Create<Entity>Schema.extend({
_id: z.string(),
userId: z.string(),
createdAt: z.string().datetime(),
updatedAt: z.string().datetime(),
});
export const <Entity>ListResponseSchema = z.array(<Entity>ResponseSchema);
Add inferred types to packages/shared-types/src/types/index.ts:
export type Create<Entity>Input = z.infer<typeof Create<Entity>Schema>;
export type Update<Entity>Input = z.infer<typeof Update<Entity>Schema>;
export type <Entity>Response = z.infer<typeof <Entity>ResponseSchema>;
Export from packages/shared-types/src/index.ts.
apps/api/src/models/<entity>.model.tsuserId: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true }timestamps: true in schema options (handles createdAt/updatedAt automatically)export const <Entity>Model = model<I<Entity>>('<Entity>', <entity>Schema)apps/api/src/services/<entity>.service.tsImplement with full type signatures:
get<Entity>s(userId: string): Promise<I<Entity>[]>get<Entity>ById(id: string, userId: string): Promise<I<Entity>> — throws ApiError.notFound if missingcreate<Entity>(userId: string, data: Create<Entity>Input): Promise<I<Entity>>update<Entity>(id: string, userId: string, data: Update<Entity>Input): Promise<I<Entity>> — throws ApiError.notFound if missingdelete<Entity>(id: string, userId: string): Promise<void> — throws ApiError.notFound if missingRules:
{ userId } as a filter — no cross-user accessApiError static factories — never throw new Error(...)null from get/update/delete — throw insteadapps/api/src/controllers/<entity>.controller.tsasyncHandlerres.status(200).json({ success: true, data: result })res.status(201).json({ success: true, data: result })ApiError factories — never raw throw new Error(...)apps/api/src/routes/<entity>.route.tsauthenticate middleware before all routesvalidate middleware with Zod schemas from @wealthwise/shared-typesapps/api/src/routes/index.tsany typesconst over let, never varasync/await over raw PromisesAfter scaffolding, run:
npx turbo lint --filter=@wealthwise/api
npx turbo test --filter=@wealthwise/api
Report all created file paths and the registered route paths (e.g., GET /api/v1/<entities>).
development
Run the WealthWise test suite with coverage reporting and summarize the results. Triggers when asked to "run tests with coverage", "check test coverage", "show coverage report", or "how many tests pass". Can be scoped to api, web, or types.
testing
Run the full WealthWise pre-PR checklist and report a pass/fail for each gate. Triggers when asked to "run pre-PR checks", "check if this is ready to merge", "validate before opening a PR", or "run the full check". Does NOT trigger implicitly.
development
Scaffold a complete new Next.js dashboard page for the WealthWise web app. Triggers when asked to "add a page", "create a dashboard screen", "build a UI for <feature>", or scaffold any new frontend feature end-to-end. Does not trigger for API-only or backend tasks.
development
Scaffold a new Mongoose model and its CRUD service for the WealthWise API. Triggers when asked to "create a model", "add a Mongoose schema", or add the data layer for a new entity without a full endpoint. Does NOT scaffold routes, controllers, or frontend code. Use $api-endpoint for the full stack.