---
name: generate-api-endpoints
description: >-
  Sets up and extends Express REST API and MCP Server Framework projects from GitHub.
  Use when building a new backend, adding endpoints, CRUD services, models, routes,
  or MCP tools. Clones the framework if missing, enforces npm run generate first,
  pending tests before implementation, full tests after build, and loops until
  npm test, npm run lint, and npm run type-check all pass.
disable-model-invocation: true
---

# Generate API Endpoints First

You are building on the **Express REST API and MCP Server Framework**. This skill only works inside a clone of that repository. Follow the steps **in order**.

## Execution order (summary)

| Step | Action |
|------|--------|
| 0 | Clone repo, `npm install`, configure `.env`, ensure MongoDB + Redis are running |
| 1 | `npm run generate -- --name <SingularName>` |
| 2 | Add `it.skip(...)` pending tests from user requirements (before logic changes) |
| 3 | Customize model and controller |
| 4 | Implement full tests (remove `.skip`; update default generated tests if schema changed) |
| 5 | `npm test` — fix until **0 failures** (entire suite) |
| 6 | `npm run lint`, `npm run type-check`, `npm run type-check:test` — fix until clean |
| 7 | `npm run build` |
| 8 | Optional: `npm run dev` smoke check |

## Hard rules (do not skip)

0. **Start from the framework repo.** If the project is not already a clone (no `gulpfile.cjs`, no `npm run generate` script), clone it first — do not scaffold a new Node/Express app from scratch.

1. **Never** create a new resource by hand-writing these from scratch:
   - `src/routes/<resource>.ts`
   - `src/controllers/<ServicePlural>.ts`
   - `src/models/<ServicePlural>.ts`
   - `src/mcp/services/<registration>.registration.ts`
   - Matching scaffold files under `test/` (the generator creates these)

2. **Always** scaffold with `npm run generate` before editing implementation files. **Do not re-run generate** on an existing resource — it overwrites files.

3. **Use singular PascalCase** for `--name` (e.g. `Order`, `User`, `Product`). The generator pluralizes file names (see naming table below).

4. **Test-first for requirements:** After generate, add **pending** unit tests for everything the user asked for **before** customizing model/controller logic. Then implement code and **complete** the tests.

5. **After** generation, you **may** edit:
   - `test/**` — pending tests first, then full implementations
   - Model schema, validations, and MCP field descriptions
   - Controller business logic (keep CRUD method signatures unless intentional)
   - JSDoc `@mcp.expose` on custom controller methods

6. **Never** remove MCP registration files created by generate.

7. **Do not finish** until `npm test`, `npm run lint`, `npm run type-check`, and `npm run type-check:test` all pass. Fix and re-run until green.

## Naming (generate `--name Order`)

| You pass | Generated files (examples) |
|----------|----------------------------|
| `--name Order` | `src/models/Orders.ts`, `src/controllers/Orders.ts`, `src/routes/orders.ts` |
| | `test/models/orders.test.ts`, `test/controllers/orders.test.ts`, `test/routes/orders.test.ts` |
| | `test/mcp/orders.test.ts`, `src/mcp/services/order.registration.ts` |
| Route URL | `/orders` (lowercase plural) |

**Wrong:** `--name Orders` (can produce awkward pluralization like `orderss`). **Right:** `--name Order`.

## Step 0 — Clone, install, and prerequisites

```bash
git clone https://github.com/iolufemi/Express-REST-API-and-MCP-Server-Framework.git <project-directory>
cd <project-directory>
npm install
```

Confirm:

- `package.json` includes `"generate": "npx gulp --gulpfile gulpfile.cjs service"`
- Folders exist: `src/`, `template/`, `gulpfile.cjs`

**Environment**

- Node.js **22.x+**
- Copy/configure `.env` (and `.env.test` if present). Minimum: `MONGOLAB_URL`, `LOG_MONGOLAB_URL`, `REDIS_URL`, `REDIS_QUEUE_URL`
- **MongoDB and Redis must be running** before `npm test` (see `docs/GETTING_STARTED.md`)

**Skill location**

- **Cursor:** `.cursor/skills/generate-api-endpoints/SKILL.md` (bundled in repo)
- **Claude Code:** copy to `.claude/skills/generate-api-endpoints/SKILL.md`

## Step 1 — Generate the service

