Update Book to sync only a new non-local data.

dev
KKlochko 2 months ago
parent 83a82a2da2
commit 72bc941d18

@ -74,6 +74,7 @@ defmodule DecentralisedBookIndex.Metadata do
define :search_book_by_bid, action: :search_by_bid, args: [:type, :bid] define :search_book_by_bid, action: :search_by_bid, args: [:type, :bid]
define :update_book, action: :update define :update_book, action: :update
define :assign_book_cover_image, args: [:cover_image_url], action: :assign_cover_image define :assign_book_cover_image, args: [:cover_image_url], action: :assign_cover_image
define :assign_book_dbi_server, args: [:dbi_server_id], action: :assign_dbi_server_id
define :destroy_book, action: :destroy define :destroy_book, action: :destroy
end end

@ -40,7 +40,8 @@ defmodule DecentralisedBookIndex.Metadata.Book do
:published, :published,
:publisher_id, :publisher_id,
:cover_image_url, :cover_image_url,
:book_editions_registry_id :book_editions_registry_id,
:dbi_server_id
] ]
argument :bids, {:array, :map} argument :bids, {:array, :map}
@ -276,6 +277,10 @@ defmodule DecentralisedBookIndex.Metadata.Book do
update :assign_cover_image do update :assign_cover_image do
accept [:cover_image_url] accept [:cover_image_url]
end end
update :assign_dbi_server_id do
accept [:dbi_server_id]
end
end end
policies do policies do

@ -8,15 +8,18 @@ defmodule DecentralisedBookIndex.Sync.BookSync do
case Metadata.get_book_by_id(attrs.id) do case Metadata.get_book_by_id(attrs.id) do
{:ok, book} -> {:ok, book} ->
if not is_local(book) and is_new(attrs, book) do
attrs = attrs =
attrs attrs
|> Map.delete(:id) |> Map.delete(:id)
|> update_registry(registry_info) |> update_registry(registry_info)
|> Map.put(:dbi_server_id, server_id) |> Map.put_new(:dbi_server_id, server_id)
book book
|> Ash.Changeset.for_update(:sync, attrs) |> Ash.Changeset.for_update(:sync, attrs)
|> Ash.update!(authorize?: false) |> Ash.update!(authorize?: false)
end
:ok :ok
@ -24,7 +27,7 @@ defmodule DecentralisedBookIndex.Sync.BookSync do
attrs = attrs =
attrs attrs
|> update_registry(registry_info) |> update_registry(registry_info)
|> Map.put(:dbi_server_id, server_id) |> Map.put_new(:dbi_server_id, server_id)
Book Book
|> Ash.Changeset.for_create(:sync_create, attrs) |> Ash.Changeset.for_create(:sync_create, attrs)
@ -58,4 +61,17 @@ defmodule DecentralisedBookIndex.Sync.BookSync do
|> Map.delete(:book_editions_registry_id) |> Map.delete(:book_editions_registry_id)
end end
end end
defp is_local(book) do
is_nil(book.dbi_server_id)
end
defp is_new(new_book, book) do
with {:ok, datetime, _offset} <- DateTime.from_iso8601(new_book[:updated_at]) do
DateTime.after?(datetime, book.updated_at)
else
{:error, reason} ->
false
end
end
end end

