Overview
Insurelytics is a desktop client management application for insurance agents. Insurelytics facilitates the tracking of client and policies, and also generates statistical analytics to provide insights for the insurance agent. The user interacts with it using a CLI and has a GUI created with JavaFX. It is written in Java, and has about 85kLoC.
Summary of contributions
- 
Major enhancement: added features to enable searching for people/policies for various specialized purposes - 
What it does: allows the user to search for people/policies according to different purposes (current policyholders, potential policyholders, potential policies, by tag, by partial keyword), notably by eligibility. 
- 
Justification: insurance agents are likely to have many different people and policies in their contact list. To make information retrieval as fast as possible, different specialized search functionalities are important. In particular, the eligibility-related search functions are useful for the insurance agent in deciding who to approach to sell what policies. 
- 
Highlights: The way of implementing eligibility is not trivial, as we need to find a way to map people to a boolean value given a policy, and vice versa. The chosen design of the underlying implementation of criteria as tags is an elegant solution which makes intuitive sense to the user. In addition, the use of Predicateto implement list filtering makes future extensions convenient and simple.
 
- 
- 
Minor enhancement: Create partial keyword search for people and policies. 
- 
Code contributed: function and test code 
- 
Other contributions: - 
Enhancements to existing features: - 
Created the Insurelytics logo 
- 
Make right panel update appropriately during commands that update the expanded person/policy: #231 
- 
Make right panel update clear during commands that delete the expanded person/policy: #231 
- 
Add/maintain commands to add tags/criteria to people and policies: #95, #117 
- 
Format person and policy cards in the UI: #117 
- 
Formatting user messages: #193 
- 
Fixed miscellaneous bugs 
 
- 
- 
Documentation: 
- 
Community: 
 
- 
Contributions to the User Guide
| Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. | 
Tutorial
Insurelytics is a Command Line Interface (CLI) application for insurance agents like yourself to manage your contacts and policies. Here is a quick tutorial to help you get started using the application!
You can use Insurelytics to manage two different kinds of data: persons and policies. The formats in which these types of data are stored are as follows:
- 
Person: - 
Name (e.g. "Alice Pauline") 
- 
NRIC (e.g. "S0000001J") 
- 
Phone number (e.g. 94351253) 
- 
Email address (e.g. "alice@example.com") 
- 
Date of birth (e.g. "12 December 1982") 
- 
Gender (e.g. "Female") 
- 
Tags (e.g. "nonsmoker, high blood pressure") 
- 
Policies (e.g. "Life Insurance, Health Insurance") 
 
- 
- 
Policy: - 
Policy Name (e.g. "Senior Care") 
- 
Description (e.g. "Insurance for elderly") 
- 
Coverage (e.g. "12 years, 0 months, 0 days") 
- 
Price (e.g. "$5000") 
- 
Start age (e.g. "50") 
- 
End age (e.g. "75") 
- 
Tags (e.g. "term insurance") 
- 
Criteria (e.g. "nonsmoker") 
 
- 
These two sets of data are displayed on the two main pages of our application, the person page and the policy page.
They can be accessed via their respective display commands listpeople and listpolicy.
First, let’s navigate to the person page and add a contact.
listpeople
add n/John Doe ic/S9999999J p/98765432 e/johnd@example.com a/John street, block 123, #01-01 dob/12.09.1980 g/MaleThen, let’s navigate to the policy page and add a policy.
listpolicy
addpolicy n/Senior Care d/Care for seniors c/days/20 months/11 years/5 pr/$50000 sa/50 ea/75Persons can be assign-ed policies that they are eligible for. A person is eligible for a policy if
he/she falls in the specified age range and possesses all the policy’s specified criteria (in his/her tags).
assignpolicy 1 pol/Life Insurance| One of our design features is to allow users to use person-related commands on the policy page and vice versa (as with the example above). | 
Persons and policies can easily be retrieved using the various find functions, whether by keyword or by tag.
Let’s find a person and add a "senior" tag to the person.
find John
addtag 1 t/senior| Note that the index of addtagrefers to the resulting list from the previousfindcommand. Indices of persons
are always based off the latest view of the person page. The same applies for policies. | 
The various functions outlined in the following section are available to further help the user manage contacts and policies. These include additional functions to help the user gather insights, rectify mistakes and validate input among others.
Locating policies by keywords: findpolicy
Finds policies whose names or descriptions contain any of the given keywords.
Format: findpolicy KEYWORD [MORE_KEYWORDS]
Examples:
- 
findpolicy family children
 Returns any policy having names or descriptions containingfamilyorchildren
Locating people by tags: findtagpeople
Finds people who have the specified tag(s).
Format: findtagpeople t/TAG [MORE_TAGS]
Locating policies by tags: findtagpolicy
Finds policies who have the specified tag(s)
Format: findtagpolicy t/TAG [MORE_TAGS]
Find current policyholders: findpolicyholders
Finds people in possession of a policy (or policies)
Format: findpolicyholders INDEX
Examples:
- 
listpolicy
 findpolicyholders 1
 Finds all people who are in current possession of the 1st policy in the list of policies.
Find eligible policies: eligiblepolicies
Finds policies a specific person is eligible for
Format: eligiblepolicies INDEX
Examples:
- 
listpeople
 eligiblepolicies 1
 Finds all policies the 1st person in the displayed person list is eligible for.
