revamp aggregate and use typestruct
All checks were successful
Build and Publish / build-release (push) Successful in 1m41s

This commit is contained in:
2026-04-22 11:37:04 -05:00
parent 5f2f9e9085
commit a7160aadcf
19 changed files with 228 additions and 185 deletions

67
.gitignore vendored
View File

@@ -1,3 +1,6 @@
/.direnv/
/result
# The directory Mix will write compiled artifacts to. # The directory Mix will write compiled artifacts to.
/_build/ /_build/
@@ -23,5 +26,67 @@ erl_crash.dump
/tmp/ /tmp/
# Ignore package tarball (built via "mix hex.build"). # Ignore package tarball (built via "mix hex.build").
policy_service-*.tar 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

@@ -21,7 +21,7 @@
mixFodDeps = beamPackages.fetchMixDeps { mixFodDeps = beamPackages.fetchMixDeps {
inherit pname version; inherit pname version;
src = ./.; src = ./.;
sha256 = "sha256-yqxq5pB7dKEhCZiJWXrKKCra45hxfyyfpP/zyNLEF7A="; sha256 = "sha256-ZyrQiL5sOCC+V9S7rVGrCNEqm/TDZkjIx6Y+MZy7+6s=";
}; };
package = beamPackages.mixRelease { package = beamPackages.mixRelease {
inherit pname version mixFodDeps; inherit pname version mixFodDeps;

View File

@@ -30,7 +30,7 @@ defmodule PolicyService.Aggregates.PolicyApplication do
ProviderQuoteReceived, ProviderQuoteReceived,
AllQuotesReceived, AllQuotesReceived,
QuoteAccepted, QuoteAccepted,
SolicitationSent, SolicitationRequestSent,
PolicyIssued PolicyIssued
} }
@@ -42,16 +42,14 @@ defmodule PolicyService.Aggregates.PolicyApplication do
:applicant_info, :applicant_info,
:policy_details, :policy_details,
:selected_providers, :selected_providers,
:accepted_quote_id,
:accepted_plan_id, :accepted_plan_id,
:accepted_provider_id, :accepted_by,
:solicitation_id, :provider_policy_number,
:policy_number,
:effective_date, :effective_date,
:expiry_date, :expiry_date,
:state, :state,
quotes: %{}, quotes: %{},
pending_endorsements: %{} endorsements: %{}
] ]
# ── Execute ──────────────────────────────────────────────────────────── # ── Execute ────────────────────────────────────────────────────────────
@@ -140,19 +138,29 @@ defmodule PolicyService.Aggregates.PolicyApplication do
end end
def execute(%__MODULE__{} = agg, %AcceptQuoteAndSolicit{} = cmd) do def execute(%__MODULE__{} = agg, %AcceptQuoteAndSolicit{} = cmd) do
with {:ok, quote} <- case Enum.find_value(agg.quotes, fn {provider_id, quote} ->
PolicyService.Aggregates.PolicyApplication.find_quote(agg, cmd.quote_id), case Enum.find(quote.plans, &(&1.plan_id == cmd.accepted_plan_id)) do
{:ok, provider} <- nil -> nil
PolicyService.Aggregates.PolicyApplication.find_provider(agg, quote.provider_id), plan -> {:ok, %{quote: quote, provider: provider_id, plan: plan}}
{:ok, plan} <- end
PolicyService.Aggregates.PolicyApplication.find_plan(quote, cmd.plan_id) do end) do
%QuoteAccepted{ nil ->
id: agg.id, {:error, :plan_not_found}
quote: quote,
plan: plan, result ->
provider: provider, [
accepted_at: DateTime.utc_now() %QuoteAccepted{
} id: agg.id,
quote: result.quote,
plan: result.plan,
provider: result.provider,
accepted_by: cmd.accepted_by
},
%SolicitationRequestSent{
id: agg.id,
plan: result.plan
}
]
end end
end end
@@ -162,7 +170,7 @@ defmodule PolicyService.Aggregates.PolicyApplication do
def execute(%__MODULE__{} = agg, %RecordPolicyIssued{} = cmd) do def execute(%__MODULE__{} = agg, %RecordPolicyIssued{} = cmd) do
%PolicyIssued{ %PolicyIssued{
id: agg.id, id: agg.id,
policy_number: cmd.policy_number, provider_policy_number: cmd.provider_policy_number,
effective_date: cmd.effective_date, effective_date: cmd.effective_date,
expiry_date: cmd.expiry_date, expiry_date: cmd.expiry_date,
issued_at: cmd.issued_at || DateTime.utc_now() issued_at: cmd.issued_at || DateTime.utc_now()
@@ -205,21 +213,22 @@ defmodule PolicyService.Aggregates.PolicyApplication do
def apply(%__MODULE__{} = agg, %QuoteAccepted{} = e) do def apply(%__MODULE__{} = agg, %QuoteAccepted{} = e) do
%__MODULE__{ %__MODULE__{
agg agg
| accepted_quote_id: e.quote.quote_id, | accepted_plan_id: e.plan.plan_id,
accepted_plan_id: e.plan.plan_id, accepted_by: e.accepted_by
accepted_provider_id: e.provider.provider_id,
state: :solicitation_sent
} }
end end
def apply(%__MODULE__{} = agg, %SolicitationSent{} = e) do def apply(%__MODULE__{} = agg, %SolicitationRequestSent{} = _e) do
%__MODULE__{agg | solicitation_id: e.solicitation_id} %__MODULE__{
agg
| state: :awaiting_policy
}
end end
def apply(%__MODULE__{} = agg, %PolicyIssued{} = e) do def apply(%__MODULE__{} = agg, %PolicyIssued{} = e) do
%__MODULE__{ %__MODULE__{
agg agg
| policy_number: e.policy_number, | provider_policy_number: e.provider_policy_number,
effective_date: e.effective_date, effective_date: e.effective_date,
expiry_date: e.expiry_date, expiry_date: e.expiry_date,
state: :issued state: :issued

View File

@@ -1,4 +1,9 @@
defmodule PolicyService.Aggregates.PolicyId do defmodule PolicyService.Aggregates.PolicyId do
@type t :: %__MODULE__{
org_id: String.t(),
policy_type: String.t(),
application_id: String.t()
}
@derive Jason.Encoder @derive Jason.Encoder
defstruct [:org_id, :policy_type, :application_id] defstruct [:org_id, :policy_type, :application_id]

View File

@@ -31,4 +31,4 @@ defmodule PolicyService.CommandedApp do
otp_app: :policy_service otp_app: :policy_service
router(PolicyService.Router) router(PolicyService.Router)
end end

View File

@@ -1,8 +1,6 @@
defmodule PolicyService.Commands.CarPolicy do defmodule PolicyService.Commands.CarPolicy do
alias PolicyService.Commands.Policy defmodule SubmitPolicyApplication, do: use(PolicyService.Commands.Policy.SubmitPolicyApplication)
defmodule RecordProviderQuote, do: use(PolicyService.Commands.Policy.RecordProviderQuote)
defmodule SubmitPolicyApplication, do: use(Policy.SubmitPolicyApplication) defmodule AcceptQuoteAndSolicit, do: use(PolicyService.Commands.Policy.AcceptQuoteAndSolicit)
defmodule RecordProviderQuote, do: use(Policy.RecordProviderQuote) defmodule RecordPolicyIssued, do: use(PolicyService.Commands.Policy.RecordPolicyIssued)
defmodule AcceptQuoteAndSolicit, do: use(Policy.AcceptQuoteAndSolicit) end
defmodule RecordPolicyIssued, do: use(Policy.RecordPolicyIssued)
end

View File

@@ -1,8 +1,6 @@
defmodule PolicyService.Commands.FirePolicy do defmodule PolicyService.Commands.FirePolicy do
alias PolicyService.Commands.Policy defmodule SubmitPolicyApplication, do: use(PolicyService.Commands.Policy.SubmitPolicyApplication)
defmodule RecordProviderQuote, do: use(PolicyService.Commands.Policy.RecordProviderQuote)
defmodule SubmitPolicyApplication, do: use(Policy.SubmitPolicyApplication) defmodule AcceptQuoteAndSolicit, do: use(PolicyService.Commands.Policy.AcceptQuoteAndSolicit)
defmodule RecordProviderQuote, do: use(Policy.RecordProviderQuote) defmodule RecordPolicyIssued, do: use(PolicyService.Commands.Policy.RecordPolicyIssued)
defmodule AcceptQuoteAndSolicit, do: use(Policy.AcceptQuoteAndSolicit) end
defmodule RecordPolicyIssued, do: use(Policy.RecordPolicyIssued)
end

View File

@@ -1,19 +1,20 @@
defmodule PolicyService.Commands.Policy do defmodule PolicyService.Commands.Policy do
@moduledoc """ @moduledoc """
Base templates for Policy commands. Base templates for Policy commands using TypedStruct.
Use these macros to ensure all policy types share the same structure.
""" """
defmodule SubmitPolicyApplication do defmodule SubmitPolicyApplication do
defmacro __using__(_opts) do defmacro __using__(_opts) do
quote do quote do
defstruct [ use TypedStruct
:id,
:submitted_by, typedstruct do
:applicant_info, field :id, PolicyService.Aggregates.PolicyId.t(), enforce: true
:policy_details, field :submitted_by, String.t(), enforce: true
:selected_providers field :applicant_info, map(), enforce: true
] field :policy_details, map()
field :selected_providers, list(), enforce: true
end
end end
end end
end end
@@ -21,16 +22,18 @@ defmodule PolicyService.Commands.Policy do
defmodule RecordProviderQuote do defmodule RecordProviderQuote do
defmacro __using__(_opts) do defmacro __using__(_opts) do
quote do quote do
defstruct [ use TypedStruct
:id,
:recorded_by, typedstruct do
:provider_id, field :id, PolicyService.Aggregates.PolicyId.t(), enforce: true
:quote_id, field :recorded_by, String.t(), enforce: true
:premium, field :provider_id, String.t(), enforce: true
:coverage_details, field :quote_id, String.t(), enforce: true
:valid_until, field :premium, String.t()
:plans field :coverage_details, map()
] field :valid_until, String.t(), enforce: true
field :plans, list(), enforce: true
end
end end
end end
end end
@@ -38,13 +41,13 @@ defmodule PolicyService.Commands.Policy do
defmodule AcceptQuoteAndSolicit do defmodule AcceptQuoteAndSolicit do
defmacro __using__(_opts) do defmacro __using__(_opts) do
quote do quote do
defstruct [ use TypedStruct
:id,
:accepted_by, typedstruct do
:quote_id, field :id, PolicyService.Aggregates.PolicyId.t(), enforce: true
:plan_id, field :accepted_by, String.t(), enforce: true
:solicitation_fields field :accepted_plan_id, String.t(), enforce: true
] end
end end
end end
end end
@@ -52,14 +55,16 @@ defmodule PolicyService.Commands.Policy do
defmodule RecordPolicyIssued do defmodule RecordPolicyIssued do
defmacro __using__(_opts) do defmacro __using__(_opts) do
quote do quote do
defstruct [ use TypedStruct
:id,
:policy_number, typedstruct do
:effective_date, field :id, PolicyService.Aggregates.PolicyId.t(), enforce: true
:expiry_date, field :provider_policy_number, String.t(), enforce: true
:issued_at field :effective_date, String.t(), enforce: true
] field :expiry_date, String.t(), enforce: true
field :issued_at, String.t()
end
end end
end end
end end
end end

View File

@@ -49,7 +49,7 @@ defmodule PolicyService.Consumers.PolicyIssuedConsumer do
"car" -> "car" ->
%CarPolicy.RecordPolicyIssued{ %CarPolicy.RecordPolicyIssued{
id: event["id"], id: event["id"],
policy_number: event["policy_number"], provider_policy_number: event["provider_policy_number"],
effective_date: event["effective_date"], effective_date: event["effective_date"],
expiry_date: event["expiry_date"], expiry_date: event["expiry_date"],
issued_at: DateTime.utc_now() issued_at: DateTime.utc_now()

View File

@@ -50,18 +50,18 @@ defmodule PolicyService.Events.Policy do
defmodule QuoteAccepted do defmodule QuoteAccepted do
use PolicyService.Events use PolicyService.Events
@derive Jason.Encoder @derive Jason.Encoder
defstruct [:id, :accepted_by, :quote, :plan, :provider, :accepted_at] defstruct [:id, :accepted_by, :quote, :plan, :provider]
end end
defmodule SolicitationSent do defmodule SolicitationRequestSent do
use PolicyService.Events use PolicyService.Events
@derive Jason.Encoder @derive Jason.Encoder
defstruct [:id, :solicitation_id, :provider_id, :template_id, :s3_key, :sent_at] defstruct [:id, :plan]
end end
defmodule PolicyIssued do defmodule PolicyIssued do
use PolicyService.Events use PolicyService.Events
@derive Jason.Encoder @derive Jason.Encoder
defstruct [:id, :policy_number, :effective_date, :expiry_date, :issued_at] defstruct [:id, :provider_policy_number, :effective_date, :expiry_date, :issued_at]
end end
end end

View File

@@ -5,11 +5,11 @@ defmodule PolicyService.Handlers.SolicitationRequestHandler do
require Logger require Logger
alias PolicyService.Events.Policy.QuoteAccepted alias PolicyService.Events.Policy.SolicitationRequestSent
alias PolicyService.MessageBus alias PolicyService.MessageBus
def handle(%QuoteAccepted{} = event, _metadata) do def handle(%SolicitationRequestSent{} = event, _metadata) do
MessageBus.publish("policy_service.events.policy_issued", "quote.accepted", event) MessageBus.publish("policy_service.events.solicitation_requested", "solicitation.requested", event)
:ok :ok
end end
end end

View File

@@ -11,7 +11,7 @@ defmodule PolicyService.Filters.PolicyApplicationFilters do
fragment("?->>'company_name' ilike ?", p.applicant_info, ^term) or fragment("?->>'company_name' ilike ?", p.applicant_info, ^term) or
fragment("?->>'document_id' ilike ?", p.applicant_info, ^term) or fragment("?->>'document_id' ilike ?", p.applicant_info, ^term) or
fragment("?->>'ruc' ilike ?", p.applicant_info, ^term) or fragment("?->>'ruc' ilike ?", p.applicant_info, ^term) or
ilike(p.policy_number, ^term) ilike(p.provider_policy_number, ^term)
) )
end end
end end

View File

@@ -2,34 +2,29 @@ defmodule PolicyService.Projections.PolicyApplication do
use Ecto.Schema use Ecto.Schema
@derive {Jason.Encoder, @derive {Jason.Encoder,
only: [ only: [
:id, :id,
:application_id, :application_id,
:org_id, :org_id,
:submitted_by, :submitted_by,
:policy_type, :policy_type,
:applicant_info, :applicant_info,
:policy_details, :policy_details,
:selected_providers, :selected_providers,
:quotes, :quotes,
:accepted_quote_id, :accepted_plan_id,
:accepted_plan_id, :accepted_by,
:accepted_provider_id, :provider_policy_number,
:accepted_by, :premium,
:accepted_at, :effective_date,
:solicitation_id, :expiry_date,
:solicitation_s3_key, :status,
:policy_number, :submitted_at,
:premium, :solicitation_sent_at,
:effective_date, :issued_at,
:expiry_date, :inserted_at,
:status, :updated_at
:submitted_at, ]}
:solicitation_sent_at,
:issued_at,
:inserted_at,
:updated_at
]}
@derive { @derive {
Flop.Schema, Flop.Schema,
@@ -61,16 +56,11 @@ defmodule PolicyService.Projections.PolicyApplication do
field :selected_providers, {:array, :string}, default: [] field :selected_providers, {:array, :string}, default: []
field :quotes, :map, default: %{} field :quotes, :map, default: %{}
field :accepted_quote_id, :string
field :accepted_plan_id, :string field :accepted_plan_id, :string
field :accepted_provider_id, :string
field :accepted_by, :string field :accepted_by, :string
field :accepted_at, :utc_datetime_usec
field :solicitation_id, :string field :provider_policy_number, :string
field :solicitation_s3_key, :string
field :policy_number, :string
field :premium, :decimal field :premium, :decimal
field :effective_date, :date field :effective_date, :date
field :expiry_date, :date field :expiry_date, :date

View File

@@ -10,12 +10,11 @@ defmodule PolicyService.Projectors.PolicyProjector do
ProviderQuoteReceived, ProviderQuoteReceived,
AllQuotesReceived, AllQuotesReceived,
QuoteAccepted, QuoteAccepted,
SolicitationSent, SolicitationRequestSent,
PolicyIssued PolicyIssued
} }
alias PolicyService.Projections.PolicyApplication alias PolicyService.Projections.PolicyApplication
alias PolicyService.Aggregates.PolicyId
import Ecto.Query import Ecto.Query
project(%PolicyApplicationSubmitted{} = e, _meta, fn multi -> project(%PolicyApplicationSubmitted{} = e, _meta, fn multi ->
@@ -69,25 +68,20 @@ defmodule PolicyService.Projectors.PolicyProjector do
end) end)
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} -> |> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
Ecto.Changeset.change(p, Ecto.Changeset.change(p,
accepted_quote_id: e.quote.quote_id,
accepted_plan_id: e.plan.plan_id, accepted_plan_id: e.plan.plan_id,
accepted_provider_id: e.provider.id, accepted_by: e.accepted_by
accepted_at: parse_datetime(e.accepted_at),
status: "solicitation_sent"
) )
end) end)
end) end)
project(%SolicitationSent{} = e, _meta, fn multi -> project(%SolicitationRequestSent{} = e, _meta, fn multi ->
multi multi
|> Ecto.Multi.run(:fetch, fn repo, _ -> |> Ecto.Multi.run(:fetch, fn repo, _ ->
{:ok, repo.get!(PolicyApplication, to_string(e.id))} {:ok, repo.get!(PolicyApplication, to_string(e.id))}
end) end)
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} -> |> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
Ecto.Changeset.change(p, Ecto.Changeset.change(p,
solicitation_id: e.solicitation_id, status: "awaiting_policy"
solicitation_s3_key: e.s3_key,
solicitation_sent_at: parse_datetime(e.sent_at)
) )
end) end)
end) end)
@@ -99,7 +93,7 @@ defmodule PolicyService.Projectors.PolicyProjector do
end) end)
|> Ecto.Multi.update(:policy_application, fn %{fetch: p} -> |> Ecto.Multi.update(:policy_application, fn %{fetch: p} ->
Ecto.Changeset.change(p, Ecto.Changeset.change(p,
policy_number: e.policy_number, provider_policy_number: e.provider_policy_number,
effective_date: parse_date(e.effective_date), effective_date: parse_date(e.effective_date),
expiry_date: parse_date(e.expiry_date), expiry_date: parse_date(e.expiry_date),
issued_at: parse_datetime(e.issued_at), issued_at: parse_datetime(e.issued_at),

View File

@@ -155,9 +155,8 @@ defmodule PolicyServiceWeb.PolicyController do
"car" -> "car" ->
%CarPolicy.AcceptQuoteAndSolicit{ %CarPolicy.AcceptQuoteAndSolicit{
id: PolicyId.new(org_id, policy.policy_type, application_id), id: PolicyId.new(org_id, policy.policy_type, application_id),
quote_id: params["quote_id"], accepted_by: params["accepted_by"] || "system",
plan_id: params["plan_id"], accepted_plan_id: params["accepted_plan_id"]
solicitation_fields: params["solicitation_fields"] || %{}
} }
end end
@@ -166,9 +165,6 @@ defmodule PolicyServiceWeb.PolicyController do
{:ok, updated} = PolicyQueries.get_by_application_id(org_id, application_id) {:ok, updated} = PolicyQueries.get_by_application_id(org_id, application_id)
conn |> put_status(:ok) |> json(%{data: policy_detail(updated)}) conn |> put_status(:ok) |> json(%{data: policy_detail(updated)})
{:error, :quote_not_found} ->
conn |> put_status(:not_found) |> json(%{error: "quote not found"})
{:error, :plan_not_found} -> {:error, :plan_not_found} ->
conn |> put_status(:not_found) |> json(%{error: "plan not found"}) conn |> put_status(:not_found) |> json(%{error: "plan not found"})
@@ -192,7 +188,7 @@ defmodule PolicyServiceWeb.PolicyController do
status: p.status, status: p.status,
applicant_info: p.applicant_info, applicant_info: p.applicant_info,
policy_details: p.policy_details, policy_details: p.policy_details,
policy_number: p.policy_number, provider_policy_number: p.provider_policy_number,
submitted_at: p.submitted_at submitted_at: p.submitted_at
} }
end end
@@ -208,13 +204,9 @@ defmodule PolicyServiceWeb.PolicyController do
policy_details: p.policy_details, policy_details: p.policy_details,
selected_providers: p.selected_providers, selected_providers: p.selected_providers,
quotes: p.quotes, quotes: p.quotes,
accepted_quote_id: p.accepted_quote_id,
accepted_plan_id: p.accepted_plan_id, accepted_plan_id: p.accepted_plan_id,
accepted_provider_id: p.accepted_provider_id, accepted_by: p.accepted_by,
accepted_at: p.accepted_at, provider_policy_number: p.provider_policy_number,
solicitation_id: p.solicitation_id,
solicitation_s3_key: p.solicitation_s3_key,
policy_number: p.policy_number,
premium: p.premium, premium: p.premium,
effective_date: p.effective_date, effective_date: p.effective_date,
expiry_date: p.expiry_date, expiry_date: p.expiry_date,

View File

@@ -227,16 +227,10 @@ defmodule PolicyServiceWeb.Schemas.Policy do
OpenApiSpex.schema(%{ OpenApiSpex.schema(%{
title: "AcceptQuoteRequest", title: "AcceptQuoteRequest",
type: :object, type: :object,
required: [:quote_id, :plan_id], required: [:accepted_plan_id],
properties: %{ properties: %{
quote_id: %Schema{type: :string}, quote_id: %Schema{type: :string},
plan_id: %Schema{type: :string}, plan_id: %Schema{type: :string}
solicitation_fields: %Schema{
type: :object,
additionalProperties: %Schema{type: :string},
description: "Optional flat map of AcroForm field names to values",
nullable: true
}
} }
}) })
end end
@@ -266,7 +260,6 @@ defmodule PolicyServiceWeb.Schemas.Policy do
type: :object, type: :object,
properties: %{ properties: %{
download_url: %Schema{type: :string}, download_url: %Schema{type: :string},
s3_key: %Schema{type: :string},
version: %Schema{type: :integer} version: %Schema{type: :integer}
} }
}) })
@@ -283,11 +276,11 @@ defmodule PolicyServiceWeb.Schemas.Policy do
policy_type: %Schema{type: :string, enum: ["car", "life", "fire"]}, policy_type: %Schema{type: :string, enum: ["car", "life", "fire"]},
status: %Schema{ status: %Schema{
type: :string, type: :string,
enum: ["quote_requested", "quotes_received", "solicitation_sent", "issued"] enum: ["quote_requested", "quotes_received", "awaiting_policy", "issued"]
}, },
applicant_info: ApplicantInfo, applicant_info: ApplicantInfo,
policy_details: PolicyDetails, policy_details: PolicyDetails,
policy_number: %Schema{type: :string, nullable: true}, provider_policy_number: %Schema{type: :string, nullable: true},
submitted_at: %Schema{type: :string, format: :"date-time"} submitted_at: %Schema{type: :string, format: :"date-time"}
} }
}) })
@@ -306,19 +299,15 @@ defmodule PolicyServiceWeb.Schemas.Policy do
policy_type: %Schema{type: :string, enum: ["car", "life", "fire"]}, policy_type: %Schema{type: :string, enum: ["car", "life", "fire"]},
status: %Schema{ status: %Schema{
type: :string, type: :string,
enum: ["quote_requested", "quotes_received", "solicitation_sent", "issued"] enum: ["quote_requested", "quotes_received", "awaiting_policy", "issued"]
}, },
applicant_info: ApplicantInfo, applicant_info: ApplicantInfo,
policy_details: PolicyDetails, policy_details: PolicyDetails,
selected_providers: %Schema{type: :array, items: %Schema{type: :string}}, selected_providers: %Schema{type: :array, items: %Schema{type: :string}},
quotes: %Schema{type: :object, additionalProperties: QuoteData}, quotes: %Schema{type: :object, additionalProperties: QuoteData},
accepted_quote_id: %Schema{type: :string, nullable: true},
accepted_plan_id: %Schema{type: :string, nullable: true}, accepted_plan_id: %Schema{type: :string, nullable: true},
accepted_provider_id: %Schema{type: :string, nullable: true}, accepted_by: %Schema{type: :string, nullable: true},
accepted_at: %Schema{type: :string, format: :"date-time", nullable: true}, provider_policy_number: %Schema{type: :string, nullable: true},
solicitation_id: %Schema{type: :string, nullable: true},
solicitation_s3_key: %Schema{type: :string, nullable: true},
policy_number: %Schema{type: :string, nullable: true},
premium: %Schema{type: :number, nullable: true}, premium: %Schema{type: :number, nullable: true},
effective_date: %Schema{type: :string, format: :date, nullable: true}, effective_date: %Schema{type: :string, format: :date, nullable: true},
expiry_date: %Schema{type: :string, format: :date, nullable: true}, expiry_date: %Schema{type: :string, format: :date, nullable: true},

