Official AI Prompt
Use this prompt to generate a complete saga with Claude, ChatGPT, Cursor, or any other AI.
The Prompt
Copy and paste, replacing [YOUR CONTEXT] with your business flow description:
You will help me implement Sagaweaw in my Spring Boot project.
Sagaweaw is a Java/Kotlin library for distributed transaction orchestration
with automatic compensation. Developers define steps using a fluent builder.
The engine handles persistence, exponential retry, reverse-order compensation,
and a REST observability API (/api/sagas, /api/dead-letters) protected by token.
## Rules — follow these exactly:
- Steps with .compensate() are automatically COMPENSABLE (reversible)
- Steps without .compensate() are automatically PIVOT (point of no return)
- Steps with infinite retry and no compensate() are automatically RETRIABLE
- Never use @Transactional on the Saga class — the engine manages transactions
- The context (SagaContext) carries state between steps
- Use mutable fields (var in Kotlin, non-final in Java) for step outputs in the context
## Two ways to develop and test the saga:
### Case 1 — Saga with no real database dependencies
Add @AutoStart and implement SagaSampler<Context> to provide sample data.
The saga fires automatically on startup when sagaweaw.auto-start.enabled=true.
Sample data does not need to reference real database IDs.
### Case 2 — Saga that needs real database data
Use the built-in trigger endpoint (POST /api/sagas/trigger/{sagaName})
with a real JSON payload containing existing IDs from the database.
## My project context:
[YOUR CONTEXT]
## Based on my context, generate:
1. Which business flow should be a Saga and why
2. The ordered list of steps with their compensations
3. Which step is the PIVOT (point of no return) and why
4. The complete Saga class in [Java / Kotlin — specify which]
5. Whether Case 1 or Case 2 applies for local testing, and why
6. If Case 1 applies: the sampleContext() implementation
7. How to fire the saga from the existing service in production (sagaManager.start())
Example
Input
[YOUR CONTEXT]
I have an e-commerce with:
- InventoryService: reserve(productId, qty) / release(productId, qty)
- PaymentService: charge(customerId, amount) / refund(chargeId)
- ShippingService: schedule(orderId, address) — cannot be cancelled automatically
- NotificationService: sendConfirmation(orderId, email) — must always succeed
I want a saga to process orders. Using Kotlin.
Expected Output
The AI will generate:
Flow analysis:
reserve-stock→ compensate:release-stockcharge-payment→ compensate:refund-paymentschedule-shipping→ PIVOT (once scheduled, cannot be automatically cancelled)send-confirmation→ RETRIABLE (must always succeed, infinite retry)
Case 1 applies — this saga doesn't depend on real DB IDs, so @AutoStart + sampleContext() works.
Complete Kotlin class:
@Saga("order-processing")
@AutoStart
@Component
class OrderProcessingSaga(
private val inventoryService: InventoryService,
private val paymentService: PaymentService,
private val shippingService: ShippingService,
private val notificationService: NotificationService,
) : SagaDefinition<OrderProcessingSaga.Context>,
SagaSampler<OrderProcessingSaga.Context> {
data class Context(
val orderId: UUID,
val customerId: UUID,
val productId: UUID,
val quantity: Int,
val amount: BigDecimal,
val email: String,
val address: String,
var chargeId: String? = null,
) : KSagaContext() {
override fun key() = orderId.toString()
}
override fun sampleContext() = Context(
orderId = UUID.fromString("00000000-0000-0000-0000-000000000001"),
customerId = UUID.fromString("00000000-0000-0000-0000-000000000002"),
productId = UUID.fromString("00000000-0000-0000-0000-000000000003"),
quantity = 2,
amount = BigDecimal("299.90"),
email = "sample@example.com",
address = "Rua das Flores, 123",
)
override fun define(saga: SagaBuilder<Context>): SagaFlow<Context> = saga
.step("reserve-stock") {
invoke { ctx -> inventoryService.reserve(ctx.productId, ctx.quantity) }
compensate { ctx -> inventoryService.release(ctx.productId, ctx.quantity) }
}
.step("charge-payment") {
invoke { ctx ->
ctx.chargeId = paymentService.charge(ctx.customerId, ctx.amount)
}
compensate { ctx ->
ctx.chargeId?.let { paymentService.refund(it) }
}
}
.step("schedule-shipping") { // PIVOT — no compensate
invoke { ctx -> shippingService.schedule(ctx.orderId, ctx.address) }
}
.step("send-confirmation") { // RETRIABLE — infinite retry
invoke { ctx -> notificationService.sendConfirmation(ctx.orderId, ctx.email) }
retry(infiniteRetry(5.seconds))
}
.build()
}
Production wiring:
@Service
class OrderService(private val sagaManager: SagaManager) {
fun placeOrder(request: OrderRequest) {
sagaManager.start<OrderProcessingSaga>(
OrderProcessingSaga.Context(
orderId = UUID.randomUUID(),
customerId = request.customerId,
productId = request.productId,
quantity = request.quantity,
amount = request.totalAmount,
email = request.email,
address = request.address,
)
)
}
}
Tips for Better Results
Do
- Name your existing services and what each one does
- Mention external integrations (Stripe, BACEN, Twilio, AWS SQS)
- Say which operations are irreversible (the PIVOT candidates)
- Mention idempotency requirements
- Specify Java or Kotlin
Avoid
- Vague descriptions like "I have a payments system"
- Asking for sagas for operations that happen in a single database transaction
- Forgetting to mention external service dependencies
IDE Integration
Cursor
- Open chat (Cmd+K / Ctrl+K)
- Paste the prompt with your context
- Review and apply the generated code
GitHub Copilot
- Create a
saga-prompt.mdwith the prompt text - Open Copilot Chat and reference the file
- Ask it to generate based on your services