# petich

> A saga engine built around one question: what is left in the system if you die halfway. Steps as interceptors, compensation in reverse, an outbox in the same transaction.

Page: https://kotlin.website/petich

## Why it exists

An operation spanning several services is not one database write. Reserve capacity, claim a
quota, apply the change, hand it downstream, notify — any step can refuse, and by then some
of the earlier ones are already irreversible. `try/catch` does not help: what needs undoing
is not a transaction but actions that already happened, in reverse, and only the ones that
really did.

## What you get

- **One interceptor, both directions.** A step declares `execute()` and `compensate()` in the
  same object, so undo cannot quietly drift from do.
- **Phases** — `ENRICHMENT → VALIDATION → AUTHORIZATION → EXECUTION → POST_PROCESSING` — with
  priority inside each.
- **Waiting for a human** without holding a thread or a connection: the saga is a value, it
  goes to storage and resumes on a later request. With a **deadline**, because a suspended
  saga nobody returns to is a resource leak with better manners.
- **An outbox in the same transaction as the state change**, which makes "the work happened
  but the notification never went out" structurally impossible. A repository without outbox
  support still works — the engine degrades visibly to no events rather than pretending.
- Optimistic locking by version plus a per-saga mutex.

## Install

```kotlin
repositories { maven("https://reposilite.kotlin.website/snapshots") }

dependencies {
    implementation("io.github.youndie:petich-core:0.1.0.2")
    implementation("io.github.youndie:petich-ktor:0.1.0.2")
    implementation("io.github.youndie:petich-postgres:0.1.0.2")
}
```

`petich-outbox-core`, `petich-idempotency` and `petich-scheduler` deliberately do **not**
depend on the core, and are usable on their own.

`petich-postgres` ships no driver and no connection pool: it takes an Exposed `Database` and
does not care what is underneath. Choosing a driver is the application's decision.
