This document was generated from the URDAD model Motor Insurer. It specifies what the business requires, independently of any technology.
It is written to be read without knowledge of URDAD or of its diagrams, as every diagram is followed by a description of what it shows, in words. The specification is organised by responsibility domain. For each, it describes the services the domain provides, i.e. what each requires and guarantees, the information exchanged with it, how the work is allocated to other domains and the business process which provides it. It then describes the entities the domain maintains, the services it depends on from other domains, and finally its lower-level responsibility domains, each in a part of its own. The first part is the model itself, specified as the responsibility domain which contains all the others. It gives the model’s scope and the top-level responsibility domains it decomposes into.
1. Motor Insurer
This part specifies the model Motor Insurer as a whole. The model is the responsibility domain which contains all the others. It decomposes into top-level responsibility domains, each of which provides services to others and may in turn rely on services of other domains.
A motor insurer, modelled in URDAD to be run as well as read.
A client onboards, insures a vehicle, claims against the policy and asks for a claims report; each morning, claims open too long are escalated. The four use cases create the model's three entities — Client, Policy owned by a client, and Claim against a policy — which an execution environment keeps, checking every pre- and post-condition against them as it runs.
Process claim is the long-running one: it waits for the client's documents against a deadline, screens and prices the claim concurrently, refers a risky claim to an investigator, and has the rest assessed, paid and repaired by a process of its own — people, rules and code each doing their part, chosen per deployment.
Generated by models/motorClaim/generate.py.
The scope diagram below shows what Motor Insurer is responsible for, i.e. the top-level responsibility domains it decomposes into.
2. Client
This part specifies the Client responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
A client is a party to whom the insurer’s services are offered.
A role, owning nothing in this model; the party playing it need not be a person — a company insuring its fleet is a client too. Every use case is published to it, which is what makes the service callable from outside; and a client is also asked, as a task, when an assessor needs more information.
The scope diagram below shows what Client is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
Nothing has been specified within this responsibility domain yet.
3. Insurer
This part specifies the Insurer responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
The motor insurer: its shared vocabulary and the departments that answer for its services.
Responsibility is divided by what each department can guarantee: Client Register knows the clients, Underwriting the policies, Claims the claims; Fraud Investigation, Assessment, Repair Network and Claims Management are people; Payments pays. There is no client-facing department: each use case is in the department whose records its post-conditions are about, and is offered to clients by being published to them.
The scope diagram below shows what Insurer is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
3.1. Dependencies
To provide its services, Insurer relies on services provided by other responsibility domains. The dependency diagram below shows which.
Insurer uses:
-
from Bank: The insurer’s bank, an external party that makes its payments.
-
the Make payment service: The insurer’s bank pays an amount to the client.
-
3.2. Lower-level responsibilities
Insurer delegates part of its responsibility to the following lower-level responsibility domains, each specified in the same way:
-
Client Register: Who the insurer’s clients are.
-
Underwriting: Pricing cover and issuing policies.
-
Claims: The claims made against policies, and the record of each.
-
Fraud Investigation: Screening claims, and investigating the risky ones.
-
Assessment: Pricing damage and assessing a claim’s loss.
-
Repair Network: The panel repairers who repair insured vehicles.
-
Payments: Computing and paying what a settled claim pays.
-
Claims Management: The claims managers, who review what has stalled.
4. Insurer / Client Register
This part specifies the Client Register responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
Who the insurer’s clients are.
Onboards them: Onboard client is the use case, Record client the write it requests.
The scope diagram below shows what Client Register is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
4.1. Services
Client Register is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Onboard client: A person becomes a client of the insurer.
-
Record client: Records a new client and issues their client number.
-
getClient: Gives the client with the client number asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
-
findClientByLogin: Gives the client with the login asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
4.1.1. Service: Onboard client
Client Register provides the Onboard client service.
A person becomes a client of the insurer.
Service requirements
The functional requirements diagram below shows who has an interest in the Onboard client service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the post-condition Client onboarded. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Identity not yet registered and Login not yet registered.
It is provided only when:
-
Identity not yet registered: Each person is onboarded once, by their identity document.
Required by Insurer. Formally:
Client.allInstances()->forAll(c | c.idNumber <> request.idNumber) -
Login not yet registered: A login identity belongs to one client.
Required by Insurer. Formally:
Client.allInstances()->forAll(c | c.login <> caller)
Once it has been provided:
-
Client onboarded: The person is a client, under the login they asked with.
Required by Client. Formally:
Client.allInstances()->exists(c | c.clientNumber = response.clientNumber and c.idNumber = request.idNumber and c.login = caller)
Exceptions
When a pre-condition does not hold, the Onboard client service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Identity not yet registered not met, raised whenIdentity not yet registereddoes not hold: Raised when 'Onboard client' is requested while 'Identity not yet registered' does not hold. -
Login not yet registered not met, raised whenLogin not yet registereddoes not hold: Raised when 'Onboard client' is requested while 'Login not yet registered' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Client Register::Request.
What is supplied when requesting 'Onboard client'.
A Insurer::Client Register::Request has:
-
one
name, aInsurer::Text: Their name. -
one
idNumber, aInsurer::Text: The number on their identity document. -
one
email, aInsurer::Text: Their e-mail address.
Response data structure
The information the service returns once provided is a Insurer::Client Register::Response.
What 'Onboard client' yields once rendered.
A Insurer::Client Register::Response has:
-
one
clientNumber, anInsurer::Identifier: The client number issued.
Responsibility allocation
The responsibility allocation diagram below shows how the Onboard client process takes care of each requirement of the Onboard client service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Identity not yet registered (pre-condition) is addressed by checking it before anything else is done.
-
Login not yet registered (pre-condition) is addressed by checking it before anything else is done.
-
Client onboarded (post-condition) is addressed by requesting the Record client service from Client Register.
To do so the process uses the following services:
-
From Client Register:
-
Record client: Records a new client and issues their client number.
-
Business process
Records the person as a client under the login they asked with.
The Onboard client business process provides the Onboard client service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Identity not yet registeredholds. If it does not, stop and raiseIdentity not yet registered not met.Formally:
Client.allInstances()->forAll(c | c.idNumber <> request.idNumber) -
Check that
Login not yet registeredholds. If it does not, stop and raiseLogin not yet registered not met.Formally:
Client.allInstances()->forAll(c | c.login <> caller) -
Request the Record client service from Client Register.
This step addresses Client onboarded.
The request is populated as follows:
-
name:
providerRequest.name = request.name -
idNumber:
providerRequest.idNumber = request.idNumber -
email:
providerRequest.email = request.email -
login:
providerRequest.login = callerThe answer is kept as
recorded, oneInsurer::Client Register::Response. -
If the service is provided:
-
Populate the response.
-
clientNumber:
response.clientNumber = recorded.clientNumber
-
-
-
4.1.2. Service: Record client
Client Register provides the Record client service.
Records a new client and issues their client number.
Service requirements
The functional requirements diagram below shows who has an interest in the Record client service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client Register: Who the insurer’s clients are.
Client Registerrequires the post-conditions Client recorded and Client number is new. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-condition Identity not yet registered.
It is provided only when:
-
Identity not yet registered: Each person is onboarded once, by their identity document.
Required by Insurer. Formally:
Client.allInstances()->forAll(c | c.idNumber <> request.idNumber)
Once it has been provided:
-
Client recorded: The client is on record with the details given.
Required by Client Register. Formally:
Client.allInstances()->exists(c | c.clientNumber = response.clientNumber and c.name = request.name and c.idNumber = request.idNumber and c.email = request.email and c.login = request.login) -
Client number is new: The number issued belonged to no client before.
Required by Client Register. Formally:
Client.allInstances@pre()->forAll(c | c.clientNumber <> response.clientNumber)
Exceptions
When a pre-condition does not hold, the Record client service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Identity not yet registered not met, raised whenIdentity not yet registereddoes not hold: Raised when 'Record client' is requested while 'Identity not yet registered' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Client Register::Request.
What is supplied when requesting 'Record client'.
A Insurer::Client Register::Request has:
-
one
name, aInsurer::Text: The client’s name. -
one
idNumber, aInsurer::Text: The number on their identity document. -
one
email, aInsurer::Text: Their e-mail address. -
one
login, aInsurer::Text: The login identity they will use.
Response data structure
The information the service returns once provided is a Insurer::Client Register::Response.
What 'Record client' yields once rendered.
A Insurer::Client Register::Response has:
-
one
clientNumber, anInsurer::Identifier: The number issued.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it creates a Client. It is thus provided by making that one change.
4.1.3. Service: getClient
Client Register provides the getClient service. It is a query, i.e. it answers from information already held and changes nothing.
Gives the client with the client number asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
Service requirements
The functional requirements diagram below shows who has an interest in the getClient service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
It is provided only when:
-
Client exists: There is a client with that client number.
Formally:
Client.allInstances()->exists(e | e.clientNumber = request.clientNumber)
Once it has been provided:
-
Client given: Every stored field of the client with that client number, an association as its target’s identity.
Formally:
response.clientNumber = Client.allInstances()->any(e | e.clientNumber = request.clientNumber).clientNumber and response.email = Client.allInstances()->any(e | e.clientNumber = request.clientNumber).email and response.idNumber = Client.allInstances()->any(e | e.clientNumber = request.clientNumber).idNumber and response.login = Client.allInstances()->any(e | e.clientNumber = request.clientNumber).login and response.name = Client.allInstances()->any(e | e.clientNumber = request.clientNumber).name
Exceptions
When a pre-condition does not hold, the getClient service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Client exists not met, raised whenClient existsdoes not hold: Raised when 'getClient' is requested while 'Client exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Client Register::Request.
What is supplied when requesting 'getClient'.
A Insurer::Client Register::Request has:
-
one
clientNumber, anInsurer::Identifier: The client number of the client asked for.
Response data structure
The information the service returns once provided is a Insurer::Client Register::Response.
What 'getClient' yields once rendered.
A Insurer::Client Register::Response has:
-
one
clientNumber, anInsurer::Identifier: The client’s client number. -
one
email, aInsurer::Text: The client’s email. -
one
idNumber, aInsurer::Text: The client’s id number. -
one
login, aInsurer::Text: The client’s login. -
one
name, aInsurer::Text: The client’s name.
4.1.4. Service: findClientByLogin
Client Register provides the findClientByLogin service. It is a query, i.e. it answers from information already held and changes nothing.
Gives the client with the login asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
Service requirements
The functional requirements diagram below shows who has an interest in the findClientByLogin service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
It is provided only when:
-
Client with that login exists: There is a client with that login.
Formally:
Client.allInstances()->exists(e | e.login = request.login)
Once it has been provided:
-
Client given: Every stored field of the client with that login, an association as its target’s identity.
Formally:
response.clientNumber = Client.allInstances()->any(e | e.login = request.login).clientNumber and response.email = Client.allInstances()->any(e | e.login = request.login).email and response.idNumber = Client.allInstances()->any(e | e.login = request.login).idNumber and response.login = Client.allInstances()->any(e | e.login = request.login).login and response.name = Client.allInstances()->any(e | e.login = request.login).name
Exceptions
When a pre-condition does not hold, the findClientByLogin service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Client with that login exists not met, raised whenClient with that login existsdoes not hold: Raised when 'findClientByLogin' is requested while 'Client with that login exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Client Register::Request.
What is supplied when requesting 'findClientByLogin'.
A Insurer::Client Register::Request has:
-
one
login, aInsurer::Text: The login of the client asked for.
Response data structure
The information the service returns once provided is a Insurer::Client Register::Response.
What 'findClientByLogin' yields once rendered.
A Insurer::Client Register::Response has:
-
one
clientNumber, anInsurer::Identifier: The client’s client number. -
one
email, aInsurer::Text: The client’s email. -
one
idNumber, aInsurer::Text: The client’s id number. -
one
login, aInsurer::Text: The client’s login. -
one
name, aInsurer::Text: The client’s name.
4.2. Entities
An entity is information which Client Register keeps over time. It is a record which outlives any one request, and which its services create, change and read. Client Register maintains the following entities:
-
Client: A person the insurer has onboarded as a client.
The entity map below shows each entity together with its facets, i.e. the data structures whose fields make up what it stores.
4.2.1. Entity: Client
A person the insurer has onboarded as a client.
An entity: a business object with an identity, whose state the insurer keeps. Its fields are those of the views that project it — here ClientRecord.
How it is populated
Client is populated as follows:
-
The Record client service creates a
Client, identified byclientNumber. -
The
ClientRecorddata structure describes part of what it holds: The insurer’s record of one client.
Entity structure
The diagram below shows the Client entity fully expanded, i.e. everything it holds, gathered from all of its facets, and the information it is related to. The same structure is described in words after it.
A Client has:
-
one
clientNumber, anInsurer::Identifier, which identifies it: The client’s number. -
one
name, aInsurer::Text: The client’s name. -
one
idNumber, aInsurer::Text: The number on the identity document the client onboarded with. -
one
email, aInsurer::Text: Where the client is written to. -
one
login, aInsurer::Text, unique: The login identity the client uses — what `caller` is compared with.
Data dictionary
This section lists what Client stores, attribute by attribute. An attribute gathers every field of that name in the entity’s facets. Where it gathers more than one, each is listed, since fields of one name are stored as one attribute whatever each was meant to hold. The services listed write or read it as their specifications say.
| Attribute | Type | Role | Multiplicity | Unique | Personal data | Merged from | Written by | Read by |
|---|---|---|---|---|---|---|---|---|
|
Insurer::Identifier |
identifies |
|
yes |
— |
— |
||
|
Insurer::Text |
states |
|
no |
personal |
— |
||
|
Insurer::Text |
states |
|
no |
personal, retention obligated |
— |
||
|
Insurer::Text |
states |
|
no |
personal |
— |
||
|
Insurer::Text |
states |
|
yes |
personal |
— |
5. Insurer / Underwriting
This part specifies the Underwriting responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
Pricing cover and issuing policies.
Sells cover: Purchase motor insurance is the use case, quoting and issuing the services it requests.
The scope diagram below shows what Underwriting is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
5.1. Services
Underwriting is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Purchase motor insurance: A client insures a vehicle.
-
Quote premium: Prices motor cover for a vehicle.
-
Issue policy: Issues a policy to a client on the terms quoted.
-
getPolicy: Gives the policy with the policy number asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
-
Name a driver: A client names another driver of the insured vehicle on their policy.
-
Name driver: Adds a driver to those a policy names.
-
Remove named driver: Removes a driver from those a policy names.
-
Correct named driver: Corrects the name a policy holds for one of its named drivers.
5.1.1. Service: Purchase motor insurance
Underwriting provides the Purchase motor insurance service.
A client insures a vehicle.
Service requirements
The functional requirements diagram below shows who has an interest in the Purchase motor insurance service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the post-conditions Policy issued to the client and Terms reported. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Applicant is a client, Vehicle not already insured and Cover does not start in the past.
It is provided only when:
-
Applicant is a client: Only an onboarded client buys cover.
Required by Insurer. Formally:
findClientByLogin(Tuple{login = caller}) <> null -
Vehicle not already insured: A vehicle has at most one policy in force.
Required by Insurer. Formally:
Policy.allInstances()->forAll(p | p.vehicle.registration <> request.vehicle.registration or p.status <> PolicyStatus::inForce) -
Cover does not start in the past: Cover starts no earlier than a day ago.
Required by Insurer. Formally:
request.startsAt + 'PT24H' >= now()
Once it has been provided:
-
Policy issued to the client: A policy in force for the vehicle is owned by the client.
Required by Client. Formally:
Policy.allInstances()->exists(p | p.policyNumber = response.policyNumber and p.owner.login = caller and p.vehicle.registration = request.vehicle.registration and p.status = PolicyStatus::inForce) -
Terms reported: The response states the policy’s terms.
Required by Client. Formally:
Policy.allInstances()->select(p | p.policyNumber = response.policyNumber)->forAll(p | p.premium = response.premium and p.excess = response.excess and p.sumInsured = response.sumInsured)
Exceptions
When a pre-condition does not hold, the Purchase motor insurance service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Applicant is a client not met, raised whenApplicant is a clientdoes not hold: Raised when 'Purchase motor insurance' is requested while 'Applicant is a client' does not hold. -
Vehicle not already insured not met, raised whenVehicle not already insureddoes not hold: Raised when 'Purchase motor insurance' is requested while 'Vehicle not already insured' does not hold. -
Cover does not start in the past not met, raised whenCover does not start in the pastdoes not hold: Raised when 'Purchase motor insurance' is requested while 'Cover does not start in the past' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
What is supplied when requesting 'Purchase motor insurance'.
A Insurer::Underwriting::Request has:
-
one
vehicle, aInsurer::Underwriting::Vehicle: The vehicle to insure. -
one
startsAt, aInsurer::Moment: When cover should start.
The following must always hold for a Insurer::Underwriting::Request:
-
Value is positive:
self.vehicle.value > 0Required by Underwriting.
Insurer::Underwriting::Vehicle: The vehicle a policy covers.
A Insurer::Underwriting::Vehicle has:
-
one
registration, aInsurer::Text: The vehicle’s registration number. -
one
make, aInsurer::Text: Its make. -
one
model, aInsurer::Text: Its model. -
one
year, aInsurer::Count: Its model year. -
one
value, aInsurer::Money: What it is worth — and what it is insured for.
Response data structure
The information the service returns once provided is a Insurer::Underwriting::Response.
What 'Purchase motor insurance' yields once rendered.
A Insurer::Underwriting::Response has:
-
one
policyNumber, anInsurer::Identifier: The policy issued. -
one
premium, aInsurer::Money: Its annual premium. -
one
excess, aInsurer::Money: Its excess. -
one
sumInsured, aInsurer::Money: Its sum insured.
Responsibility allocation
The responsibility allocation diagram below shows how the Purchase motor insurance process takes care of each requirement of the Purchase motor insurance service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Applicant is a client (pre-condition) is addressed by checking it before anything else is done.
-
Vehicle not already insured (pre-condition) is addressed by checking it before anything else is done.
-
Cover does not start in the past (pre-condition) is addressed by checking it before anything else is done.
-
Policy issued to the client (post-condition) is addressed by requesting the Issue policy service from Underwriting.
-
Terms reported (post-condition) is addressed by populating the response.
To do so the process uses the following services:
-
From Client Register:
-
findClientByLogin: Gives the client with the login asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
-
-
From Underwriting:
-
Quote premium: Prices motor cover for a vehicle.
-
Issue policy: Issues a policy to a client on the terms quoted.
-
Business process
Quotes the cover, issues the policy to the client, and reports its terms.
Quote premium is a function the execution environment answers from its post-conditions alone; Issue policy writes the policy, owned by the client.
The Purchase motor insurance business process provides the Purchase motor insurance service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Applicant is a clientholds. If it does not, stop and raiseApplicant is a client not met.Formally:
findClientByLogin(Tuple{login = caller}) <> null -
Check that
Vehicle not already insuredholds. If it does not, stop and raiseVehicle not already insured not met.Formally:
Policy.allInstances()->forAll(p | p.vehicle.registration <> request.vehicle.registration or p.status <> PolicyStatus::inForce) -
Check that
Cover does not start in the pastholds. If it does not, stop and raiseCover does not start in the past not met.Formally:
request.startsAt + 'PT24H' >= now() -
Request the findClientByLogin service from Client Register.
The request is populated as follows:
-
login:
providerRequest.login = callerThe answer is kept as
applicant, oneInsurer::Client Register::Response. -
If the service is provided:
-
Request the Quote premium service from Underwriting.
The request is populated as follows:
-
vehicleValue:
providerRequest.vehicleValue = request.vehicle.valueThe answer is kept as
quote, oneInsurer::Underwriting::Response. -
If the service is provided:
-
Request the Issue policy service from Underwriting.
This step addresses Policy issued to the client.
The request is populated as follows:
-
ownerNumber:
providerRequest.ownerNumber = applicant.clientNumber -
vehicle:
providerRequest.vehicle = request.vehicle -
startsAt:
providerRequest.startsAt = request.startsAt -
premium:
providerRequest.premium = quote.premium -
excess:
providerRequest.excess = quote.excess -
sumInsured:
providerRequest.sumInsured = quote.sumInsuredThe answer is kept as
issued, oneInsurer::Underwriting::Response. -
If the service is provided:
-
Populate the response.
This step addresses Terms reported.
-
policyNumber:
response.policyNumber = issued.policyNumber -
premium:
response.premium = quote.premium -
excess:
response.excess = quote.excess -
sumInsured:
response.sumInsured = quote.sumInsured
-
-
-
-
-
-
-
5.1.2. Service: Quote premium
Underwriting provides the Quote premium service. It is a query, i.e. it answers from information already held and changes nothing.
Prices motor cover for a vehicle.
A function, and one whose post-conditions determine its whole response from the request: the premium is 0.04 of the value, the excess 7500 above 300000 and 5000 otherwise, the sum insured the value. An execution environment can therefore answer it with no code — a specified realization evaluates these recipes.
Service requirements
The functional requirements diagram below shows who has an interest in the Quote premium service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the post-condition Insured for its value. -
Underwriting: Pricing cover and issuing policies.
Underwritingrequires the post-conditions Premium priced and Excess set.
Once it has been provided:
-
Premium priced: The premium is 0.04 of the value.
Required by Underwriting. Formally:
response.premium = request.vehicleValue * 0.04 -
Excess set: The excess depends on the vehicle’s value.
Required by Underwriting. Formally:
response.excess = if request.vehicleValue > 300000 then 7500 else 5000 endif -
Insured for its value: The sum insured is the vehicle’s value.
Required by Client. Formally:
response.sumInsured = request.vehicleValue
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
What is supplied when requesting 'Quote premium'.
A Insurer::Underwriting::Request has:
-
one
vehicleValue, aInsurer::Money: What the vehicle is worth.
The following must always hold for a Insurer::Underwriting::Request:
-
Value is positive:
self.vehicleValue > 0Required by Underwriting.
Response data structure
The information the service returns once provided is a Insurer::Underwriting::Response.
What 'Quote premium' yields once rendered.
A Insurer::Underwriting::Response has:
-
one
premium, aInsurer::Money: The annual premium. -
one
excess, aInsurer::Money: What the client bears of each claim. -
one
sumInsured, aInsurer::Money: The most a claim pays.
5.1.3. Service: Issue policy
Underwriting provides the Issue policy service.
Issues a policy to a client on the terms quoted.
Service requirements
The functional requirements diagram below shows who has an interest in the Issue policy service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-condition Owner is a client. -
Underwriting: Pricing cover and issuing policies.
Underwritingrequires the post-conditions Policy issued and Policy number is new.
It is provided only when:
-
Owner is a client: A policy is issued only to an onboarded client.
Required by Insurer. Formally:
getClient(Tuple{clientNumber = request.ownerNumber}) <> null
Once it has been provided:
-
Policy issued: A policy in force on the terms quoted is owned by the client.
Required by Underwriting. Formally:
Policy.allInstances()->exists(p | p.policyNumber = response.policyNumber and p.owner.clientNumber = request.ownerNumber and p.vehicle = request.vehicle and p.premium = request.premium and p.excess = request.excess and p.sumInsured = request.sumInsured and p.startsAt = request.startsAt and p.status = PolicyStatus::inForce) -
Policy number is new: The number issued belonged to no policy before.
Required by Underwriting. Formally:
Policy.allInstances@pre()->forAll(p | p.policyNumber <> response.policyNumber)
Exceptions
When a pre-condition does not hold, the Issue policy service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Owner is a client not met, raised whenOwner is a clientdoes not hold: Raised when 'Issue policy' is requested while 'Owner is a client' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
What is supplied when requesting 'Issue policy'.
A Insurer::Underwriting::Request has:
-
one
ownerNumber, anInsurer::Identifier: The number of the client who will own the policy. -
one
vehicle, aInsurer::Underwriting::Vehicle: The vehicle covered. -
one
startsAt, aInsurer::Moment: When cover starts. -
one
premium, aInsurer::Money: The premium quoted. -
one
excess, aInsurer::Money: The excess quoted. -
one
sumInsured, aInsurer::Money: The sum insured quoted.
Insurer::Underwriting::Vehicle: The vehicle a policy covers.
A Insurer::Underwriting::Vehicle has:
-
one
registration, aInsurer::Text: The vehicle’s registration number. -
one
make, aInsurer::Text: Its make. -
one
model, aInsurer::Text: Its model. -
one
year, aInsurer::Count: Its model year. -
one
value, aInsurer::Money: What it is worth — and what it is insured for.
Response data structure
The information the service returns once provided is a Insurer::Underwriting::Response.
What 'Issue policy' yields once rendered.
A Insurer::Underwriting::Response has:
-
one
policyNumber, anInsurer::Identifier: The number issued.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it creates a Policy. It is thus provided by making that one change.
5.1.4. Service: getPolicy
Underwriting provides the getPolicy service. It is a query, i.e. it answers from information already held and changes nothing.
Gives the policy with the policy number asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
Service requirements
The functional requirements diagram below shows who has an interest in the getPolicy service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
It is provided only when:
-
Policy exists: There is a policy with that policy number.
Formally:
Policy.allInstances()->exists(e | e.policyNumber = request.policyNumber)
Once it has been provided:
-
Policy given: Every stored field of the policy with that policy number, an association as its target’s identity.
Formally:
response.endsAt = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).endsAt and response.excess = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).excess and response.namedDrivers = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).namedDrivers and response.owner = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).owner.clientNumber and response.policyNumber = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).policyNumber and response.premium = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).premium and response.startsAt = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).startsAt and response.status = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).status and response.sumInsured = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).sumInsured and response.vehicle = Policy.allInstances()->any(e | e.policyNumber = request.policyNumber).vehicle
Exceptions
When a pre-condition does not hold, the getPolicy service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy exists not met, raised whenPolicy existsdoes not hold: Raised when 'getPolicy' is requested while 'Policy exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
What is supplied when requesting 'getPolicy'.
A Insurer::Underwriting::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy number of the policy asked for.
Response data structure
The information the service returns once provided is a Insurer::Underwriting::Response.
What 'getPolicy' yields once rendered.
A Insurer::Underwriting::Response has:
-
one
endsAt, aInsurer::Moment: The policy’s ends at. -
one
excess, aInsurer::Money: The policy’s excess. -
up to 4
namedDrivers, each aInsurer::Underwriting::NamedDriver: The policy’s named drivers. -
one
owner, anInsurer::Identifier: The identity of the policy’s owner. -
one
policyNumber, anInsurer::Identifier: The policy’s policy number. -
one
premium, aInsurer::Money: The policy’s premium. -
one
startsAt, aInsurer::Moment: The policy’s starts at. -
one
status, aInsurer::PolicyStatus: The policy’s status.One of
inForce,lapsedandcancelled. -
one
sumInsured, aInsurer::Money: The policy’s sum insured. -
one
vehicle, aInsurer::Underwriting::Vehicle: The policy’s vehicle.
Insurer::Underwriting::NamedDriver: A person a policy names as a driver of its vehicle.
A Insurer::Underwriting::NamedDriver has:
-
one
licenceNumber, aInsurer::Text: The number of the driver’s licence, which tells a policy’s drivers apart. -
one
name, aInsurer::Text: The driver’s name, as the licence gives it. -
one
licensedSince, aInsurer::Moment: When the driver was first licensed, which underwriting weighs.
Insurer::Underwriting::Vehicle: The vehicle a policy covers.
A Insurer::Underwriting::Vehicle has:
-
one
registration, aInsurer::Text: The vehicle’s registration number. -
one
make, aInsurer::Text: Its make. -
one
model, aInsurer::Text: Its model. -
one
year, aInsurer::Count: Its model year. -
one
value, aInsurer::Money: What it is worth — and what it is insured for.
5.1.5. Service: Name a driver
Underwriting provides the Name a driver service.
A client names another driver of the insured vehicle on their policy.
Service requirements
The functional requirements diagram below shows who has an interest in the Name a driver service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the post-condition Driver named on the policy. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Applicant is a client, Policy is the applicant’s, Driver not yet named and Room for another driver.
It is provided only when:
-
Applicant is a client: The caller is a client of the insurer.
Required by Insurer. Formally:
findClientByLogin(Tuple{login = caller}) <> null -
Policy is the applicant’s: The policy is the caller’s own.
Required by Insurer. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.owner.clientNumber = findClientByLogin(Tuple{login = caller}).clientNumber) -
Driver not yet named: The policy does not already name the driver.
Required by Insurer. Formally:
not Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->exists(d | d.licenceNumber = request.driver.licenceNumber) -
Room for another driver: The policy names fewer than four drivers, the most it may name.
Required by Insurer. Formally:
Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->size() < 4
Once it has been provided:
-
Driver named on the policy: The client’s policy names the driver.
Required by Client. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.namedDrivers->exists(d | d.licenceNumber = request.driver.licenceNumber))
Exceptions
When a pre-condition does not hold, the Name a driver service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Applicant is a client not met, raised whenApplicant is a clientdoes not hold: Raised when the request is made while 'Applicant is a client' does not hold. -
Policy is the applicant's not met, raised whenPolicy is the applicant'sdoes not hold: Raised when the request is made while 'Policy is the applicant’s' does not hold. -
Driver not yet named not met, raised whenDriver not yet nameddoes not hold: Raised when the request is made while 'Driver not yet named' does not hold. -
Room for another driver not met, raised whenRoom for another driverdoes not hold: Raised when the request is made while 'Room for another driver' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
The client’s policy, and the driver to name on it.
A Insurer::Underwriting::Request has:
-
one
policyNumber, anInsurer::Identifier: The client’s policy. -
one
driver, aInsurer::Underwriting::NamedDriver: The driver to name.
Insurer::Underwriting::NamedDriver: A person a policy names as a driver of its vehicle.
A Insurer::Underwriting::NamedDriver has:
-
one
licenceNumber, aInsurer::Text: The number of the driver’s licence, which tells a policy’s drivers apart. -
one
name, aInsurer::Text: The driver’s name, as the licence gives it. -
one
licensedSince, aInsurer::Moment: When the driver was first licensed, which underwriting weighs.
Responsibility allocation
The responsibility allocation diagram below shows how the Name a driver process takes care of each requirement of the Name a driver service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Applicant is a client (pre-condition) is addressed by checking it before anything else is done.
-
Policy is the applicant’s (pre-condition) is addressed by checking it before anything else is done.
-
Driver not yet named (pre-condition) is addressed by checking it before anything else is done.
-
Room for another driver (pre-condition) is addressed by checking it before anything else is done.
-
Driver named on the policy (post-condition) is addressed by requesting the Name driver service from Underwriting.
To do so the process uses the following services:
-
From Underwriting:
-
Name driver: Adds a driver to those a policy names.
-
Business process
Checks the client may name the driver, then names them on the policy.
The Name a driver business process provides the Name a driver service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Applicant is a clientholds. If it does not, stop and raiseApplicant is a client not met.Formally:
findClientByLogin(Tuple{login = caller}) <> null -
Check that
Policy is the applicant'sholds. If it does not, stop and raisePolicy is the applicant's not met.Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.owner.clientNumber = findClientByLogin(Tuple{login = caller}).clientNumber) -
Check that
Driver not yet namedholds. If it does not, stop and raiseDriver not yet named not met.Formally:
not Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->exists(d | d.licenceNumber = request.driver.licenceNumber) -
Check that
Room for another driverholds. If it does not, stop and raiseRoom for another driver not met.Formally:
Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->size() < 4 -
Request the Name driver service from Underwriting.
This step addresses Driver named on the policy.
The request is populated as follows:
-
policyNumber:
providerRequest.policyNumber = request.policyNumber -
driver:
providerRequest.driver = request.driver
-
5.1.6. Service: Name driver
Underwriting provides the Name driver service.
Adds a driver to those a policy names.
The request's driver is a member of the policy's namedDrivers (Member of): the facet of Policy this request is contributes the collection to the entity, and PolicyRecord states its bound. The post-condition is one of the collection forms a specified realization writes.
Service requirements
The functional requirements diagram below shows who has an interest in the Name driver service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Policy is on record, Driver not on the policy yet and Policy has room for a driver. -
Underwriting: Pricing cover and issuing policies.
Underwritingrequires the post-condition Driver named.
It is provided only when:
-
Policy is on record: The policy the driver is named on is stored.
Required by Insurer. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber) -
Driver not on the policy yet: No driver the policy names holds the new driver’s licence number.
Required by Insurer. Formally:
not Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->exists(d | d.licenceNumber = request.driver.licenceNumber) -
Policy has room for a driver: The policy names fewer than four drivers, the most it may name.
Required by Insurer. Formally:
Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->size() < 4
Once it has been provided:
-
Driver named: The policy names the driver, beside those it named before.
Required by Underwriting. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.namedDrivers = p.namedDrivers@pre->including(request.driver))
Exceptions
When a pre-condition does not hold, the Name driver service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy is on record not met, raised whenPolicy is on recorddoes not hold: Raised when the request is made while 'Policy is on record' does not hold. -
Driver not on the policy yet not met, raised whenDriver not on the policy yetdoes not hold: Raised when the request is made while 'Driver not on the policy yet' does not hold. -
Policy has room for a driver not met, raised whenPolicy has room for a driverdoes not hold: Raised when the request is made while 'Policy has room for a driver' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::NameDriverRequest.
The policy, and the driver to name on it.
A Insurer::Underwriting::NameDriverRequest has:
-
one
policyNumber, anInsurer::Identifier, which identifies it: The policy’s number. -
one
driver, aInsurer::Underwriting::NamedDriver, one member of the entity’snamedDrivers: The driver named, who becomes one of the policy’s named drivers.
Insurer::Underwriting::NamedDriver: A person a policy names as a driver of its vehicle.
A Insurer::Underwriting::NamedDriver has:
-
one
licenceNumber, aInsurer::Text: The number of the driver’s licence, which tells a policy’s drivers apart. -
one
name, aInsurer::Text: The driver’s name, as the licence gives it. -
one
licensedSince, aInsurer::Moment: When the driver was first licensed, which underwriting weighs.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it updates a Policy. It is thus provided by making that one change.
5.1.7. Service: Remove named driver
Underwriting provides the Remove named driver service.
Removes a driver from those a policy names.
Service requirements
The functional requirements diagram below shows who has an interest in the Remove named driver service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Policy is on record and Driver is on the policy. -
Underwriting: Pricing cover and issuing policies.
Underwritingrequires the post-condition Driver removed.
It is provided only when:
-
Policy is on record: The policy the driver is removed from is stored.
Required by Insurer. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber) -
Driver is on the policy: The policy names a driver holding the licence number.
Required by Insurer. Formally:
Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->exists(d | d.licenceNumber = request.licenceNumber)
Once it has been provided:
-
Driver removed: The policy names every driver it named before but the one removed.
Required by Underwriting. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.namedDrivers = p.namedDrivers@pre->reject(d | d.licenceNumber = request.licenceNumber))
Exceptions
When a pre-condition does not hold, the Remove named driver service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy is on record not met, raised whenPolicy is on recorddoes not hold: Raised when the request is made while 'Policy is on record' does not hold. -
Driver is on the policy not met, raised whenDriver is on the policydoes not hold: Raised when the request is made while 'Driver is on the policy' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
The policy, and the licence number of the driver to remove.
A Insurer::Underwriting::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy whose drivers change. -
one
licenceNumber, aInsurer::Text: The licence number of the named driver concerned.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it updates a Policy. It is thus provided by making that one change.
5.1.8. Service: Correct named driver
Underwriting provides the Correct named driver service.
Corrects the name a policy holds for one of its named drivers.
Service requirements
The functional requirements diagram below shows who has an interest in the Correct named driver service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Policy is on record and Driver is on the policy. -
Underwriting: Pricing cover and issuing policies.
Underwritingrequires the post-condition Driver’s name corrected.
It is provided only when:
-
Policy is on record: The policy whose driver is corrected is stored.
Required by Insurer. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber) -
Driver is on the policy: The policy names a driver holding the licence number.
Required by Insurer. Formally:
Policy.allInstances()->any(p | p.policyNumber = request.policyNumber).namedDrivers->exists(d | d.licenceNumber = request.licenceNumber)
Once it has been provided:
-
Driver’s name corrected: The driver holding the licence number bears the corrected name; nothing else of the policy changes.
Required by Underwriting. Formally:
Policy.allInstances()->exists(p | p.policyNumber = request.policyNumber and p.namedDrivers->any(d | d.licenceNumber = request.licenceNumber).name = request.name)
Exceptions
When a pre-condition does not hold, the Correct named driver service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy is on record not met, raised whenPolicy is on recorddoes not hold: Raised when the request is made while 'Policy is on record' does not hold. -
Driver is on the policy not met, raised whenDriver is on the policydoes not hold: Raised when the request is made while 'Driver is on the policy' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Underwriting::Request.
The policy, the driver’s licence number and the corrected name.
A Insurer::Underwriting::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy whose drivers change. -
one
licenceNumber, aInsurer::Text: The licence number of the named driver concerned. -
one
name, aInsurer::Text: The driver’s name as it should read.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it updates a Policy. It is thus provided by making that one change.
5.2. Entities
An entity is information which Underwriting keeps over time. It is a record which outlives any one request, and which its services create, change and read. Underwriting maintains the following entities:
-
Policy: A motor policy the insurer has issued.
The entity map below shows each entity together with its facets, i.e. the data structures whose fields make up what it stores.
5.2.1. Entity: Policy
A motor policy the insurer has issued.
Identified by its policy number, and owned by a client: PolicyRecord.owner is an association to the client's record, stored as the client's identity and navigated as the client it denotes.
How it is populated
Policy is populated as follows:
-
The Issue policy service creates a
Policy, identified bypolicyNumber. -
The Name driver service updates a
Policy, identified bypolicyNumber. -
The Remove named driver service updates a
Policy, identified bypolicyNumber. -
The Correct named driver service updates a
Policy, identified bypolicyNumber. -
The
PolicyRecorddata structure describes part of what it holds: The insurer’s record of one policy. -
The
NameDriverRequestdata structure (the request of the Name driver service) carries information into it.
Entity structure
The diagram below shows the Policy entity fully expanded, i.e. everything it holds, gathered from all of its facets, and the information it is related to. The same structure is described in words after it.
A Policy has:
-
one
policyNumber, anInsurer::Identifier, which identifies it: The policy’s number. -
one
vehicle, aInsurer::Underwriting::Vehicle: The vehicle covered. -
one
premium, aInsurer::Money: What the cover costs a year. -
one
excess, aInsurer::Money: What the client bears of each claim. -
one
sumInsured, aInsurer::Money: The most a claim pays. -
one
startsAt, aInsurer::Moment: When cover starts. -
one
endsAt, aInsurer::Moment: When cover ends. -
one
status, aInsurer::PolicyStatus: Whether it gives cover.One of
inForce,lapsedandcancelled. -
up to 4
namedDrivers, each aInsurer::Underwriting::NamedDriver: The drivers the policy names, at most four, told apart by their licence numbers.
A Policy is associated with:
-
one
owner, aInsurer::Client Register::ClientRecord: The client who owns the policy.
Insurer::Underwriting::Vehicle: The vehicle a policy covers.
A Insurer::Underwriting::Vehicle has:
-
one
registration, aInsurer::Text: The vehicle’s registration number. -
one
make, aInsurer::Text: Its make. -
one
model, aInsurer::Text: Its model. -
one
year, aInsurer::Count: Its model year. -
one
value, aInsurer::Money: What it is worth — and what it is insured for.
Insurer::Underwriting::NamedDriver: A person a policy names as a driver of its vehicle.
A Insurer::Underwriting::NamedDriver has:
-
one
licenceNumber, aInsurer::Text: The number of the driver’s licence, which tells a policy’s drivers apart. -
one
name, aInsurer::Text: The driver’s name, as the licence gives it. -
one
licensedSince, aInsurer::Moment: When the driver was first licensed, which underwriting weighs.
Insurer::Client Register::ClientRecord: The insurer’s record of one client.
A Insurer::Client Register::ClientRecord has:
-
one
clientNumber, anInsurer::Identifier, which identifies it: The client’s number. -
one
name, aInsurer::Text: The client’s name. -
one
idNumber, aInsurer::Text: The number on the identity document the client onboarded with. -
one
email, aInsurer::Text: Where the client is written to. -
one
login, aInsurer::Text, unique: The login identity the client uses — what `caller` is compared with.
The following must always hold for a Insurer::Client Register::ClientRecord:
-
Client number format:
self.clientNumber.matches('CL-[0-9]{4,}')
Data dictionary
This section lists what Policy stores, attribute by attribute. An attribute gathers every field of that name in the entity’s facets. Where it gathers more than one, each is listed, since fields of one name are stored as one attribute whatever each was meant to hold. The services listed write or read it as their specifications say.
| Attribute | Type | Role | Multiplicity | Unique | Personal data | Merged from | Written by | Read by |
|---|---|---|---|---|---|---|---|---|
|
Insurer::Identifier |
identifies |
|
yes |
— |
|
||
|
Insurer::Client Register::ClientRecord |
states |
|
no |
— |
— |
||
|
Insurer::Underwriting::Vehicle |
states |
|
no |
— |
— |
||
|
Insurer::Money |
states |
|
no |
— |
— |
||
|
Insurer::Money |
states |
|
no |
— |
— |
||
|
Insurer::Money |
states |
|
no |
— |
— |
||
|
Insurer::Moment |
states |
|
no |
— |
— |
||
|
Insurer::Moment |
states |
|
no |
— |
— |
||
|
Insurer::PolicyStatus |
states |
|
no |
— |
— |
||
|
Insurer::Underwriting::NamedDriver |
states |
|
no |
— |
|
5.3. Dependencies
To provide its services, Underwriting relies on services provided by other responsibility domains. The dependency diagram below shows which.
Underwriting uses:
-
from Client Register: Who the insurer’s clients are.
-
the findClientByLogin service: Gives the client with the login asked for, as its owning domain holds it. Generated from the entity; generate again rather than editing it.
-
6. Insurer / Claims
This part specifies the Claims responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
The claims made against policies, and the record of each.
Answers for a claim's outcome: Process claim orchestrates the departments that screen, assess, repair and pay, and Provide claims report reads the record.
The scope diagram below shows what Claims is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
6.1. Services
Claims is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Process claim: A client claims against their policy, and the insurer settles or declines it.
-
Provide claims report: Lists the claims made against a client’s policy within a period.
-
Record claim: Records a claim against a policy, and reports the cover it is made under.
-
Update claim: Moves a claim on to a new status, recording its payout once settled.
-
Note claim review: Records a claims manager’s note on a claim, as the claim stood when they reviewed it.
-
Find claims: Lists the claims made against a policy within a period.
-
Find stale claims: Lists the claims that have stayed open too long.
-
Assess and settle claim: Assesses a recorded claim, pays it, and has the vehicle repaired.
6.1.1. Service: Process claim
Claims provides the Process claim service.
A client claims against their policy, and the insurer settles or declines it.
The long-running use case: it waits on the client's documents, on investigators, assessors and repairers, and may take weeks. Each wait is a step of the process, not a gap in it.
Service requirements
The functional requirements diagram below shows who has an interest in the Process claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the pre-condition Requested by the policy owner and the post-conditions Claim recorded against the policy and Outcome recorded. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-conditions Policy in force at the incident, Requested by the policy owner, Incident has happened and Reported in time and the post-condition Payout within cover.
It is provided only when:
-
Policy in force at the incident: The policy gave cover when the incident happened.
Required by Insurer. Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and p.status = PolicyStatus::inForce and p.startsAt <= request.incidentAt and request.incidentAt < p.endsAt -
Requested by the policy owner: Only the policy’s owner claims against it.
-
Incident has happened: A claim is for something that has already happened.
Required by Insurer. Formally:
request.incidentAt <= now() -
Reported in time: The incident is reported within 30 days.
Required by Insurer. Formally:
now() - request.incidentAt <= 'PT720H'
Once it has been provided:
-
Claim recorded against the policy: The claim is on record, against the policy.
Required by Client. Formally:
Claim.allInstances()->exists(c | c.claimNumber = response.claimNumber and c.policy.policyNumber = request.policyNumber and c.incidentAt = request.incidentAt) -
Outcome recorded: The claim ends settled or declined, as reported.
Required by Client. Formally:
Claim.allInstances()->exists(c | c.claimNumber = response.claimNumber and c.status = response.status) -
Payout within cover: Nothing is paid beyond the sum insured.
Required by Insurer. Formally:
Policy.allInstances()->select(p | p.policyNumber = request.policyNumber)->forAll(p | response.payout <= p.sumInsured)
Exceptions
When a pre-condition does not hold, the Process claim service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy in force at the incident not met, raised whenPolicy in force at the incidentdoes not hold: Raised when 'Process claim' is requested while 'Policy in force at the incident' does not hold. -
Requested by the policy owner not met, raised whenRequested by the policy ownerdoes not hold: Raised when 'Process claim' is requested while 'Requested by the policy owner' does not hold. -
Incident has happened not met, raised whenIncident has happeneddoes not hold: Raised when 'Process claim' is requested while 'Incident has happened' does not hold. -
Reported in time not met, raised whenReported in timedoes not hold: Raised when 'Process claim' is requested while 'Reported in time' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Process claim'.
A Insurer::Claims::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy claimed against. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
description, aInsurer::Text: What happened. -
one or more
damagedItems, each aInsurer::Claims::DamagedItem: What was damaged.
Insurer::Claims::DamagedItem: One damaged part of the vehicle, as the client reports it.
A Insurer::Claims::DamagedItem has:
-
one
description, aInsurer::Text: What was damaged. -
one
estimate, aInsurer::Money: The client’s estimate of the repair.
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Process claim' yields once rendered.
A Insurer::Claims::Response has:
-
one
claimNumber, anInsurer::Identifier: The claim’s number. -
one
status, aInsurer::ClaimStatus: How it ended: settled or declined.One of
lodged,documented,documentsOverdue,settledanddeclined. -
one
payout, aInsurer::Money: What was paid.
The following must always hold for a Insurer::Claims::Response:
Responsibility allocation
The responsibility allocation diagram below shows how the Process claim process takes care of each requirement of the Process claim service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Policy in force at the incident (pre-condition) is addressed by checking it before anything else is done.
-
Requested by the policy owner (pre-condition) is addressed by checking it before anything else is done.
-
Incident has happened (pre-condition) is addressed by checking it before anything else is done.
-
Reported in time (pre-condition) is addressed by checking it before anything else is done.
-
Claim recorded against the policy (post-condition) is addressed by requesting the Record claim service from Claims.
-
Outcome recorded (post-condition) is addressed by the step
Refer to an investigator?. -
Payout within cover (post-condition) is addressed by the step
Refer to an investigator?.
To do so the process uses the following services:
-
From Claims:
-
Record claim: Records a claim against a policy, and reports the cover it is made under.
-
Update claim: Moves a claim on to a new status, recording its payout once settled.
-
Assess and settle claim: Assesses a recorded claim, pays it, and has the vehicle repaired.
-
-
From Fraud Investigation:
-
Screen claim: Scores how likely a claim is to need investigating.
-
Investigate claim: An investigator decides whether a referred claim is genuine.
-
-
From Assessment:
-
Price damaged item: Prices the repair of one damaged item.
-
Business process
Records the claim, waits for the client’s documents, screens and prices it, and then either declines it or has it assessed and settled.
The showcase. In order:
- Record claim writes the claim against the policy, and reports the cover.
- Event-triggered flows: the client's supporting documents, a message sent to this claim, race a 14-day deadline. Whichever comes first is recorded; a deployment may shorten the deadline.
- Concurrent flows: fraud screening, alongside a for-each pricing the damaged items that folds their total and stops early once it passes the vehicle's value — a write-off.
- Alternate flows: a high risk score is referred to an investigator, who may decline the claim; anything else goes straight to Assess and settle claim, a service realized by a process of its own.
The Process claim business process provides the Process claim service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Policy in force at the incidentholds. If it does not, stop and raisePolicy in force at the incident not met.Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and p.status = PolicyStatus::inForce and p.startsAt <= request.incidentAt and request.incidentAt < p.endsAt -
Check that
Requested by the policy ownerholds. If it does not, stop and raiseRequested by the policy owner not met.Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and (let c = findClientByLogin(Tuple{login = caller}) in c <> null and p.owner = c.clientNumber) -
Check that
Incident has happenedholds. If it does not, stop and raiseIncident has happened not met.Formally:
request.incidentAt <= now() -
Check that
Reported in timeholds. If it does not, stop and raiseReported in time not met.Formally:
now() - request.incidentAt <= 'PT720H' -
Request the Record claim service from Claims.
This step addresses Claim recorded against the policy.
The request is populated as follows:
-
policyNumber:
providerRequest.policyNumber = request.policyNumber -
incidentAt:
providerRequest.incidentAt = request.incidentAt -
description:
providerRequest.description = request.descriptionThe answer is kept as
recorded, oneInsurer::Claims::Response. -
If the service is provided:
-
Populate the response.
-
claimNumber:
response.claimNumber = recorded.claimNumber
-
-
Wait for whichever of the following happens first, and react to it:
-
When
Insurer::Claims::SupportingDocumentsarrives:-
Request the Update claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
status:
providerRequest.status = ClaimStatus::documented -
If it raises
Claim exists not met:the exception is ignored and the process carries on.
-
-
-
When
P14Dhas passed:-
Request the Update claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
status:
providerRequest.status = ClaimStatus::documentsOverdue -
If it raises
Claim exists not met:the exception is ignored and the process carries on.
-
-
-
-
Do the following at the same time, and carry on once all of them are done:
-
Flow 1:
-
Request the Screen claim service from Fraud Investigation.
The request is populated as follows:
-
claimedAmount:
providerRequest.claimedAmount = request.damagedItems->collect(i | i.estimate)->sum()The answer is kept as
screening, oneInsurer::Fraud Investigation::Response.
-
-
-
Flow 2:
-
For each
iteminrequest.damagedItems, one at a time, for as long asrepairTotal <= recorded.vehicleValueholds:-
Carried from one pass to the next:
-
repairTotal, starting as0, then becomingrepairTotal + priced.amount-
Request the Price damaged item service from Assessment.
The request is populated as follows:
-
-
item:
providerRequest.item = itemThe answer is kept as
priced, oneInsurer::Assessment::Response.
-
-
-
Define
writtenOff, oneInsurer::FlagasrepairTotal > recorded.vehicleValue.
-
-
-
Choose one way to continue, the first whose condition holds:
This step addresses Outcome recorded and Payout within cover.
-
If
screening.riskScore >= 70(The risk is high):-
Request the Investigate claim service from Fraud Investigation.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
riskScore:
providerRequest.riskScore = screening.riskScoreThe answer is kept as
investigation, oneInsurer::Fraud Investigation::Response.
-
-
Choose one way to continue, the first whose condition holds:
-
If
investigation.genuine(The investigator found it genuine):-
Request the Assess and settle claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
repairTotal:
providerRequest.repairTotal = repairTotal -
sumInsured:
providerRequest.sumInsured = recorded.sumInsured -
excess:
providerRequest.excess = recorded.excess -
writtenOff:
providerRequest.writtenOff = writtenOffThe answer is kept as
settlement, oneInsurer::Claims::Response. -
If the service is provided:
-
Populate the response.
-
status:
response.status = settlement.status -
payout:
response.payout = settlement.payout
-
-
-
If it raises
Claim exists not met:-
Request the Update claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
status:
providerRequest.status = ClaimStatus::declined -
If it raises
Claim exists not met:the exception is ignored and the process carries on.
-
-
Populate the response.
-
status:
response.status = ClaimStatus::declined -
payout:
response.payout = 0
-
-
-
-
-
Otherwise:
-
Request the Update claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
status:
providerRequest.status = ClaimStatus::declined -
If it raises
Claim exists not met:the exception is ignored and the process carries on.
-
-
Populate the response.
-
status:
response.status = ClaimStatus::declined -
payout:
response.payout = 0
-
-
-
-
-
Otherwise:
-
Request the Assess and settle claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
repairTotal:
providerRequest.repairTotal = repairTotal -
sumInsured:
providerRequest.sumInsured = recorded.sumInsured -
excess:
providerRequest.excess = recorded.excess -
writtenOff:
providerRequest.writtenOff = writtenOffThe answer is kept as
settlement, oneInsurer::Claims::Response. -
If the service is provided:
-
Populate the response.
-
status:
response.status = settlement.status -
payout:
response.payout = settlement.payout
-
-
-
If it raises
Claim exists not met:-
Request the Update claim service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = recorded.claimNumber -
status:
providerRequest.status = ClaimStatus::declined -
If it raises
Claim exists not met:the exception is ignored and the process carries on.
-
-
Populate the response.
-
status:
response.status = ClaimStatus::declined -
payout:
response.payout = 0
-
-
-
-
-
-
-
6.1.2. Service: Provide claims report
Claims provides the Provide claims report service.
Lists the claims made against a client’s policy within a period.
Its post-conditions are about the insurer's records — every claim in the period is listed, and only those — so the execution environment checks them against the claims it actually holds, each time the report is asked for.
Service requirements
The functional requirements diagram below shows who has an interest in the Provide claims report service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the pre-condition Requested by the policy owner and the post-conditions Every claim in the period and Only claims in the period. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-condition Policy exists.
It is provided only when:
-
Policy exists: There is a policy with that number.
Required by Insurer. Formally:
getPolicy(Tuple{policyNumber = request.policyNumber}) <> null -
Requested by the policy owner: Only the policy’s owner sees its claims.
Required by Client. Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and (let c = findClientByLogin(Tuple{login = caller}) in c <> null and p.owner = c.clientNumber)
Once it has been provided:
-
Every claim in the period: No claim against the policy in the period is left out.
Required by Client. Formally:
response.claims->size() = Claim.allInstances()->select(c | c.policy.policyNumber = request.policyNumber and c.incidentAt >= request.from and c.incidentAt <= request.to)->size() -
Only claims in the period: Every claim listed is one against the policy in the period.
Required by Client. Formally:
response.claims->forAll(s | Claim.allInstances()->select(c | c.policy.policyNumber = request.policyNumber and c.incidentAt >= request.from and c.incidentAt <= request.to)->exists(c | c.claimNumber = s.claimNumber))
Exceptions
When a pre-condition does not hold, the Provide claims report service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy exists not met, raised whenPolicy existsdoes not hold: Raised when 'Provide claims report' is requested while 'Policy exists' does not hold. -
Requested by the policy owner not met, raised whenRequested by the policy ownerdoes not hold: Raised when 'Provide claims report' is requested while 'Requested by the policy owner' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Provide claims report'.
A Insurer::Claims::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy. -
one
from, aInsurer::Moment: The start of the period. -
one
to, aInsurer::Moment: The end of the period.
The following must always hold for a Insurer::Claims::Request:
-
Period is valid:
self.from <= self.toRequired by Insurer.
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Provide claims report' yields once rendered.
A Insurer::Claims::Response has:
-
any number of
claims, each aInsurer::Claims::ClaimSummary: Every claim against the policy in the period.
Insurer::Claims::ClaimSummary: One line of a claims report.
A Insurer::Claims::ClaimSummary has:
-
one
claimNumber, anInsurer::Identifier: The claim’s number. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
status, aInsurer::ClaimStatus: Where it stands.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, if settled. -
one
version, aInsurer::Count: The version of the claim this line was read at.
Responsibility allocation
The responsibility allocation diagram below shows how the Provide claims report process takes care of each requirement of the Provide claims report service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Policy exists (pre-condition) is addressed by checking it before anything else is done.
-
Requested by the policy owner (pre-condition) is addressed by checking it before anything else is done.
-
Every claim in the period (post-condition) is addressed by requesting the Find claims service from Claims.
-
Only claims in the period (post-condition) is addressed by requesting the Find claims service from Claims.
To do so the process uses the following services:
-
From Claims:
-
Find claims: Lists the claims made against a policy within a period.
-
Business process
Finds the policy’s claims in the period and reports them.
The Provide claims report business process provides the Provide claims report service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Policy existsholds. If it does not, stop and raisePolicy exists not met.Formally:
getPolicy(Tuple{policyNumber = request.policyNumber}) <> null -
Check that
Requested by the policy ownerholds. If it does not, stop and raiseRequested by the policy owner not met.Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and (let c = findClientByLogin(Tuple{login = caller}) in c <> null and p.owner = c.clientNumber) -
Request the Find claims service from Claims.
This step addresses Every claim in the period and Only claims in the period.
The request is populated as follows:
-
policyNumber:
providerRequest.policyNumber = request.policyNumber -
from:
providerRequest.from = request.from -
to:
providerRequest.to = request.toThe answer is kept as
found, oneInsurer::Claims::Response. -
If the service is provided:
-
Populate the response.
-
claims:
response.claims = found.claims
-
-
-
6.1.3. Service: Record claim
Claims provides the Record claim service.
Records a claim against a policy, and reports the cover it is made under.
It reports the cover because a process cannot read the insurer's records itself. The cover is Underwriting's to say: it is asked of getPolicy, the policies' query service, as its pre-condition asks whether the policy was in force.
Service requirements
The functional requirements diagram below shows who has an interest in the Record claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims: The claims made against policies, and the record of each.
Claimsrequires the post-conditions Claim recorded, Claim number is new and Cover reported. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the pre-condition Policy in force at the incident.
It is provided only when:
-
Policy in force at the incident: The policy gave cover when the incident happened.
Required by Insurer. Formally:
let p = getPolicy(Tuple{policyNumber = request.policyNumber}) in p <> null and p.status = PolicyStatus::inForce and p.startsAt <= request.incidentAt and request.incidentAt < p.endsAt
Once it has been provided:
-
Claim recorded: A lodged claim against the policy is on record, in the client’s words, as of when it was recorded.
Required by Claims. Formally:
Claim.allInstances()->exists(c | c.claimNumber = response.claimNumber and c.policy.policyNumber = request.policyNumber and c.incidentAt = request.incidentAt and c.description = request.description and c.lodgedAt = now() and c.status = ClaimStatus::lodged) -
Claim number is new: The number issued belonged to no claim before.
Required by Claims. Formally:
Claim.allInstances@pre()->forAll(c | c.claimNumber <> response.claimNumber) -
Cover reported: The response states the policy’s cover, as Underwriting gives it.
Required by Claims. Formally:
response.sumInsured = getPolicy(Tuple{policyNumber = request.policyNumber}).sumInsured and response.excess = getPolicy(Tuple{policyNumber = request.policyNumber}).excess and response.vehicleValue = getPolicy(Tuple{policyNumber = request.policyNumber}).vehicle.value
Exceptions
When a pre-condition does not hold, the Record claim service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy in force at the incident not met, raised whenPolicy in force at the incidentdoes not hold: Raised when 'Record claim' is requested while 'Policy in force at the incident' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Record claim'.
A Insurer::Claims::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy claimed against. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
description, aInsurer::Text: What happened.
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Record claim' yields once rendered.
A Insurer::Claims::Response has:
-
one
claimNumber, anInsurer::Identifier: The number issued. -
one
sumInsured, aInsurer::Money: The policy’s sum insured. -
one
excess, aInsurer::Money: The policy’s excess. -
one
vehicleValue, aInsurer::Money: The insured vehicle’s value.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it creates a Claim. It is thus provided by making that one change.
6.1.4. Service: Update claim
Claims provides the Update claim service.
Moves a claim on to a new status, recording its payout once settled.
Service requirements
The functional requirements diagram below shows who has an interest in the Update claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims: The claims made against policies, and the record of each.
Claimsrequires the pre-condition Claim exists and the post-condition Status recorded.
It is provided only when:
-
Claim exists: There is a claim with that number.
Required by Claims. Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber)
Once it has been provided:
-
Status recorded: The claim has the status asked for, and the payout given with it.
Required by Claims. Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber and c.status = request.status and c.payout = request.payout)
Exceptions
When a pre-condition does not hold, the Update claim service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Claim exists not met, raised whenClaim existsdoes not hold: Raised when 'Update claim' is requested while 'Claim exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Update claim'.
A Insurer::Claims::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
status, aInsurer::ClaimStatus: Its new status.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, when settling.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it updates a Claim. It is thus provided by making that one change.
6.1.5. Service: Note claim review
Claims provides the Note claim review service.
Records a claims manager’s note on a claim, as the claim stood when they reviewed it.
Decided on a version. The manager reviews the claim as it was found stale; the claim may move on while they look — its documents arrive, it is settled. A note about a claim that no longer stands would mislead, so it is refused unless the claim is still at the version reviewed (docs/design/domainOwnedEntityData.md P5).
Service requirements
The functional requirements diagram below shows who has an interest in the Note claim review service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims Management: The claims managers, who review what has stalled.
Claims Managementrequires the pre-condition Claim unchanged since review and the post-condition Note recorded.
It is provided only when:
-
Claim unchanged since review: The claim is still as the manager reviewed it.
Required by Claims Management. Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber and c.version = request.claimVersion)
Once it has been provided:
-
Note recorded: The claim carries the manager’s note.
Required by Claims Management. Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber and c.reviewNote = request.note)
Exceptions
When a pre-condition does not hold, the Note claim review service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Claim unchanged since review not met, raised whenClaim unchanged since reviewdoes not hold: Raised when 'Note claim review' is requested while 'Claim unchanged since review' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Note claim review'.
A Insurer::Claims::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
claimVersion, aInsurer::Count: The version of the claim the manager reviewed. -
one
note, aInsurer::Text: What the manager made of it.
Business process
No business process is needed. The service’s post-conditions say exactly what it records, i.e. it updates a Claim. It is thus provided by making that one change.
6.1.6. Service: Find claims
Claims provides the Find claims service. It is a query, i.e. it answers from information already held and changes nothing.
Lists the claims made against a policy within a period.
Service requirements
The functional requirements diagram below shows who has an interest in the Find claims service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims: The claims made against policies, and the record of each.
Claimsrequires the pre-condition Policy exists and the post-condition Claims listed.
It is provided only when:
-
Policy exists: There is a policy with that number.
Required by Claims. Formally:
getPolicy(Tuple{policyNumber = request.policyNumber}) <> null
Once it has been provided:
-
Claims listed: Exactly the claims against the policy in the period, oldest incident first.
Required by Claims. Formally:
response.claims = Claim.allInstances()->select(c | c.policy.policyNumber = request.policyNumber and c.incidentAt >= request.from and c.incidentAt <= request.to)->sortedBy(c | c.incidentAt)->collect(c | Tuple{claimNumber = c.claimNumber, incidentAt = c.incidentAt, status = c.status, payout = c.payout, version = c.version})
Exceptions
When a pre-condition does not hold, the Find claims service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Policy exists not met, raised whenPolicy existsdoes not hold: Raised when 'Find claims' is requested while 'Policy exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Find claims'.
A Insurer::Claims::Request has:
-
one
policyNumber, anInsurer::Identifier: The policy. -
one
from, aInsurer::Moment: The start of the period. -
one
to, aInsurer::Moment: The end of the period.
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Find claims' yields once rendered.
A Insurer::Claims::Response has:
-
any number of
claims, each aInsurer::Claims::ClaimSummary: Every claim in the period.
Insurer::Claims::ClaimSummary: One line of a claims report.
A Insurer::Claims::ClaimSummary has:
-
one
claimNumber, anInsurer::Identifier: The claim’s number. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
status, aInsurer::ClaimStatus: Where it stands.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, if settled. -
one
version, aInsurer::Count: The version of the claim this line was read at.
6.1.7. Service: Find stale claims
Claims provides the Find stale claims service.
Lists the claims that have stayed open too long.
Service requirements
The functional requirements diagram below shows who has an interest in the Find stale claims service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims Management: The claims managers, who review what has stalled.
Claims Managementrequires the post-condition Every stale claim listed.
Once it has been provided:
-
Every stale claim listed: Exactly the claims still open, and open for longer than asked.
Required by Claims Management. Formally:
response.claims = Claim.allInstances()->select(c | c.status <> ClaimStatus::settled and c.status <> ClaimStatus::declined and now() - c.lodgedAt > request.openFor)->collect(c | Tuple{claimNumber = c.claimNumber, incidentAt = c.incidentAt, status = c.status, payout = c.payout, version = c.version})
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Find stale claims'.
A Insurer::Claims::Request has:
-
one
openFor, aInsurer::Period: How long a claim may stay open.
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Find stale claims' yields once rendered.
A Insurer::Claims::Response has:
-
any number of
claims, each aInsurer::Claims::ClaimSummary: Every claim open longer than that.
Insurer::Claims::ClaimSummary: One line of a claims report.
A Insurer::Claims::ClaimSummary has:
-
one
claimNumber, anInsurer::Identifier: The claim’s number. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
status, aInsurer::ClaimStatus: Where it stands.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, if settled. -
one
version, aInsurer::Count: The version of the claim this line was read at.
6.1.8. Service: Assess and settle claim
Claims provides the Assess and settle claim service.
Assesses a recorded claim, pays it, and has the vehicle repaired.
Internal — published to nobody — and realized by its own process, which an execution environment runs as a child of the claim asking for it.
Service requirements
The functional requirements diagram below shows who has an interest in the Assess and settle claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims: The claims made against policies, and the record of each.
Claimsrequires the pre-condition Claim exists and the post-condition Claim settled. -
Client: A client is a party to whom the insurer’s services are offered.
Clientrequires the post-condition Claim settled. -
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the post-condition Payout within cover.
It is provided only when:
-
Claim exists: There is a claim with that number.
Required by Claims. Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber)
Once it has been provided:
-
Claim settled: The claim is settled, with the payout recorded.
-
Payout within cover: Nothing is paid beyond the sum insured.
Required by Insurer. Formally:
response.payout <= request.sumInsured
Exceptions
When a pre-condition does not hold, the Assess and settle claim service is not provided. Instead, it raises the exception belonging to that pre-condition, which the requester may handle. These are the ways in which the service can fail:
-
Claim exists not met, raised whenClaim existsdoes not hold: Raised when 'Assess and settle claim' is requested while 'Claim exists' does not hold.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims::Request.
What is supplied when requesting 'Assess and settle claim'.
A Insurer::Claims::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
repairTotal, aInsurer::Money: What the damaged items were priced at. -
one
sumInsured, aInsurer::Money: The policy’s sum insured. -
one
excess, aInsurer::Money: The policy’s excess. -
one
writtenOff, aInsurer::Flag: Whether the repair would cost more than the vehicle is worth.
The following must always hold for a Insurer::Claims::Request:
-
Excess not negative:
self.excess >= 0 -
Sum insured not negative:
self.sumInsured >= 0
Response data structure
The information the service returns once provided is a Insurer::Claims::Response.
What 'Assess and settle claim' yields once rendered.
A Insurer::Claims::Response has:
-
one
status, aInsurer::ClaimStatus: Settled.One of
lodged,documented,documentsOverdue,settledanddeclined. -
one
payout, aInsurer::Money: What was paid.
The following must always hold for a Insurer::Claims::Response:
-
Payout not negative:
self.payout >= 0Required by Insurer.
Responsibility allocation
The responsibility allocation diagram below shows how the Assess and settle claim process takes care of each requirement of the Assess and settle claim service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Claim exists (pre-condition) is addressed by checking it before anything else is done.
-
Claim settled (post-condition) is addressed by requesting the Update claim service from Claims.
-
Payout within cover (post-condition) is addressed by requesting the Compute payout service from Payments.
To do so the process uses the following services:
-
From Assessment:
-
Assess claim: An assessor assesses the loss, or says what more is needed.
-
Provide further information: The client answers an assessor’s question about their claim.
-
-
From Payments:
-
Compute payout: Works out what a settled claim pays.
-
Pay claim: Pays a settled claim.
-
-
From Claims:
-
Update claim: Moves a claim on to a new status, recording its payout once settled.
-
-
From Repair Network:
-
Offer repair: A panel repairer says whether it can take on repairing the insured vehicle.
-
Repair vehicle: A panel repairer repairs the insured vehicle.
-
Business process
An assessor assesses the loss — asking the client for more until the assessment is complete — then the payout is computed, recorded and paid, and the vehicle repaired unless written off.
While, with carried variables. The loop carries whether the assessment is complete and the amount assessed so far; each time round the assessor answers, and when they need more the client is asked, as a task of their own. At most 5 rounds.
The Assess and settle claim business process provides the Assess and settle claim service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Check that
Claim existsholds. If it does not, stop and raiseClaim exists not met.Formally:
Claim.allInstances()->exists(c | c.claimNumber = request.claimNumber) -
While
not completeholds, repeat (at most 5 times):-
Carried from one pass to the next:
-
complete, starting asfalse, then becomingassessment.complete -
assessed, starting as0, then becomingassessment.assessedAmount-
Request the Assess claim service from Assessment.
The request is populated as follows:
-
-
claimNumber:
providerRequest.claimNumber = request.claimNumber -
repairTotal:
providerRequest.repairTotal = request.repairTotalThe answer is kept as
assessment, oneInsurer::Assessment::Response.It needs no undoing: An assessment is advice: nothing acts on it until the claim is settled, so a claim refused before then leaves nothing of it to undo. .. Choose one way to continue, the first whose condition holds:
-
If
not assessment.complete(The assessment is not complete):-
Request the Provide further information service from Assessment.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumber -
query:
providerRequest.query = assessment.queryIt needs no undoing: The client’s answer becomes part of the claim’s record whether or not the claim is settled; there is nothing to take back.
-
-
-
Otherwise:
Nothing is done.
-
-
-
Request the Compute payout service from Payments.
This step addresses Payout within cover.
The request is populated as follows:
-
assessedAmount:
providerRequest.assessedAmount = assessed -
sumInsured:
providerRequest.sumInsured = request.sumInsured -
excess:
providerRequest.excess = request.excessThe answer is kept as
computed, oneInsurer::Payments::Response.
-
-
Request the Update claim service from Claims.
This step addresses Claim settled.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumber -
status:
providerRequest.status = ClaimStatus::settled -
payout:
providerRequest.payout = computed.payout
-
-
Request the Pay claim service from Payments.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumber -
amount:
providerRequest.amount = computed.payout
-
-
Choose one way to continue, the first whose condition holds:
-
If
not request.writtenOff(The vehicle is repairable):-
Request the Offer repair service from one or more providers, one after another.
Further providers are asked only while
not offer.acceptedholds.The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumberThe answer is kept as
offer, oneInsurer::Repair Network::Response.It needs no undoing: An offer binds nobody: nothing is booked until the repair is requested.
-
-
Request the Repair vehicle service from Repair Network.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumber
-
-
-
Otherwise:
Nothing is done.
-
-
Populate the response.
-
payout:
response.payout = computed.payout
-
6.2. Entities
An entity is information which Claims keeps over time. It is a record which outlives any one request, and which its services create, change and read. Claims maintains the following entities:
-
Claim: A claim made against a policy.
The entity map below shows each entity together with its facets, i.e. the data structures whose fields make up what it stores.
6.2.1. Entity: Claim
A claim made against a policy.
Identified by its claim number, and made against a policy: ClaimRecord.policy is an association to the policy's record. So a claim reaches its owner through two associations — c.policy.owner.login.
How it is populated
Claim is populated as follows:
-
The Record claim service creates a
Claim, identified byclaimNumber. -
The Update claim service updates a
Claim, identified byclaimNumber. -
The Note claim review service updates a
Claim, identified byclaimNumber. -
The Assess and settle claim service updates a
Claim, identified byclaimNumber, through the Assess and settle claim process. -
The
ClaimRecorddata structure describes part of what it holds: The insurer’s record of one claim.
Entity structure
The diagram below shows the Claim entity fully expanded, i.e. everything it holds, gathered from all of its facets, and the information it is related to. The same structure is described in words after it.
A Claim has:
-
one
claimNumber, anInsurer::Identifier, which identifies it: The claim’s number. -
one
lodgedAt, aInsurer::Moment: When the claim was recorded. -
one
status, aInsurer::ClaimStatus: Where the claim stands.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, once settled. -
optionally one
reviewNote, aInsurer::Text: A claims manager’s note on the claim, as they reviewed it. -
one
version, aInsurer::Count, the version of the instance read, which an update is decided on: Which version of the claim was read: what a change is decided on. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
description, aInsurer::Text: What happened, in the client’s words.
A Claim is associated with:
-
one
policy, aInsurer::Underwriting::PolicyRecord: The policy claimed against.
Insurer::Underwriting::PolicyRecord: The insurer’s record of one policy.
A Insurer::Underwriting::PolicyRecord has:
-
one
policyNumber, anInsurer::Identifier, which identifies it: The policy’s number. -
one
vehicle, aInsurer::Underwriting::Vehicle: The vehicle covered. -
one
premium, aInsurer::Money: What the cover costs a year. -
one
excess, aInsurer::Money: What the client bears of each claim. -
one
sumInsured, aInsurer::Money: The most a claim pays. -
one
startsAt, aInsurer::Moment: When cover starts. -
one
endsAt, aInsurer::Moment: When cover ends. -
one
status, aInsurer::PolicyStatus: Whether it gives cover.One of
inForce,lapsedandcancelled. -
up to 4
namedDrivers, each aInsurer::Underwriting::NamedDriver: The drivers the policy names, at most four, told apart by their licence numbers.
A Insurer::Underwriting::PolicyRecord is associated with:
-
one
owner, aInsurer::Client Register::ClientRecord: The client who owns the policy.
The following must always hold for a Insurer::Underwriting::PolicyRecord:
-
Cover is a year:
self.endsAt = self.startsAt + 'PT8760H' -
Excess within the sum insured:
self.excess < self.sumInsured -
Policy number format:
self.policyNumber.matches('PO-[0-9]{4,}') -
Excess not negative:
self.excess >= 0
Insurer::Underwriting::Vehicle: The vehicle a policy covers.
A Insurer::Underwriting::Vehicle has:
-
one
registration, aInsurer::Text: The vehicle’s registration number. -
one
make, aInsurer::Text: Its make. -
one
model, aInsurer::Text: Its model. -
one
year, aInsurer::Count: Its model year. -
one
value, aInsurer::Money: What it is worth — and what it is insured for.
Insurer::Underwriting::NamedDriver: A person a policy names as a driver of its vehicle.
A Insurer::Underwriting::NamedDriver has:
-
one
licenceNumber, aInsurer::Text: The number of the driver’s licence, which tells a policy’s drivers apart. -
one
name, aInsurer::Text: The driver’s name, as the licence gives it. -
one
licensedSince, aInsurer::Moment: When the driver was first licensed, which underwriting weighs.
Insurer::Client Register::ClientRecord: The insurer’s record of one client.
A Insurer::Client Register::ClientRecord has:
-
one
clientNumber, anInsurer::Identifier, which identifies it: The client’s number. -
one
name, aInsurer::Text: The client’s name. -
one
idNumber, aInsurer::Text: The number on the identity document the client onboarded with. -
one
email, aInsurer::Text: Where the client is written to. -
one
login, aInsurer::Text, unique: The login identity the client uses — what `caller` is compared with.
The following must always hold for a Insurer::Client Register::ClientRecord:
-
Client number format:
self.clientNumber.matches('CL-[0-9]{4,}')
Data dictionary
This section lists what Claim stores, attribute by attribute. An attribute gathers every field of that name in the entity’s facets. Where it gathers more than one, each is listed, since fields of one name are stored as one attribute whatever each was meant to hold. The services listed write or read it as their specifications say.
| Attribute | Type | Role | Multiplicity | Unique | Personal data | Merged from | Written by | Read by |
|---|---|---|---|---|---|---|---|---|
|
Insurer::Identifier |
identifies |
|
yes |
— |
— |
||
|
Insurer::Underwriting::PolicyRecord |
states |
|
no |
— |
— |
||
|
Insurer::Moment |
states |
|
no |
— |
— |
||
|
Insurer::ClaimStatus |
states |
|
no |
— |
— |
||
|
Insurer::Money |
states |
|
no |
— |
— |
||
|
Insurer::Text |
states |
|
no |
— |
— |
— |
|
|
Insurer::Moment |
states |
|
no |
— |
— |
||
|
Insurer::Text |
states |
|
no |
personal |
— |
— |
6.3. Dependencies
To provide its services, Claims relies on services provided by other responsibility domains. The dependency diagram below shows which.
Claims uses:
-
from Fraud Investigation: Screening claims, and investigating the risky ones.
-
the Screen claim service: Scores how likely a claim is to need investigating.
-
the Investigate claim service: An investigator decides whether a referred claim is genuine.
-
-
from Assessment: Pricing damage and assessing a claim’s loss.
-
the Price damaged item service: Prices the repair of one damaged item.
-
the Assess claim service: An assessor assesses the loss, or says what more is needed.
-
the Provide further information service: The client answers an assessor’s question about their claim.
-
-
from Payments: Computing and paying what a settled claim pays.
-
the Compute payout service: Works out what a settled claim pays.
-
the Pay claim service: Pays a settled claim.
-
-
from Repair Network: The panel repairers who repair insured vehicles.
-
the Offer repair service: A panel repairer says whether it can take on repairing the insured vehicle.
-
the Repair vehicle service: A panel repairer repairs the insured vehicle.
-
7. Insurer / Fraud Investigation
This part specifies the Fraud Investigation responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
Screening claims, and investigating the risky ones.
Screening is a rule; investigating is a person's judgement.
The scope diagram below shows what Fraud Investigation is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
7.1. Services
Fraud Investigation is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Screen claim: Scores how likely a claim is to need investigating.
-
Investigate claim: An investigator decides whether a referred claim is genuine.
7.1.1. Service: Screen claim
Fraud Investigation provides the Screen claim service. It is a query, i.e. it answers from information already held and changes nothing.
Scores how likely a claim is to need investigating.
Determined outright by its post-condition, so specified in a demonstration — and swappable for a person, or a scoring engine, by configuration alone: the process asking for it does not change.
Service requirements
The functional requirements diagram below shows who has an interest in the Screen claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Fraud Investigation: Screening claims, and investigating the risky ones.
Fraud Investigationrequires the post-condition Risk scored.
Once it has been provided:
-
Risk scored: A claim above 150000 scores 80, any other 20.
Required by Fraud Investigation. Formally:
response.riskScore = if request.claimedAmount > 150000 then 80 else 20 endif
Request data structure
The information a requester provides when asking for the service is a Insurer::Fraud Investigation::Request.
What is supplied when requesting 'Screen claim'.
A Insurer::Fraud Investigation::Request has:
-
one
claimedAmount, aInsurer::Money: What the client estimates the damage at.
Response data structure
The information the service returns once provided is a Insurer::Fraud Investigation::Response.
What 'Screen claim' yields once rendered.
A Insurer::Fraud Investigation::Response has:
-
one
riskScore, aInsurer::Count: From 0 to 100; the higher, the likelier a referral.
7.1.2. Service: Investigate claim
Fraud Investigation provides the Investigate claim service.
An investigator decides whether a referred claim is genuine.
A person's service: a task in the investigators' work list.
Service requirements
The functional requirements diagram below shows who has an interest in the Investigate claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Fraud Investigation::Request.
What is supplied when requesting 'Investigate claim'.
A Insurer::Fraud Investigation::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
riskScore, aInsurer::Count: Why it was referred.
Response data structure
The information the service returns once provided is a Insurer::Fraud Investigation::Response.
What 'Investigate claim' yields once rendered.
A Insurer::Fraud Investigation::Response has:
-
one
genuine, aInsurer::Flag: Whether the claim stands. -
one
finding, aInsurer::Text: What the investigator found.
The following must always hold for a Insurer::Fraud Investigation::Response:
8. Insurer / Assessment
This part specifies the Assessment responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
Pricing damage and assessing a claim’s loss.
Pricing is a tariff; assessing is a person's judgement.
The scope diagram below shows what Assessment is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
8.1. Services
Assessment is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Price damaged item: Prices the repair of one damaged item.
-
Assess claim: An assessor assesses the loss, or says what more is needed.
-
Provide further information: The client answers an assessor’s question about their claim.
8.1.1. Service: Price damaged item
Assessment provides the Price damaged item service. It is a query, i.e. it answers from information already held and changes nothing.
Prices the repair of one damaged item.
Service requirements
The functional requirements diagram below shows who has an interest in the Price damaged item service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Claims: The claims made against policies, and the record of each.
Claimsrequires the post-condition Item priced.
Once it has been provided:
-
Item priced: The client’s estimate plus the labour rate.
Required by Claims. Formally:
response.amount = request.item.estimate + 1500
Request data structure
The information a requester provides when asking for the service is a Insurer::Assessment::Request.
What is supplied when requesting 'Price damaged item'.
A Insurer::Assessment::Request has:
-
one
item, aInsurer::Claims::DamagedItem: The item.
Insurer::Claims::DamagedItem: One damaged part of the vehicle, as the client reports it.
A Insurer::Claims::DamagedItem has:
-
one
description, aInsurer::Text: What was damaged. -
one
estimate, aInsurer::Money: The client’s estimate of the repair.
Response data structure
The information the service returns once provided is a Insurer::Assessment::Response.
What 'Price damaged item' yields once rendered.
A Insurer::Assessment::Response has:
-
one
amount, aInsurer::Money: What its repair will cost.
8.1.2. Service: Assess claim
Assessment provides the Assess claim service.
An assessor assesses the loss, or says what more is needed.
A person's service: a task in the assessors' work list.
Service requirements
The functional requirements diagram below shows who has an interest in the Assess claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Assessment::Request.
What is supplied when requesting 'Assess claim'.
A Insurer::Assessment::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
repairTotal, aInsurer::Money: What the damaged items were priced at.
Response data structure
The information the service returns once provided is a Insurer::Assessment::Response.
What 'Assess claim' yields once rendered.
A Insurer::Assessment::Response has:
-
one
complete, aInsurer::Flag: Whether the assessment is done. -
one
assessedAmount, aInsurer::Money: The loss assessed. -
optionally one
query, aInsurer::Text: What more the assessor needs, when not complete.
The following must always hold for a Insurer::Assessment::Response:
8.1.3. Service: Provide further information
Assessment provides the Provide further information service.
The client answers an assessor’s question about their claim.
A task for the client, in the same portal the insurer's staff use.
Service requirements
The functional requirements diagram below shows who has an interest in the Provide further information service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Assessment::Request.
What is supplied when requesting 'Provide further information'.
A Insurer::Assessment::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
query, aInsurer::Text: What the assessor needs.
Response data structure
The information the service returns once provided is a Insurer::Assessment::Response.
What 'Provide further information' yields once rendered.
A Insurer::Assessment::Response has:
-
one
information, aInsurer::Text: The client’s answer.
The following must always hold for a Insurer::Assessment::Response:
-
Answered:
self.information.size() > 0Required by Assessment.
9. Insurer / Repair Network
This part specifies the Repair Network responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
The panel repairers who repair insured vehicles.
The scope diagram below shows what Repair Network is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
9.1. Services
Repair Network is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Offer repair: A panel repairer says whether it can take on repairing the insured vehicle.
-
Repair vehicle: A panel repairer repairs the insured vehicle.
9.1.1. Service: Offer repair
Repair Network provides the Offer repair service.
A panel repairer says whether it can take on repairing the insured vehicle.
Asked of the panel repairers in turn — a sequential multi-instance request — until one accepts. Each repairer is a provider of its own.
Service requirements
The functional requirements diagram below shows who has an interest in the Offer repair service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Repair Network::Request.
What is supplied when requesting 'Offer repair'.
A Insurer::Repair Network::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim the repair is for.
Response data structure
The information the service returns once provided is a Insurer::Repair Network::Response.
What 'Offer repair' yields once rendered.
A Insurer::Repair Network::Response has:
-
one
accepted, aInsurer::Flag: Whether the repairer takes the repair on.
The following must always hold for a Insurer::Repair Network::Response:
-
Answer given:
self.accepted <> nullRequired by Claims.
9.1.2. Service: Repair vehicle
Repair Network provides the Repair vehicle service.
A panel repairer repairs the insured vehicle.
A person's service: a task in the repairers' work list.
Service requirements
The functional requirements diagram below shows who has an interest in the Repair vehicle service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Repair Network::Request.
What is supplied when requesting 'Repair vehicle'.
A Insurer::Repair Network::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim the repair is for.
Response data structure
The information the service returns once provided is a Insurer::Repair Network::Response.
What 'Repair vehicle' yields once rendered.
A Insurer::Repair Network::Response has:
-
one
completedAt, aInsurer::Moment: When the repair was done.
The following must always hold for a Insurer::Repair Network::Response:
10. Insurer / Payments
This part specifies the Payments responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
Computing and paying what a settled claim pays.
Designs its own service in the shared model: Pay claim, which Claims requests, is realized by Payments' own process — an officer authorises a large payment, and the bank pays.
The scope diagram below shows what Payments is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
10.1. Services
Payments is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Compute payout: Works out what a settled claim pays.
-
Pay claim: Pays a settled claim.
-
Authorise payment: A payments officer authorises a payment above the authorisation limit.
10.1.1. Service: Compute payout
Payments provides the Compute payout service. It is a query, i.e. it answers from information already held and changes nothing.
Works out what a settled claim pays.
The loss up to the sum insured, less the excess, and never below nothing — a specified service: no code computes it, the post-condition does.
Service requirements
The functional requirements diagram below shows who has an interest in the Compute payout service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
Once it has been provided:
-
Payout computed: The capped loss less the excess, never negative.
Request data structure
The information a requester provides when asking for the service is a Insurer::Payments::Request.
What is supplied when requesting 'Compute payout'.
A Insurer::Payments::Request has:
-
one
assessedAmount, aInsurer::Money: The loss assessed. -
one
sumInsured, aInsurer::Money: The most the policy pays. -
one
excess, aInsurer::Money: What the client bears.
The following must always hold for a Insurer::Payments::Request:
-
Excess not negative:
self.excess >= 0 -
Sum insured not negative:
self.sumInsured >= 0
Response data structure
The information the service returns once provided is a Insurer::Payments::Response.
What 'Compute payout' yields once rendered.
A Insurer::Payments::Response has:
-
one
payout, aInsurer::Money: What is paid.
10.1.2. Service: Pay claim
Payments provides the Pay claim service.
Pays a settled claim.
Requested by Claims, and designed by Payments, in its own part of the model: Payments realizes it by a process of its own. Assess and settle claim relies only on this contract, so Payments may change that process — or hand the service to a payments provider — without Claims noticing.
Service requirements
The functional requirements diagram below shows who has an interest in the Pay claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Its stakeholders, and what each requires of it, are:
-
Insurer: The motor insurer: its shared vocabulary and the departments that answer for its services.
Insurerrequires the post-condition Large payment authorised.
Once it has been provided:
-
Large payment authorised: A payment above 200000 names the payments officer who authorised it.
Required by Insurer. Formally:
request.amount <= 200000 or response.authorisedBy <> null
Request data structure
The information a requester provides when asking for the service is a Insurer::Payments::Request.
What is supplied when requesting 'Pay claim'.
A Insurer::Payments::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim. -
one
amount, aInsurer::Money: What to pay.
Response data structure
The information the service returns once provided is a Insurer::Payments::Response.
What 'Pay claim' yields once rendered.
A Insurer::Payments::Response has:
-
one
paymentReference, aInsurer::Text: The payment’s reference. -
optionally one
authorisedBy, aInsurer::Text: Who authorised the payment, when it was above the authorisation limit.
The following must always hold for a Insurer::Payments::Response:
-
Payment referenced:
self.paymentReference.size() > 0Required by Claims.
Responsibility allocation
The responsibility allocation diagram below shows how the Pay claim process takes care of each requirement of the Pay claim service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
Requirement by requirement:
-
Large payment authorised (post-condition) is addressed by the step
Above the authorisation limit?.
To do so the process uses the following services:
-
From Payments:
-
Authorise payment: A payments officer authorises a payment above the authorisation limit.
-
-
From Bank:
-
Make payment: The insurer’s bank pays an amount to the client.
-
Business process
Has a payments officer authorise a payment above the limit, then has the bank pay it.
Another department's design, in the shared model. Claims requests Pay claim and knows only its contract; this process is Payments', and so is every decision in it. Above the authorisation limit a payments officer authorises the payment first — the four-eyes control the insurer requires — and either way the payment itself is the bank's: an external provider, held to Make payment's contract.
The Pay claim business process provides the Pay claim service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Choose one way to continue, the first whose condition holds:
This step addresses Large payment authorised.
-
If
request.amount > 200000(The payment is above the limit):-
Request the Authorise payment service from Payments.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = request.claimNumber -
amount:
providerRequest.amount = request.amountThe answer is kept as
authorisation, oneInsurer::Payments::Response.
-
-
Request the Make payment service from Bank.
The request is populated as follows:
-
reference:
providerRequest.reference = request.claimNumber -
amount:
providerRequest.amount = request.amountThe answer is kept as
payment, oneBank::Response.
-
-
Populate the response.
-
paymentReference:
response.paymentReference = payment.bankReference -
authorisedBy:
response.authorisedBy = authorisation.authorisedBy
-
-
-
Otherwise:
-
Request the Make payment service from Bank.
The request is populated as follows:
-
reference:
providerRequest.reference = request.claimNumber -
amount:
providerRequest.amount = request.amountThe answer is kept as
payment, oneBank::Response.
-
-
Populate the response.
-
paymentReference:
response.paymentReference = payment.bankReference
-
-
-
10.1.3. Service: Authorise payment
Payments provides the Authorise payment service.
A payments officer authorises a payment above the authorisation limit.
A person's service: a task in the payments officers' work list. Withholding authorisation is not modelled: Pay claim states no ground for refusing, and adding one would oblige every process requesting it to say what then happens.
Service requirements
The functional requirements diagram below shows who has an interest in the Authorise payment service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Payments::Request.
What is supplied when requesting 'Authorise payment'.
A Insurer::Payments::Request has:
-
one
claimNumber, anInsurer::Identifier: The claim being paid. -
one
amount, aInsurer::Money: What is to be paid.
Response data structure
The information the service returns once provided is a Insurer::Payments::Response.
What 'Authorise payment' yields once rendered.
A Insurer::Payments::Response has:
-
one
authorisedBy, aInsurer::Text: The officer who authorised it.
The following must always hold for a Insurer::Payments::Response:
-
Authoriser named:
self.authorisedBy.size() > 0Required by Payments.
10.2. Dependencies
To provide its services, Payments relies on services provided by other responsibility domains. The dependency diagram below shows which.
Payments uses:
-
from Bank: The insurer’s bank, an external party that makes its payments.
-
the Make payment service: The insurer’s bank pays an amount to the client.
-
11. Insurer / Claims Management
This part specifies the Claims Management responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
The claims managers, who review what has stalled.
Its morning escalation runs on the calendar's initiative; the reviews are people.
The scope diagram below shows what Claims Management is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
11.1. Services
Claims Management is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Escalate stale claims: Every morning, puts each claim open for too long before a claims manager.
-
Review stale claim: A claims manager reviews a claim that has stayed open too long.
11.1.1. Service: Escalate stale claims
Claims Management provides the Escalate stale claims service.
Every morning, puts each claim open for too long before a claims manager.
Published to nobody: it runs on the calendar's initiative, as the environment's schedule caller, not because anyone asked.
Service requirements
The functional requirements diagram below shows who has an interest in the Escalate stale claims service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims Management::Request.
What is supplied when requesting 'Escalate stale claims'.
A Insurer::Claims Management::Request carries no information of its own.
Response data structure
The information the service returns once provided is a Insurer::Claims Management::Response.
What 'Escalate stale claims' yields once rendered.
A Insurer::Claims Management::Response has:
-
one
escalated, aInsurer::Count: How many claims were escalated.
The following must always hold for a Insurer::Claims Management::Response:
-
Escalations counted:
self.escalated >= 0Required by Claims Management.
Responsibility allocation
The responsibility allocation diagram below shows how the Escalate stale claims process takes care of each requirement of the Escalate stale claims service. It shows which of its steps addresses each pre- and post-condition, and which services it uses from other responsibility domains to do so.
To do so the process uses the following services:
-
From Claims:
-
Find stale claims: Lists the claims that have stayed open too long.
-
Note claim review: Records a claims manager’s note on a claim, as the claim stood when they reviewed it.
-
-
From Claims Management:
-
Review stale claim: A claims manager reviews a claim that has stayed open too long.
-
Business process
Finds the claims open too long and puts each before a claims manager at once.
The Escalate stale claims business process provides the Escalate stale claims service. The diagram below shows its flow. The numbered steps after it describe the same flow in words, with each choice, loop and parallel flow holding its own steps beneath it.
Step by step:
-
Request the Find stale claims service from Claims.
The request is populated as follows:
-
openFor:
providerRequest.openFor = 'PT336H'The answer is kept as
stale, oneInsurer::Claims::Response.
-
-
For each
claiminstale.claims, all at once:-
Request the Review stale claim service from Claims Management.
The request is populated as follows:
-
claim:
providerRequest.claim = claimThe answer is kept as
reviewed, oneInsurer::Claims Management::Response. -
If the service is provided:
-
Request the Note claim review service from Claims.
The request is populated as follows:
-
claimNumber:
providerRequest.claimNumber = claim.claimNumber -
claimVersion:
providerRequest.claimVersion = claim.version -
note:
providerRequest.note = reviewed.action -
If it raises
Claim unchanged since review not met:the exception is ignored and the process carries on.
-
-
-
-
-
Populate the response.
-
escalated:
response.escalated = stale.claims->size()
-
11.1.2. Service: Review stale claim
Claims Management provides the Review stale claim service.
A claims manager reviews a claim that has stayed open too long.
A person's service: a task in the claims managers' work list.
Service requirements
The functional requirements diagram below shows who has an interest in the Review stale claim service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Insurer::Claims Management::Request.
What is supplied when requesting 'Review stale claim'.
A Insurer::Claims Management::Request has:
-
one
claim, aInsurer::Claims::ClaimSummary: The claim.
Insurer::Claims::ClaimSummary: One line of a claims report.
A Insurer::Claims::ClaimSummary has:
-
one
claimNumber, anInsurer::Identifier: The claim’s number. -
one
incidentAt, aInsurer::Moment: When the incident happened. -
one
status, aInsurer::ClaimStatus: Where it stands.One of
lodged,documented,documentsOverdue,settledanddeclined. -
optionally one
payout, aInsurer::Money: What was paid, if settled. -
one
version, aInsurer::Count: The version of the claim this line was read at.
Response data structure
The information the service returns once provided is a Insurer::Claims Management::Response.
What 'Review stale claim' yields once rendered.
A Insurer::Claims Management::Response has:
-
one
action, aInsurer::Text: What the manager did about it.
The following must always hold for a Insurer::Claims Management::Response:
-
Action stated:
self.action.size() > 0Required by Claims Management.
11.2. Dependencies
To provide its services, Claims Management relies on services provided by other responsibility domains. The dependency diagram below shows which.
Claims Management uses:
-
from Claims: The claims made against policies, and the record of each.
-
the Find stale claims service: Lists the claims that have stayed open too long.
-
the Note claim review service: Records a claims manager’s note on a claim, as the claim stood when they reviewed it.
-
12. Bank
This part specifies the Bank responsibility domain. A responsibility domain is an area of responsibility, e.g. a business unit, a role or a system, which provides services to others and may in turn rely on services of other domains.
The insurer’s bank, an external party that makes its payments.
Outside the insurer: the model holds what the insurer requires of the bank's service, and nothing of how the bank provides it.
The scope diagram below shows what Bank is responsible for, i.e. the services it provides and the lower-level responsibility domains it contains.
12.1. Services
Bank is responsible for providing the following services. Each is described in its own section below: what it requires and what it guarantees (its service requirements), the information exchanged with it, how the work is allocated to the responsibility domains taking part, and the business process providing it.
-
Make payment: The insurer’s bank pays an amount to the client.
12.1.1. Service: Make payment
Bank provides the Make payment service.
The insurer’s bank pays an amount to the client.
An external provider's service: the bank designs and runs it, and the model holds only what the insurer requires of it. A stub in the demonstration environment.
Service requirements
The functional requirements diagram below shows who has an interest in the Make payment service, i.e. its stakeholders, and what each requires of it. A pre-condition is a condition which must hold for the service to be provided at all. When one does not, the request is refused with an exception. A post-condition is what must be true once the service has been provided, i.e. what it must have achieved.
Request data structure
The information a requester provides when asking for the service is a Bank::Request.
What is supplied when requesting 'Make payment'.
A Bank::Request has:
-
one
reference, anInsurer::Identifier: The insurer’s reference for the payment: the claim. -
one
amount, aInsurer::Money: What to pay.
Response data structure
The information the service returns once provided is a Bank::Response.
What 'Make payment' yields once rendered.
A Bank::Response has:
-
one
bankReference, aInsurer::Text: The bank’s reference for the payment.
The following must always hold for a Bank::Response:
-
Payment confirmed:
self.bankReference.size() > 0Required by Payments.