Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ locals_without_parens = [
initial_states: 1,
default_initial_state: 1,
state_attribute: 1,
transition: 1
transition: 1,
compact: 1,
label: 1
]

[
Expand Down
42 changes: 42 additions & 0 deletions lib/diffo/changes/detail_event.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule Diffo.Changes.DetailEvent do
@moduledoc """
Diffo - TMF Service and Resource Management with a difference

DetailEvent - Ash Resource Change for detailing an Event

"""
use Ash.Resource.Change

def change(changeset, _opts, _context) do
instance_id = Ash.Changeset.get_data(changeset, :id)

case Diffo.Provider.get_instance_by_id(instance_id, load: [:event]) do
{:ok, instance} ->
event =
Ash.Changeset.get_argument(changeset, :event)
|> Map.put(:firing_type, instance.type)
|> Map.put(:firing_snapshot, Jason.encode!(instance))

earlier_event = Map.get(instance, :event)

event =
if earlier_event do
Map.put(event, :earlier_id, earlier_event.id)
else
event
end

Ash.Changeset.force_set_argument(changeset, :event, event)

{:error, _error} ->
changeset
end
end

# this can be used as follows, where it will set the Event's firing_type, firing_snapshot and earlier_id from the refreshed Instance
# change Diffo.Changes.DetailEvent
end
46 changes: 46 additions & 0 deletions lib/diffo/helpers/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,52 @@ defmodule Diffo.Util do
end
end

@doc """
Nest values from list of tuples into a list, with a new tuple key
## Examples
iex> list = [state: :up, weeks: 1, days: 5]
iex> Diffo.Util.nest(list, [:weeks, :days], :duration)
[state: :up, duration: [weeks: 1, days: 5]]

"""
def nest(list, tuple_keys, new_tuple_key) when is_list(list) and is_list(tuple_keys) do
{nested_list, remainder_list} =
Enum.split_with(list, fn {tuple_key, _} -> tuple_key in tuple_keys end)

set(remainder_list, new_tuple_key, nested_list)
end

@doc """
Nest values from list of tuples into a map, with a new tuple key
## Examples
iex> list = [state: :up, weeks: 1, days: 5]
iex> Diffo.Util.nest_as_map(list, [:weeks, :days], :duration)
[state: :up, duration: %{weeks: 1, days: 5}]

"""
def nest_as_map(list, tuple_keys, new_tuple_key) when is_list(list) and is_list(tuple_keys) do
{nested_list, remainder_list} =
Enum.split_with(list, fn {tuple_key, _} -> tuple_key in tuple_keys end)

set(remainder_list, new_tuple_key, Map.new(nested_list))
end

@doc """
Encapsulate a tuple value as a Jason Fragment
## Examples
iex> list = [state: :initial, service: Jason.encode!(%{state: :initial})]
iex> list = Diffo.Util.fragment(list, :service)
iex> {:service, %name{}} = List.keyfind(list, :service, 0)
iex> name
Jason.Fragment

"""
def fragment(list, tuple_key) when is_list(list) do
tuple_value = get(list, tuple_key)
value = Jason.Fragment.new(tuple_value)
list |> List.keystore(tuple_key, 0, {tuple_key, value})
end

defimpl Jason.Encoder, for: Tuple do
def encode(tuple, _opts) when is_tuple(tuple) do
tuple
Expand Down
12 changes: 12 additions & 0 deletions lib/diffo/provider.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ defmodule Diffo.Provider do
define :relate_instance_characteristics, action: :relate_characteristics
define :unrelate_instance_characteristics, action: :unrelate_characteristics
define :annotate_instance, action: :annotate
define :fire_instance_event, action: :fire_event
define :delete_instance, action: :destroy
end

Expand Down Expand Up @@ -215,5 +216,16 @@ defmodule Diffo.Provider do
define :update_entity_ref, action: :update
define :delete_entity_ref, action: :destroy
end

resource Diffo.Provider.Event do
define :get_event_by_id, action: :read, get_by: :id
define :list_events, action: :list

define :list_events_by_instance_id,
action: :list_events_by_instance_id,
args: [:instance_id]

define :delete_event, action: :destroy
end
end
end
2 changes: 1 addition & 1 deletion lib/diffo/provider/assigner/assignable_value.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule Diffo.Provider.AssignableValue do

jason do
pick [:first, :last, :free, :type, :algorithm]
compact(true)
compact true
end

typed_struct do
Expand Down
2 changes: 1 addition & 1 deletion lib/diffo/provider/assigner/assignment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule Diffo.Provider.Assignment do

jason do
pick [:id, :assignee_id, :operation]
compact(true)
compact true
end

typed_struct do
Expand Down
27 changes: 23 additions & 4 deletions lib/diffo/provider/components/base_instance.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ defmodule Diffo.Provider.BaseInstance do
{:characteristics, :HAS, :outgoing, :Characteristic},
{:entities, :RELATES, :outgoing, :EntityRef},
{:notes, :ANNOTATES, :incoming, :Note},
{:event, :FIRED, :outgoing, :Event},
{:places, :LOCATED_BY, :outgoing, :PlaceRef},
{:parties, :INVOLVED_WITH, :outgoing, :PartyRef}
]