```bash
# MongoDB (default)
npm run generate -- --name Order

# SQL
npm run generate -- --name Product --sql

# External API as data source
npm run generate -- --name ExternalOrder --baseurl http://localhost:8080 --endpoint orders
```

Short flags: `-n`, `-b`, `-e`.

Wait until the command finishes successfully.

## Step 2 — Write pending unit tests (before customizing logic)

From the **user’s requirements**, list acceptance criteria. Edit the **generated** test files under `test/models/`, `test/controllers/`, `test/routes/`, and `test/mcp/` — do not create parallel test files from scratch.

Use `it.skip` so intent is documented without failing yet:

```typescript
it.skip('should reject create when customerId is missing', function (done) {
  // Expected: 400 Bad Request; body mentions customerId
  done();
});
```

Rules:

- One `it.skip` per user requirement (or group related assertions in one test)
- Clear names: *should &lt;behavior&gt; when &lt;condition&gt;*
- Comment the expected status code, fields, or error message inside each test
- Cover model, controller, and route layers where relevant
- **Keep** the generator’s default CRUD tests — extend, do not delete
- When un-skipping, replace with **real assertions** (chai `should`/`expect`, supertest for routes) — never leave a test that only calls `done()` with no asserts

Optional: `npm test test/models/orders.test.ts` to confirm new tests show as **pending**, not failing.

## Step 3 — Build: customize model and controller

| File | What to change |
|------|----------------|
| `src/models/Orders.ts` | Fields, types, required flags, `description` / `mcpDescription` |
| `src/controllers/Orders.ts` | Business rules; custom methods with `@mcp.expose` if needed |
| `src/routes/orders.ts` | Rarely — prefer controller + generate patterns |

If you changed the schema (fields, required, defaults), **update the default generated tests** in Step 4 so they match the new model — do not only implement the new `it.skip` tests.

Optional quick check before Step 4:

```bash
npm run type-check
```

## Step 4 — Implement full unit tests

For each `it.skip`:

1. Change `it.skip` → `it`
2. Implement arrange / act / assert using project patterns (chai, sinon, supertest in route tests)
3. Fix any **default** generator tests that broke due to schema changes

**Route tests**

- POST requests need `x-tag` from `GET /initialize` (header or query param)
- Use supertest against the app pattern in `test/routes/*.test.ts`

**API-as-DB route tests**

- Require the API server running at `TEST_API_BASEURL` (default `http://localhost:8080`)
- In a separate terminal: `npm run build && npm start` (or `npm run dev`)

**Faster iteration during development**

```bash
npm test test/models/orders.test.ts
npm test test/controllers/orders.test.ts
npm test test/routes/orders.test.ts
```

Before marking done, run the **full** suite:

```bash
npm test
```

## Step 5 — Run tests and fix until all pass

If any test **fails**:

1. Read the failure output (including failures outside the new service — fix all of them)
2. Fix implementation or test
3. Re-run `npm test`
4. Repeat until **0 failures**

Only leave `it.skip` for requirements the user explicitly deferred.

## Step 6 — Lint and type-check (required)

```bash
npm run lint          # ESLint on src/**/*.ts only
npm run type-check    # TypeScript on src
npm run type-check:test   # TypeScript on test files
```

Fix all reported issues and re-run until clean. Test files are **not** covered by `npm run lint` — use `type-check:test`.

Then:

```bash
npm run build
```

## Step 7 — Manual smoke check (recommended)

```bash
npm run dev
# GET http://localhost:8080/health
# GET http://localhost:8080/orders
# GET http://localhost:8080/initialize  (x-tag for POST)
```

## Definition of done

- [ ] Framework cloned; MongoDB + Redis available; `.env` configured
- [ ] `npm run generate -- --name <SingularName>` used (not hand-written scaffold)
- [ ] Pending tests added before model/controller customization
- [ ] Model/controller implement requirements; default tests updated if schema changed
- [ ] All tests implemented; no inappropriate `.skip`
- [ ] `npm test` — **0 failures** (full suite)
- [ ] `npm run lint`, `npm run type-check`, `npm run type-check:test` pass
- [ ] `npm run build` succeeds

## Extending this skill

Add rules under **Project overrides** below. Link to `docs/GETTING_STARTED.md` and `docs/MCP_GUIDE.md`.

## Project overrides

<!-- Example:
- Every model must include `tenantId` (string, required, indexed).
- Run `npm run test:coverage` before merging.
-->
