use-case

SKILL.md

Implement the use case: $ARGUMENTS

Follow this exact sequence (TDD + Hexagonal Architecture):

Step 1: Write the failing use case test (RED)

Create the test file FIRST in tests/application/use-cases/.

tests/application/use-cases/$ARGUMENTS.test.ts

The test should:

  • Use describe with the use case name
  • Start with the happy path
  • Reference any fakes it needs (they may not exist yet — that's fine)
  • Run pnpm run test and confirm it FAILS

Step 2: Identify needed dependencies

Before making the test pass, check if the use case needs:

  • New Value Objects in src/domain/models/
  • New Entities/Aggregates in src/domain/models/
  • New Domain Errors in src/domain/errors/
  • New Output Ports in src/domain/ports/

Reuse existing domain objects when possible.

Step 3: TDD the output port adapter (nested cycle)

If a NEW output port is needed, pause the use case cycle and TDD the adapter first:

3a. Define the output port interface

Create the interface in src/domain/ports/. This defines what the domain needs from the outside world.

3b. Write the contract test

Create a contract test that defines the expected behavior of ANY implementation of this port. Contract tests belong to the application layer — they define how the application expects the port to behave:

tests/application/ports/<PortName>.contract.ts

The contract is a reusable function that receives a factory. Add test cases for every method the use case will need.

3c. Write the fake test file

Create a test file that runs the contract with the fake:

tests/application/ports/Fake<PortName>.test.ts

Run pnpm run test — the contract tests should FAIL (fake doesn't exist yet).

3d. Implement the fake (GREEN)

Create the fake implementation. Fakes belong to the application layer — they are test doubles for the application's ports:

tests/application/ports/Fake<PortName>.ts

Write the minimum code to make the contract tests pass. Run pnpm run test to confirm.

Now resume the use case cycle.

Step 4: Implement domain objects

Create any needed Value Objects, Entities, Aggregates, and Domain Errors. Keep them minimal — only what the current use case test requires.

Step 5: Implement the use case (GREEN)

Create the implementation in src/application/use-cases/.

src/application/use-cases/$ARGUMENTS.ts

The implementation should:

  • Receive output port dependencies via constructor injection
  • Contain ONLY orchestration logic (business rules belong in the domain)
  • Write the MINIMUM code to make the test pass

Run pnpm run test to verify the use case test passes.

Step 6: Add edge cases and error tests

Add tests for:

  • Invalid inputs
  • Domain error scenarios
  • Boundary conditions

For each new test: RED → GREEN → refactor. If a new test requires a new method on an output port, go back to Step 3 and add it to the contract first.

Step 7: Refactor

With all tests green:

  • Extract Value Objects if primitives are being passed around
  • Ensure domain logic is in the domain layer, not the use case
  • Check naming follows ubiquitous language
  • Verify the contract test covers all repository behaviors used by the use case
Weekly Installs
1
First Seen
3 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1