Adding criteria to a policy : addcriteria
Adds new criteria (singular or plural) to the policy at the specified index.
Format: addcriteria INDEX cr/CRITERIA [MORE_CRITERIA]
Examples:
- 
listpolicy
 addcriteria 2 t/nonsmoker
 Adds anonsmokercriteria to the 2nd policy in the list of policies.
- 
findpolicy Betsy
 addcriteria 1 t/nonsmoker
 Adds anonsmokertag to the 1st policy in the results of thefindpolicycommand.
Deleting criteria from a policy : deletecriteria
Deletes criteria (singular or plural) from the policy at the specified index.
Format: deletecriteria INDEX cr/CRITERIA [MORE_CRITERIA]
Examples:
- 
listpolicy
 deletecriteria 2 t/nonsmoker
 Deletes thenonsmokercriteria from the 2nd policy in the list of policies.
- 
findpolicy Betsy
 deletecriteria 1 t/nonsmoker
 Deletes thenonsmokertag from the 1st policy in the results of thefindpolicycommand.
Contributions to the Developer Guide
| Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. | 
Eligibility Feature
Implementation
Eligibility was implemented as part of the overall search feature. It comprises the following two separate but related
functionalities: searching for eligible policies given a person and searching for eligible people given a policy. These
features can be accessed by the user from the eligiblepolicies and eligiblepeople commands respectively. The feature
is supported by the Person, Policy and Tag, StartAge and EndAge classes from the model component. The
eligibility functionality is supported by the following main operations:
- 
Policy#isEligible(Person person)— Checks if a person is eligible for the policy the method is called from
- 
Policy#isEligibleAge(int age)— Checks if an age is eligible for the policy the method is called from
- 
Person#getTags()— Returns aSet<Tag>of all the tags a person possesses
- 
Tag#equals(Object other)— Checks if a tag is equal to another object
The following is a class diagram illustrating the relationship between the classes involved in determining eligibility:
 
Given below is an example usage scenario of eligiblepeople and how the eligibility mechanism works at each step. The
eligibility mechanism for eligiblepolicies is similar.
Step 1. The user enters the eligiblepeople command with a valid policy index (e.g. eligiblepeople 1) to display the
list of people eligible for the policy, resulting in the EligiblePeopleCommand#execute() command being called.
Step 2. A PersonEligibleForPolicy predicate is created from the specified policy and passed into the
model#updateFilteredPersonList command.
Step 3. The FilteredList object entitled 'filteredList' is then updated through testing of each person with
PersonEligibleForPolicyPredicate#test(Person person).
- 
For each iteration, the Policy#isEligible(Person person)method is called, which checks if the person possesses all the policy’s criteria in its tags (fromPerson#getTags()) and that his or her age (calculated from his date of birth), lies between the policy’s start and end age.
- 
If both of these conditions are met, the item passes the predicate and remains on the filtered list; otherwise it is removed. 
Step 4. The EligiblePeopleCommand#execute() method returns a CommandResult with the listPeople attribute set as true.
Following is the sequence diagram that illustrates the above process:
 
Design Considerations
Aspect: Format to store criteria
- 
Alternative 1 (current choice): Store each criteria as a Tagobject- 
Pros: Since criteria are stored as tags, checking to see if a person’s tag and a policy’s criterion match is extremely simple, utilizing the Tag#equals(Other object)method. Repetition of code can therefore be avoided.
- 
Cons: Future developers unaware of this design choice may be confused by the method of checking eligibility. 
 
- 
- 
Alternative 2: Create a separate Criteriaclass for criteria- 
Pros: Separation of concerns and Single Responsibility Principle for TagandCriteriais maintained.
- 
Cons: An equivalence function will need to be written to compare TagandCriteriaobjects, which is unnecessary code to be written and maintained. Increases coupling betweenTagandCriteria, changing the format of one will inevitably need to be reflected in the other. Failing to do so would introduce bugs. === Eligibility- 
People who are eligible for policies show up during eligiblepeople- 
Test case: 
 add n/John Doe ic/S0000001J p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 dob/12.12.1982 g/Male
 addtag [INDEX OF PERSON JUST ADDED] t/test
 addpolicy n/Motor Care d/Insurance for cars c/months/10 pr/$50000 sa/18 ea/100
 addcriteria [INDEX OF POLICY JUST ADDED] cr/test `eligiblepeople [INDEX OF POLICY JUST ADDED]
 Expected: Person just added should show up on the list that appears during the run ofeligiblepeople
 
- 
- 
Policies that are eligible for people show up during eligiblepolicies- 
Test case: 
 add n/John Doe ic/S0000001J p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 dob/12.12.1982 g/Male
 addtag [INDEX OF PERSON JUST ADDED] t/test
 addpolicy n/Motor Care d/Insurance for cars c/months/10 pr/$50000 sa/18 ea/100
 addcriteria [INDEX OF POLICY JUST ADDED] cr/test `eligiblepolicies [INDEX OF PERSON JUST ADDED]
 Expected: Policy just added should show up on the list that appears during the run ofeligiblepolicies
 
- 
 
- 
 
- 
