From 2bf99bfb37e2b88c0d01f1fee0221c51901cc218 Mon Sep 17 00:00:00 2001 From: HaimKortovich Date: Tue, 21 Apr 2026 12:55:38 -0500 Subject: [PATCH] add type specs and fix id issues --- .../aggregates/application_id.ex | 8 +++- lib/workload_service/aggregates/task.ex | 15 ++++++-- lib/workload_service/aggregates/task_id.ex | 6 +++ lib/workload_service/commands/quote_task.ex | 38 +++++++++++-------- .../commands/solicitation_task.ex | 38 +++++++++++-------- .../handlers/task_completed_handler.ex | 2 +- .../controllers/task_controller.ex | 13 +++++-- 7 files changed, 78 insertions(+), 42 deletions(-) diff --git a/lib/workload_service/aggregates/application_id.ex b/lib/workload_service/aggregates/application_id.ex index 4e725bd..4c46eb5 100644 --- a/lib/workload_service/aggregates/application_id.ex +++ b/lib/workload_service/aggregates/application_id.ex @@ -4,6 +4,12 @@ defmodule WorkloadService.Aggregates.ApplicationId do Used to track which policy-service application this task belongs to. """ + @type t :: %__MODULE__{ + org_id: String.t(), + application_id: String.t(), + policy_type: String.t() + } + @derive Jason.Encoder defstruct [:org_id, :application_id, :policy_type] @@ -49,4 +55,4 @@ defmodule WorkloadService.Aggregates.ApplicationId do def decode(id), do: id end -end \ No newline at end of file +end diff --git a/lib/workload_service/aggregates/task.ex b/lib/workload_service/aggregates/task.ex index 4cf791d..2276845 100644 --- a/lib/workload_service/aggregates/task.ex +++ b/lib/workload_service/aggregates/task.ex @@ -10,6 +10,15 @@ defmodule WorkloadService.Aggregates.Task do end """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t() | nil, + application_id: WorkloadService.Aggregates.ApplicationId.t() | nil, + task_info: map() | nil, + submission: map() | nil, + attachments: [String.t()], + status: String.t() | nil + } + @callback validate_submission(map()) :: :ok | {:error, term()} defmacro __using__(opts) do @@ -55,8 +64,6 @@ defmodule WorkloadService.Aggregates.Task do def execute(%__MODULE__{status: status}, %SubmitResponse{} = cmd) when status in [nil, "created", "draft", "approved"] do with :ok <- validate_submission(cmd.submission) do - new_status = if status == "approved", do: "draft", else: "draft" - %WorkloadService.Events.SubmissionUpdated{ id: cmd.id, submission: cmd.submission, @@ -78,9 +85,9 @@ defmodule WorkloadService.Aggregates.Task do end @impl Aggregate - def execute(%__MODULE__{status: "approved"}, %CompleteTask{} = cmd) do + def execute(%__MODULE__{status: "approved", id: id}, %CompleteTask{} = cmd) do %WorkloadService.Events.TaskCompleted{ - id: cmd.id, + id: id, completed_by: cmd.completed_by } end diff --git a/lib/workload_service/aggregates/task_id.ex b/lib/workload_service/aggregates/task_id.ex index aacf480..a92494d 100644 --- a/lib/workload_service/aggregates/task_id.ex +++ b/lib/workload_service/aggregates/task_id.ex @@ -4,6 +4,12 @@ defmodule WorkloadService.Aggregates.TaskId do ID format: "org_id:type:task_id" (e.g., "test:quote:uuid") """ + @type t :: %__MODULE__{ + org_id: String.t(), + type: String.t(), + task_id: String.t() + } + @derive Jason.Encoder defstruct [:org_id, :type, :task_id] diff --git a/lib/workload_service/commands/quote_task.ex b/lib/workload_service/commands/quote_task.ex index 9a194eb..1c3d6f5 100644 --- a/lib/workload_service/commands/quote_task.ex +++ b/lib/workload_service/commands/quote_task.ex @@ -7,47 +7,53 @@ defmodule WorkloadService.Commands.QuoteTask do @moduledoc """ Command to create a new quote task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + application_id: WorkloadService.Aggregates.ApplicationId.t(), + task_info: map(), + attachments: [String.t()] + } + @derive Jason.Encoder defstruct [:id, :application_id, :task_info, :attachments] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule SubmitResponse do @moduledoc """ Command to submit response for a quote task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + submission: map(), + attachments: [String.t()] + } + @derive Jason.Encoder defstruct [:id, :submission, :attachments] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule ApproveSubmission do @moduledoc """ Command to approve submission for a quote task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t() + } + @derive Jason.Encoder defstruct [:id] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule CompleteTask do @moduledoc """ Command to complete a quote task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + completed_by: String.t() + } + @derive Jason.Encoder defstruct [:id, :completed_by] - - def new(attrs) do - struct(__MODULE__, attrs) - end end end diff --git a/lib/workload_service/commands/solicitation_task.ex b/lib/workload_service/commands/solicitation_task.ex index 201ff97..76776dd 100644 --- a/lib/workload_service/commands/solicitation_task.ex +++ b/lib/workload_service/commands/solicitation_task.ex @@ -7,47 +7,53 @@ defmodule WorkloadService.Commands.SolicitationTask do @moduledoc """ Command to create a new solicitation task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + application_id: WorkloadService.Aggregates.ApplicationId.t(), + task_info: map(), + attachments: [String.t()] + } + @derive Jason.Encoder defstruct [:id, :application_id, :task_info, :attachments] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule SubmitResponse do @moduledoc """ Command to submit response for a solicitation task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + submission: map(), + attachments: [String.t()] + } + @derive Jason.Encoder defstruct [:id, :submission, :attachments] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule ApproveSubmission do @moduledoc """ Command to approve submission for a solicitation task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t() + } + @derive Jason.Encoder defstruct [:id] - - def new(attrs) do - struct(__MODULE__, attrs) - end end defmodule CompleteTask do @moduledoc """ Command to complete a solicitation task. """ + @type t :: %__MODULE__{ + id: WorkloadService.Aggregates.TaskId.t(), + completed_by: String.t() + } + @derive Jason.Encoder defstruct [:id, :completed_by] - - def new(attrs) do - struct(__MODULE__, attrs) - end end end \ No newline at end of file diff --git a/lib/workload_service/handlers/task_completed_handler.ex b/lib/workload_service/handlers/task_completed_handler.ex index 666edf0..6c43149 100644 --- a/lib/workload_service/handlers/task_completed_handler.ex +++ b/lib/workload_service/handlers/task_completed_handler.ex @@ -29,7 +29,7 @@ defmodule WorkloadService.Handlers.TaskCompletedHandler do {:ok, module} -> case Aggregate.aggregate_state( WorkloadService.CommandedApp, - aggregate_module, + module, event.id ) do nil -> diff --git a/lib/workload_service_web/controllers/task_controller.ex b/lib/workload_service_web/controllers/task_controller.ex index 01dcf58..d1e6a80 100644 --- a/lib/workload_service_web/controllers/task_controller.ex +++ b/lib/workload_service_web/controllers/task_controller.ex @@ -4,6 +4,7 @@ defmodule WorkloadServiceWeb.TaskController do alias WorkloadService.CommandedApp alias WorkloadService.Workload.Queries + alias WorkloadService.Aggregates.TaskId alias WorkloadServiceWeb.Schemas.Task, as: S tags(["Tasks"]) @@ -93,8 +94,9 @@ defmodule WorkloadServiceWeb.TaskController do conn |> put_status(:not_found) |> json(%{error: "task not found"}) {:ok, %{status: "created"} = _task} -> + task_id = TaskId.parse!(id) command = %WorkloadService.Commands.QuoteTask.SubmitResponse{ - id: id, + id: task_id, submission: %{ "quote_id" => params["quote_id"], "plans" => params["plans"], @@ -118,8 +120,9 @@ defmodule WorkloadServiceWeb.TaskController do conn |> put_status(:not_found) |> json(%{error: "task not found"}) {:ok, %{status: "created"} = _task} -> + task_id = TaskId.parse!(id) command = %WorkloadService.Commands.SolicitationTask.SubmitResponse{ - id: id, + id: task_id, submission: %{ "recorded_by" => params["recorded_by"] || "system" }, @@ -166,7 +169,8 @@ defmodule WorkloadServiceWeb.TaskController do conn |> put_status(:not_found) |> json(%{error: "task not found"}) {:ok, %{status: "draft"} = _task} -> - command = struct(command_module, id: id) + task_id = TaskId.parse!(id) + command = struct(command_module, id: task_id) dispatch_and_respond(conn, id, command) {:ok, _task} -> @@ -214,7 +218,8 @@ defmodule WorkloadServiceWeb.TaskController do conn |> put_status(:not_found) |> json(%{error: "task not found"}) {:ok, %{status: "approved"} = _task} -> - command = struct(command_module, id: id, completed_by: completed_by) + task_id = TaskId.parse!(id) + command = struct(command_module, id: task_id, completed_by: completed_by) dispatch_and_respond(conn, id, command) {:ok, _task} ->