Add relations

This commit is contained in:
Mirai Kumiko 2025-06-18 06:35:58 +02:00
parent f43b4bd038
commit 3a57d74357
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278
12 changed files with 81 additions and 85 deletions

View file

@ -1,7 +1,8 @@
defmodule Nulla.Models.Activity do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.SnowFlake
alias Nulla.Repo
alias Nulla.Snowflake
@primary_key {:id, :integer, autogenerate: false}
schema "activities" do
@ -27,7 +28,7 @@ defmodule Nulla.Models.Activity do
%__MODULE__{}
|> __MODULE__.changeset(attrs)
|> Ecto.Changeset.put_change(:id, id)
|> Changeset.put_change(:id, id)
|> Repo.insert()
end
end

View file

@ -106,7 +106,7 @@ defmodule Nulla.Models.Actor do
%__MODULE__{}
|> changeset(attrs)
|> Ecto.Changeset.put_change(:id, id)
|> Changeset.put_change(:id, id)
|> Repo.insert()
end

View file

@ -1,32 +0,0 @@
defmodule Nulla.Models.Follow do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.Repo
alias Nulla.Snowflake
alias Nulla.Models.Actor
@primary_key {:id, :integer, autogenerate: false}
schema "follows" do
belongs_to :follower, Actor
belongs_to :followed, Actor
timestamps()
end
@doc false
def changeset(follow, attrs) do
follow
|> cast(attrs, [:user_id, :target_id])
|> validate_required([:user_id, :target_id])
|> unique_constraint([:user_id, :target_id])
end
def create_follow(attrs) do
id = Snowflake.next_id()
%__MODULE__{}
|> __MODULE__.changeset(attrs)
|> Ecto.Changeset.put_change(:id, id)
|> Repo.insert()
end
end

View file

@ -1,6 +1,7 @@
defmodule Nulla.Models.MediaAttachment do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.Models.Note
@primary_key {:id, :integer, autogenerate: false}
schema "media_attachments" do
@ -8,7 +9,7 @@ defmodule Nulla.Models.MediaAttachment do
field :mime_type, :string
field :description, :string
belongs_to :note, Nulla.Models.Note
belongs_to :note, Note
timestamps(type: :utc_datetime)
end

View file

@ -1,6 +1,7 @@
defmodule Nulla.Models.ModerationLog do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.Models.User
@primary_key {:id, :integer, autogenerate: false}
schema "moderation_logs" do
@ -10,7 +11,7 @@ defmodule Nulla.Models.ModerationLog do
field :reason, :string
field :metadata, :map
belongs_to :moderator, Nulla.Models.User
belongs_to :moderator, User
timestamps()
end

View file

@ -1,30 +1,62 @@
defmodule Nulla.Models.Relation do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.Repo
alias Nulla.Snowflake
alias Nulla.Models.Actor
alias Nulla.Models.Activity
@primary_key {:id, :integer, autogenerate: false}
@foreign_key_type :integer
schema "relations" do
field :type, :string
field :status, :string
field :following, :boolean, default: false
field :followed_by, :boolean, default: false
field :showing_replies, :boolean, default: true
field :showing_reblogs, :boolean, default: true
field :notifying, :boolean, default: false
field :muting, :boolean, default: false
field :muting_notifications, :boolean, default: false
field :blocking, :boolean, default: false
field :blocked_by, :boolean, default: false
field :domain_blocking, :boolean, default: false
field :requested, :boolean, default: false
field :note, :string
belongs_to :source, Actor, foreign_key: :source_id, type: :integer
belongs_to :target, Actor, foreign_key: :target_id, type: :integer
belongs_to :activity, Activity, foreign_key: :activity_id, type: :integer
belongs_to :local_actor_id, Actor
belongs_to :remote_actor_id, Actor
timestamps()
end
@doc false
def changeset(relation, attrs) do
relation
|> cast(attrs, [:id, :source_id, :target_id, :type, :status, :activity_id])
|> validate_required([:id, :source_id, :target_id, :type])
|> validate_inclusion(:type, ~w(follow block mute friend_request))
|> validate_inclusion(:status, ~w(pending accepted rejected active))
|> foreign_key_constraint(:source_id)
|> foreign_key_constraint(:target_id)
|> foreign_key_constraint(:activity_id)
|> unique_constraint([:source_id, :target_id, :type])
|> cast(attrs, [
:id,
:following,
:followed_by,
:showing_replies,
:showing_reblogs,
:notifying,
:muting,
:muting_notifications,
:blocking,
:blocked_by,
:domain_blocking,
:requested,
:note,
:source_id,
:target_id
])
|> validate_required([:id, :local_actor_id, :remote_actor_id])
|> unique_constraint([:local_actor_id, :remote_actor_id])
end
def create_relation(attrs) do
id = Snowflake.next_id()
%__MODULE__{}
|> __MODULE__.changeset(attrs)
|> Changeset.put_change(:id, id)
|> Repo.insert()
end
end