@ -7,6 +7,11 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.BookSyncTest do
alias DecentralisedBookIndex.TestEndpoints alias DecentralisedBookIndex.TestEndpoints
@test_server_endpoint TestEndpoints.test_api_endpoint() @test_server_endpoint TestEndpoints.test_api_endpoint()
setup do
user = generate(user(role: :moderator))
%{user: user}
end
describe "sync book transformations" do describe "sync book transformations" do
test "a new book will be created" do test "a new book will be created" do
server = generate(dbi_server(url: @test_server_endpoint)) server = generate(dbi_server(url: @test_server_endpoint))
@ -164,11 +169,62 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.BookSyncTest do
assert {:ok, saved_book} = Metadata.get_book_by_id(book.id) assert {:ok, saved_book} = Metadata.get_book_by_id(book.id)
end end
test "update book's relationship for an existing book" do test "the local existing book wouldn't updated", %{user: user} do
server = generate(dbi_server(url: @test_server_endpoint))
book = generate(book())
book_attrs = %{
id: book.id,
cover_image_url: "/images/book_cover2.png",
description: "A cool book 2.",
format: "Ebook",
inserted_at: "2025-01-20T14:44:36.162986Z",
language: "English",
page_count: 1001,
published: "2025-03-05",
title: "New Book2",
updated_at: "2025-02-01T18:14:25.754055Z"
}
assert :ok = BookSync.create_update(book_attrs, server.id)
assert {:ok, saved_book} = Metadata.get_book_by_id(book.id)
assert get_submap(saved_book, book_attrs) != book_attrs
assert saved_book.title != "New Book2"
assert saved_book.dbi_server_id == nil
end
test "old book wouldn't be sync", %{user: user} do
server = generate(dbi_server(url: @test_server_endpoint)) server = generate(dbi_server(url: @test_server_endpoint))
book = generate(book()) book = generate(book())
book_attrs = %{
id: book.id,
cover_image_url: "/images/book_cover2.png",
description: "A cool book 2.",
format: "Ebook",
inserted_at: "2025-01-20T14:44:36.162986Z",
language: "English",
page_count: 1001,
published: "2025-03-05",
title: "New Book2",
updated_at: "2025-02-01T18:14:25.754055Z"
}
assert :ok = BookSync.create_update(book_attrs, server.id)
assert {:ok, saved_book} = Metadata.get_book_by_id(book.id)
assert get_submap(saved_book, book_attrs) != book_attrs
assert saved_book.title != "New Book2"
end
test "update book's relationship for an existing book" do
server = generate(dbi_server(url: @test_server_endpoint))
book = generate(book(dbi_server_id: server.id))
author1 = generate(author()) author1 = generate(author())
author2 = generate(author()) author2 = generate(author())
publisher = generate(publisher()) publisher = generate(publisher())
@ -212,7 +268,8 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.BookSyncTest do
published: "2025-03-04", published: "2025-03-04",
publisher_id: publisher.id, publisher_id: publisher.id,
title: "Book 6", title: "Book 6",
updated_at: "2025-04-08T07:02:42.778095Z" updated_at: datetime_add_second_as_string(book.updated_at, 10),
dbi_server_id: server.id
} }
assert :ok = BookSync.create_update(book_attrs, server.id) assert :ok = BookSync.create_update(book_attrs, server.id)
@ -228,7 +285,7 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.BookSyncTest do
test "olds bids and roles are destroyed after update" do test "olds bids and roles are destroyed after update" do
server = generate(dbi_server(url: @test_server_endpoint)) server = generate(dbi_server(url: @test_server_endpoint))
book = generate(book()) book = generate(book(dbi_server_id: server.id))
author1 = generate(author()) author1 = generate(author())
author2 = generate(author()) author2 = generate(author())
@ -273,7 +330,8 @@ defmodule DecentralisedBookIndex.Sync.DataTransformers.BookSyncTest do
published: "2025-03-04", published: "2025-03-04",
publisher_id: publisher.id, publisher_id: publisher.id,
title: "Book 6", title: "Book 6",
updated_at: "2025-04-08T07:02:42.778095Z" updated_at: datetime_add_second_as_string(book.updated_at, 10),
dbi_server_id: server.id
} }
old_bids = get_ids(Metadata.list_book_ids!()) old_bids = get_ids(Metadata.list_book_ids!())

@ -179,6 +179,8 @@ defmodule DecentralisedBookIndex.Generators do
related_book = opts[:related_book] || nil related_book = opts[:related_book] || nil
dbi_server_id = opts[:dbi_server_id] || nil
book_editions_registry_id = book_editions_registry_id =
if related_book do if related_book do
related_book.book_editions_registry_id related_book.book_editions_registry_id
@ -199,7 +201,8 @@ defmodule DecentralisedBookIndex.Generators do
bids: bids, bids: bids,
author_roles: author_roles, author_roles: author_roles,
publisher_id: publisher_id, publisher_id: publisher_id,
book_editions_registry_id: book_editions_registry_id book_editions_registry_id: book_editions_registry_id,
dbi_server_id: dbi_server_id
], ],
overrides: opts, overrides: opts,
actor: actor actor: actor

Loading…
Cancel
Save