xiaohongshu
xiaohongshu
ddd-da-massa
Practical DDD patterns for Jakarta EE web applications with cognitive load distribution. Use when designing controllers, entities, services, or evaluating cohesion and load balance.
Full skill instructions
Practical Domain-Driven Design patterns for web applications, applying Cognitive Load Theory to create maintainable code. Based on Alberto Souza's "DDD da Massa".
Enable web application development that does what's necessary, has sufficiently flexible design, and where understanding most of the project requires low effort.
Different parts of a web application have different complexity budgets:
| Component | Max Points | Rationale |
|---|---|---|
| Controller/Resource | 7 | Handles information flow, must be clear |
| Domain Service | 7 | Business flow should be easily understood |
| Form/Request DTO | 9 | Transient state with transformation logic |
| Entity | 9 | Persistent state with behavior |
| Repository | 3 | Framework does the heavy lifting |
| Infrastructure | ∞ | Rarely touched, OK to be complex |
| Configuration | ∞ | Template, rarely modified |
Every method in a controller must use ALL injected dependencies.
@Path("/orders/{orderId}/payments")
@RequestScoped
public class OrderPaymentResource {
@Inject
private OrderRepository orders; // Used by all methods
@Inject
private PaymentGateway gateway; // Used by all methods
@Inject
private Event<PaymentEvent> events; // Used by all methods
@POST
@Transactional
public Response processPayment(
@PathParam("orderId") Long orderId,
@Valid PaymentRequest request) {
Order order = orders.findById(orderId)
.orElseThrow(NotFoundException::new);
Payment payment = request.toPayment(order);
PaymentResult result = gateway.process(payment);
events.fire(new PaymentEvent(order, result));
return Response.ok(PaymentResponse.from(result)).build();
}
}
// All 3 dependencies used ✓
DTOs that know how to convert themselves to domain objects.
public record CreateOrderRequest(
@NotBlank String customerId,
@NotEmpty List<@Valid OrderItemRequest> items,
String notes
) {
// Conversion logic lives HERE, not in a separate Mapper
public Order toEntity(Customer customer) {
return new Order(
customer,
items.stream().map(OrderItemRequest::toEntity).toList(),
notes
);
}
}
Entities hold business logic, not just data.
@Entity
public class Bolao {
private Instant expiresAt;
@ElementCollection
private Set<String> invitedEmails;
// ✓ Logic on state lives in the entity
public Participation accept(User participant) {
if (expiresAt.isBefore(Instant.now())) {
throw new InvitationExpiredException();
}
if (!invitedEmails.contains(participant.getEmail())) {
throw new NotInvitedException(participant);
}
return new Participation(this, participant);
}
}
When controller + service roles merge (for simple flows):
@Path("/payments/pagseguro/{orderId}")
@RequestScoped
public class PagseguroPaymentCallbackResource {
@Inject
private OrderRepository orders;
@Inject
private PaymentRepository payments;
@Inject
private Event<NewPaymentEvent> paymentEvents;
@POST
@Transactional
public void processCallback(
@PathParam("orderId") Long orderId,
@Valid PagseguroCallbackRequest request) {
Order order = orders.findById(orderId)
.orElseThrow(NotFoundException::new);
Payment payment = request.toPayment(order);
payments.save(payment);
paymentEvents.fire(new NewPaymentEvent(payment));
}
}
// Acts as both controller AND domain service
If entity has LOW load but calling code has HIGH load → bad distribution:
// ❌ Entity too thin, controller too fat
@POST
public Response accept(@Valid AcceptRequest request) {
Bolao bolao = bolaoRepo.findById(request.bolaoId()).get();
// All this logic should be IN the entity
if (bolao.getExpiresAt().isBefore(Instant.now())) {
return Response.status(422).entity("Expired").build();
}
if (!bolao.getEmails().contains(request.email())) {
return Response.status(422).entity("Not invited").build();
}
// ... more external logic
}
// ✓ Move logic to entity
@POST
public Response accept(@Valid AcceptRequest request) {
Bolao bolao = bolaoRepo.findById(request.bolaoId()).get();
User user = userRepo.findByEmail(request.email()).orElseThrow();
Participation participation = bolao.accept(user); // Entity has the logic
participationRepo.save(participation);
return Response.ok().build();
}
Only create new files when:
Do NOT create classes just because it "feels cleaner".
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience