Files
self b4b8c83ddb feat: namespace plugin identity
Adopt canonical plugin id/slug manifest fields, vendor-prefixed OTP app naming, and fully-qualified capability ids for Aether.
2026-05-27 19:05:51 +02:00

181 lines
3.4 KiB
Elixir

defmodule TribeOne.TribesPlugin.Aether.Chat.Channel do
@moduledoc """
Public chat channel metadata.
"""
use Ash.Resource,
otp_app: :tribe_one_aether,
domain: TribeOne.TribesPlugin.Aether.Chat,
data_layer: AshPostgres.DataLayer,
extensions: [AshNostrSync]
import Ash.Expr
@backends [:public_sync, :nostr_nip17, :nostr_nip04, :marmot]
@conversation_kinds [:group, :context_group, :dm, :legacy_dm, :marmot_group]
postgres do
table("aether_chat_channels")
repo(Tribes.Repo)
custom_indexes do
index([:slug], unique: true, where: "deleted_at IS NULL")
index([:context_provider, :context_type, :context_id], where: "deleted_at IS NULL")
end
end
nostr_sync do
namespace("plugins.aether.chat.channel")
lane(:control)
publish?(true)
consume?(true)
end
actions do
defaults([:read])
read :by_id do
get?(true)
get_by(:id)
end
read :by_slug do
get?(true)
argument :slug, :string do
allow_nil?(false)
end
filter(expr(slug == ^arg(:slug)))
end
create :create do
accept([
:id,
:slug,
:title,
:description,
:backend,
:conversation_kind,
:context_provider,
:context_type,
:context_id,
:metadata
])
change(AshNostrSync.PublishChange)
end
create :sync_upsert do
accept([
:id,
:slug,
:title,
:description,
:backend,
:conversation_kind,
:context_provider,
:context_type,
:context_id,
:metadata
])
upsert?(true)
end
update :update do
require_atomic?(false)
accept([
:title,
:description,
:backend,
:conversation_kind,
:context_provider,
:context_type,
:context_id,
:metadata
])
change(AshNostrSync.PublishChange)
end
destroy :destroy do
require_atomic?(false)
soft?(true)
soft_delete()
change(AshNostrSync.PublishChange)
end
end
relationships do
has_many :messages, TribeOne.TribesPlugin.Aether.Chat.Message do
destination_attribute(:channel_id)
public?(true)
end
has_many :participants, TribeOne.TribesPlugin.Aether.Chat.Participant do
destination_attribute(:channel_id)
public?(true)
end
end
attributes do
attribute :id, :uuid do
allow_nil?(false)
primary_key?(true)
public?(true)
writable?(true)
default(&Ash.UUID.generate/0)
end
attribute :slug, :string do
allow_nil?(false)
public?(true)
end
attribute :title, :string do
allow_nil?(false)
public?(true)
end
attribute :description, :string do
public?(true)
end
attribute :backend, :atom do
constraints(one_of: @backends)
allow_nil?(false)
default(:public_sync)
public?(true)
end
attribute :conversation_kind, :atom do
constraints(one_of: @conversation_kinds)
allow_nil?(false)
default(:group)
public?(true)
end
attribute :context_provider, :string do
public?(true)
end
attribute :context_type, :string do
public?(true)
end
attribute :context_id, :string do
public?(true)
end
attribute :metadata, :map do
allow_nil?(false)
default(%{})
public?(true)
end
timestamps(type: :utc_datetime)
end
end