### Setup Test Adapter Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Adapters.Test.md Clear the test adapter's store before running tests. Call this in your test setup. ```elixir setup do Chimeway.Adapters.Test.clear() :ok end ``` -------------------------------- ### Example Usage: Full Trace and Deliveries Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Demonstrates how to load a full event trace and then access its associated deliveries. ```elixir {:ok, event} = Chimeway.Traces.get_trace("event-uuid-here") event.notifications |> Enum.flat_map(& &1.deliveries) ``` -------------------------------- ### Example Usage: Delivery Explanation Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Shows how to explain a delivery, access its suppression reason, and view its timeline. ```elixir {:ok, explanation} = Chimeway.Traces.explain_delivery("delivery-uuid-here") explanation.suppression_reason #=> "channel_disabled" explanation.timeline #=> [%{at: ~U[...], event: :event_created, detail: %{}}, ...] ``` -------------------------------- ### Example: Forwarding Telemetry to StatsD/Datadog Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Telemetry.md Example of a custom telemetry handler that forwards Chimeway dispatch events to StatsD/Datadog using the Statix library. It extracts relevant metadata to create tags. ```elixir defmodule MyApp.ChimewayStatsD do def handle([:chimeway, :dispatch, :sync, :stop], measurements, meta, _config) do tags = ["channel:#{meta.channel}", "key:#{meta.notification_key}"] Statix.timing("chimeway.dispatch.sync", measurements.duration, tags: tags) end end ``` -------------------------------- ### Example Usage: Find Traces for Recipient Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Illustrates finding recent traces for a recipient, optionally filtering by notification key. ```elixir traces = Chimeway.Traces.find_traces_for_recipient("user:123", notification_key: "order_shipped") ``` -------------------------------- ### clear Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Adapters.Test.md Clears all deliveries from the current process's test adapter store. Recommended to call in test setup or teardown. ```APIDOC ## clear ### Description Clears all deliveries from the current process's test adapter store. Call in test setup/teardown. ### Function Signature `Chimeway.Adapters.Test.clear()` ``` -------------------------------- ### Define a Multi-Step Workflow with Wait and Stop Conditions Source: https://hexdocs.pm/chimeway/1.0.0/multi-step-journeys.md Implement the `Chimeway.Workflow` behavior to define a structured workflow map. This example includes an in-app notification, a 2-hour wait with a stop condition for 'notification_read', and an email escalation. ```elixir defmodule MyApp.Workflows.MentionEscalation do @behaviour Chimeway.Workflow @impl true def workflow(_args) do %{ key: "mention_escalation", version: 1, steps: [ %{ id: "step_in_app", action: %{ type: :notify, channel: :in_app, render_key: "mention_notification" } }, %{ id: "step_wait_for_read", action: %{ type: :wait, duration: "PT2H", # Wait 2 hours (ISO 8601 duration) stop_conditions: [ %{ type: :signal_received, signal_type: "notification_read" } ] } }, %{ id: "step_email_escalation", action: %{ type: :notify, channel: :email, render_key: "mention_email" } } ] } end end ``` -------------------------------- ### Explain a Delivery Source: https://hexdocs.pm/chimeway/1.0.0/cheatsheet.md Get a detailed explanation of a specific delivery by its UUID. The explanation includes the delivery status and a timeline of events. ```elixir {:ok, explanation} = Chimeway.Traces.explain_delivery("delivery-uuid") explanation.status #=> :suppressed explanation.suppression_reason #=> "channel_disabled" explanation.timeline #=> [%{at: ~U[...], event: :event_created, detail: %{}}, ...] ``` -------------------------------- ### Explain a Specific Delivery in IEx Source: https://hexdocs.pm/chimeway/1.0.0/tracing-a-notification.md Use `Chimeway.Traces.explain_delivery/1` in IEx to get a detailed explanation of why a specific notification was or was not delivered, based on its `delivery_id`. ```elixir alias Chimeway.Traces # If you have the delivery_id: Traces.explain_delivery(delivery_id) ``` -------------------------------- ### Define Option Types for WindowMath Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Orchestration.WindowMath.md Defines the possible options that can be passed to window math functions, including time zone, quiet hours start, and quiet hours end. ```elixir @type option() :: {:time_zone, String.t()} | {:quiet_hours_start_minute, non_neg_integer()} | {:quiet_hours_end_minute, non_neg_integer()} ``` -------------------------------- ### Get Full Event Trace Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Load the complete trace for a single event using its event ID. Preloads notifications, deliveries, and attempts. ```elixir Chimeway.Traces.get_trace("event-uuid-here") ``` -------------------------------- ### Secure Runtime Configuration in Adapter Source: https://hexdocs.pm/chimeway/1.0.0/custom-adapter.md Demonstrates reading adapter configuration securely at runtime using `Keyword.get/2` and `Application.get_env/3` within the `deliver/2` function. This ensures multi-environment safety and testability. ```elixir defmodule MyApp.MyCustomAdapter do @behaviour Chimeway.Adapter @impl true def deliver(%Chimeway.Delivery{} = delivery, config) do # Good: Reading config at runtime api_key = Keyword.get(config, :api_key) || Application.get_env(:my_app, :custom_adapter_api_key) # ... external API call ... end end ``` -------------------------------- ### Get Delivery Category Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Policy.md Retrieves the delivery category for a given Chimeway Delivery struct. ```elixir @spec delivery_category(Chimeway.Delivery.t()) :: String.t() | nil ``` -------------------------------- ### explain Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves the state and details of a workflow run. ```APIDOC ## explain ### Description Returns the workflow run state for the given `tenant_id` and `execution_id`. The returned map includes the authoritative State Spine fields plus the current step key for operator-friendly inspection. ### Parameters - `tenant_id`: (String.t()) - The ID of the tenant. - `execution_id`: (Ecto.UUID.t()) - The execution ID (primary key) of the workflow run. ### Returns - `{:ok, map()}`: A map containing workflow run details including `id`, `tenant_id`, `state`, `status_reason`, `current_step_name`, `suspended_until`, `pending_signals`, and `terminal_reason`. - `{:error, :not_found}`: If the workflow run does not exist or belongs to a different tenant. ``` -------------------------------- ### Fetch Project Dependencies Source: https://hexdocs.pm/chimeway/1.0.0/installation.md Run this command in your terminal after updating mix.exs to download the new chimeway dependency. ```bash mix deps.get ``` -------------------------------- ### explain Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Executes an EXPLAIN statement or similar for the given query according to its kind and the adapter in the given repository. ```APIDOC ## explain ### Description Executes an EXPLAIN statement or similar for the given query according to its kind and the adapter in the given repository. This function is safe to execute for updates and deletes, as no data change will be committed. ### Method `explain(:all | :update_all | :delete_all, Ecto.Queryable.t(), opts :: Keyword.t())` ### Parameters #### Path Parameters None #### Query Parameters - **kind** (:all | :update_all | :delete_all) - Required - Specifies the type of operation to explain. - **query** (Ecto.Queryable.t()) - Required - The query to explain. - **opts** (Keyword.t()) - Optional - Additional options for the explain statement, such as `analyze: true` or `timeout: 20000`. ### Request Example ```elixir # Postgres example MyRepo.explain(:all, Post) # MySQL example with a filter MyRepo.explain(:all, from(p in Post, where: p.title == "title")) # Example with options MyRepo.explain(:all, Post, analyze: true, timeout: 20_000) # Explaining an update_all query MyRepo.explain(Repo, :update_all, from(p in Post, update: [set: [title: "new title"]])) ``` ### Response #### Success Response (200) - **String.t() | Exception.t() | [map()]** - The result of the EXPLAIN statement, which can be a string, an exception, or a list of maps depending on the adapter and query. #### Response Example ``` # Postgres output example "Seq Scan on posts p0 (cost=0.00..12.12 rows=1 width=443)" # MySQL output example +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | p0 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.0 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ ``` ``` -------------------------------- ### Configure Oban Queues and Workers Source: https://hexdocs.pm/chimeway/1.0.0/oban-integration.md Set up Oban's configuration in `config/config.exs`, including the Ecto repository, plugins like Pruner and Cron, and defining queues for Chimeway tasks. ```elixir config :my_app, Oban, repo: MyApp.Repo, plugins: [ Oban.Plugins.Pruner, # Configure the ProgressionWorker to run periodically (e.g., every minute) {Oban.Plugins.Cron, crontab: [ {"* * * * *", Chimeway.Workflows.Workers.ProgressionWorker} ]} ], queues: [ default: 10, chimeway_delivery: [limit: 20], # For async dispatch of notifications chimeway_signals: [limit: 10], # For processing workflow signals chimeway_workflows: [limit: 5] # For general workflow progression tasks (if any) ] ``` -------------------------------- ### Generate Chimeway Database Migrations Source: https://hexdocs.pm/chimeway/1.0.0/installation.md Execute this mix task to create the necessary migration files for Chimeway's database schema. ```bash mix chimeway.gen.migrations ``` -------------------------------- ### Get digest rule by ID Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Digests.md Fetches a digest rule using its unique identifier. Raises an error if the rule is not found. ```elixir @spec get_rule!(binary()) :: Chimeway.Digests.DigestRule.t() ``` -------------------------------- ### preview/3 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Rendering.Preview.md Generates a preview of the rendering pipeline. It takes a module, render data, and options, returning either a successful preview or an error. ```APIDOC ## `preview` ### Description Generates a preview of the rendering pipeline. ### Function Signature ```elixir preview(module(), map(), keyword()) :: {:ok, t()} | {:error, term()} ``` ### Parameters * `module()` - The module to use for rendering. * `map()` - The render data to be processed. * `keyword()` - Options for the preview generation. ### Returns * `{:ok, t()}` - On success, returns a tuple with `:ok` and the preview structure. * `{:error, term()}` - On failure, returns a tuple with `:error` and the error term. ``` -------------------------------- ### Run Ecto Database Migrations Source: https://hexdocs.pm/chimeway/1.0.0/installation.md Apply the generated Chimeway migrations to your database using this Ecto command. ```bash mix ecto.migrate ``` -------------------------------- ### Clear Test Adapter Store Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Adapters.Test.md Clears all stored deliveries from the current process's test adapter. Recommended for use in test setup or teardown. ```elixir Chimeway.Adapters.Test.clear() ``` -------------------------------- ### Explain Delivery Suppression Reason Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Get a structured explanation for a specific delivery, including its suppression reason and timeline. Returns an error if the delivery is not found. ```elixir Chimeway.Traces.explain_delivery("delivery-uuid-here") ``` -------------------------------- ### Create Initial Workflow Run Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Creates the initial workflow run record. Requires an Ecto repository, workflow run ID, workflow definition, current DateTime, and a string identifier. ```elixir @spec create_initial_run( Ecto.Repo.t(), Ecto.UUID.t(), Chimeway.Workflows.WorkflowDefinition.t(), DateTime.t(), String.t() ) :: {:ok, Chimeway.Workflows.WorkflowRun.t()} | {:error, term()} ``` -------------------------------- ### Get Terminal Delivery States Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Deliveries.md Returns a list of terminal delivery states. This is used by the dispatcher to avoid processing deliveries that are already in a final state. ```elixir terminal_states() ``` -------------------------------- ### create_initial_run Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Creates the initial workflow run record. ```APIDOC ## create_initial_run ### Description Creates the initial workflow run record. ### Parameters - `repo`: (Ecto.Repo.t()) - The Ecto repository. - `workflow_run_id`: (Ecto.UUID.t()) - The ID for the new workflow run. - `workflow_definition`: (Chimeway.Workflows.WorkflowDefinition.t()) - The workflow definition. - `start_time`: (DateTime.t()) - The start time of the workflow run. - `tenant_id`: (String.t()) - The tenant ID for the workflow run. ### Returns - `{:ok, Chimeway.Workflows.WorkflowRun.t()}`: The newly created workflow run. - `{:error, term()}`: An error if creation fails. ``` -------------------------------- ### Trace a Notification Source: https://hexdocs.pm/chimeway/1.0.0/cheatsheet.md Retrieve traces for notifications. You can get a full trace by event ID, find all traces for a recipient with optional filters, or search by correlation ID. ```elixir # Full trace by event ID {:ok, event} = Chimeway.Traces.get_trace("event-uuid") # All traces for a recipient traces = Chimeway.Traces.find_traces_for_recipient("user:42", notification_key: "order_shipped", limit: 10 ) # By correlation ID (e.g., request ID) events = Chimeway.Traces.find_traces_by_correlation_id("req-abc") ``` -------------------------------- ### Run Custom SQL Query (Raises on Error) Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Similar to `query/3`, but returns the result directly without an `:ok` tuple and raises an exception on invalid queries. ```elixir @spec query!(iodata(), Ecto.Adapters.SQL.query_params(), Keyword.t()) :: Ecto.Adapters.SQL.query_result() ``` -------------------------------- ### Get Workflow Run by ID Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves the canonical workflow run row by its ID. Raises an error if the row is not found. This is used by the progression service after locking the row within a transaction. ```elixir @spec get_run!(Ecto.UUID.t()) :: Chimeway.Workflows.WorkflowRun.t() ``` -------------------------------- ### resolve Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Dispatch.ChannelAdapterConfig.md Resolves per-channel adapter configuration. ```APIDOC ## resolve ### Description Resolves per-channel adapter configuration without creating atoms from runtime channel data. ### Function Signature ```elixir @spec resolve(String.t(), keyword()) :: keyword() ``` ### Parameters * `channel_name` (String.t()) - The name of the channel. * `opts` (keyword()) - A keyword list of options. ### Returns * `keyword()` - The resolved adapter configuration. ``` -------------------------------- ### Get Current Workflow Step Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves the active workflow step row for a given workflow run. Raises an error if no active step is found. This function is intended for use after locking the workflow run row. ```elixir @spec get_current_step!(Chimeway.Workflows.WorkflowRun.t()) :: Chimeway.Workflows.WorkflowStep.t() ``` -------------------------------- ### Get Active Step Linkage Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves linkage information for an active workflow step. Returns {:ok, map} with workflow run ID, step ID, and channel, or nil if not found. Can also return {:error, term}. ```elixir @spec active_step_linkage(Ecto.UUID.t() | map()) :: {:ok, %{workflow_run_id: Ecto.UUID.t(), workflow_step_id: Ecto.UUID.t(), channel: String.t()} | nil} | {:error, term()} ``` -------------------------------- ### rendering Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Optional callback function to define how a notification should be rendered. It takes context and configuration maps, returning a map with rendering details or an error tuple. ```APIDOC ## rendering *optional* ### Description Optional callback function to define how a notification should be rendered. ### Method `@callback rendering(map(), map()) :: {:ok, map()} | {:error, term()}` ``` -------------------------------- ### emit_bucket Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Digests.Emission.md Emits a digest bucket. It takes a bucket identifier (binary or DigestBucket struct) and a keyword list of options. It returns either an :ok tuple with the emission result or an :error tuple. ```APIDOC ## `emit_bucket` ### Description Emits a digest bucket. ### Function Signature ```elixir emit_bucket(binary() | Chimeway.Digests.DigestBucket.t(), keyword()) :: {:ok, emit_result()} | {:error, term()} ``` ### Parameters * `bucket` - A binary or a `Chimeway.Digests.DigestBucket.t()` representing the bucket to emit. * `options` - A keyword list of options. ### Returns * `{:ok, emit_result()}` - On successful emission, returns a map containing the bucket, digest delivery, and immediate deliveries. * `{:error, term()}` - On failure, returns an error term. ``` -------------------------------- ### Run Multiple Custom SQL Queries (Raises on Error) Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Similar to `query_many/3`, but returns the results directly without an `:ok` tuple and raises an exception on invalid queries. ```elixir @spec query_many!(iodata(), Ecto.Adapters.SQL.query_params(), Keyword.t()) :: [ Ecto.Adapters.SQL.query_result() ] ``` -------------------------------- ### build Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Callback function to build a notification payload. It takes a map of context and a map of configuration, returning either an OK tuple with the payload or an error tuple. ```APIDOC ## build ### Description Callback function to build a notification payload. ### Method `@callback build(map(), map()) :: {:ok, map()} | {:error, term()}` ``` -------------------------------- ### preview_rendering Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.md Previews a single channel rendering without persisting rows or dispatching traffic. ```APIDOC ## preview_rendering ### Description Previews a single channel rendering without persisting rows or dispatching traffic. ### Method (Not specified, likely a function call in an SDK) ### Parameters (Not specified) ### Request Example (Not specified) ### Response (Not specified) ``` -------------------------------- ### Configure Chimeway Ecto Repo Source: https://hexdocs.pm/chimeway/1.0.0/installation.md Specify your application's Ecto Repo module in the configuration file to enable Chimeway's persistence. ```elixir config :chimeway, repo: MyApp.Repo ``` -------------------------------- ### Basic Custom Adapter Structure Source: https://hexdocs.pm/chimeway/1.0.0/custom-adapter.md Defines the fundamental structure for a custom Chimeway adapter by implementing the `Chimeway.Adapter` behaviour and its `deliver/2` callback. ```elixir defmodule MyApp.MyCustomAdapter do @behaviour Chimeway.Adapter @impl true def deliver(%Chimeway.Delivery{} = delivery, config) do # Implementation goes here end end ``` -------------------------------- ### begin_recovery Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Deliveries.md Claims a recoverable delivery row by stamping durable recovery metadata on the canonical row. ```APIDOC ## begin_recovery ### Description Claims a recoverable delivery row by stamping durable recovery metadata on the canonical row. Returns `{:noop, delivery}` if the row is no longer eligible. ### Method APIDOC ### Parameters - **delivery** (binary() | Chimeway.Delivery.t()) - The delivery ID or delivery object. - **keyword** (keyword()) - Keyword list for recovery options. ### Response #### Success Response (ok) - **Chimeway.Delivery.t()**: The updated delivery object with recovery metadata. #### No Operation Response (noop) - **Chimeway.Delivery.t()**: The original delivery object if no operation was performed. ### Request Example ```elixir # Example usage with delivery ID Chimeway.Deliveries.begin_recovery("delivery_id_123", [timeout: :infinity]) # Example usage with delivery object # Chimeway.Deliveries.begin_recovery(delivery_object, [timeout: :infinity]) ``` ### Response Example ```elixir # Success {:ok, %Chimeway.Delivery{...}} # No operation {:noop, %Chimeway.Delivery{...}} ``` ``` -------------------------------- ### Configure Chimeway Dispatcher Source: https://hexdocs.pm/chimeway/1.0.0/oban-integration.md Configure Chimeway to use Oban for asynchronous dispatch by setting the dispatcher in `config/config.exs`. ```elixir config :chimeway, dispatcher: Chimeway.Dispatch.Oban ``` -------------------------------- ### fetch_definition Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Fetches a workflow definition by name and version. ```APIDOC ## fetch_definition ### Description Fetches a workflow definition by its name and version. ### Parameters - `definition_name`: (String.t()) - The name of the workflow definition. - `version`: (pos_integer()) - The version of the workflow definition. ### Returns - `{:ok, Chimeway.Workflows.WorkflowDefinition.t() | nil}`: The workflow definition if found, otherwise `nil`. - `{:error, term()}`: An error if the operation fails. ``` -------------------------------- ### Preview Function Signature Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Rendering.Preview.md Specifies the signature for the `preview` function. It takes a module, a map of render data, and keyword arguments, returning either a successful preview tuple or an error. ```elixir @spec preview(module(), map(), keyword()) :: {:ok, t()} | {:error, term()} ``` -------------------------------- ### Add Oban Dependency Source: https://hexdocs.pm/chimeway/1.0.0/oban-integration.md Add the Oban dependency to your project's `mix.exs` file. ```elixir defp deps do [ {:oban, "~> 2.17"} ] end ``` -------------------------------- ### list_traces Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves the structural workflow transitions for a given execution. ```APIDOC ## list_traces ### Description Returns the structural `WorkflowTransition` records for a given execution, strictly scoped to the supplied `tenant_id`. Trace context intentionally contains only structural progression metadata. ### Parameters - `tenant_id`: (String.t()) - The ID of the tenant. - `execution_id`: (Ecto.UUID.t()) - The execution ID of the workflow run. - `opts`: (keyword()) - Options for filtering the traces. Supported options: - `:limit`: Maximum number of traces to return (default: all). ### Returns - `{:ok, [Chimeway.Workflows.WorkflowTransition.t()]}`: A list of workflow transitions. - `{:error, :not_found}`: If the workflow run does not exist or belongs to a different tenant. ``` -------------------------------- ### fetch_step_by_key Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Looks up a workflow step by its key within a workflow definition. ```APIDOC ## fetch_step_by_key ### Description Looks up a workflow_step by step_key inside the same workflow definition. Returns `nil` if the step does not exist. ### Parameters - `workflow_definition_id`: (Ecto.UUID.t()) - The ID of the workflow definition. - `step_key`: (String.t()) - The key of the workflow step to fetch. ### Returns - `Chimeway.Workflows.WorkflowStep.t() | nil`: The workflow step if found, otherwise `nil`. ``` -------------------------------- ### Run Custom SQL Query with Options Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Executes a custom SQL query and returns the result. Supports options for logging and timeouts. The result includes the number of rows affected and the result set. ```elixir @spec query(iodata(), Ecto.Adapters.SQL.query_params(), Keyword.t()) :: {:ok, Ecto.Adapters.SQL.query_result()} | {:error, Exception.t()} ``` ```elixir iex> MyRepo.query("SELECT $1::integer + $2", [40, 2]) {:ok, %{rows: [[42]], num_rows: 1}} ``` ```elixir iex> Ecto.Adapters.SQL.query(MyRepo, "SELECT $1::integer + $2", [40, 2]) {:ok, %{rows: [[42]], num_rows: 1}} ``` -------------------------------- ### from_delivery/2 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.ProgressionOutcome.md Returns either :not_branchable_yet or a three-tuple {:branchable, outcome, evidence} based on the delivery status and suppression reason. ```APIDOC ## `from_delivery/2` ### Description Maps canonical delivery facts to a curated workflow-facing outcome vocabulary. ### Method Signature `from_delivery(delivery :: Chimeway.Delivery.t(), delivery_attempt :: Chimeway.DeliveryAttempt.t() | nil) :: Chimeway.Workflows.ProgressionOutcome.result()` ### Returns - `:not_branchable_yet`: If the delivery status is :pending, :dispatched, :digested, or if the suppression reason is not explicitly curated. - `{:branchable, outcome, evidence}`: Where `outcome` is one of the defined curated outcomes and `evidence` provides details about the delivery and attempt. ``` -------------------------------- ### Elixir Callback: Rendering Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Optional callback to define how a notification should be rendered. It takes context maps and returns a rendering declaration map or an error. ```elixir @callback rendering(map(), map()) :: {:ok, map()} | {:error, term()} ``` -------------------------------- ### query!/3 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Same as query/3 but returns the result directly without an :ok tuple and raises on invalid queries. ```APIDOC ## query!/3 ### Description Same as `query/3` but returns result directly without `:ok` tuple and raises on invalid queries. ``` -------------------------------- ### Add Chimeway Supervisor to Application Source: https://hexdocs.pm/chimeway/1.0.0/installation.md Integrate the Chimeway.Application into your application's supervision tree to manage its background processes. ```elixir def start(_type, _args) do children = [ MyApp.Repo, # ... other children Chimeway.Application ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end ``` -------------------------------- ### resolve_rendering Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Resolves the rendering declaration for a given notifier module, context, and configuration. Returns either an OK tuple with the rendering declaration or an error tuple. ```APIDOC ## resolve_rendering ### Description Resolves the rendering declaration. ### Method `@spec resolve_rendering(module(), map(), map()) :: {:ok, Chimeway.Rendering.rendering_declaration()} | {:error, term()}` ``` -------------------------------- ### run_delivery/1 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Dispatch.Executor.md Executes the delivery process and records an attempt. It handles different return types based on success or failure, and integrates with Oban workers for retry logic. ```APIDOC ## `run_delivery/1` ### Description Executes the delivery process, recording an attempt and returning the delivery and attempt details on success, or an error tuple on failure. ### Function Signature ```elixir @spec run_delivery(Chimeway.Delivery.t()) :: {:ok, %{delivery: Chimeway.Delivery.t(), attempt: Chimeway.DeliveryAttempt.t()}} | {:error, atom(), term(), map()} | {:error, term()} ``` ### Parameters #### Arguments - `delivery` (Chimeway.Delivery.t()) - The delivery object to process. ``` -------------------------------- ### Fetch Workflow Step by Key Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Looks up a workflow step by its key within the same workflow definition. Returns the WorkflowStep struct or nil if the step does not exist. Callers should treat nil as a no-op. ```elixir @spec fetch_step_by_key(Ecto.UUID.t(), String.t()) :: Chimeway.Workflows.WorkflowStep.t() | nil ``` -------------------------------- ### Fetch Workflow Definition by Name and Version Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Fetches a specific workflow definition by its string name and a positive integer version. Returns {:ok, WorkflowDefinition | nil} or {:error, term}. ```elixir @spec fetch_definition(String.t(), pos_integer()) :: {:ok, Chimeway.Workflows.WorkflowDefinition.t() | nil} | {:error, term()} ``` -------------------------------- ### get_settings Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Policy.Settings.md Fetches the policy settings for a specific recipient. Returns the setting object if found, or nil if no settings exist for the recipient. ```APIDOC ## get_settings ### Description Fetches the policy settings row for a recipient, or nil. ### Function Signature ```elixir @spec get_settings(String.t()) :: Chimeway.Policy.Settings.Setting.t() | nil ``` ``` -------------------------------- ### Explain SQL Query for Ecto Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Executes an EXPLAIN statement for a given Ecto query. It can be used for :all, :update_all, or :delete_all operations and accepts shared options like analyze and timeout. ```elixir @spec explain( :all | :update_all | :delete_all, Ecto.Queryable.t(), opts :: Keyword.t() ) :: String.t() | Exception.t() | [map()] ``` ```elixir iex> MyRepo.explain(:all, Post) "Seq Scan on posts p0 (cost=0.00..12.12 rows=1 width=443)" ``` ```elixir iex> Ecto.Adapters.SQL.explain(Repo, :all, Post) "Seq Scan on posts p0 (cost=0.00..12.12 rows=1 width=443)" ``` ```elixir iex> MyRepo.explain(:all, from(p in Post, where: p.title == "title")) |> IO.puts() +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | p0 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.0 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ ``` ```elixir iex> MyRepo.explain(:all, Post, analyze: true, timeout: 20_000) "Seq Scan on posts p0 (cost=0.00..11.70 rows=170 width=443) (actual time=0.013..0.013 rows=0 loops=1)\nPlanning Time: 0.031 ms\nExecution Time: 0.021 ms" ``` ```elixir iex> MyRepo.explain(Repo, :update_all, from(p in Post, update: [set: [title: "new title"]])) "Update on posts p0 (cost=0.00..11.70 rows=170 width=449)\n -> Seq Scan on posts p0 (cost=0.00..11.70 rows=170 width=449)" ``` ```elixir iex> MyRepo.explain(:all, from(p in Post, where: p.title == "title")) "Seq Scan on posts p0 (cost=0.00..12.12 rows=1 width=443)\n Filter: ((title)::text = 'title'::text)" ``` -------------------------------- ### apply_planning_decision Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Deliveries.md Persists planning-time orchestration facts on the canonical delivery row. ```APIDOC ## apply_planning_decision ### Description Persists planning-time orchestration facts on the canonical delivery row. ### Method APIDOC ### Parameters - **delivery** (Chimeway.Delivery.t()) - Description of the delivery object. - **map** (map()) - Map containing planning facts. ### Response #### Success Response (ok) - **Chimeway.Delivery.t()**: The updated delivery object. #### Error Response (error) - **term()**: An error term. ### Request Example ```elixir # Example usage (assuming 'delivery' is a Chimeway.Delivery.t()) Chimeway.Deliveries.apply_planning_decision(delivery, %{key: "value"}) ``` ### Response Example ```elixir # Success {:ok, %Chimeway.Delivery{...}} # Error {:error, :some_error} ``` ``` -------------------------------- ### resume_deferred_delivery Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Deliveries.md Promotes a due deferred delivery row back to the :ready state. ```APIDOC ## resume_deferred_delivery ### Description Promotes a due deferred delivery row back to the `:ready` state without changing its delivery identity. Returns `{:noop, delivery}` if the row is no longer pending, deferred, and due. ### Function Signature ```elixir resume_deferred_delivery(binary() | Chimeway.Delivery.t(), keyword()) :: :ok | :noop ``` ### Parameters - `delivery` (binary() | Chimeway.Delivery.t()): The delivery identifier or record to resume. - `opts` (keyword()): Optional keyword list for configuration. ### Returns - `{:ok, Chimeway.Delivery.t()}`: On successful promotion to `:ready`. - `{:noop, Chimeway.Delivery.t()}`: If the delivery is not due for resumption. ``` -------------------------------- ### next_eligible_at Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Orchestration.WindowMath.md Calculates the next eligible time based on a given DateTime and a list of options. It returns either an OK tuple with the next DateTime or an Error tuple. ```APIDOC ## `next_eligible_at` ### Description Calculates the next eligible time based on a given DateTime and a list of options. It returns either an OK tuple with the next DateTime or an Error tuple. ### Function Signature ```elixir @spec next_eligible_at(DateTime.t(), [option()]) :: {:ok, DateTime.t()} | {:error, term()} ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response - `{:ok, DateTime.t()}`: The next eligible DateTime. #### Error Response - `{:error, term()}`: An error term if the calculation fails. #### Response Example ```json { "example": "{:ok, ~U\"2023-10-27 10:00:00Z\"}" } ``` ``` -------------------------------- ### Attach a Telemetry Logger to Delivery Attempts Source: https://hexdocs.pm/chimeway/1.0.0/tracing-a-notification.md This module attaches to the `[:chimeway, :delivery, :attempt, :stop]` telemetry event to log the status and details of each delivery attempt. Ensure `MyApp.ChimewayLogger.setup()` is called during application startup. ```elixir defmodule MyApp.ChimewayLogger do require Logger def setup do :telemetry.attach( "chimeway-logger-delivery-stop", [:chimeway, :delivery, :attempt, :stop], &__MODULE__.handle_event/4, nil ) end def handle_event(_event, measurements, metadata, _config) do # ⚠️ Notice that `metadata` only contains safe correlation IDs and state. # The actual payload is intentionally omitted. delivery_id = metadata[:delivery_id] correlation_id = metadata[:correlation_id] notification_key = metadata[:notification_key] status = metadata[:status] Logger.info( "Delivery Attempt Finished [#{status}] " <> "delivery_id=#{delivery_id} " <> "correlation_id=#{correlation_id} " <> "key=#{notification_key} " <> "duration=#{measurements.duration}" ) end end ``` -------------------------------- ### Run Multiple Custom SQL Queries Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Executes multiple custom SQL queries and returns a list of results. Supports options for logging and timeouts. Each result includes the number of rows affected and the result set. ```elixir @spec query_many(iodata(), Ecto.Adapters.SQL.query_params(), Keyword.t()) :: {:ok, [Ecto.Adapters.SQL.query_result()]} | {:error, Exception.t()} ``` ```elixir iex> MyRepo.query_many("SELECT $1; SELECT $2;", [40, 2]) {:ok, [%{rows: [[40]], num_rows: 1}, %{rows: [[2]], num_rows: 1}]} ``` ```elixir iex> Ecto.Adapters.SQL.query_many(MyRepo, "SELECT $1; SELECT $2;", [40, 2]) {:ok, [%{rows: [[40]], num_rows: 1}, %{rows: [[2]], num_rows: 1}]} ``` -------------------------------- ### Transactional Enqueue with Oban Dispatcher Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Dispatch.Oban.md Pass a %Ecto.Multi{} to `dispatch/2` to enqueue Oban jobs within the same database transaction as delivery rows. When `:multi` is absent, jobs are inserted directly using `Oban.insert/2`. ```elixir dispatcher.dispatch(notifications, multi: existing_multi) ``` -------------------------------- ### Implement Channel Render Validator Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Rendering.Channel.md Implement this behavior to create custom channel render validators. Ensure the `validate/1` function handles map attributes and returns either `{:ok, stringified_map}` or `{:error, :invalid}`. ```elixir defmodule MyApp.Channels.Slack do use Chimeway.Rendering.Channel @impl Chimeway.Rendering.Channel def validate(attrs) when is_map(attrs) do # Ecto.Changeset validation producing a stringified map {:ok, attrs} end def validate(_other) do {:error, :invalid} end end ``` -------------------------------- ### version Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Callback function to return the version of the notifier. ```APIDOC ## version ### Description Callback function to return the version of the notifier. ### Method `@callback version() :: pos_integer()` ``` -------------------------------- ### Adapter deliver callback signature Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Adapter.md Defines the signature for the `deliver` callback, which is responsible for sending a single delivery to its outbound channel. It takes a pre-populated delivery struct and adapter-specific configuration. ```elixir @callback deliver(delivery :: Chimeway.Delivery.t(), config :: keyword()) :: {:ok, map()} | {:error, atom(), map()} ``` -------------------------------- ### Elixir Callback: Channels Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Optional callback to define available outbound channels. It takes context maps and returns a list of channel atoms or strings, or an error. ```elixir @callback channels(map(), map()) :: {:ok, [atom() | String.t()]} | {:error, term()} ``` -------------------------------- ### explain_delivery/1 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Provides a structured explanation for a given delivery_id, including its timeline, suppression reason, and final status. ```APIDOC ## explain_delivery/1 ### Description Returns a structured explanation for the given delivery_id. The explanation includes the full timeline derived from row timestamps, the final status, suppression reason, and last attempt outcome. ### Method `explain_delivery(String.t(), keyword())` ### Parameters - `delivery_id` (String.t()) - The unique identifier for the delivery. - `options` (keyword()) - Optional keyword list. ### Response - `{:ok, Chimeway.Traces.Explanation.t()}` - On success, returns the delivery explanation. - `{:error, :not_found}` - If the delivery_id is not found. ``` -------------------------------- ### Adapter verify_webhook callback signature Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Adapter.md Defines the optional `verify_webhook` callback signature. Required for adapters supporting async feedback loops, this function verifies the cryptographic signature of an incoming webhook from the provider. ```elixir @callback verify_webhook(raw_body :: binary(), headers :: list(), config :: keyword()) :: :ok | {:error, :unauthorized} ``` -------------------------------- ### Configure Chimeway Dispatcher Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Dispatch.md Configure the dispatcher via the application's config. The default implementation is Chimeway.Dispatch.Sync. Chimeway.Dispatch.Oban is an alternative for background job processing. ```elixir config :chimeway, :dispatcher, Chimeway.Dispatch.Sync ``` -------------------------------- ### channels Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Notifier.md Optional callback function to define the available notification channels. It takes context and configuration maps and returns a list of channel atoms or strings, or an error tuple. ```APIDOC ## channels *optional* ### Description Optional callback function to define the available notification channels. ### Method `@callback channels(map(), map()) :: {:ok, [atom() | String.t()]} | {:error, term()}` ``` -------------------------------- ### query/3 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Runs a custom SQL query. Returns an :ok tuple with query results or an :error tuple. Supports options like :log and :timeout. ```APIDOC ## query/3 ### Description Runs a custom SQL query. If the query was successful, it will return an :ok tuple containing a map with at least two keys: `:num_rows` and `:rows`. ### Options * `:log` - When false, does not log the query * `:timeout` - Execute request timeout, accepts: `:infinity` (default: `15000`); ### Request Example ```elixir MyRepo.query("SELECT $1::integer + $2", [40, 2]) # {:ok, %{rows: [[42]], num_rows: 1}} Ecto.Adapters.SQL.query(MyRepo, "SELECT $1::integer + $2", [40, 2]) # {:ok, %{rows: [[42]], num_rows: 1}} ``` ### Response #### Success Response (200) - `:num_rows` (integer) - the number of rows affected - `:rows` (list) - the result set as a list. `nil` may be returned instead of the list if the command does not yield any row as result. #### Response Example ```json { "rows": [[42]], "num_rows": 1 } ``` ``` -------------------------------- ### to_sql Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Repo.md Converts an Ecto query to its SQL representation based on the repository adapter. It accepts `:all`, `:update_all`, or `:delete_all` as the kind of conversion. ```APIDOC ## `to_sql` ### Description Converts the given query to SQL according to its kind and the adapter in the given repository. ### Function Signature ```elixir @spec to_sql(:all | :update_all | :delete_all, Ecto.Queryable.t()) :: {String.t(), Ecto.Adapters.SQL.query_params()} ``` ### Examples #### Example 1: `:all` query ```elixir MysRepo.to_sql(:all, Post) ``` Response: ``` {"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p", []} ``` #### Example 2: `:update_all` query ```elixir Ecto.Adapters.SQL.to_sql(:all, MyRepo, Post) ``` Response: ``` {"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p", []} ``` #### Example 3: `:update_all` with specific update ```elixir MysRepo.to_sql(:update_all, from(p in Post, update: [set: [title: ^"hello"]])) ``` Response: ``` {"UPDATE posts AS p SET title = $1", ["hello"]} ``` ``` -------------------------------- ### process Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Webhooks.md Ingests and verifies inbound webhooks synchronously. Returns `{:ok, ingress}` on success, indicating successful transaction commits for the ingress row and ProcessFeedbackWorker job. Returns specific error tuples for various failure conditions. ```APIDOC ## process ### Description Ingests and verifies inbound webhooks synchronously. Returns `{:ok, ingress}` on success, indicating successful transaction commits for the ingress row and ProcessFeedbackWorker job. Returns specific error tuples for various failure conditions. ### Function Signature ```elixir process(module(), binary(), list(), keyword()) :: {:ok, Chimeway.Webhooks.Ingress.t()} | {:error, :unauthorized} | {:error, :unparseable_body} | {:error, :unresolvable_delivery} | {:error, :unnormalizable_feedback} | {:error, Ecto.Changeset.t()} | {:error, term()} ``` ### Parameters - `module()`: The module to use for processing. - `binary()`: The webhook payload body. - `list()`: A list of headers. - `keyword()`: A keyword list of options. ``` -------------------------------- ### get_trace/1 Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Traces.md Loads the full trace for a single event using its event_id. It preloads notifications, deliveries, and attempts. ```APIDOC ## get_trace/1 ### Description Loads the full event trace for a given event_id with all associations preloaded. ### Method `get_trace(String.t(), keyword())` ### Parameters - `event_id` (String.t()) - The unique identifier for the event. - `options` (keyword()) - Optional keyword list for preloading associations. ### Response - `{:ok, Chimeway.Events.Event.t()}` - On success, returns the event trace. - `{:error, :not_found}` - If the event_id is not found. ``` -------------------------------- ### get_run! Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Retrieves a workflow run by its ID. ```APIDOC ## get_run! ### Description Returns the canonical workflow_run row by id, raising if not found. Used by the progression service after locking the row inside its transaction. ### Parameters - `workflow_run_id`: (Ecto.UUID.t()) - The ID of the workflow run. ### Returns - `Chimeway.Workflows.WorkflowRun.t()`: The workflow run record. ``` -------------------------------- ### Append Workflow Transition Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Workflows.md Appends a workflow transition row using the provided Ecto repository. Requires `workflow_run_id`, `to_state`, and `reason`. Optional keys include `workflow_step_id`, `delivery_id`, `from_state`, `context`, and `inserted_at`. Returns {:ok, WorkflowTransition} on success or {:error, Ecto.Changeset} on failure. ```elixir @spec append_transition(Ecto.Repo.t(), map()) :: {:ok, Chimeway.Workflows.WorkflowTransition.t()} | {:error, Ecto.Changeset.t()} ``` -------------------------------- ### Define Chimeway Rendering Preview Type Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Rendering.Preview.md Defines the structure of the `t()` type for `Chimeway.Rendering.Preview`. This type represents the data associated with a preview rendering. ```elixir @type t() :: %Chimeway.Rendering.Preview{ channel: String.t(), render_data: map(), render_key: String.t(), render_version: pos_integer() } ``` -------------------------------- ### Define Channel Rendering Type Source: https://hexdocs.pm/chimeway/1.0.0/Chimeway.Rendering.md Defines the structure for channel rendering, specifying the render key and version. ```elixir @type channel_rendering() :: %{render_key: String.t(), render_version: pos_integer()} ```