defmodule Jido.Chat.ThreadSummary do
@moduledoc """
Lightweight thread descriptor for channel-level thread listing.
"""
alias Jido.Chat.{Incoming, Message}
@schema Zoi.struct(
__MODULE__,
%{
id: Zoi.string(),
last_reply_at: Zoi.any() |> Zoi.nullish(),
reply_count: Zoi.integer() |> Zoi.nullish(),
root_message: Zoi.struct(Message) |> Zoi.nullish(),
metadata: Zoi.map() |> Zoi.default(%{})
},
coerce: true
)
@type t :: unquote(Zoi.type_spec(@schema))
@enforce_keys Zoi.Struct.enforce_keys(@schema)
defstruct Zoi.Struct.struct_fields(@schema)
@doc "Returns the Zoi schema for ThreadSummary."
def schema, do: @schema
@doc "Creates a thread summary and normalizes root message payload."
def new(attrs) when is_map(attrs) do
attrs
|> normalize_root_message()
|> then(&Jido.Chat.Schema.parse!(__MODULE__, @schema, &1))
end
defp normalize_root_message(attrs) do
case attrs[:root_message] || attrs["root_message"] do
%Message{} ->
attrs
%Incoming{} = incoming ->
Map.put(attrs, :root_message, Message.from_incoming(incoming))
nil ->
attrs
map when is_map(map) ->
if Map.has_key?(map, :external_room_id) || Map.has_key?(map, "external_room_id") do
message = map |> Incoming.new() |> Message.from_incoming()
Map.put(attrs, :root_message, message)
else
Map.put(attrs, :root_message, Message.new(map))
end
_other ->
attrs
end
end
end