Use Case Pattern

Use Case Pattern: методология, где описывают не изменение, а систему, и спека живёт столько же, сколько сервис. Паттерн, уровни зрелости, биндинги и скиллы.

Статья внедрена в скилл AI-агента ucp-pattern-review / ucp-pattern-design Эталонная библиотека к статье usecase-pattern

An optional layer — for those who want to understand the engine. The courses and learning programs run on this methodology, but you don't need to start here. Open this section when you want to understand what is under the hood of a product and how to apply the method yourself.

Use Case Pattern is a methodology, not a library. Four components:

  1. The pattern itself. UseCase + Handler + Dispatcher — a single way to describe business operations in code.
  2. Specification. A universal template for what must be described about a service; stored in git as code.
  3. Three maturity levels. How the pattern and the specification grow as the service grows — from a layered MVP to DDD with dozens of integrations.
  4. The end-to-end case. A business description of a marketplace, against which the pattern, the specification, and the maturity levels are all tested. Without it, the methodology stays theory.

The skills for AI agents work with all four — they're a tool, not a separate component.

Contract and bindings

All four components are language-neutral — that's the methodology's contract. The implementation for a specific stack is provided by language bindings: the same rules, the same codes, their own idioms. The second axis is specialization: backend (the main track), frontend (React + TypeScript, a scaffold), e2e (reserved).

BindingStackStatus
JavaSpring Boot, jOOQ, reference librariesready — articles in the Standards
PythonFastAPI, SQLAlchemy, Pydanticready — style guide and ucp-py-* skills in the skills repo
NodeNestJS, TypeORM, class-validatorready — style guide and ucp-node-* skills in the skills repo
Gonet/http + chi, sqlcin progress

The rule is the same on any stack: R-UC-1 means "one UseCase — one business operation" in Java, in Python, and in Node alike — only how it looks in code changes. That's why a team on any of these stacks reads the same contracts, and the AI skills check the same rule codes.


1. The pattern itself

Every business operation is a separate UseCase and a separate UseCaseHandler. Between the input (HTTP, queue, cron) and the output (the database, external APIs) runs a UseCaseDispatcher that matches them by type.

input HTTP, queue, schedule inbound adapter translates the request into a UseCase UseCaseDispatcher finds the handler by UseCase type UseCaseHandler the business logic of one operation outbound adapter storage, external services

Between the request and the logic sits the operation type, not a controller: the handler does not care whether the call came over HTTP, from a queue or on a schedule.

The essentials:

  • One UseCase — one business operation. CreateOrder, ConfirmPayment, GetOrderById. No "universal services".
  • Controllers, queue handlers, and cron are different inbound adapters to the same UseCase.
  • Layers don't mix data models. Between them — explicit mapping.

The pattern is language-neutral. For Java there's a ready-made library, usecase-pattern; in the Python and Node bindings the pattern is assembled by hand from lightweight interfaces — exactly how is described by the binding guides in the skills repo.


2. Specification as code

At the core of the methodology lies a simple rule: the specification is code. Not a Word document, not a Confluence page, not a PDF from an analyst. A Markdown file in the same repository as the service's code.

What follows from this:

  • The spec lives in git next to the code and goes through PR review like any commit.
  • The change history is visible in git log — who changed a rule, when, and why.
  • The format is structured: 16 sections with headings, tables, and lists. Both people and tools read it — linters, code generators, AI agents.
  • Contracts are derived, not duplicated: OpenAPI comes out of the "Commands" section, AsyncAPI out of "Domain Events", aggregate scaffolds out of "Domain Model".
  • The spec and the code must match. A discrepancy is a bug, not "we'll fix it later".

The depth of the spec = the service's maturity level (a single axis, 0–3), which the spec declares via the level field in the frontmatter:

  • Level 0 — As-is. The spec is reconstructed from existing code without a business brief (ucp-spec-tier-0): a snapshot of "how it is now", with not-declared for the gaps. A starting point for migration.
  • Level 1 — Layered. A minimal spec from a business brief: glossary, ER diagram, operations, rules. No aggregates or events.
  • Level 2 — Use Case Pattern. UseCases and command/query cards are added; CQRS + Read Model is optional.
  • Level 3 — DDD + Hexagonal. Full depth: aggregates, value objects, domain events, sagas, contracts on the edges.

→ Use Case specification: the universal template + 9 role guides (BA, architect, developer, QA, DevOps, security, designer, maintenance, AI agent).

