commit 8c4c5042e968c5c188936e45999f014c6778a441
parent 75e959d0bf8c502df3a154fef7fe530acc4d0b3a
Author: srfsh <dev@srf.sh>
Date: Fri, 9 Dec 2022 11:41:34 +0300
Zenflows.VF.Satisfaction.{Domain,Resolv,Type}: add support for Satisfactions
Diffstat:
3 files changed, 388 insertions(+), 0 deletions(-)
diff --git a/src/zenflows/vf/satisfaction/domain.ex b/src/zenflows/vf/satisfaction/domain.ex
@@ -0,0 +1,145 @@
+# Zenflows is designed to implement the Valueflows vocabulary,
+# written and maintained by srfsh <info@dyne.org>.
+# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+defmodule Zenflows.VF.Satisfaction.Domain do
+@moduledoc "Domain logic of Satisfactions."
+
+alias Ecto.{Changeset, Multi}
+alias Zenflows.DB.{Page, Repo, Schema}
+alias Zenflows.VF.{Measure, Satisfaction}
+
+@spec one(Ecto.Repo.t(), Schema.id() | map() | Keyword.t())
+ :: {:ok, Satisfaction.t()} | {:error, String.t()}
+def one(repo \\ Repo, _)
+def one(repo, id) when is_binary(id), do: one(repo, id: id)
+def one(repo, clauses) do
+ case repo.get_by(Satisfaction, clauses) do
+ nil -> {:error, "not found"}
+ found -> {:ok, found}
+ end
+end
+
+@spec one!(Ecto.Repo.t(), Schema.id() | map() | Keyword.t()) :: Satisfaction.t()
+def one!(repo \\ Repo, id_or_clauses) do
+ {:ok, value} = one(repo, id_or_clauses)
+ value
+end
+
+@spec all(Page.t()) :: {:ok, [Satisfaction.t()]} | {:error, Changeset.t()}
+def all(page \\ Page.new()) do
+ {:ok, Page.all(Satisfaction, page)}
+end
+
+@spec all!(Page.t()) :: [Satisfaction.t()]
+def all!(page \\ Page.new()) do
+ {:ok, value} = all(page)
+ value
+end
+
+@spec create(Schema.params()) :: {:ok, Satisfaction.t()} | {:error, Changeset.t()}
+def create(params) do
+ key = multi_key()
+ Multi.new()
+ |> multi_insert(params)
+ |> Repo.transaction()
+ |> case do
+ {:ok, %{^key => value}} -> {:ok, value}
+ {:error, _, cset, _} -> {:error, cset}
+ end
+end
+
+@spec create!(Schema.params()) :: Satisfaction.t()
+def create!(params) do
+ {:ok, value} = create(params)
+ value
+end
+
+@spec update(Schema.id(), Schema.params())
+ :: {:ok, Satisfaction.t()} | {:error, String.t() | Changeset.t()}
+def update(id, params) do
+ key = multi_key()
+ Multi.new()
+ |> multi_update(id, params)
+ |> Repo.transaction()
+ |> case do
+ {:ok, %{^key => value}} -> {:ok, value}
+ {:error, _, reason, _} -> {:error, reason}
+ end
+end
+
+@spec update!(Schema.id(), Schema.params()) :: Satisfaction.t()
+def update!(id, params) do
+ {:ok, value} = update(id, params)
+ value
+end
+
+@spec delete(Schema.id()) :: {:ok, Satisfaction.t()} | {:error, String.t() | Changeset.t()}
+def delete(id) do
+ key = multi_key()
+ Multi.new()
+ |> multi_delete(id)
+ |> Repo.transaction()
+ |> case do
+ {:ok, %{^key => value}} -> {:ok, value}
+ {:error, _, reason, _} -> {:error, reason}
+ end
+end
+
+@spec delete!(Schema.id) :: Satisfaction.t()
+def delete!(id) do
+ {:ok, value} = delete(id)
+ value
+end
+
+@spec preload(Satisfaction.t(), :satisfies | :satisfied_by_event
+ | :satisfied_by_commitment | :resource_quantity | :effort_quantity)
+ :: Satisfaction.t()
+def preload(satis, x) when x in ~w[
+ satisfies satisfied_by_event satisfied_by_commitment
+]a,
+ do: Repo.preload(satis, x)
+def preload(satis, x) when x in ~w[effort_quantity resource_quantity]a,
+ do: Measure.preload(satis, x)
+
+@spec multi_key() :: atom()
+def multi_key(), do: :satisfaction
+
+@spec multi_one(Multi.t(), term(), Schema.id()) :: Multi.t()
+def multi_one(m, key \\ multi_key(), id) do
+ Multi.run(m, key, fn repo, _ -> one(repo, id) end)
+end
+
+@spec multi_insert(Multi.t(), term(), Schema.params()) :: Multi.t()
+def multi_insert(m, key \\ multi_key(), params) do
+ Multi.insert(m, key, Satisfaction.changeset(params))
+end
+
+@spec multi_update(Multi.t(), term(), Schema.id(), Schema.params()) :: Multi.t()
+def multi_update(m, key \\ multi_key(), id, params) do
+ m
+ |> multi_one("#{key}.one", id)
+ |> Multi.update(key,
+ &Satisfaction.changeset(Map.fetch!(&1, "#{key}.one"), params))
+end
+
+@spec multi_delete(Multi.t(), term(), Schema.id()) :: Multi.t()
+def multi_delete(m, key \\ multi_key(), id) do
+ m
+ |> multi_one("#{key}.one", id)
+ |> Multi.delete(key, &Map.fetch!(&1, "#{key}.one"))
+end
+end
diff --git a/src/zenflows/vf/satisfaction/resolv.ex b/src/zenflows/vf/satisfaction/resolv.ex
@@ -0,0 +1,77 @@
+# Zenflows is designed to implement the Valueflows vocabulary,
+# written and maintained by srfsh <info@dyne.org>.
+# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+defmodule Zenflows.VF.Satisfaction.Resolv do
+@moduledoc false
+
+alias Zenflows.GQL.Connection
+alias Zenflows.VF.Satisfaction.Domain
+
+def satisfaction(params, _) do
+ Domain.one(params)
+end
+
+def satisfactions(params, _) do
+ with {:ok, page} <- Connection.parse(params),
+ {:ok, schemas} <- Domain.all(page) do
+ {:ok, Connection.from_list(schemas, page)}
+ end
+end
+
+def create_satisfaction(%{satisfaction: params}, _) do
+ with {:ok, satis} <- Domain.create(params) do
+ {:ok, %{satisfaction: satis}}
+ end
+end
+
+def update_satisfaction(%{satisfaction: %{id: id} = params}, _) do
+ with {:ok, satis} <- Domain.update(id, params) do
+ {:ok, %{satisfaction: satis}}
+ end
+end
+
+def delete_satisfaction(%{id: id}, _) do
+ with {:ok, _} <- Domain.delete(id) do
+ {:ok, true}
+ end
+end
+
+def satisfies(satis, _, _) do
+ satis = Domain.preload(satis, :satisfies)
+ {:ok, satis.satisfies}
+end
+
+def satisfied_by_event(satis, _, _) do
+ satis = Domain.preload(satis, :satisfied_by_event)
+ {:ok, satis.satisfied_by_event}
+end
+
+def satisfied_by_commitment(satis, _, _) do
+ satis = Domain.preload(satis, :satisfied_by_commitment)
+ {:ok, satis.satisfied_by_commitment}
+end
+
+def resource_quantity(satis, _, _) do
+ satis = Domain.preload(satis, :resource_quantity)
+ {:ok, satis.resource_quantity}
+end
+
+def effort_quantity(satis, _, _) do
+ satis = Domain.preload(satis, :effort_quantity)
+ {:ok, satis.effort_quantity}
+end
+end
diff --git a/src/zenflows/vf/satisfaction/type.ex b/src/zenflows/vf/satisfaction/type.ex
@@ -0,0 +1,166 @@
+# Zenflows is designed to implement the Valueflows vocabulary,
+# written and maintained by srfsh <info@dyne.org>.
+# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+defmodule Zenflows.VF.Satisfaction.Type do
+@moduledoc false
+
+use Absinthe.Schema.Notation
+
+alias Zenflows.VF.Satisfaction.Resolv
+
+@note "A textual description or comment."
+@satisfies """
+An intent satisfied fully or partially by an economic event or commitment.
+"""
+@satisfies_id "(`Intent`) #{@satisfies}"
+@satisfied_by_event """
+An economic event fully or partially satisfying an intent.
+
+Mutually exclusive with commitment.
+"""
+@satisfied_by_event_id "(`EconomicEvent`) #{@satisfied_by_event}"
+#@satisfied_by_commitment """
+#A commitment fully or partially satisfying an intent."
+#
+#Mutually exclusive with event.
+#"""
+#@satisfied_by_commitment_id "(`Commitment`) #{@satisfied_by_commitment}"
+@resource_quantity """
+The amount and unit of the economic resource counted or inventoried.
+"""
+@effort_quantity """
+The amount and unit of the work or use or citation effort-based
+action. This is often a time duration, but also could be cycle
+counts or other measures of effort or usefulness.
+"""
+
+@desc """
+Represents many-to-many relationships between intents and commitments
+or events that partially or full satisfy one or more intents.
+"""
+object :satisfaction do
+ field :id, non_null(:id)
+
+ @desc @note
+ field :note, :string
+
+ @desc @satisfies
+ field :satisfies, non_null(:intent), resolve: &Resolv.satisfies/3
+
+ @desc @satisfied_by_event
+ field :satisfied_by_event, :economic_event,
+ resolve: &Resolv.satisfied_by_event/3
+
+ #@desc @satisfied_by_commitment
+ #field :satisfied_by_commitment, :commitment,
+ # resolve: &Resolv.satisfied_by_commitment/3
+
+ @desc @resource_quantity
+ field :resource_quantity, :measure, resolve: &Resolv.resource_quantity/3
+
+ @desc @effort_quantity
+ field :effort_quantity, :measure, resolve: &Resolv.effort_quantity/3
+end
+
+input_object :satisfaction_create_params do
+ @desc @note
+ field :note, :string
+
+ @desc @satisfies_id
+ field :satisfies_id, non_null(:id), name: "satisfies"
+
+ @desc @satisfied_by_event_id
+ field :satisfied_by_event_id, :id, name: "satisfied_by_event"
+
+ #@desc @satisfied_by_commitment_id
+ #field :satisfied_by_commitment_id, :id, name: "satisfied_by_commitment"
+
+ @desc @resource_quantity
+ field :resource_quantity, :imeasure
+
+ @desc @effort_quantity
+ field :effort_quantity, :imeasure
+end
+
+input_object :satisfaction_update_params do
+ field :id, non_null(:id)
+
+ @desc @note
+ field :note, :string
+
+ @desc @satisfies_id
+ field :satisfies_id, :id, name: "satisfies"
+
+ @desc @satisfied_by_event_id
+ field :satisfied_by_event_id, :id, name: "satisfied_by_event"
+
+ #@desc @satisfied_by_commitment_id
+ #field :satisfied_by_commitment_id, :id, name: "satisfied_by_commitment"
+
+ @desc @resource_quantity
+ field :resource_quantity, :imeasure
+
+ @desc @effort_quantity
+ field :effort_quantity, :imeasure
+end
+
+object :satisfaction_response do
+ field :satisfaction, non_null(:satisfaction)
+end
+
+object :satisfaction_edge do
+ field :cursor, non_null(:id)
+ field :node, non_null(:satisfaction)
+end
+
+object :satisfaction_connection do
+ field :page_info, non_null(:page_info)
+ field :edges, non_null(list_of(non_null(:satisfaction_edge)))
+end
+
+object :query_satisfaction do
+ field :satisfaction, :satisfaction do
+ arg :id, non_null(:id)
+ resolve &Resolv.satisfaction/2
+ end
+
+ field :satisfactions, non_null(:satisfaction_connection) do
+ arg :first, :integer
+ arg :after, :id
+ arg :last, :integer
+ arg :before, :id
+ resolve &Resolv.satisfactions/2
+ end
+end
+
+object :mutation_satisfaction do
+ field :create_satisfaction, non_null(:satisfaction_response) do
+ arg :satisfaction, non_null(:satisfaction_create_params)
+ resolve &Resolv.create_satisfaction/2
+ end
+
+ field :update_satisfaction, non_null(:satisfaction_response) do
+ arg :satisfaction, non_null(:satisfaction_update_params)
+ resolve &Resolv.update_satisfaction/2
+ end
+
+ field :delete_satisfaction, non_null(:boolean) do
+ arg :id, non_null(:id)
+ resolve &Resolv.delete_satisfaction/2
+ end
+end
+end