From praxis
Applies Domain-Driven Design with hexagonal (ports & adapters) architecture. Use when designing backend application structure, separating domain from infrastructure, creating testable boundaries, or when user mentions DDD, ports, adapters, hexagonal, or clean architecture.
How this skill is triggered — by the user, by Claude, or both
Slash command
/praxis:backend-architectureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
icon: 🏗️
icon: 🏗️
Something belongs inside the hexagon if it has no infrastructure dependencies — direct or transitive.
Inside (domain or application):
Outside (adapters):
┌──────────────────────┐
│ Adapters │
│ (implement ports) │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ Application │
│ (orchestration) │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ Domain │
│ (defines ports) │
└──────────────────────┘
Dependencies flow INWARD (down)
MemberEmail*Request → CreateMemberRequest*Response → MemberResponseas*() method → request.asMember() → Memberstatic from(domain) → MemberResponse.from(member)MemberRepository → SqlMemberRepositoryAWS.S3.GetObjectOutput). Map to domain types at the adapter boundary.Rule: Expose only what you use today, in your domain's language.
Single-class — When the SDK is simple (1-3 methods, minimal config). The adapter implements the port and calls the SDK directly.
Two-layer (client + adapter) — When the SDK is complex, needs shared config, or serves multiple adapters:
Use two-layer when: the SDK requires configuration (credentials, regions, connection pools) that would be duplicated across adapters, or when multiple adapters share the same underlying SDK client.
src/
components/
<bounded-context>/
__tests__/
<entry-point>/
index.spec.ts # integration test (handler → use case)
fixtures/ # .approved.txt approval snapshots
domain/
entity/
subscription.ts # entity
valueObject/
subscriptionProduct.ts # value object
repository/
subscriptionRepository.ts # port (interface)
service/
subscriptionFinder.ts # domain service (interface)
event/
subscriptionCreatedDomainEvent.ts # domain event
error/
subscriptionNotFound.ts # domain error
definition/
subscriptionStatus.ts # types, const maps
mapper/
subscriptionMapper.ts # domain mapper
strategy/
subscriptionActiveStrategy.ts # domain strategy
application/
<action>/
<action>UseCase.ts # use case (extends UseCase<Req, Res>)
<action>UseCase.spec.ts # unit test
<action>Request.ts # incoming DTO (type alias)
mapper/
subscriptionResponseMapper.ts # response mapper (static .map())
response/
subscriptionResponse.ts # outgoing DTO (type alias)
event/
paymentOrderedIntegrationEvent.ts # integration event
infrastructure/
controller/
http/<verb>/
<action>GetController.ts # HTTP controller (API Gateway)
<action>GetHandler.ts # Lambda handler export
lambda/<action>/
<action>InvokeController.ts # Lambda-to-Lambda controller
<action>InvokeHandler.ts # Lambda handler export
sns/
on<Event>SnsController.ts # SNS event controller
on<Event>SnsHandler.ts # Lambda handler export
webhook/
<context>WebhookControllerStripe.ts # Stripe webhook controller
persistence/
dynamodb/
<entity>RepositoryDynamoDb.ts # implements port (@injectable)
s3/
<entity>RepositoryS3.ts # implements port (extends S3Repository)
service/
stripe/
<entity>ServiceStripe.ts # external service adapter
network/
<entity>NetworkService.ts # inter-service Lambda invoke adapter
validator/
<action>RequestValidator.ts # request validation (extends ValidatorJoi)
mapper/
<entity>DynamoDbMapper.ts # infra ↔ domain mapping
definition/
dto/
<entity>DbDto.ts # persistence DTO
shared/
domain/
entity/ valueObject/ repository/ service/ event/ error/ definition/
application/
useCases/ mapper/ event/
infrastructure/
clients/ controller/ persistence/ services/ validators/
config/
di/
module/
<bounded-context>.ts # Inversify ContainerModule per context
shared/
index.ts # shared DI bindings
environment.ts # stage guards (isDev, isProd, ...)
Build from the inside out — domain first, infrastructure last, integration at the end:
ports → use case + tests (with fakes) → adapters + tests → integration (tool registration, wiring)
Each layer builds on the previous one. No layer depends on something that hasn't been built yet.
Ports give clean seams for test doubles. Test domain exhaustively with fast unit tests. Test adapters with controlled infrastructure.
npx claudepluginhub acunap/praxis --plugin praxisImplements Clean Architecture, Hexagonal Architecture, and Domain-Driven Design for backend systems. Use when architecting new systems or refactoring for maintainability.
Implements Clean Architecture, DDD, and Hexagonal Architecture patterns in NestJS/TypeScript apps for complex backend structuring, domain layers with entities/aggregates, ports/adapters, use cases, and refactoring anemic models.
Implements Clean Architecture, Hexagonal Architecture (Ports & Adapters), and Domain-Driven Design patterns in Python FastAPI/Flask apps for layered backends, repository patterns, entities/value objects, and testable domain logic.