ObanChore 🎭

Bridge the gap between robust background processing and safe, manual operational control in Elixir.

ObanChore is an Elixir library that transforms your standard Oban workers into secure, UI-driven operational tools. It automatically generates a Phoenix LiveView dashboard allowing your team to trigger, monitor, and audit ad-hoc scripts and backfills without touching a production console.


πŸ›‘ The Problem: The "IEx Bottleneck"

In growing applications, developers frequently write ad-hoc scripts: data migrations, one-off backfills, or specific customer support actions (like resetting a stuck billing state or refunding a transaction).

Historically, executing these scripts involves:

  1. A developer SSH-ing into the production server.
  2. Opening an iex -S mix console.
  3. Manually typing execution commands and passing arguments.

This is risky and unscalable. Direct production shell access is a security risk, typos in the shell can cause catastrophic data loss, there is zero auditability for compliance, and developers become a permanent bottleneck for Customer Support and Operations teams.

πŸ’‘ The Solution: Democratized Execution

ObanChore solves this by bringing operations out of the terminal and into a secure UI, backed by the resilience of Oban.

Instead of writing a disposable script, developers write a standard, resilient Oban worker and declare its expected inputs (e.g., user_id, reason). ObanChore dynamically reads these declarations and automatically generates a secure Phoenix LiveView interface.

defmodule MyApp.Chores.UserBackfill do
  use ObanChore.Worker,
    name: "User Data Backfill",
    fields: [
      user_id: [type: :integer, required: true],
      reason: [type: :string, default: "Manual Update"]
    ]

  @impl Oban.Worker
  def perform(%Oban.Job{args: args}) do
    # Logic here
  end
end

Support, QA, or Product Managers can now log into an admin dashboard, fill out a user-friendly form, and safely trigger the jobβ€”while Oban handles the reliable, asynchronous execution in the background.

πŸš€ Getting Started

1. Install Dependency

Add oban_chore to your mix.exs:

def deps do
  [
    {:oban_chore, "~> 0.1.0"}
  ]
end

2. Define a Chore

Replace use Oban.Worker with use ObanChore.Worker and define your fields:

defmodule MyApp.Chores.UserBackfill do
  use ObanChore.Worker,
    name: "User Data Backfill",
    fields: [
      user_id: [type: :integer, required: true],
      reason: [type: :string, default: "Manual Update"]
    ]

  @impl Oban.Worker
  def perform(%Oban.Job{args: args}) do
    # Your logic here
    :ok
  end

  # Optional: Add custom validations using Ecto.Changeset
  @impl ObanChore.Worker
  def custom_changeset(changeset) do
    Ecto.Changeset.validate_number(changeset, :user_id, greater_than: 0)
  end
end

3. Mount the Dashboard

Add the dashboard to your Phoenix router:

# lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  import ObanChore.Router

  scope "/" do
    pipe_through :browser
    
    # Mount the dashboard at any path
    oban_chore_dashboard "/chores"
  end
end

4. Configure PubSub (Optional but Recommended)

To enable real-time logging from your workers, configure your PubSub server:

# config/config.exs
config :oban_chore, pubsub_server: MyApp.PubSub

5. Use Real-Time Logging

Inside your worker's perform/1 function, use ObanChore.log/2 to stream updates:

defmodule MyApp.Chores.UserBackfill do
  use ObanChore.Worker, name: "User Backfill"

  @impl Oban.Worker
  def perform(%Oban.Job{} = job) do
    ObanChore.log(job, "Starting backfill...")
    # ... logic ...
    ObanChore.log(job, "Processed 50%...")
    # ... logic ...
    ObanChore.log(job, "Done!")
    :ok
  end
end

✨ Core Features

πŸ—οΈ Architectural Philosophy

ObanChore is not a replacement for Oban. It is a complementary operational layer.

While Oban excels at automated, system-driven tasks (sending emails, processing webhooks), ObanChore provides the missing interface for human-driven tasks. By piggybacking on your existing Oban supervision tree and PostgreSQL queues, ObanChore requires minimal infrastructure overhead while delivering massive operational value.

🎯 Who is this for?