↑ ↓ to move · Enter to open · Esc to closeTap a result

Architecture
skill · class design · opus

use-case-design

Turns a request into one use case: its boundary, flow and canonical names.

skill · designopuswrites 00-caso-de-uso.mdonly inside docs/use-cases/UC-*/**
§ the file it writes

00-caso-de-uso.md, block by block

A real partial: UC-001-create-customer, in bank-app, excerpted. Hover or click a block to see what the skill fixes there. The sections of the file are also chips: click one to jump to it.

bank-app/docs/use-cases/UC-001-create-customer/00-caso-de-uso.md

UC-001 · Create customer

Parent spec. Fixes the boundary and the names; doesn't detail any layer. Per-layer detail lives in this folder's partials, each with its own owner.
FieldValue
IdentifierUC-001-create-customer
Date2026-10-07
Triggercustomer creation, over HTTP — inbound REST adapter. The exact path and verb belong to rest-api-architect, in 30-rest.md
Accesspublic — anyone may call it, no caller identity required (business fact, user's answer). Mechanism, the permitAll reason and status belong to security-architect, in 32-seguranca.md
Side effects1 — INSERT into customers
External callsnone — no side effect reaches a system this service does not own
Publicationnone — no other system needs to learn that a customer was created; no domain event is published by this case
Transactionopens at the use case CreateCustomerUseCase, closes before the response
Repetitionrepeating the request with the same security number must not create a second customer (business fact): one customer per security number, the repeat is a conflict. The mechanism — Idempotency-Key or none — is delegated to rest-api-architect
Concurrencythe uniqueness of the security number is arbitrated by a unique constraint on the stored value; no application-level lock. Two concurrent requests with the same number: one is created, the other is a conflict
Personal datasecurityNumber (national identification number, 11 digits) and birthDate are personal data. They never appear in clear in logs — @.claude/rules/personal-data.md, @.claude/rules/logging.md. The response carries only a reference, so neither leaves the service in a response body
Active blueprintclean-architecture-single-module

## Trigger, payload, and response

In

FieldTypeRequiredRule
namestring✅leading and trailing whitespace trimmed; after trimming, not blank and 2 to 120 characters
securityNumberstring✅exactly 11 numeric digits (0–9); no check-digit validation; unique in the system
birthDatedate✅the customer's 18th birthday is strictly before today (a customer whose 18th birthday is today is rejected); the customer is not over 130 years old today; a date in the future is rejected

How "today" and the anniversaries are computed:

  • "Today" is the current calendar date taken from the application's clock, never from the
  • The N-th birthday is birthDate plus N calendar years. For a birthDate of 29 February,
  • Accepted when birthDate + 18 years < today and birthDate + 131 years > today —

Out

Situations, not statuses. The HTTP code for each is rest-api-architect's decision.

… cut here, the rest is in the file

## Flow

  1. The inbound adapter receives the request and validates the payload's shape.
  2. Translates it into the command CreateCustomerCommand.
  3. The use case CreateCustomerUseCase executes: checks through the outbound port
  4. The outbound port CustomerRepository persists it. A unique-constraint violation from a
  5. The adapter translates the returned aggregate into the response — a reference only.

Nothing in this flow names annotations, columns, or framework types — that belongs to the partials.

## Components

State: NEW to be created · CHANGE already exists and changes · REUSE already exists and serves.

Paths relative to src/main/java/dev/nerviz/bankapp/ unless they start with src/.

… cut here, the rest is in the file

## Invariants

RuleGuaranteed byWho violates it
securityNumber is exactly 11 numeric digitsthe security number's creationcaller with letters, punctuation, or a different length
securityNumber is unique in the systemcheck at the outbound port + unique constraintsecond registration, or a race between two requests
name, trimmed, is 2 to 120 characters and not blankCustomer's creationblank or overly long payload
18th birthday strictly before todayCustomer's creation, against the clock's datea minor, or a customer whose 18th birthday is today
completed age at most 130Customer's creation, against the clock's datea typo such as 1825 instead of 1985
birthDate is not in the futureCustomer's creation, against the clock's datea typo, or a wrong date format interpreted

Invariants live in the aggregate, never in the caller — @.claude/rules/architecture-ddd.md.

## Errors

SituationKind
security number already registeredconflict with existing state
customer not strictly over 18business rule
security number not exactly 11 digitsvalidation
name blank or outside 2 to 120 charactersvalidation
birth date in the future, or age over 130validation
required field missing, or a date that does not parseshape — rejected in the adapter, never reaches the domain

Situations and kinds, never exception names or statuses. The exception class and errorCode belong to 10-dominio.md (@.claude/rules/error-handling.md); the HTTP mapping belongs to 30-rest.md.

## Expected tests

LevelTargetDetailed by
unitCustomer: name trim and length, 11-digit security number, age boundaries (18th birthday yesterday / today / tomorrow, 29 February, age 130 / 131, future date) with a fixed clocktest-architect
unituse case: security number already registered is a conflict, nothing persistedtest-architect
slicecontroller: created with reference only, malformed payload, each validation error, under-age, conflicttest-architect
integrationCustomerRepositoryJpaAdapter against a real database, including the unique constrainttest-architect

## Out of scope for this use case

Written down so nobody merges it back in by accident:

  • Reading, updating and deleting a customer → their own use cases, their own triggers; not
  • Check-digit validation of the security number (Brazilian CPF algorithm) → decided against:
  • Publishing a CustomerCreated event → no consumer exists; a future case that needs it adds
  • Authentication of the caller → the endpoint is public by decision.

## Impact on approved use cases

none — UC-001 is the first case.

## Implementation order

Derived from the Components table, in compile order.

  • [ ] 1. domain typed fields (SecurityNumber, and name / birth date if typed)
  • [ ] 2. domain/model/Customer.java
  • [ ] 3. domain exceptions — named in 10-dominio.md
  • [ ] 4. application/usecase/customer/CreateCustomerCommand.java
  • [ ] 5. application/port/CustomerRepository.java
  • [ ] 6. application/usecase/customer/CreateCustomerUseCase.java
  • [ ] 7. src/main/resources/db/migration/V1__create_customers.sql
  • [ ] 8. infrastructure/persistence/customer/ (entity, Spring Data, adapter)
  • [ ] 9. infrastructure/rest/ (DTOs, mapper, controller, exception handler)
  • [ ] 10. tests for the levels above
  • [ ] 11. ./mvnw clean verify green
Open the full file on GitHub →
§ behavior

What it reads, writes and refuses

The skill's own contract, from SKILL.md, in the original wording.

Class

design — the territory is skill_classes.design in @.claude/schemas/extensions.json and ArchHook.java guard enforces it. Writes inside the use case folder and the backlog, nothing else; a write anywhere outside is refused with exit 2, not reported.

Reads

@.claude/rules/architecture-ddd.md (Application section — where the transaction opens, what doesn't go in the signatures), @.claude/rules/naming.md, @.claude/rules/error-handling.md (the four kinds only — names belong to domain-modeling), @.claude/rules/api-graphql.md (§ Choosing the inbound protocol only, for an HTTP trigger), @.claude/rules/spec-diagrams.md (the sequence diagram and the flowchart) with references/mermaid-use-case-diagrams.md, @.claude/rules/spec-external-facts.md (every fact about another system carries a source), the active blueprint's packages.map and naming convention, and this skill's references/scope-boundary.md before counting effects.

Writes

docs/use-cases/UC-NNN-<slug>/00-use-case.md and appends to docs/use-cases/BACKLOG.md. Only those. The 10- through 40- partials belong to the layer skills; the consolidated UC-NNN-spec.md belongs to the /new-feature orchestrator.

Owns

the use case number and slug. No other piece assigns them.

Shares one sequence, with one other named writer

BL-NN is assigned here when a split appends a backlog row, and by /new-feature's consolidation when a partial defers something to the backlog. Those two, never a third: a design skill that appended its own row would compute "highest plus one" against the same file in the same run and issue a duplicate.

Does not

edit an approved spec (status: approved, implemented or implemented-blocked) — reads it as a contract, and records the needed change in its own impact section.

Does not

write code, tests, migrations, or OpenAPI, and never writes under src/. Doesn't touch the inbound REST adapter — the package the blueprint's packages.map gives that role (rest-api-architect) —, the domain or application (gof-design-patterns, domain-modeling), nor .claude/rules/**. Doesn't weigh a storage technology: records the storage family and the search engine the request states or the user answers.

Does not

reproduce rules. Cites by path; what the rule already says isn't repeated in the spec.

Also carries

examples/ — twelve complete 00-use-case.md fixtures for testing /new-feature and java-spring-boot-developer, indexed in examples/README.md. Meta-repo documentation, not this skill's runtime output: the export manifest keeps only SKILL.md, templates/ and references/, so this directory does not travel.

Source: SKILL.md § Contract, at nerviz e4cae27.

§ guard and hook

What the guard does with it

design is the skill's class. ArchHook opens a phase when the skill is called and checks every write against the class's territory. The text on the right is the hook's own.

write_allow of class design

  • ✓docs/use-cases/UC-*/**
  • ✓docs/use-cases/BACKLOG.md
  • src/**: migrations and classes are the executor's
  • docker-compose.yml: another class's file
  • a use case already approved: its specs are frozen

A refusal exits with code 2 and the message goes back to the model.

PreToolUse  Skill(use-case-design)
  audit call                       exit 0
  guard call                       exit 0
# a skill of another class replaces the phase
# write_allow: docs/use-cases/UC-*/**, docs/use-cases/BACKLOG.md
§ orchestration

Where it sits on the rail

Each card is a step of /new-feature; the arrow carries the partial one step hands to the next. Dashed steps run only when the use case needs them.

/new-feature-implement Who reads the partial next

After approval, /new-feature-implement has the executor build the code. The spec is consolidated by reference and wins where it and a partial disagree; the partial is read, by section, for detail.

00-caso-de-uso.mddocs/use-cases/UC-NNN-…/
read by section, for detail
java-spring-boot-developeragent · executor
writes the code
src/**designs one use case into a spec, writes no code
← back to the chains