بنقرة واحدة
state-change-slice
Generate commands, events, aggregates, REST controllers (POST), and tests for STATE_CHANGE slices
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Generate commands, events, aggregates, REST controllers (POST), and tests for STATE_CHANGE slices
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | state-change-slice |
| description | Generate commands, events, aggregates, REST controllers (POST), and tests for STATE_CHANGE slices |
A STATE_CHANGE slice modifies aggregate state through commands and events. It generates:
domain/commands)events)domain)<context>/slices/<slicename>)Note: STATE_CHANGE slices do NOT generate projections. Those belong to STATE_VIEW slices.
REST Controller (POST) → Command → Aggregate (@CommandHandler) → Event
Location: src/main/java/de/eventmodelers/domain/commands/<CommandName>Command.java
package de.eventmodelers.domain.commands;
import de.eventmodelers.common.Command;
import org.axonframework.modelling.command.TargetAggregateIdentifier;
import java.util.UUID;
public record <CommandName>Command(
@TargetAggregateIdentifier UUID aggregateId
// Add fields from slice command definition
) implements Command {}
Location: src/main/java/de/eventmodelers/events/<EventName>Event.java
package de.eventmodelers.events;
import de.eventmodelers.common.Event;
import java.util.UUID;
public record <EventName>Event(
UUID aggregateId
// Add fields from slice event definition
) implements Event {}
Location: src/main/java/de/eventmodelers/domain/<Aggregate>Aggregate.java
For new aggregate (createsAggregate: true or first command):
@CreationPolicy(AggregateCreationPolicy.ALWAYS)
@CommandHandler
public CommandResult handle(<CommandName>Command command) {
AggregateLifecycle.apply(
new <EventName>Event(
command.aggregateId()
// Map command fields to event fields
)
);
return new CommandResult(command.aggregateId(), AggregateLifecycle.getVersion());
}
For existing aggregate:
@CommandHandler
public CommandResult handle(<CommandName>Command command) {
// Business validation logic
AggregateLifecycle.apply(
new <EventName>Event(
command.aggregateId()
// Map command fields to event fields
)
);
return new CommandResult(command.aggregateId(), AggregateLifecycle.getVersion());
}
@EventSourcingHandler
public void on(<EventName>Event event) {
this.aggregateId = event.aggregateId();
// Update other state fields
}
Location: src/main/java/de/eventmodelers/<context>/slices/<slicename>/<SliceName>Controller.java
package de.eventmodelers.<context>.slices.<slicename>;
import de.eventmodelers.domain.commands.<CommandName>Command;
import de.eventmodelers.common.CommandResult;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequestMapping("/api/<context>")
public class <SliceName>Controller {
private final CommandGateway commandGateway;
public <SliceName>Controller(CommandGateway commandGateway) {
this.commandGateway = commandGateway;
}
@PostMapping("/<resource>")
public ResponseEntity<CommandResult> execute(@RequestBody <CommandName>Command command) {
var result = commandGateway.sendAndWait(command);
return ResponseEntity.ok(result);
}
@GetMapping("/debug/<command-name-kebab-case>")
public ResponseEntity<CommandResult> debug(
@RequestParam(required = false) UUID aggregateId,
@RequestParam <Type> <fieldName>
// Add @RequestParam for each command field
) {
var command = new <CommandName>Command(
aggregateId != null ? aggregateId : UUID.randomUUID(),
<fieldName>
// Map all parameters to command
);
var result = commandGateway.sendAndWait(command);
return ResponseEntity.ok(result);
}
}
Debug endpoint notes:
/debug/register-customer) to avoid conflicts with STATE_VIEW endpointsaggregateId is optional - generates a new UUID if not provided@RequestParamLocation: src/test/java/de/eventmodelers/<context>/slices/<slicename>/<CommandName>Test.java
package de.eventmodelers.<context>.slices.<slicename>;
import de.eventmodelers.domain.<Aggregate>Aggregate;
import de.eventmodelers.domain.commands.<CommandName>Command;
import de.eventmodelers.events.<EventName>Event;
import org.axonframework.test.aggregate.AggregateTestFixture;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.UUID;
class <CommandName>Test {
private AggregateTestFixture<<Aggregate>Aggregate> fixture;
@BeforeEach
void setUp() {
fixture = new AggregateTestFixture<>(<Aggregate>Aggregate.class);
}
@Test
void <specTitleAsCamelCase>() {
var aggregateId = UUID.randomUUID();
fixture
.given(/* events from spec.given */)
.when(new <CommandName>Command(aggregateId, /* fields from spec.when */))
.expectSuccessfulHandlerExecution()
.expectEvents(new <EventName>Event(aggregateId, /* fields from spec.then */));
}
}
| Slice Type | Java Type |
|---|---|
| UUID | UUID |
| String | String |
| Date | LocalDate |
| Integer | Integer |
| Boolean | Boolean |
| Decimal | BigDecimal |
| Multiple cardinality | List |
| optional: true | @Nullable T |
Location: src/main/java/de/eventmodelers/<context>/ProcessingGroups.java
package de.eventmodelers.<context>;
public final class ProcessingGroups {
public static final String <CONTEXT> = "<CONTEXT>";
private ProcessingGroups() {}
}
Generate event-driven automation processors for AUTOMATION slices
Generate projection integration tests from STATE_VIEW specifications
Transform slice definitions from config.json into executable Java code
Generate read models, projectors, queries, and REST controllers (GET) for STATE_VIEW slices