add dialyzer and fix id
All checks were successful
Build and Publish / build-release (push) Successful in 1m28s

This commit is contained in:
2026-04-21 14:26:37 -05:00
parent 2bf99bfb37
commit ca86980833
9 changed files with 158 additions and 29 deletions

1
.dialyzer_ignore.exs Normal file
View File

@@ -0,0 +1 @@
[]

92
.gitignore vendored Normal file
View File

@@ -0,0 +1,92 @@
/.direnv/
/result
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where 3rd-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Temporary files, for example, from tests.
/tmp/
# Ignore package tarball (built via "mix hex.build").
plausible-*.tar
# If NPM crashes, it generates a log, let's ignore it too.
npm-debug.log
# If running Clickhouse through the Makefile, its data is written here
/.clickhouse_db_vol/
# The directory NPM downloads your dependencies sources to.
/assets/node_modules/
/tracker/node_modules/
# Files generated by Playwright when running tracker tests
/tracker/test-results/
/tracker/playwright-report/
/tracker/blob-report/
/tracker/playwright/.cache/
# Stored hash of source tracker files used in development environment
# to detect changes in /tracker/src and avoid unnecessary compilation.
/tracker/compiler/last-hash.txt
# Temporary file used by analyze-sizes.js
/tracker/compiler/.analyze-sizes.json
# Tracker npm module files that are generated by the compiler for the NPM package
/tracker/npm_package/plausible.js*
/tracker/npm_package/plausible.cjs*
/tracker/npm_package/plausible.d.cts
# test coverage directory
/assets/coverage
# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
# this depending on your deployment strategy.
/priv/static/css
/priv/static/js
/priv/version.json
# Files matching config/*.secret.exs pattern contain sensitive
# data and you should not commit them into version control.
#
# Alternatively, you may comment the line below and commit the
# secrets files as long as you replace their contents by environment
# variables.
/config/*.secret.exs
# Ignore Elixir Language Server files
.elixir_ls
plausible-report.xml
.idea
*.iml
*.log
*.code-workspace
.vscode
# Dializer
/priv/plts/*.plt
/priv/plts/*.plt.hash
.env
.claude

View File

@@ -1,7 +1,8 @@
defmodule WorkloadService.Aggregates.QuoteTask do defmodule WorkloadService.Aggregates.QuoteTask do
use WorkloadService.Aggregates.Task, use WorkloadService.Aggregates.Task,
task_type: "quote", task_type: "quote",
commands: WorkloadService.Commands.QuoteTask commands: WorkloadService.Commands.QuoteTask,
submission_type: map()
def validate_submission(_) do def validate_submission(_) do
:ok :ok

View File

@@ -1,7 +1,8 @@
defmodule WorkloadService.Aggregates.SolicitationTask do defmodule WorkloadService.Aggregates.SolicitationTask do
use WorkloadService.Aggregates.Task, use WorkloadService.Aggregates.Task,
task_type: "solicitation", task_type: "solicitation",
commands: WorkloadService.Commands.SolicitationTask commands: WorkloadService.Commands.SolicitationTask,
submission_type: map()
def validate_submission(_) do def validate_submission(_) do
:ok :ok

View File

@@ -8,24 +8,37 @@ defmodule WorkloadService.Aggregates.Task do
use WorkloadService.Aggregates.Task, use WorkloadService.Aggregates.Task,
task_type: "quote" task_type: "quote"
end end
"""
@type t :: %__MODULE__{ ## With custom submission type
id: WorkloadService.Aggregates.TaskId.t() | nil,
application_id: WorkloadService.Aggregates.ApplicationId.t() | nil, defmodule QuoteTaskWithCustomSubmission do
task_info: map() | nil, defmodule CustomSubmission do
submission: map() | nil, @type t :: %{...custom_fields: term()}
attachments: [String.t()], end
status: String.t() | nil
} use WorkloadService.Aggregates.Task,
task_type: "quote",
submission_type: CustomSubmission.t()
end
"""
@callback validate_submission(map()) :: :ok | {:error, term()} @callback validate_submission(map()) :: :ok | {:error, term()}
defmacro __using__(opts) do defmacro __using__(opts) do
task_type = Keyword.fetch!(opts, :task_type) task_type = Keyword.fetch!(opts, :task_type)
commands_module = Keyword.get(opts, :commands, WorkloadService.Commands.Task) commands_module = Keyword.get(opts, :commands, WorkloadService.Commands.Task)
submission_type = Keyword.get(opts, :submission_type, quote(do: map()))
quote do quote do
@type t :: %__MODULE__{
id: WorkloadService.Aggregates.TaskId.t() | nil,
application_id: WorkloadService.Aggregates.ApplicationId.t() | nil,
task_info: map() | nil,
submission: unquote(submission_type) | nil,
attachments: [String.t()],
status: String.t() | nil
}
@behaviour Commanded.Aggregates.Aggregate @behaviour Commanded.Aggregates.Aggregate
@task_type unquote(task_type) @task_type unquote(task_type)

View File

@@ -17,8 +17,8 @@ defmodule WorkloadService.Consumers.QuoteRequestedConsumer do
{:ok, conn} = AMQP.Connection.open(amqp_url()) {:ok, conn} = AMQP.Connection.open(amqp_url())
{:ok, channel} = AMQP.Channel.open(conn) {:ok, channel} = AMQP.Channel.open(conn)
AMQP.Queue.declare(channel, @queue, durable: true) :ok = AMQP.Queue.declare(channel, @queue, durable: true)
AMQP.Queue.bind(channel, @queue, @exchange, routing_key: @routing_key) :ok = AMQP.Queue.bind(channel, @queue, @exchange, routing_key: @routing_key)
{:ok, _tag} = AMQP.Basic.consume(channel, @queue) {:ok, _tag} = AMQP.Basic.consume(channel, @queue)
Logger.info("QuoteRequestedConsumer started, listening on #{@queue}") Logger.info("QuoteRequestedConsumer started, listening on #{@queue}")
@@ -31,6 +31,7 @@ defmodule WorkloadService.Consumers.QuoteRequestedConsumer do
def handle_info({:basic_cancel_ok, _}, state), do: {:noreply, state} def handle_info({:basic_cancel_ok, _}, state), do: {:noreply, state}
def handle_info({:basic_deliver, payload, meta}, state) do def handle_info({:basic_deliver, payload, meta}, state) do
:ok =
case process(payload) do case process(payload) do
:ok -> :ok ->
AMQP.Basic.ack(state.channel, meta.delivery_tag) AMQP.Basic.ack(state.channel, meta.delivery_tag)

View File

@@ -6,12 +6,14 @@ defmodule WorkloadService.Release do
@app :workload_service @app :workload_service
def migrate do def migrate do
load_app() :ok = load_app()
init_event_store() :ok = init_event_store()
for repo <- repos() do for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end end
:ok
end end
def rollback(repo, version) do def rollback(repo, version) do
@@ -24,9 +26,10 @@ defmodule WorkloadService.Release do
end end
defp load_app do defp load_app do
Application.ensure_all_started(:ssl) {:ok, _} = Application.ensure_all_started(:ssl)
Application.ensure_all_started(:postgrex) {:ok, _} = Application.ensure_all_started(:postgrex)
Application.ensure_loaded(@app) :ok = Application.ensure_loaded(@app)
:ok
end end
def init_event_store do def init_event_store do

21
mix.exs
View File

@@ -9,14 +9,28 @@ defmodule WorkloadService.MixProject do
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod, start_permanent: Mix.env() == :prod,
aliases: aliases(), aliases: aliases(),
deps: deps() deps: deps(),
dialyzer: [
plt_file: {:no_warn, "priv/plts/dialyzer.plt"},
plt_add_apps: [:mix, :ex_unit],
flags: [
# warn on ignored return values
:unmatched_returns,
# warn on error handling issues
:error_handling,
# warn when spec is too broad
:underspecs,
# warn on opaque type violations
:no_opaque
]
]
] ]
end end
def application do def application do
[ [
mod: {WorkloadService.Application, []}, mod: {WorkloadService.Application, []},
extra_applications: [:logger, :runtime_tools] extra_applications: [:logger, :runtime_tools, :dialyzer]
] ]
end end
@@ -45,7 +59,8 @@ defmodule WorkloadService.MixProject do
{:amqp, "~> 4.1"}, {:amqp, "~> 4.1"},
{:uuid, "~> 1.1"}, {:uuid, "~> 1.1"},
{:req, "~> 0.5"}, {:req, "~> 0.5"},
{:cors_plug, "~> 3.0"} {:cors_plug, "~> 3.0"},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}
] ]
end end

View File

@@ -10,9 +10,11 @@
"credentials_obfuscation": {:hex, :credentials_obfuscation, "3.5.0", "61e282adfb4439486b3994faaec69543c7ee6cc7e70c6340e8853fd9deaf8219", [:rebar3], [], "hexpm", "843adbe3246861ce0f1a0fa3222f384834eb31defd8d6b9cba7afd2977c957bc"}, "credentials_obfuscation": {:hex, :credentials_obfuscation, "3.5.0", "61e282adfb4439486b3994faaec69543c7ee6cc7e70c6340e8853fd9deaf8219", [:rebar3], [], "hexpm", "843adbe3246861ce0f1a0fa3222f384834eb31defd8d6b9cba7afd2977c957bc"},
"db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"}, "db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"},
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
"dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"},
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"}, "dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
"ecto": {:hex, :ecto, "3.13.5", "9d4a69700183f33bf97208294768e561f5c7f1ecf417e0fa1006e4a91713a834", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df9efebf70cf94142739ba357499661ef5dbb559ef902b68ea1f3c1fabce36de"}, "ecto": {:hex, :ecto, "3.13.5", "9d4a69700183f33bf97208294768e561f5c7f1ecf417e0fa1006e4a91713a834", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df9efebf70cf94142739ba357499661ef5dbb559ef902b68ea1f3c1fabce36de"},
"ecto_sql": {:hex, :ecto_sql, "3.13.5", "2f8282b2ad97bf0f0d3217ea0a6fff320ead9e2f8770f810141189d182dc304e", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aa36751f4e6a2b56ae79efb0e088042e010ff4935fc8684e74c23b1f49e25fdc"}, "ecto_sql": {:hex, :ecto_sql, "3.13.5", "2f8282b2ad97bf0f0d3217ea0a6fff320ead9e2f8770f810141189d182dc304e", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aa36751f4e6a2b56ae79efb0e088042e010ff4935fc8684e74c23b1f49e25fdc"},
"erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"},
"eventstore": {:hex, :eventstore, "1.4.8", "26778c991cfb078f3906a4267060efc7bb5e5943f69ddb8ae6fb60f07042a66e", [:mix], [{:fsm, "~> 0.3", [hex: :fsm, repo: "hexpm", optional: false]}, {:gen_stage, "~> 1.2", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "30c914602fdea8db5992a90ecb1f84068531e764cf0c066be71ff0eec4e3bcb9"}, "eventstore": {:hex, :eventstore, "1.4.8", "26778c991cfb078f3906a4267060efc7bb5e5943f69ddb8ae6fb60f07042a66e", [:mix], [{:fsm, "~> 0.3", [hex: :fsm, repo: "hexpm", optional: false]}, {:gen_stage, "~> 1.2", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "30c914602fdea8db5992a90ecb1f84068531e764cf0c066be71ff0eec4e3bcb9"},
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
"finch": {:hex, :finch, "0.21.0", "b1c3b2d48af02d0c66d2a9ebfb5622be5c5ecd62937cf79a88a7f98d48a8290c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87dc6e169794cb2570f75841a19da99cfde834249568f2a5b121b809588a4377"}, "finch": {:hex, :finch, "0.21.0", "b1c3b2d48af02d0c66d2a9ebfb5622be5c5ecd62937cf79a88a7f98d48a8290c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87dc6e169794cb2570f75841a19da99cfde834249568f2a5b121b809588a4377"},