api-endpoint

star 16

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.

hoangsonww By hoangsonww schedule Updated 3/3/2026

name: api-endpoint description: > 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 ", or scaffold any new REST resource end-to-end. Does not trigger for frontend-only tasks.

Scaffold a complete new API endpoint for the WealthWise API following all project conventions.

The entity/resource name is provided in the task prompt.

Scope

Create all four layers in this exact order:

1. Zod schema — packages/shared-types/src/schemas/<entity>.schema.ts

import { 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.

2. Mongoose model — apps/api/src/models/<entity>.model.ts

  • userId: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true }
  • timestamps: true in schema options (handles createdAt/updatedAt automatically)
  • Define compound indexes in the schema file
  • Export: export const <Entity>Model = model<I<Entity>>('<Entity>', <entity>Schema)

3. Service — apps/api/src/services/<entity>.service.ts

Implement 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 missing
  • create<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 missing
  • delete<Entity>(id: string, userId: string): Promise<void> — throws ApiError.notFound if missing

Rules:

  • Every query includes { userId } as a filter — no cross-user access
  • Use ApiError static factories — never throw new Error(...)
  • Never return null from get/update/delete — throw instead

4. Controller — apps/api/src/controllers/<entity>.controller.ts

  • Import service and call exactly one method per handler
  • Wrap every handler with asyncHandler
  • Success: res.status(200).json({ success: true, data: result })
  • Created: res.status(201).json({ success: true, data: result })
  • Errors: use ApiError factories — never raw throw new Error(...)

5. Route — apps/api/src/routes/<entity>.route.ts

  • Apply authenticate middleware before all routes
  • Apply validate middleware with Zod schemas from @wealthwise/shared-types
  • Add JSDoc Swagger annotations for every endpoint
  • Register the router in apps/api/src/routes/index.ts

Standards

  • No any types
  • Named exports only
  • const over let, never var
  • async/await over raw Promises

Verification

After 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>).

Install via CLI
npx skills add https://github.com/hoangsonww/WealthWise-Finance-Tracker --skill api-endpoint
Repository Details
star Stars 16
call_split Forks 11
navigation Branch main
article Path SKILL.md
More from Creator