All checks were successful
deploy / deploy (push) Successful in 4m22s
Single activity_log table powering two views: chronological timeline on each order detail page (replacing the old fulfilment card) and a global feed at /admin/activity with tabs, category filters, search, and pagination. Real-time via PubSub — new entries appear instantly, nav badge updates across all admin pages. Instrumented across all event points: Stripe webhooks, order notifier, submission worker, fulfilment status worker, product sync worker, and Oban exhausted-job telemetry. Contextual action buttons (retry submission, retry sync, dismiss) with Oban unique constraints to prevent double-enqueue. 90-day pruning via cron. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
37 lines
839 B
Elixir
37 lines
839 B
Elixir
defmodule Berrypod.ActivityLog.Entry do
|
|
use Ecto.Schema
|
|
import Ecto.Changeset
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
@foreign_key_type :binary_id
|
|
|
|
@levels ~w(info warning error)
|
|
|
|
schema "activity_log" do
|
|
field :event_type, :string
|
|
field :level, :string, default: "info"
|
|
field :order_id, :binary_id
|
|
field :payload, :map, default: %{}
|
|
field :message, :string
|
|
field :resolved_at, :utc_datetime
|
|
field :occurred_at, :utc_datetime
|
|
|
|
timestamps(type: :utc_datetime)
|
|
end
|
|
|
|
def changeset(entry, attrs) do
|
|
entry
|
|
|> cast(attrs, [
|
|
:event_type,
|
|
:level,
|
|
:order_id,
|
|
:payload,
|
|
:message,
|
|
:resolved_at,
|
|
:occurred_at
|
|
])
|
|
|> validate_required([:event_type, :level, :message, :occurred_at])
|
|
|> validate_inclusion(:level, @levels)
|
|
end
|
|
end
|