diff --git a/lib/decentralised_book_index/metadata.ex b/lib/decentralised_book_index/metadata.ex index 1192bcb..a84113d 100644 --- a/lib/decentralised_book_index/metadata.ex +++ b/lib/decentralised_book_index/metadata.ex @@ -98,6 +98,7 @@ defmodule DecentralisedBookIndex.Metadata do define :search_author, action: :search, args: [:name] define :update_author, action: :update define :assign_author_avatar_image, args: [:avatar_url], action: :assign_avatar_image + define :assign_author_dbi_server, args: [:dbi_server_id], action: :assign_dbi_server_id define :destroy_author, action: :destroy end diff --git a/lib/decentralised_book_index/metadata/author.ex b/lib/decentralised_book_index/metadata/author.ex index a474aeb..1d407a2 100644 --- a/lib/decentralised_book_index/metadata/author.ex +++ b/lib/decentralised_book_index/metadata/author.ex @@ -195,6 +195,10 @@ defmodule DecentralisedBookIndex.Metadata.Author do update :assign_avatar_image do accept [:avatar_url] end + + update :assign_dbi_server_id do + accept [:dbi_server_id] + end end policies do diff --git a/lib/decentralised_book_index/sync/sync/author_sync.ex b/lib/decentralised_book_index/sync/sync/author_sync.ex index 867fbae..53f2ecf 100644 --- a/lib/decentralised_book_index/sync/sync/author_sync.ex +++ b/lib/decentralised_book_index/sync/sync/author_sync.ex @@ -8,15 +8,17 @@ defmodule DecentralisedBookIndex.Sync.AuthorSync do case Metadata.get_author_by_id(attrs.id) do {:ok, author} -> - attrs = - attrs - |> Map.delete(:id) - |> update_registry(registry_info) - |> Map.put(:dbi_server_id, server_id) + if not is_local(author) and is_new(attrs, author) do + attrs = + attrs + |> Map.delete(:id) + |> update_registry(registry_info) + |> Map.put_new(:dbi_server_id, server_id) - author - |> Ash.Changeset.for_update(:sync, attrs) - |> Ash.update!(authorize?: false) + author + |> Ash.Changeset.for_update(:sync, attrs) + |> Ash.update!(authorize?: false) + end :ok @@ -24,7 +26,7 @@ defmodule DecentralisedBookIndex.Sync.AuthorSync do attrs = attrs |> update_registry(registry_info) - |> Map.put(:dbi_server_id, server_id) + |> Map.put_new(:dbi_server_id, server_id) Author |> Ash.Changeset.for_create(:sync_create, attrs) @@ -58,4 +60,17 @@ defmodule DecentralisedBookIndex.Sync.AuthorSync do |> Map.delete(:author_alias_registry_id) end end + + defp is_local(author) do + is_nil(author.dbi_server_id) + end + + defp is_new(new_author, author) do + with {:ok, datetime, _offset} <- DateTime.from_iso8601(new_author[:updated_at]) do + DateTime.after?(datetime, author.updated_at) + else + {:error, reason} -> + false + end + end end diff --git a/test/decentralised_book_index/sync/sync/author_sync_test.exs b/test/decentralised_book_index/sync/sync/author_sync_test.exs index 9cd19b0..a611348 100644 --- a/test/decentralised_book_index/sync/sync/author_sync_test.exs +++ b/test/decentralised_book_index/sync/sync/author_sync_test.exs @@ -90,5 +90,51 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.AuthorSyncTest do assert author = saved_author end + + test "the local existing author wouldn't updated", %{user: user} do + server = generate(dbi_server(url: @test_server_endpoint)) + + {:ok, author} = Metadata.create_author("Author", "An description", nil, nil, actor: user) + + author_attrs = %{ + id: author.id, + name: "Author", + description: "Something2", + avatar_url: "/images/avatar.png", + author_alias_registry_id: nil, + inserted_at: "2025-03-21T09:20:48.791539Z", + updated_at: "2025-03-21T09:20:48.791539Z" + } + + assert :ok = AuthorSync.create_update(author_attrs, server.id) + assert {:ok, saved_author} = Metadata.get_author_by_id(author.id) + + assert get_submap(saved_author, author_attrs) != author_attrs + assert saved_author.name == "Author" + assert saved_author.dbi_server_id == nil + end + + test "old author wouldn't be sync", %{user: user} do + server = generate(dbi_server(url: @test_server_endpoint)) + + {:ok, author} = Metadata.create_author("Author", "An description", nil, nil, actor: user) + {:ok, author} = Metadata.assign_author_dbi_server(author, server.id, actor: user) + + author_attrs = %{ + id: author.id, + name: "Author", + description: "Something2", + avatar_url: "/images/avatar.png", + author_alias_registry_id: nil, + inserted_at: "2025-03-21T09:20:48.791539Z", + updated_at: "2025-03-21T09:20:48.791539Z" + } + + assert :ok = AuthorSync.create_update(author_attrs, server.id) + assert {:ok, saved_author} = Metadata.get_author_by_id(author.id) + + assert get_submap(saved_author, author_attrs) != author_attrs + assert saved_author.name == "Author" + end end end