Threadline.Semantics.ActorRef (Threadline v1.0.0)

Copy Markdown View Source

An actor reference identifies who performed an audited operation, including when the actor is not a user.

Implements Ecto.ParameterizedType for use as a JSONB field in Ecto schemas. Stored as %{"type" => "user", "id" => "123"} in PostgreSQL; loaded back as %ActorRef{type: :user, id: "123"} in Elixir.

Actor types

  • :user — end user with a non-empty id
  • :admin — administrator with a non-empty id
  • :service_account — service account with a non-empty id
  • :job — background job with a non-empty id
  • :system — system process with a non-empty id
  • :anonymous — unauthenticated actor; id is nil

Use new/2 to construct a validated reference, from_map/1 to validate a decoded JSON map, identifiable?/1 to check whether the reference has a stable identity, and to_map/1 to encode it for JSON storage.

Summary

Types

A string-keyed map emitted by to_map/1. It always contains "type"; non-anonymous refs also contain "id", and no other keys are emitted.

One of the actor categories accepted by new/2.

Any value accepted by new/2; unsupported values return :unknown_actor_type.

t()

A stable actor reference with a supported type and an optional string identifier.

Functions

Returns an ActorRef decoded from a string-keyed JSON object.

Returns whether an actor has a stable identity suitable for resource ownership.

Returns a validated ActorRef for a supported actor type and identifier.

Returns the string-keyed JSON object used to store an ActorRef.

Types

actor_map()

@type actor_map() :: %{required(String.t()) => String.t() | nil}

A string-keyed map emitted by to_map/1. It always contains "type"; non-anonymous refs also contain "id", and no other keys are emitted.

from_map/1 recognizes only string "type" and "id" keys. It ignores additional string or atom keys, and recognized string keys take precedence in mixed maps. An atom-only type key is not recognized and returns {:error, :invalid_actor_ref_map}. Anonymous refs ignore "id". new/2 and from_map/1 produce validated refs with nil id only for anonymous refs, but a directly constructed non-anonymous %ActorRef{} with nil id emits "id" => nil.

actor_type()

@type actor_type() :: :anonymous | :system | :job | :service_account | :admin | :user

One of the actor categories accepted by new/2.

actor_type_input()

@type actor_type_input() ::
  atom()
  | bitstring()
  | number()
  | %{optional(actor_type_input()) => actor_type_input()}
  | tuple()
  | list()
  | pid()
  | port()
  | reference()
  | function()

Any value accepted by new/2; unsupported values return :unknown_actor_type.

t()

@type t() :: %Threadline.Semantics.ActorRef{id: String.t() | nil, type: actor_type()}

A stable actor reference with a supported type and an optional string identifier.

Functions

from_map(arg1)

@spec from_map(term()) ::
  {:ok, t()}
  | {:error, :invalid_actor_ref_map | :unknown_actor_type | :missing_actor_id}

Returns an ActorRef decoded from a string-keyed JSON object.

Accepts any input so callers can validate decoded JSON. An anonymous object has no "id" key; its "id" value is ignored if present. Every other supported type requires a non-empty string identifier.

Decoding recognizes only string "type" and "id" keys and ignores additional string or atom keys. The recognized string keys take precedence over atom keys in mixed maps. An atom-only :type key is not recognized and returns {:error, :invalid_actor_ref_map}. to_map/1 emits only "type" and, for non-anonymous actors, "id".

Returns {:ok, actor_ref} or {:error, reason} for :invalid_actor_ref_map, :unknown_actor_type, or :missing_actor_id.

identifiable?(actor_ref)

@spec identifiable?(term()) :: boolean()

Returns whether an actor has a stable identity suitable for resource ownership.

new(type, id \\ nil)

@spec new(actor_type_input(), String.t() | nil) ::
  {:ok, t()} | {:error, :unknown_actor_type | :missing_actor_id}

Returns a validated ActorRef for a supported actor type and identifier.

The anonymous type discards its identifier. Other types require a non-empty string identifier.

Returns {:ok, actor_ref} or {:error, reason} where the reason is :unknown_actor_type for an unsupported type or :missing_actor_id for a missing or empty identifier.

to_map(actor_ref)

@spec to_map(t()) :: actor_map()

Returns the string-keyed JSON object used to store an ActorRef.

It always emits the string "type" key and no extra keys. Anonymous actors omit "id"; other actor types include it. Validated non-anonymous refs have a non-empty string id, while a directly constructed non-anonymous struct with a nil id emits "id" => nil.