Skip to content
Agentmart
Submit a tool

ts-ddd-controller

Create, review, or guide HTTP controllers in a TypeScript + DDD api.

Skill by llodev

IndexedMIT★ 2
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/llodev-ts-ddd-controller

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Create, review, or guide HTTP controllers in a TypeScript + DDD api. Use when the request involves `*.controller.ts` under `apps/api/src/<bc>/presentation/controllers/`, route definition, `ApiKeyGuard` on mutations, `ZodValidationPipe` against `@acme/<bc>-contracts` schemas, use case orchestration, mapping `Result` to HTTP via `mapResultToHttp`, signed-URL enrichment through a response mapper, HTTP status conventions (200/201/204), or controller tests using `@nestjs/testing` + `supertest` with an in-memory repository.

Use cases: presentations, backend, testing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/ts-ddd-controller

What's inside

Skill name
ts-ddd-controller
Description
Create, review, or guide HTTP controllers in a TypeScript + DDD api. Use when the request involves `*.controller.ts` under `apps/api/src/<bc>/presentation/controllers/`, route definition, `ApiKeyGuard` on mutations, `ZodValidationPipe` against `@acme/<bc>-contracts` schemas, use case orchestration, mapping `Result` to HTTP via `mapResultToHttp`, signed-URL enrichment through a response mapper, HTTP status conventions (200/201/204), or controller tests using `@nestjs/testing` + `supertest` with an in-memory repository.
License
MIT
Metadata
version: 0.1.0
Instructions
78 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (10)

  • CHANGELOG.md
  • LICENSE
  • README.md
  • SKILL.md
  • README.es-ES.md · docs/i18n/
  • README.pt-BR.md · docs/i18n/
  • product.controller.nestjs.ts · examples/
  • package.json
  • controller-pattern.md · references/
  • nestjs.md · references/

SKILL.md (first lines)

# TypeScript DDD Controller

**MANDATORY — READ ENTIRE FILE**: before writing or reviewing any controller, read
[`references/controller-pattern.md`](references/controller-pattern.md) completely.

Then load the framework reference:

- **NestJS 11** (this repo) → also read [`references/nestjs.md`](references/nestjs.md) completely.
- Other frameworks (Express, Fastify, Hono…) are not yet documented; apply the principles from `controller-pattern.md`.

**Do NOT load** sibling DDD skills (`ts-ddd-entity`, `ts-ddd-use-case`, `ts-ddd-repository`, `ts-ddd-dto`, `ts-ddd-value-object`) unless the request explicitly asks for them.

---

## When to trigger this skill

- File path matches `apps/api/src/<bc>/presentation/controllers/*.controller.ts`.
- Request mentions `@Controller`, `@Get/@Post/@Put/@Delete`, `@UseGuards(ApiKeyGuard)`, `ZodValidationPipe`, `mapResultToHttp`, or a response mapper.
- Adding/changing routes for a bounded context (e.g. `celebrations`).
- Wiring controllers into a `<bc>.module.ts`.
- Writing a controller test under `apps/api/test/<bc>/presentation/controllers/*.controller.test.ts`.

## Where controllers live

```
apps/api/src/<bc>/
  presentation/
    controllers/<name>.controller.ts
    guards/api-key.guard.ts
    mappers/<name>-response.mapper.ts
    index.ts                  ← barrel per leaf folder
  application/
    usecases/                 ← injected here
  <bc>.module.ts              ← registers controllers, mappers, guard, use cases
```

Every leaf folder exports through an `index.ts` barrel. Imports across layers use the path aliases `@<bc>/*` (e.g. `@celebrations/application/usecases`) and `@shared/*` (`apps/api/src/shared/*`); inside the same folder use relative paths. Cross-package types come from `@acme/<bc>-contracts` and `@acme/shared` — never `@ddd/shared` or any older name.

## Before You Start

Answer these before writing a handler:

