# `Chronicle.Captures.Capture`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle/captures/capture.ex#L4)

DSL for defining discoverable Chronicle captures.

A capture turns data that arrives from outside the event log — an external API, a webhook,
or another event store's public events — into events appended to this event store. The DSL
compiles at build time to [Capture Declaration Language](https://github.com/Cratis/Chronicle/blob/main/Documentation/captures/capture-declaration-language/index.md)
(CDL) text, the same text format the Chronicle kernel's Workbench and `SaveCapture` accept.

## Example

    defmodule MyApp.Captures.InvoiceCapture do
      use Chronicle.Captures.Capture, name: "InvoiceCapture"

      api_source "InvoicingApi", route: "/invoices", poll: "10m"

      key "id"

      append MyApp.Events.InvoiceStatusChanged, when: "status" do
        set :status, "$.status"
      end
    end

## Options for `use Chronicle.Captures.Capture`

  * `:name` — the capture's name. Defaults to the module's last segment.
  * `:id` — the capture's stable id (a GUID string). Defaults to a deterministic UUIDv5
    derived from the module's full name, so re-registering the same module updates the
    same kernel-side capture instead of creating a new one.
  * `:start` — when `true`, `Chronicle.Captures.Registrar` starts the capture after
    registering it (opt-in; defaults to `false`, leaving a freshly saved capture stopped).

## Sources (exactly one is required)

  * `api_source/1,2` — polls an [External Service](https://github.com/Cratis/Chronicle/blob/main/Documentation/external-services/index.md)
    by name. Options: `:route`, `:poll` (e.g. `poll: "10m"`).
  * `webhook_source/1` — an inbound webhook at the given path.
  * `events_source/1` — captures from the public events of another event store, given as a
    list of registered `Chronicle.Events.EventType` modules.

Only `api_source` and `events_source` captures are run by the Chronicle engine as of
Chronicle 19.6; see the CDL documentation linked above.

## Key

`key/1` names the property path (on the captured item) used to identify and diff it between
observations. For an `events_source`, use `"$eventSourceId"` to key on the incoming event's
event source.

## Map (optional)

`map do ... end` declares operations applied to the captured item before `append` reads it:

    map do
      rename :full_name, :fornavn
      template :greeting, "Hello, ${fornavn}"
      translate :status, :status, [{"aktiv", "active"}, {"inaktiv", "inactive"}]
      split :full_name, by: ",", into: [:first_name, :last_name]
    end

## Append

The kernel's CDL parser requires an append's event type to start with an uppercase letter
(letters, digits, and underscores only - no hyphens), even though it is otherwise free to
register event types with any id. Register the event type you intend to append from a
capture with a matching id (`id: "InvoiceStatusChanged"` rather than
`id: "invoice-status-changed"`); `append/2,3` raises `ArgumentError` at compile time
otherwise, rather than letting the capture fail validation on the kernel.

`append/2,3` declares an event to append when its `when:` condition matches. `set/2` inside
its block maps a target field of the event's struct from a source expression (`"$.path"` for
the current payload, `"$previous.path"` for the previous one, `"$context.<property>"` for
the capture/event context, `"$env.VARIABLE"` for an environment lookup):

    append MyApp.Events.CustomerChanged, when: {:any, ["firstName", "lastName"]} do
      set :first_name, "$.firstName"
    end

`when:` accepts:

  * a string — `when: "status"` (fires when that property changes)
  * `{:any, [...]}` / `{:all, [...]}` — `"p1 or p2"` / `"p1 and p2"`
  * `{:transition, property, from, to}` — `"status from a to b"`
  * `:added` / `:removed`
  * `{:expression, "template"}` — a raw CDL expression

## Nested and children scopes

    nested :billing_address do
      map do
        rename :street, :"fakturaAdresse.gate"
      end

      append MyApp.Events.BillingAddressChanged, when: "street" do
        set :street, "$.street"
      end
    end

    children :line_items, identified_by: :line_number do
      append MyApp.Events.ItemAdded, when: :added do
        set :line_number, "$.lineNumber"
      end
    end

## Introspection

    MyApp.Captures.InvoiceCapture.__chronicle_capture__(:id)
    MyApp.Captures.InvoiceCapture.__chronicle_capture__(:name)
    MyApp.Captures.InvoiceCapture.__chronicle_capture__(:declaration)

## Registering with Chronicle.Client

    {Chronicle.Client,
      ...
      captures: [MyApp.Captures.InvoiceCapture]}

Or use `otp_app:` auto-discovery — modules that export `__chronicle_capture__/1` are
discovered automatically. See `Chronicle.Captures.Registrar` for how registration happens.

# `api_source`
*macro* 

Declares an API source, polling the named External Service.

# `append`
*macro* 

Appends an event when its `when:` condition matches. See the moduledoc.

# `children`
*macro* 

Declares a child collection scope, identified by a per-item key. See the moduledoc.

# `events_source`
*macro* 

Declares an events source, capturing from the public events of another event store.

`events` is a list of registered `Chronicle.Events.EventType` modules.

# `key`
*macro* 

Names the property path used to identify and diff a captured item.

# `map`
*macro* 

Declares map operations for the capture's root scope. See the moduledoc.

# `nested`
*macro* 

Declares a nested object scope. See the moduledoc.

# `webhook_source`
*macro* 

Declares an inbound webhook source at the given path.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
