ts-ddd-use-case
Create, review, or guide use case (application service) implementation in a TypeScript + DDD codebase.
Skill by llodev
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-use-case
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.
About
Use cases: backend, testing
Reviews
Write a reviewNo 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-use-case
What's inside
- Skill name
ts-ddd-use-case- Description
- Create, review, or guide use case (application service) implementation in a TypeScript + DDD codebase. Use when the request involves `*.usecase.ts` files under `apps/api/src/<bc>/application/usecases/`, `application/services/<name>.service.ts` orchestrators, `UseCase<IN,OUT>` from `@acme/shared`, NestJS `@Injectable()` + `@Inject(<REPO_TOKEN>)` wiring, `Result.ok` / `Result.fail` / `withFail` / `Result.combine`, repository-port orchestration (`findBySlug`, `save`, `listByStatus`), aggregate state-transitions (`publish`, `addSection`), enum-typed inputs (`CelebrationKind`, `CelebrationStatusEnum.DRAFT`), or use-case tests under `apps/api/test/<bc>/application/usecases/` using `InMemoryCelebrationRepository`.
- License
- MIT
- Metadata
- version: 0.1.0
- Instructions
- 73 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/
- README.md · examples/
- create-greeting.usecase.example.ts · examples/
- package.json
- use-case-pattern.md · references/
SKILL.md (first lines)
# TypeScript DDD Use Case
**MANDATORY — READ ENTIRE FILE**: Before any implementation step, read
[`references/use-case-pattern.md`](references/use-case-pattern.md) completely.
**Do NOT load** other DDD skills (entity, repository, dto, controller) unless explicitly requested.
A use case orchestrates one application intent. It is the only layer allowed to talk to repository ports, domain entities, and other application services in the same bounded context. It **never** throws for expected failures, **never** maps to HTTP, **never** validates VO invariants itself.
---
## Before You Start
Answer these before touching code:
- **Is this an IN→OUT verb (`create-*`, `publish-*`, `add-*`, `list-*`)?** → `application/usecases/<verb>-<noun>.usecase.ts` implementing `UseCase<IN, OUT>`.
- **Is this a reusable orchestrator without a clean IN→OUT shape (allocator, coordinator, resolver)?** → `application/services/<name>.service.ts` exposing one or more domain methods, no `UseCase` interface. See `SlugAllocator` for the canonical pattern.
- **Command or query?** Write/mutation → repository port + domain entity. Read/projection → query port (or `repo.listByX` when the read still returns entities).
- **What fails?** Which pre-conditions must hold? What does each `await` return on `isFailure`?
- **Update or create?** Update requires loading current state first (`findBySlug`/`findById`) and mutating via a named domain method (`publish`, `addSection`, `cloneWith`). Never merge raw input blind.
- **Does the input carry a discriminator/status/kind?** Type it with the **enum-typed union** from contracts (`CelebrationKind`), never `string`. Pass enum members (`CelebrationStatusEnum.DRAFT`), never literals.
---
## Dependency Decision Table
| Goal | Dependency type | Returns |
| -------------------------------------- | ---------------------------------------- | -------------------------------------- |
| Create a new aggregate | `CelebrationRepository.save` | `Result<void>` → return the entity |
| State transition on existing aggregate | `findBySlug` + `save` | `Result<Celebration>` |
| Mutate a nested entity (section, item) | `findBySlug` + `save` (or `saveSection`) | `Result<Section>` (the new sub-entity) |
| List by status / filter | `listByStatus` | `Result<Celebration[]>` |
| Allocate unique slug across retries | `SlugAllocator` (application service) | `Result<Slug>` |
| Existence check before write | `findBySlug` → `Result.fail(NOT_FOUND)` | Domain error code |
| Aggregate across multiple BCs (rare) | Cross-BC contract or domain event | Combined DTO |
---
## Core Rules
- Implement `UseCase<IN, OUT>` from `@acme/shared`: `execute(input: IN): Promise<Result<OUT>>`.
- Decorate the class with `@Injectable()` from `@nestjs/common`. Use cases are providers, registered in the BC module.
- Inject repository ports via `@Inject(<TOKEN>)` using the symbol token from `@<bc>/domain/repositories` (e.g. `CELEBRATION_REPOSITORY`). Never inject the concrete adapter class.
- Type the constructor field with the **port interface** (`CelebrationRepository`), not the Firestore/InMemory class.
- Fail early: every `await` is followed by `if (X.isFailure) return X.withFail;`. Domain error codes go through `Result.fail("CODE")`.
- Delegate every invariant to the entity: call `Entity.tryCreate(...)`, `entity.publish()`, `entity.addSection(...)`, etc. The use case checks `isFailure` and forwards; it does **not** re-validate VOs.
- For enum-backed fields (status / kind / palette / layout / provider) pass enum members from contracts. Literal strings are a bug even when they match — they break refactors and silent renames.
- Imports use workspace aliases: `@acme/shared`, `@acme/<bc>-contracts`, `@<bc>/domain/...`, `@<bc>/application/...`. No relative paths across layers.
- The barrel `apps/api/src/<bc>/application/usecases/index.ts` re-exports every use case; update it the moment a new file lands.
- Class name **drops** the `UseCase` suffix (`CreateCelebration`, not `CreateCelebrationUseCase`). The file extension `.usecase.ts` already encodes the role; doubling it in the class name is noise. Constructor injection sites read better as `private readonly create: CreateCelebration`.
## NEVER
- **NEVER** `throw` inside `execute` for expected failures. Return `Result.fail(...)` or `result.withFail`. Throwing breaks `result-to-http` mapping and lets unhandled exceptions reach NestJS.
- **NEVER** map errors to HTTP status codes here. That is the controller's job (`presentation/<bc>.controller.ts` via `result-to-http`).
- **NEVER** import from `@nestjs/common` other than `Inject` + `Injectable`. No `HttpException`, no `Logger` (use injected logger if needed). No Firebase, no Zod, no DTO classes — those live in `presentation/` and `infra/`.
- **NEVER** re-implement VO validation (slug shape, kind whitelist, palette lookup). Call `Celebration.tryCreate` / `Section.tryCreate`; propagate `withFail`.
- **NEVER** inject the concrete repository (`FirestoreCelebrationRepository`, `InMemoryCelebrationRepository`). Only the symbol token + port interface.
- **NEVER** type a status/kind field as `string`. Use `CelebrationKind` / `CelebrationStatus` from contracts. Never write `status: "draft"`; write `status: CelebrationStatusEnum.DRAFT`.
- **NEVER** update without loading the aggregate first (`findBySlug`). Partial merges destroy existing props.
- **NEVER** put cross-cutting orchestration that doesn't fit IN→OUT into a use case. Promote it to `application/services/<name>.service.ts` (e.g. `SlugAllocator`).
## Result API — project-specific bits
- `result.withFail` — getter that re-wraps a failed `Result<A>` as `Result<B>` without recomputing. Use it for every `if (x.isFailure) return x.withFail;` step. Not the generic `Result` API — this is our shortcut.
- Domain error codes are **SCREAMING_SNAKE_CASE** and catalogued in `apps/api/src/shared/http/error-codes.ts`. Add new codes there before using them in a use case.
## References
See [`references/use-case-pattern.md`](references/use-case-pattern.md) for: real file layout, the canonical create / state-transition / nested-mutation / list snippets, the `application/services/` exception, the test strategy with `InMemoryCelebrationRepository`, enum-fixture rules, and the implementation checklist.
See [`examples/create-greeting.usecase.example.ts`](examples/create-greeting.usecase.example.ts) for a self-contained use case + fake repo + Jest test using enum members.From llodev/skills, MIT.
More from llodev/skills
- 0.563score
ts-ddd-dto
llodev
Create, review, or guide Data Transfer Objects in a TypeScript + DDD monorepo.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-domain-service
llodev
Create, review, or guide pure Domain Service implementation in a TypeScript + DDD monorepo.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-repository
llodev
Create, review, or guide repository contracts and implementations in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-controller
llodev
Create, review, or guide HTTP controllers in a TypeScript + DDD api.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-entity
llodev
Create, review, or guide Domain Entity implementation in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-value-object
llodev
Create, review, or guide Value Object implementation in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-query-cqrs
llodev
Create, review, or guide read-side queries in a TypeScript + DDD CQRS codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.558score
django-schema-design
llodev
Design robust Django database schemas with model best practices, migration patterns, and primary key strategy (incremental, UUID, UUIDv7).
SkillBFreshness: B★ 2Claude Code +9 - 0.558score
pm-tasks-asana
llodev
Asana adapter for the @llodev/pm-tasks-* family.
SkillBFreshness: B★ 2Claude Code +9 - 0.558score
pm-tasks-core
llodev
Core extraction + vocabulary for the @llodev/pm-tasks-* family.
SkillBFreshness: B★ 2Claude Code +9 - 0.558score
pm-tasks-trello
llodev
Trello adapter for the @llodev/pm-tasks-* family.
SkillBFreshness: B★ 2Claude Code +9 - 0.554score
pm-tasks-linear
llodev
Linear adapter for the @llodev/pm-tasks-* family.
SkillBFreshness: B★ 2Claude Code +9
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
- Repository
- github.com/llodev/skills
- Website
- www.npmjs.com/org/llodev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from llodev
- 0.563score
ts-ddd-value-object
llodev
Create, review, or guide Value Object implementation in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-controller
llodev
Create, review, or guide HTTP controllers in a TypeScript + DDD api.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-domain-service
llodev
Create, review, or guide pure Domain Service implementation in a TypeScript + DDD monorepo.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-dto
llodev
Create, review, or guide Data Transfer Objects in a TypeScript + DDD monorepo.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-entity
llodev
Create, review, or guide Domain Entity implementation in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
ts-ddd-repository
llodev
Create, review, or guide repository contracts and implementations in a TypeScript + DDD codebase.
SkillBFreshness: B★ 2Claude Code +9
Cite this page
ts-ddd-use-case skill. Agent Mart. https://agentmart.dev/skills/llodev-ts-ddd-use-case (last updated 2026-10-24)