View file

@ -1,6 +1,7 @@
defmodule Nulla.Models.Session do
use Ecto.Schema
import Ecto.Changeset
alias Nulla.Models.User
@primary_key {:id, :integer, autogenerate: false}
schema "sessions" do
@ -8,7 +9,7 @@ defmodule Nulla.Models.Session do
field :user_agent, :string
field :ip, :string
belongs_to :user, Nulla.Models.User
belongs_to :user, User
timestamps(type: :utc_datetime)
end

View file

@ -69,7 +69,7 @@ defmodule Nulla.Models.User do
def update_last_active(user) do
user
|> Ecto.Changeset.change(last_active_at: DateTime.utc_now())
|> Changeset.change(last_active_at: DateTime.utc_now())
|> Repo.update()
end
end

View file

@ -1,7 +1,6 @@
defmodule NullaWeb.ActorController do
use NullaWeb, :controller
alias Nulla.ActivityPub
alias Nulla.Utils
alias Nulla.Models.Actor
alias Nulla.Models.Note
alias Nulla.Models.InstanceSettings

View file

@ -5,6 +5,7 @@ defmodule NullaWeb.InboxController do
alias Nulla.Utils
alias Nulla.Models.Actor
alias Nulla.Models.Relation
alias Nulla.Models.Activity
def inbox(
conn,
@ -24,19 +25,19 @@ defmodule NullaWeb.InboxController do
Activity.create_activity(%{
ap_id: follow_id,
type: "Follow",
actor: actor_uri,
actor: remote_actor.id,
object: target_uri
}),
accept_activity <-
Activity.create_activity(%{
type: "Accept",
actor: target_uri,
actor: target_actor.id,
object: follow_activity
}),
relation <- Relation.create_relation(%{
id: 1,
follower: remote_actor.id,
followed: target_actor.id
followed_by: true,
local_actor_id: target_actor.id,
remote_actor_id: remote_actor.id
}) do
conn
|> put_resp_content_type("application/activity+json")

View file

@ -1,16 +0,0 @@
defmodule Nulla.Repo.Migrations.CreateFollows do
use Ecto.Migration
def change do
create table(:follows, primary_key: false) do
add :id, :bigint, primary_key: true
add :follower_id, references(:actors, on_delete: :delete_all), null: false
add :following_id, references(:actors, on_delete: :delete_all), null: false
timestamps()
end
create unique_index(:follows, [:follower_id, :following_id])
create index(:follows, [:following_id])
end
end

View file

@ -4,20 +4,28 @@ defmodule Nulla.Repo.Migrations.CreateActorRelations do
def change do
create table(:relations, primary_key: false) do
add :id, :bigint, primary_key: true
add :source_id, :bigint, null: false
add :target_id, :bigint, null: false
add :type, :string, null: false
add :status, :string, null: false
add :activity_id, :bigint
add :following, :boolean, null: false, default: false
add :followed_by, :boolean, null: false, default: false
add :showing_replies, :boolean, null: false, default: true
add :showing_reblogs, :boolean, null: false, default: true
add :notifying, :boolean, null: false, default: false
add :muting, :boolean, null: false, default: false
add :muting_notifications, :boolean, null: false, default: false
add :blocking, :boolean, null: false, default: false
add :blocked_by, :boolean, null: false, default: false
add :domain_blocking, :boolean, null: false, default: false
add :requested, :boolean, null: false, default: false
add :note, :string
add :local_actor_id, references(:actors, type: :bigint), null: false
add :remote_actor_id, references(:actors, type: :bigint), null: false
timestamps()
end
create index(:relations, [:source_id])
create index(:relations, [:target_id])
create index(:relations, [:type])
create index(:relations, [:activity_id])
create index(:relations, [:local_actor_id])
create index(:relations, [:remote_actor_id])
create unique_index(:relations, [:source_id, :target_id, :type])
create unique_index(:relations, [:local_actor_id, :remote_actor_id])
end
end