Files
policy-service/lib/policy_service_web/schemas/policy.ex
HaimKortovich dfce7873fb
All checks were successful
Build and Publish / build-release (push) Successful in 1m36s
rename policy_details to insured_object
2026-04-30 13:13:41 -05:00

505 lines
15 KiB
Elixir

defmodule PolicyServiceWeb.Schemas.Policy do
alias OpenApiSpex.Schema
defmodule PaginationMeta do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "PaginationMeta",
type: :object,
properties: %{
total_count: %Schema{type: :integer},
total_pages: %Schema{type: :integer},
current_page: %Schema{type: :integer},
page_size: %Schema{type: :integer},
has_next: %Schema{type: :boolean},
has_prev: %Schema{type: :boolean}
}
})
end
defmodule InsuredIndividual do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "InsuredIndividual",
type: :object,
required: [:type, :name, :date_of_birth, :document_id, :gender],
properties: %{
type: %Schema{type: :string, enum: ["individual"]},
name: %Schema{type: :string, example: "Juan Pérez"},
date_of_birth: %Schema{type: :string, format: :date, example: "1985-06-15"},
document_id: %Schema{type: :string, example: "8-123-456"},
gender: %Schema{type: :string, enum: ["male", "female"], example: "male"},
email: %Schema{type: :string, format: :email, example: "juan@example.com"},
phone: %Schema{type: :string, example: "+507-1234-5678"},
address: %Schema{type: :string, example: "Calle 50, Panama City"}
}
})
end
defmodule InsuredCorporate do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "InsuredCorporate",
type: :object,
required: [:type, :company_name, :ruc, :legal_rep_name, :legal_rep_document],
properties: %{
type: %Schema{type: :string, enum: ["corporate"]},
company_name: %Schema{type: :string, example: "Empresa ABC S.A."},
ruc: %Schema{type: :string, example: "123456-1-123456"},
legal_rep_name: %Schema{type: :string, example: "María García"},
legal_rep_document: %Schema{type: :string, example: "8-456-789"},
email: %Schema{type: :string, format: :email, example: "contact@empresa-abc.com"},
phone: %Schema{type: :string, example: "+507-1234-5678"},
address: %Schema{type: :string, example: "Calle 50, Panama City"}
}
})
end
defmodule Insured do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "Insured",
oneOf: [InsuredIndividual, InsuredCorporate]
})
end
defmodule BuyerIndividual do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "BuyerIndividual",
type: :object,
required: [:type, :name, :date_of_birth, :document_id],
properties: %{
type: %Schema{type: :string, enum: ["individual"]},
name: %Schema{type: :string, example: "María García"},
date_of_birth: %Schema{type: :string, format: :date, example: "1980-03-20"},
document_id: %Schema{type: :string, example: "8-456-789"},
email: %Schema{type: :string, format: :email, example: "maria@example.com"},
phone: %Schema{type: :string, example: "+507-8765-4321"},
address: %Schema{type: :string, example: "Calle 75, Panama City"}
}
})
end
defmodule BuyerCorporate do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "BuyerCorporate",
type: :object,
required: [:type, :company_name, :ruc, :legal_rep_name, :legal_rep_document],
properties: %{
type: %Schema{type: :string, enum: ["corporate"]},
company_name: %Schema{type: :string, example: "Empresa XYZ S.A."},
ruc: %Schema{type: :string, example: "987654-1-987654"},
legal_rep_name: %Schema{type: :string, example: "Carlos López"},
legal_rep_document: %Schema{type: :string, example: "8-789-012"},
email: %Schema{type: :string, format: :email, example: "carlos@empresa-xyz.com"},
phone: %Schema{type: :string, example: "+507-8765-4321"},
address: %Schema{type: :string, example: "Calle 100, Panama City"}
}
})
end
defmodule Buyer do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "Buyer",
oneOf: [BuyerIndividual, BuyerCorporate]
})
end
# ---------------------------------------------------------------------------
# Policy details — one per policy type
# ---------------------------------------------------------------------------
defmodule ApplicantIndividual do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ApplicantIndividual",
type: :object,
required: [:name, :date_of_birth, :document_id],
properties: %{
name: %Schema{type: :string, example: "Juan Pérez"},
date_of_birth: %Schema{type: :string, format: :date, example: "1985-06-15"},
document_id: %Schema{type: :string, example: "8-123-456"}
}
})
end
defmodule ApplicantCorporate do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ApplicantCorporate",
type: :object,
required: [:company_name, :ruc, :legal_rep_name, :legal_rep_document],
properties: %{
company_name: %Schema{type: :string, example: "Empresa ABC S.A."},
ruc: %Schema{type: :string, example: "123456-1-123456"},
legal_rep_name: %Schema{type: :string, example: "María García"},
legal_rep_document: %Schema{type: :string, example: "8-456-789"}
}
})
end
defmodule ApplicantInfo do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ApplicantInfo",
oneOf: [ApplicantIndividual, ApplicantCorporate]
})
end
# ---------------------------------------------------------------------------
# Policy details — one per policy type
# ---------------------------------------------------------------------------
defmodule CarPolicyDetails do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "CarPolicyDetails",
type: :object,
required: [
:plate,
:make,
:model,
:year,
:use_type,
:car_type,
:rc_limits,
:market_value,
:requested_value
],
properties: %{
plate: %Schema{type: :string, example: "ABC-1234"},
make: %Schema{type: :string, example: "Toyota"},
model: %Schema{type: :string, example: "Corolla"},
year: %Schema{type: :integer, example: 2022},
use_type: %Schema{type: :string, enum: ["private", "commercial", "bus", "taxi", "school"]},
car_type: %Schema{
type: :string,
enum: [
"sedan",
"suv",
"hatchback",
"coupe",
"convertible",
"pickup",
"van",
"minivan",
"truck"
]
},
chassis_number: %Schema{type: :string, example: "9BWZZZ377VT004251"},
engine_number: %Schema{type: :string, example: "1NZ-FE-1234567"},
rc_limits: %Schema{
type: :object,
properties: %{
bodily_injury: %Schema{type: :number, example: 50000},
property_damage: %Schema{type: :number, example: 25000}
}
},
market_value: %Schema{type: :number, example: 18000},
requested_value: %Schema{type: :number, example: 20000}
}
})
end
defmodule LifePolicyDetails do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "LifePolicyDetails",
type: :object,
required: [:coverage_type, :coverage_amount, :coverage_years, :smoker],
properties: %{
coverage_type: %Schema{
type: :string,
enum: ["banking", "protection"]
},
coverage_amount: %Schema{type: :number, example: 100_000},
coverage_years: %Schema{type: :integer, example: 10},
smoker: %Schema{type: :boolean, example: false},
medications: %Schema{type: :array, items: %Schema{type: :string}, example: ["Aspirin", "Lisinopril"]},
surgeries: %Schema{type: :array, items: %Schema{type: :string}, example: ["Appendectomy, 2015"]},
weight: %Schema{type: :number, example: 70},
height: %Schema{type: :number, example: 175}
}
})
end
defmodule FireStructurePolicyDetails do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "FireStructurePolicyDetails",
type: :object,
required: [:location, :property_value, :property_use, :security_measures, :market_value],
properties: %{
location: %Schema{type: :string, example: "Calle 50, Panama City"},
property_value: %Schema{type: :number, example: 250_000},
property_use: %Schema{type: :string, example: "residential"},
security_measures: %Schema{type: :array, items: %Schema{type: :string}},
market_value: %Schema{type: :number, example: 260_000}
}
})
end
defmodule FireContentsPolicyDetails do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "FireContentsPolicyDetails",
type: :object,
required: [:location, :contents_value, :property_use, :security_measures],
properties: %{
location: %Schema{type: :string, example: "Calle 50, Panama City"},
contents_value: %Schema{type: :number, example: 50_000},
property_use: %Schema{type: :string, example: "residential"},
security_measures: %Schema{type: :array, items: %Schema{type: :string}},
high_value_items: %Schema{
type: :array,
items: %Schema{
type: :object,
properties: %{
description: %Schema{type: :string},
value: %Schema{type: :number},
type: %Schema{type: :string, enum: ["electronic", "other"]}
}
}
}
}
})
end
defmodule InsuredObject do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "InsuredObject",
oneOf: [
CarPolicyDetails,
LifePolicyDetails,
FireStructurePolicyDetails,
FireContentsPolicyDetails
]
})
end
# ---------------------------------------------------------------------------
# Shared
# ---------------------------------------------------------------------------
defmodule SelectedProvider do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "SelectedProvider",
type: :object,
required: [:provider_id, :email],
properties: %{
provider_id: %Schema{type: :string, format: :uuid},
email: %Schema{type: :string, format: :email}
}
})
end
defmodule Plan do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "Plan",
type: :object,
properties: %{
plan_id: %Schema{type: :string},
name: %Schema{type: :string},
premium: %Schema{type: :number},
coverage_details: %Schema{type: :string},
deductible: %Schema{type: :number, nullable: true},
coverage_limit: %Schema{type: :number, nullable: true}
}
})
end
defmodule QuoteData do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "QuoteData",
type: :object,
properties: %{
quote_id: %Schema{type: :string},
valid_until: %Schema{type: :string, format: :date},
received_at: %Schema{type: :string, format: :"date-time"},
plans: %Schema{type: :array, items: Plan}
}
})
end
# ---------------------------------------------------------------------------
# Requests
# ---------------------------------------------------------------------------
defmodule CreatePolicyRequest do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "CreatePolicyRequest",
type: :object,
required: [:policy_type, :insured, :buyer, :insured_object, :selected_providers],
properties: %{
policy_type: %Schema{
type: :string,
enum: ["car", "life", "fire_structure", "fire_contents"],
description: "Determines the shape of insured_object"
},
insured: Insured,
buyer: Buyer,
insured_object: InsuredObject,
selected_providers: %Schema{type: :array, items: SelectedProvider, minItems: 1}
}
})
end
defmodule AcceptQuoteRequest do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "AcceptQuoteRequest",
type: :object,
required: [:accepted_plan_id],
properties: %{
accepted_plan_id: %Schema{
type: :string,
description: "Plan ID to accept"
}
}
})
end
# ---------------------------------------------------------------------------
# Responses
# ---------------------------------------------------------------------------
defmodule QuoteResponse do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "QuoteResponse",
type: :object,
properties: %{
application_id: %Schema{type: :string},
status: %Schema{type: :string}
}
})
end
defmodule PolicySummary do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "PolicySummary",
type: :object,
properties: %{
application_id: %Schema{type: :string},
policy_type: %Schema{
type: :string,
enum: ["car", "life", "fire_structure", "fire_contents"]
},
status: %Schema{
type: :string,
enum: ["quote_requested", "quotes_received", "awaiting_policy", "issued"]
},
insured: Insured,
buyer: Buyer,
insured_object: InsuredObject,
provider_policy_number: %Schema{type: :string, nullable: true},
submitted_at: %Schema{type: :string, format: :"date-time"}
}
})
end
defmodule PolicyDetail do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "PolicyDetail",
type: :object,
properties: %{
application_id: %Schema{type: :string},
org_id: %Schema{type: :string},
submitted_by: %Schema{type: :string},
policy_type: %Schema{
type: :string,
enum: ["car", "life", "fire_structure", "fire_contents"]
},
status: %Schema{
type: :string,
enum: ["quote_requested", "quotes_received", "awaiting_policy", "issued"]
},
insured: Insured,
buyer: Buyer,
insured_object: InsuredObject,
selected_providers: %Schema{type: :array, items: %Schema{type: :string}},
quotes: %Schema{type: :object, additionalProperties: QuoteData},
accepted_plan_id: %Schema{type: :string, nullable: true},
accepted_by: %Schema{type: :string, nullable: true},
provider_policy_number: %Schema{type: :string, nullable: true},
premium: %Schema{type: :number, nullable: true},
effective_date: %Schema{type: :string, format: :date, nullable: true},
expiry_date: %Schema{type: :string, format: :date, nullable: true},
submitted_at: %Schema{type: :string, format: :"date-time"},
solicitation_sent_at: %Schema{type: :string, format: :"date-time", nullable: true},
issued_at: %Schema{type: :string, format: :"date-time", nullable: true}
}
})
end
defmodule PolicyListResponse do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "PolicyListResponse",
type: :object,
properties: %{
data: %Schema{type: :array, items: PolicySummary},
meta: PaginationMeta
}
})
end
defmodule PolicyDetailResponse do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "PolicyDetailResponse",
type: :object,
properties: %{
data: PolicyDetail
}
})
end
defmodule ErrorResponse do
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ErrorResponse",
type: :object,
properties: %{
error: %Schema{type: :string}
}
})
end
end