label(:Instance)
label :Instance
end

jason do
Expand All @@ -58,7 +59,7 @@ defmodule Diffo.Provider.BaseInstance do
:type
]

compact(true)
compact true

customize fn result, record ->
result
Expand Down Expand Up @@ -204,7 +205,7 @@ defmodule Diffo.Provider.BaseInstance do
constraints one_of: Diffo.Provider.Service.service_operating_statuses()
end

create_timestamp :inserted_at
create_timestamp :created_at

update_timestamp :updated_at

Expand Down Expand Up @@ -271,6 +272,12 @@ defmodule Diffo.Provider.BaseInstance do
destination_attribute :instance_id
end

has_one :event, Diffo.Provider.Event do
description "the most recently fired event"
public? true
destination_attribute :instance_id
end

has_many :places, Diffo.Provider.PlaceRef do
description "the instance's collection of related places"
public? true
Expand Down Expand Up @@ -451,6 +458,18 @@ defmodule Diffo.Provider.BaseInstance do
argument :note, :uuid
change manage_relationship(:note, :notes, type: :append)
end

update :fire_event do
description "fires an event, maintaining the event chain"

argument :event, :map do
allow_nil? false
end

change Diffo.Changes.DetailEvent
change manage_relationship(:event, type: :create)
change load [:event]
end
end

code_interface do
Expand Down Expand Up @@ -479,7 +498,7 @@ defmodule Diffo.Provider.BaseInstance do
:places,
:parties
],
sort: [inserted_at: :desc]
sort: [created_at: :desc]
)
end

Expand Down
8 changes: 7 additions & 1 deletion lib/diffo/provider/components/characteristic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ defmodule Diffo.Provider.Characteristic do
constraints one_of: [:instance, :feature, :relationship]
end

create_timestamp :inserted_at
create_timestamp :created_at

update_timestamp :updated_at
end
Expand Down Expand Up @@ -149,6 +149,12 @@ defmodule Diffo.Provider.Characteristic do
end
end

validations do
validate present([:instance_id, :feature_id, :relationship_id], at_most: 1) do
message "characteristic must be related to at most one of an instance, feature or relationship"
end
end

preparations do
prepare build(sort: [name: :asc])
end
Expand Down
4 changes: 2 additions & 2 deletions lib/diffo/provider/components/entity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Diffo.Provider.Entity do

jason do
pick [:id, :href, :name, :referredType, :type]
compact(true)
compact true
rename referredType: "@referredType", type: "@type"
end

Expand Down Expand Up @@ -112,7 +112,7 @@ defmodule Diffo.Provider.Entity do
public? true
end

create_timestamp :inserted_at
create_timestamp :created_at

update_timestamp :updated_at
end
Expand Down
4 changes: 2 additions & 2 deletions lib/diffo/provider/components/entity_ref.ex
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ defmodule Diffo.Provider.EntityRef do
public? true
end

create_timestamp :inserted_at
create_timestamp :created_at

update_timestamp :updated_at
end
Expand All @@ -121,7 +121,7 @@ defmodule Diffo.Provider.EntityRef do
end

preparations do
prepare build(load: [:entity], sort: [inserted_at: :desc])
prepare build(load: [:entity], sort: [created_at: :desc])
end

@doc """
Expand Down
Loading