PhoenixKitCatalogue.Catalogue.PubSub (PhoenixKitCatalogue v0.1.12)

Copy Markdown View Source

Real-time fan-out for catalogue mutations.

Every successful write in the Catalogue context broadcasts a small {:catalogue_data_changed, kind, uuid} event to a single shared topic. List/detail LiveViews subscribe/0 once in mount/3 (after connected?(socket)) and re-fetch the affected slice on any event, so two admins editing the same data converge without manual refresh.

Payloads are intentionally minimal — UUID + kind, no record data — to (a) avoid leaking field-level changes through PubSub, and (b) keep the consumer in charge of how much to re-load (single row vs full list).

Subscriptions are cleaned up automatically when the LV process terminates; callers don't need to unsubscribe.

Summary

Types

Event message format for handle_info/2.

Resource kind that mutated.

Functions

Broadcasts a {:catalogue_data_changed, kind, uuid} event after a successful write. Pass nil for uuid when the change isn't tied to a specific record (e.g. a bulk link sync).

Subscribes the current process to the catalogue PubSub topic.

Returns the canonical topic name. Useful for tests.

Types

event()

@type event() :: {:catalogue_data_changed, kind(), Ecto.UUID.t() | nil}

Event message format for handle_info/2.

kind()

@type kind() ::
  :catalogue
  | :category
  | :item
  | :manufacturer
  | :supplier
  | :smart_rule
  | :links

Resource kind that mutated.

Functions

broadcast(kind, uuid)

@spec broadcast(kind(), Ecto.UUID.t() | nil) :: :ok

Broadcasts a {:catalogue_data_changed, kind, uuid} event after a successful write. Pass nil for uuid when the change isn't tied to a specific record (e.g. a bulk link sync).

subscribe()

@spec subscribe() :: :ok | {:error, term()}

Subscribes the current process to the catalogue PubSub topic.

Call from mount/3 guarded by connected?(socket) so the disconnected (initial render) pass doesn't subscribe and never unsubscribes. Do this after any subscription requirements but before the initial DB load to avoid a race where a write between the load and the subscribe leaves the UI stale.

topic()

@spec topic() :: String.t()

Returns the canonical topic name. Useful for tests.