- **Contract**: status + payload? (`200` payload, `201 CREATED`, `204 NO_CONTENT`, `200` for explicit OK on actions like `/publish`).
- **Mutation?**: If yes, `@UseGuards(ApiKeyGuard)` is required (writes are 401 without `x-api-key`, 503 `MUTATIONS_DISABLED` when `API_WRITE_KEY` is unset — see `references/controller-pattern.md`).
- **Wire shape**: Which Zod schema in the contracts package validates `@Body` / `@Param`? Don't redefine wire types locally.
- **Failure mapping**: Is the error code already in `apps/api/src/shared/http/error-codes.ts`? If new, add it there with the right HTTP status before throwing it from a use case.
- **Response shape**: Does the entity need enrichment (signed Storage URLs, ISO dates)? Then go through the response mapper, not raw entity props.

---

## Core Rules

- Controllers are **thin translators** between HTTP and the application layer. No business logic, no domain conditionals, no repository calls.
- **Inject** use cases and mappers via the constructor — never `new UseCase(...)`.
- **Validate at the boundary** with `ZodValidationPipe(schema)` over schemas exported by the BC's contracts package.
- **Map `Result` → HTTP** with `mapResultToHttp(result, ok => …)` from `@shared/http`. Don't throw NestJS exceptions directly from controller handlers.
- **Mutations** carry `@UseGuards(ApiKeyGuard)`. Reads stay public.
- **Enrich** entity → response DTO inside a dedicated mapper (e.g. `CelebrationResponseMapper`) — that's where signed URLs, date serialization, and tagged-union variant handling live.

## NEVER

- **NEVER** apply `@UseGuards(ApiKeyGuard)` at the class level. **Why**: it 401s every read. The canonical `CelebrationsController` mixes public reads (`GET /celebrations`, `GET /celebrations/:slug`) with per-method-guarded writes; a class-level guard breaks that mix and silently breaks the public web client. Always attach `@UseGuards(ApiKeyGuard)` to each mutating handler individually.
- **NEVER** `throw` a NestJS `HttpException` (or its subclasses like `BadRequestException` / `NotFoundException`) directly from a controller. **Why**: the error-code catalog in `apps/api/src/shared/http/error-codes.ts` is the single source of truth for `code → HTTP status` mapping. Throwing inline forks that mapping, defeats the `Result` pattern in use cases, and produces envelopes that don't match `HttpExceptionFilter`. Always pipe `Result` failures through `mapResultToHttp`.
- **NEVER** put domain logic, branching, or repository access inside a controller method.
- **NEVER** instantiate use cases or mappers with `new` — breaks DI and tests.
- **NEVER** remove `ApiKeyGuard` on a write to "fix" a 503; the 503 is the intentional `MUTATIONS_DISABLED` contract when `API_WRITE_KEY` is unset.
- **NEVER** redefine wire-shape interfaces in the controller; import the DTO type + Zod schema from `@acme/<bc>-contracts`.
- **NEVER** leak entity internals (e.g. `Date` objects, raw `storagePath` without signed URL) into the response — funnel through the mapper.

---

## References

- [`references/controller-pattern.md`](references/controller-pattern.md) — repo-grounded: folder layout, `ZodValidationPipe`, `ApiKeyGuard` semantics, `mapResultToHttp`, response mapper, test strategy (enum members in fixtures).
- [`references/nestjs.md`](references/nestjs.md) — NestJS 11 patterns actually used here: DI symbol tokens (`FIREBASE_APP`), `@Inject(SYMBOL)`, `@Global()` modules (`FirebaseModule`, `AppConfigModule`), Zod-validated `ConfigModule.forRoot`, `@nestjs/testing` + `supertest` test bed.
- [`examples/product.controller.nestjs.ts`](examples/product.controller.nestjs.ts) — runnable-style mirror of `CelebrationsController`.

From llodev/skills, MIT.

More from llodev/skills

Signals

Stars
2
Forks
0
Open issues
0
Last commit (this folder)
Jul 17, 2026 (3 months ago)
Last release
Aug 21, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

Version
0.1.0
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from llodev

Cite this page

ts-ddd-controller skill. Agent Mart. https://agentmart.dev/skills/llodev-ts-ddd-controller (last updated 2026-10-24)