dev vouch dev on at. thats about it atvouch.dev

add tap event handling

+103 -27
+12
appview/lib/atvouch/identity.ex
··· 23 23 |> Atvouch.Repo.insert() 24 24 end 25 25 26 + def upsert(attrs) do 27 + case one(attrs[:did] || attrs["did"]) do 28 + nil -> 29 + create(attrs) 30 + 31 + existing -> 32 + existing 33 + |> changeset(attrs) 34 + |> Atvouch.Repo.update() 35 + end 36 + end 37 + 26 38 def one(did) do 27 39 Atvouch.Repo.get(__MODULE__, did) 28 40 end
+78 -27
appview/lib/atvouch/tap_handler.ex
··· 2 2 @behaviour Atvouch.Tap.Handler 3 3 require Logger 4 4 5 - # TODO: implement vouch creation from tap events 6 - # @impl true 7 - # def handle_record(%{collection: "dev.atvouch.graph.vouch", action: :create} = event) do 8 - # Logger.info("tap record: #{event.action} #{event.collection}/#{event.rkey} from #{event.did}") 9 - # 10 - # # Ensure the creator identity exists 11 - # case Atvouch.Identity.one(event.did) do 12 - # nil -> Atvouch.Identity.create(%{did: event.did}) 13 - # identity -> {:ok, identity} 14 - # end 15 - # 16 - # at_uri = "at://#{event.did}/#{event.collection}/#{event.rkey}" 17 - # 18 - # case Atvouch.Vouch.create(%{ 19 - # at_uri: at_uri, 20 - # creator_did: event.did, 21 - # target_did: event.record["subject"], 22 - # created_at: event.record["createdAt"] 23 - # }) do 24 - # {:ok, _vouch} -> :ok 25 - # {:error, reason} -> {:error, reason} 26 - # end 27 - # end 5 + @collection "dev.atvouch.graph.vouch" 28 6 29 7 @impl true 8 + def handle_record(%{collection: @collection, action: :create} = event) do 9 + at_uri = "at://#{event.did}/#{@collection}/#{event.rkey}" 10 + created_at = event.record["createdAt"] 11 + target_did = event.record["subject"] 12 + 13 + # Ensure both identities exist 14 + ensure_identity(event.did) 15 + ensure_identity(target_did) 16 + 17 + case Atvouch.Vouch.create(%{ 18 + at_uri: at_uri, 19 + creator_did: event.did, 20 + target_did: target_did, 21 + original_created_at: created_at, 22 + remote_created_at: created_at, 23 + remote_updated_timestamp: false, 24 + at_cid: event.cid, 25 + live: event.live 26 + }) do 27 + {:ok, _vouch} -> :ok 28 + {:error, reason} -> {:error, reason} 29 + end 30 + end 31 + 32 + def handle_record(%{collection: @collection, action: :update} = event) do 33 + at_uri = "at://#{event.did}/#{@collection}/#{event.rkey}" 34 + created_at = event.record["createdAt"] 35 + 36 + case Atvouch.Vouch.one(at_uri) do 37 + nil -> 38 + {:error, :not_found} 39 + 40 + vouch -> 41 + updated_timestamp = created_at != vouch.original_created_at 42 + 43 + case Atvouch.Vouch.update(vouch, %{ 44 + remote_created_at: created_at, 45 + remote_updated_timestamp: updated_timestamp, 46 + at_cid: event.cid, 47 + live: event.live 48 + }) do 49 + {:ok, _vouch} -> :ok 50 + {:error, reason} -> {:error, reason} 51 + end 52 + end 53 + end 54 + 55 + def handle_record(%{collection: @collection, action: :delete} = event) do 56 + at_uri = "at://#{event.did}/#{@collection}/#{event.rkey}" 57 + 58 + case Atvouch.Vouch.delete(at_uri) do 59 + {:ok, _vouch} -> :ok 60 + {:error, reason} -> {:error, reason} 61 + end 62 + end 63 + 30 64 def handle_record(event) do 31 - Logger.info("tap record: #{event.action} #{event.collection}/#{event.rkey} from #{event.did}") 32 - {:error, :skip} 65 + Logger.debug( 66 + "explicit skip for record event #{inspect(event)}, not handled by others. is tap misconfigured?" 67 + ) 68 + 69 + {:error, :invalid_collection_or_action} 33 70 end 34 71 35 72 @impl true 36 73 def handle_identity(event) do 37 - Logger.info("tap identity: #{event.did} handle=#{event.handle} active=#{event.is_active}") 38 - {:error, :skip} 74 + case Atvouch.Identity.upsert(%{ 75 + did: event.did, 76 + handle: event.handle, 77 + active: event.is_active, 78 + status: event.status 79 + }) do 80 + {:ok, _identity} -> :ok 81 + {:error, reason} -> {:error, reason} 82 + end 83 + end 84 + 85 + defp ensure_identity(did) do 86 + case Atvouch.Identity.one(did) do 87 + nil -> Atvouch.Identity.create(%{did: did}) 88 + _existing -> :ok 89 + end 39 90 end 40 91 end
+13
appview/lib/atvouch/vouch.ex
··· 28 28 |> Atvouch.Repo.insert() 29 29 end 30 30 31 + def update(vouch, attrs) do 32 + vouch 33 + |> changeset(attrs) 34 + |> Atvouch.Repo.update() 35 + end 36 + 37 + def delete(at_uri) do 38 + case one(at_uri) do 39 + nil -> {:error, :not_found} 40 + vouch -> Atvouch.Repo.delete(vouch) 41 + end 42 + end 43 + 31 44 def one(at_uri) do 32 45 Atvouch.Repo.get(__MODULE__, at_uri) 33 46 end