PROJECT: Insurelytics


InsurelyticsLogo

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 Predicate to 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:

      • Added miscellaneous commands to User Guide: #70, #71, #133, #136, #206

      • Added documentation for eligibility function to Developer Guide: #231

    • 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/Male

Then, 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/75

Persons 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 addtag refers to the resulting list from the previous find command. 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]

  • The search is case insensitive. e.g senior will match Seniors

  • The order of the keywords does not matter. e.g. Senior Care will match Care Seniors

  • Partially-matching keywords will be matched e.g. Senior will match Seniors

  • Policies matching at least one keyword will be returned (i.e. OR search). e.g. Senior Life will return Life Insurance, Senior Insurance.

Examples:

  • findpolicy family children
    Returns any policy having names or descriptions containing family or children

Locating people by tags: findtagpeople

Finds people who have the specified tag(s).
Format: findtagpeople t/TAG [MORE_TAGS]

  • The search is case insensitive. e.g. diabetic will match Diabetic

  • The order of the tags does not matter.

  • Tags must be specified completely and accurately.

  • Only people who possess all specified tags will be returned (e.g. searching diabetic and smoker will only return people with both tags).

Locating policies by tags: findtagpolicy

Finds policies who have the specified tag(s)
Format: findtagpolicy t/TAG [MORE_TAGS]

  • The search is case insensitive. e.g. accident will match Accident

  • The order of the tags does not matter.

  • Tags must be specified completely and accurately.

  • Only policies that possess all specified tags will be returned (e.g. searching accident and life will only return policies with both tags).

Find current policyholders: findpolicyholders

Finds people in possession of a policy (or policies)
Format: findpolicyholders INDEX

  • The index refers to the index number shown in the displayed policy list.

  • The index must be a positive integer 1, 2, 3, …​

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

  • The index refers to the index number shown in the displayed person list.

  • The index must be a positive integer 1, 2, 3, …​

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]

  • Adds the criteria to the policy at the specified INDEX.

  • The index refers to the index number shown in the displayed policies list.

  • The index must be a positive integer 1, 2, 3, …​

  • Any number of criteria can be added.

Examples:

  • listpolicy
    addcriteria 2 t/nonsmoker
    Adds a nonsmoker criteria to the 2nd policy in the list of policies.

  • findpolicy Betsy
    addcriteria 1 t/nonsmoker
    Adds a nonsmoker tag to the 1st policy in the results of the findpolicy command.

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]

  • Deletes the criteria from the policy at the specified INDEX.

  • The index refers to the index number shown in the displayed policies list.

  • The index must be a positive integer 1, 2, 3, …​

  • Any number of criteria can be added.

Examples:

  • listpolicy
    deletecriteria 2 t/nonsmoker
    Deletes the nonsmoker criteria from the 2nd policy in the list of policies.

  • findpolicy Betsy
    deletecriteria 1 t/nonsmoker
    Deletes the nonsmoker tag from the 1st policy in the results of the findpolicy command.

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 a Set<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:

EligibilityClassDiagram

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 (from Person#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:

EligibilitySequenceDiagram

Design Considerations

Aspect: Format to store criteria
  • Alternative 1 (current choice): Store each criteria as a Tag object

    • 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 Criteria class for criteria

    • Pros: Separation of concerns and Single Responsibility Principle for Tag and Criteria is maintained.

    • Cons: An equivalence function will need to be written to compare Tag and Criteria objects, which is unnecessary code to be written and maintained. Increases coupling between Tag and Criteria, changing the format of one will inevitably need to be reflected in the other. Failing to do so would introduce bugs. === Eligibility

      1. People who are eligible for policies show up during eligiblepeople

        1. 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 of eligiblepeople

      2. Policies that are eligible for people show up during eligiblepolicies

        1. 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 of eligiblepolicies