View File

@@ -61,7 +61,8 @@ defmodule PolicyService.MixProject do
{:cors_plug, "~> 3.0"}, {:cors_plug, "~> 3.0"},
{:flop, "~> 0.26"}, {:flop, "~> 0.26"},
{:req, "~> 0.5"}, {:req, "~> 0.5"},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false} {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
{:typedstruct, "~> 0.5"}
] ]
end end

View File

@@ -45,6 +45,10 @@
"telemetry_registry": {:hex, :telemetry_registry, "0.3.2", "701576890320be6428189bff963e865e8f23e0ff3615eade8f78662be0fc003c", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7ed191eb1d115a3034af8e1e35e4e63d5348851d556646d46ca3d1b4e16bab9"}, "telemetry_registry": {:hex, :telemetry_registry, "0.3.2", "701576890320be6428189bff963e865e8f23e0ff3615eade8f78662be0fc003c", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7ed191eb1d115a3034af8e1e35e4e63d5348851d556646d46ca3d1b4e16bab9"},
"thoas": {:hex, :thoas, "1.2.1", "19a25f31177a17e74004d4840f66d791d4298c5738790fa2cc73731eb911f195", [:rebar3], [], "hexpm", "e38697edffd6e91bd12cea41b155115282630075c2a727e7a6b2947f5408b86a"}, "thoas": {:hex, :thoas, "1.2.1", "19a25f31177a17e74004d4840f66d791d4298c5738790fa2cc73731eb911f195", [:rebar3], [], "hexpm", "e38697edffd6e91bd12cea41b155115282630075c2a727e7a6b2947f5408b86a"},
"thousand_island": {:hex, :thousand_island, "1.4.3", "2158209580f633be38d43ec4e3ce0a01079592b9657afff9080d5d8ca149a3af", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6e4ce09b0fd761a58594d02814d40f77daff460c48a7354a15ab353bb998ea0b"}, "thousand_island": {:hex, :thousand_island, "1.4.3", "2158209580f633be38d43ec4e3ce0a01079592b9657afff9080d5d8ca149a3af", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6e4ce09b0fd761a58594d02814d40f77daff460c48a7354a15ab353bb998ea0b"},
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
"typed_struct_ctor": {:hex, :typed_struct_ctor, "0.1.2", "00cc745439e99047615bb0700b43652311c199043293c13335151873505c5d01", [:mix], [{:ecto, "~> 3.10", [hex: :ecto, repo: "hexpm", optional: false]}, {:typed_struct_ecto_changeset, "~> 1.0.0", [hex: :typed_struct_ecto_changeset, repo: "hexpm", optional: false]}, {:typedstruct, "~> 0.5.2", [hex: :typedstruct, repo: "hexpm", optional: false]}], "hexpm", "79695303f7402f1a5b92e5914446014020b234bbfa1fccc664bacdf47101567f"},
"typed_struct_ecto_changeset": {:hex, :typed_struct_ecto_changeset, "1.0.0", "40b6946074eabef74b44a6c55c79bbbcfda1abff9f82bd6fcbb738931937fa8f", [:mix], [], "hexpm", "9dccc15467402a75749907b7d07441638e92f45a2460cb068f0269d82bbc7a4e"},
"typedstruct": {:hex, :typedstruct, "0.5.4", "d1d33d58460a74f413e9c26d55e66fd633abd8ac0fb12639add9a11a60a0462a", [:make, :mix], [], "hexpm", "ffaef36d5dbaebdbf4ed07f7fb2ebd1037b2c1f757db6fb8e7bcbbfabbe608d8"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
"websock_adapter": {:hex, :websock_adapter, "0.5.9", "43dc3ba6d89ef5dec5b1d0a39698436a1e856d000d84bf31a3149862b01a287f", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "5534d5c9adad3c18a0f58a9371220d75a803bf0b9a3d87e6fe072faaeed76a08"}, "websock_adapter": {:hex, :websock_adapter, "0.5.9", "43dc3ba6d89ef5dec5b1d0a39698436a1e856d000d84bf31a3149862b01a287f", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "5534d5c9adad3c18a0f58a9371220d75a803bf0b9a3d87e6fe072faaeed76a08"},
} }

View File

@@ -20,22 +20,15 @@ defmodule PolicyService.Repo.Migrations.CreatePolicyApplications do
add :selected_providers, {:array, :string}, default: [] add :selected_providers, {:array, :string}, default: []
add :quotes, :map, default: %{} add :quotes, :map, default: %{}
# Accepted plan # Accepted plan
add :accepted_quote_id, :string add :accepted_plan_id, :string
add :accepted_plan_id, :string add :accepted_by, :string
add :accepted_provider_id, :string
add :accepted_by, :string
add :accepted_at, :utc_datetime_usec
# Solicitation # Issued policy
add :solicitation_id, :string add :provider_policy_number, :string
add :solicitation_s3_key, :string add :premium, :decimal
add :effective_date, :date
# Issued policy add :expiry_date, :date
add :policy_number, :string
add :premium, :decimal
add :effective_date, :date
add :expiry_date, :date
# Status + timestamps # Status + timestamps
add :status, :string, null: false add :status, :string, null: false