ワンクリックで
state-change-slice
Knows how to build state change slices
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Knows how to build state change slices
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | state change slice |
| description | Knows how to build state change slices |
A STATE_CHANGE slice represents a business operation that modifies aggregate state through commands and events. This is the core CQRS/Event Sourcing pattern.
{
"sliceType": "STATE_CHANGE",
"title": "slice: <Name>",
"context": "<BoundedContext>",
"commands": [...],
"events": [...],
"readmodels": [...],
"screens": [...],
"processors": [...],
"specifications": [...]
}
Screen (UI) → Command → Aggregate (@CommandHandler) → Event → ReadModel (via @EventHandler Projector)
↓
Automation (if processors exist)
Location: src/main/kotlin/de/alex/<module>/domain/commands/<commandname>/<CommandName>Command.kt
Template:
package de.alex.<module>.domain.commands.<commandname>
import de.alex.common.Command
import org.axonframework.modelling.command.TargetAggregateIdentifier
import java.util.UUID
data class <CommandName>Command(
@TargetAggregateIdentifier var aggregateId: UUID,
// Add fields from slice command definition
// Map types: UUID, String, Date → LocalDate, Integer → Int, Boolean, Decimal → BigDecimal
// Handle cardinality: Single → regular type, Multiple → List<type>
) : Command
Field Mapping Rules:
| Slice Type | Kotlin Type |
|---|---|
| UUID | UUID |
| String | String |
| Date | LocalDate |
| Integer | Int |
| Boolean | Boolean |
| Decimal | BigDecimal |
| Multiple cardinality | List |
| optional: true | Nullable (T?) |
Location: src/main/kotlin/de/alex/events/<EventName>Event.kt
Template:
package de.alex.events
import de.alex.common.Event
import java.util.UUID
data class <EventName>Event(
var aggregateId: UUID,
// Add fields from slice event definition
// Fields typically mirror command fields
) : Event
Location: src/main/kotlin/de/alex/domain/<Aggregate>Aggregate.kt
Template for existing aggregate:
@CommandHandler
fun handle(command: <CommandName>Command): CommandResult {
// Business validation logic
AggregateLifecycle.apply(
<EventName>Event(
command.aggregateId,
// Map command fields to event fields
)
)
return CommandResult(command.aggregateId.toString(), AggregateLifecycle.getVersion())
}
Template for new aggregate creation (when createsAggregate: true):
@CreationPolicy(AggregateCreationPolicy.ALWAYS)
@CommandHandler
fun handle(command: <CommandName>Command): CommandResult {
AggregateLifecycle.apply(
<EventName>Event(
command.aggregateId,
// Map command fields to event fields
)
)
return CommandResult(command.aggregateId.toString(), AggregateLifecycle.getVersion())
}
@EventSourcingHandler
fun on(event: <EventName>Event) {
// Update aggregate state from event
this.aggregateId = event.aggregateId
// Update other state fields
}
Input:
{
"sliceType": "STATE_CHANGE",
"title": "slice: Assign Clerk to Case",
"commands": [{
"title": "Assign Clerk to Case",
"aggregate": "Case",
"fields": [
{"name": "caseId", "type": "UUID", "idAttribute": true},
{"name": "clerkId", "type": "UUID"},
{"name": "hourlyRate", "type": "Decimal"}
]
}],
"events": [{
"title": "Clerk Assigned to Case",
"fields": [...]
}]
}
Generated Files:
src/main/kotlin/de/alex/cases/domain/commands/assignclerktocase/AssignClerkToCaseCommand.ktsrc/main/kotlin/de/alex/events/ClerkAssignedToCaseEvent.ktsrc/main/kotlin/de/alex/domain/CaseAggregate.kt with handlersEnsure the module has a ProcessingGroups file:
Location: src/main/kotlin/de/alex/<module>/ProcessingGroups.kt
package de.alex.<module>
class ProcessingGroups {
companion object {
const val <MODULE> = "<MODULE>"
}
}