Spec → AI agents

Because the specification is structured code, automation tools apply to it. For every article on the site there's a Claude Code skill that reads the spec and:

  • generates API contracts from the "Commands" section (ucp-api-design);
  • generates aggregates and events from "Domain Model" (ucp-ddd-tactical-design);
  • generates UseCase + Handler from "Use Cases" (ucp-pattern-design);
  • checks the code against the spec's rules (ucp-pattern-review, ucp-ddd-tactical-review).

There are skills for every binding: ucp-* — Java, ucp-py-* — Python, ucp-node-* — Node. The installer sets up the slice for the team's language and specialization (UCP_LANG × UCP_TRACK).

An article with an attached skill shows a yellow badger on the site. Articles with a reference library get a green one. With a reference example project — blue. All skills are in github.com/remodov/usecase-pattern-skills.


3. Maturity levels

The methodology is a ladder. Each next level adds an answer to a problem the previous one can no longer handle. You move up when there's a reason, not "because it's fashionable". The level is a single axis; the spec declares it via the level field.

Level 0 — As-is

The spec is reconstructed from existing code without a business brief (ucp-spec-tier-0) — a snapshot of "how it is now". Not a place to live, but a starting point. When to use: a brownfield service in production without a spec, onboarding, before a migration. When to leave: right after onboarding — you replace not-declared with business facts and design the target level.

Level 1 — Layered

Classic layered architecture (Controller → Service → Repository), without usecase-pattern. The base rung. When to use: CRUD, thin business logic, an MVP, an internal tool. When to leave: when operations in service classes become indistinguishable and you need per-operation metrics/audit.

Level 2 — Use Case Pattern

Every business operation is a separate UseCase and handler; one shared route, per-operation metrics. CQRS (commands/queries + a Read Model) is an option at this level, when reads and writes diverge in load. When to use: a noticeable number of operations, you need structure. When to leave: when there are so many business rules that they "spread out" across handlers.

Level 3 — DDD + Hexagonal

An explicit domain model (aggregates, value objects, domain events) + infrastructure isolation via ports and adapters, with boundary checks by ArchUnit. Business logic lives in the domain, infrastructure is swappable. When to use: complex invariants, the language matters, boundaries (Bounded Contexts) are carved out, dozens of integrations, a long lifespan.

A hint for choosing

What's in the projectLevel
CRUD, thin business logic, an MVP1
A noticeable number of operations; different load on reads and writes2
Complex invariants, a domain language, many integrations, isolation from infrastructure3

Within one service, different modules can live at different levels: the business core at level 3, reference data at level 1. That's normal and often more worthwhile than "everything at level 3 for uniformity". As-is from existing code — Level 0.


4. The end-to-end case

The methodology stays theory until it's grounded in a concrete business. That's why it comes with an end-to-end case — a marketplace: a business description in the "how I understood the task" format, without architectural terms.

The case is an equal part of the methodology:

  • A starting point for every new service. Before the spec and the code — the text about the business. If the business isn't articulated, there's no point going further.
  • A reference for the skills. The business description is run through the skills (/api-design, /ddd-tactical-design, /usecase-pattern-design), and from it API contracts, aggregates, and UseCases are generated — we see that the methodology works.
  • A shared coordinate system for all the site's articles. DDD, CQRS, Saga, Resilience4j, OAuth2 — everything is examined on the same case. No need to invent a new domain each time.

→ Case: a marketplace — the business description: stakeholders, glossary, processes, rules, errors, target volumes.

From this text the skills derive the artifacts for each service of the case. Already covered:

The remaining services (Customer BFF, Payment, Inventory) will follow as the case grows.


The main rules

Six principles common to all maturity levels. The technical details are in the specialized articles linked below.

  1. One UseCase — one business operation. No "universal services".
  2. Layers don't mix data models. The API model ≠ the domain model ≠ the storage model.
  3. External dependencies sit behind interfaces. The payment gateway, the bus, sending SMS — all through ports.
  4. One business operation — one transaction. All or nothing.
  5. Events are published atomically with the write. No "wrote it, but the event never arrived".
  6. Idempotency is mandatory where it makes sense — payments, order creation, redelivered messages.

Site map

Every layer builds on established practices. The site is a methodical breakdown of each of them.

Controller / inbound adapter

UseCase + Handler (business logic)

Outbound adapter / data

Cross-cutting

Architecture and design

Specification and team


Next