PROJECT: Incident Management System


Overview

Incident Management System is a desktop incident Manager application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.

Summary of contributions

  • Major enhancement: Implemented Incident Search and Listing

    • What it does: allows the user to list a filtered or unfiltered list of incidents dependent on commands and parameters used.

    • Justification: This feature improves the product significantly because a user can handle large sets of data efficiently through searching for relevant incident reports based on the parameters, to prepare these incidents for filling and submission, or for reviewing.

    • Highlights: This enhancement is easily extendable to various data within the Incident model, and has been designed to easily accommodate additional parameters. It required an in-depth analysis of design alternatives, as the implementation was challenging, requiring a good understanding of how to parse multiple parameters with multiple words for each parameter, and consideration of the abstraction of said parameters.

    • Credits: Extended from the FindPerson command in the initial AB3

  • Major enhancement: Implemented initial Incident GUI layout

    • Summary: Modified the GUI for a new panel for displaying Incidents and the relevant information in the initial implementation.

    • Highlights: This enhancement required an in-depth understanding of the GUI design and the JavaFX library, as well as great familiarity with the initial Incident class. Further abstraction of the Incident class was also executed to ensure SLAP principlese were adhered to.

  • Code contributed: [View on RepoSense]

  • Other contributions:

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.

Listing all incidents: list-i

Shows a list of all incidents in the Incident Manager
Format: list-i

Example usage and expected outcome:

listIncidentsCommand
Fig X. The list-i command returns all incidents within the system.
  • The listing returns all incidents, inclusive of all incomplete drafts and complete drafts and submitted incident reports

  • Adding any keywords or parameters will result in an error. Only list-i is allowed.

Locating an incident report using incident ID, operator name or description keyword: find-i

Finds incidents containing the relevant specified parameters. Possible Parameters: id/, op/, desc/, self

Different Parameters

By Operator Name
Format: find-i op/<OPERATOR KEYWORD [MORE_KEYWORDS]>
Lists all incidents whereby the operator name contains any of the given keywords

  • Accepts multiple search terms for the parameter, searching for any match with any search term

  • Example of Successful Single Operator Search and Expected Outcome:

findIncidentsCommandWithOperatorParameter
Fig X. The find-i command has been called with one word under parameter op\, returning all incidents whereby the operator name matches alex (case-insensitive)
  • Example of Successful Multiple Operator Search and Expected Outcome:

findIncidentsCommandWithOperatorsParameter
Fig X. The find-i command has been called multiple words under parameter op\, returning all incidents whereby the operator name matches irfan or bernice (case-insensitive)

By Description
Format: find-i desc/<DESCRIPTION KEYWORD [MORE_KEYWORDS]…​>
Lists all incidents whereby the incident description contains any the given keywords

  • Example of Successful Usage and Expected Outcome:

findIncidentsCommandWithDescriptionParameter
Fig X. The find-i command has been called with parameter desc\, returning all incidents whereby the description contains either keyword fire or arson

By ID
Format: find-i id/KEYWORD
Lists all incidents whereby the incident ID is an exact match with the given keyword

  • Requires an exact ID match, only accepts one ID

  • Example of Successful Usage and Expected Outcome:

findIncidentsCommandWithIdParameter
Fig X. The find-i command has been called with parameter id\, returning all incidents whereby the ID matches 0620150001 exactly

Self-Search
Format: find-i self
Lists all incidents whereby the operator name matches the logged-in user’s name.

  • Example of Successful Usage and Expected Outcome:

findIncidentsCommandWithSelfParameter
Fig X. Executing find-i self lists all completed drafts ready for submission
  • Requires an exact name match with the logged-in user’s name

  • The search is case insensitive. e.g dave will match Dave

  • The search returns all incidents found regardless of state (incomplete and complete drafts, submitted incidents)

  • Multiple words can be taken for the operator and description parameter. The command returns all incidents which contains at least one of the words within the parameter

  • The ID parameter requires an exact match

  • Multiple parameters can be searched, returning incidents whereby all parameters match

  • Only full words/IDs will be matched e.g. Fir will not match Fire

Examples:

  • ID Match: find-i id/0920160001
    Returns Incident #0920160001

  • Multiple Parameters: find-i op/Dave desc/fire
    Returns any incidents whereby the operator’s name contains 'Dave' and the description contains 'fire'

  • Multi-word Parameter Search: find-i op/Alex Bernice
    Returns any incidents whereby the operator’s name contains either 'Alex' or 'Bernice'

  • Self-Search: find-i self
    Returns any incidents whereby the operator’s name matches the logged-in operator’s name

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.

Incident Search feature

Implementation

The incident search mechanism features a set of different types of searches that a user could utilise to list out all related incidents, inclusive of incomplete drafts, complete drafts and completed reports. Further documentation on the commands available in this set can be found in the User Guide. The types of searches are as listed:

  • Unfiltered - Displays all incidents in Model
    eg. list-i

  • ID - Displays all incidents with exact matches in IncidentId incidentId in Incident incident, within Model
    eg. find-i id/0620150001

  • Description - Displays all incidents with keyword(s) contained within the Description description in Incident incident, within Model+ eg. find-i desc/traffic

  • Operator - Displays all incidents with keyword(s) contained within the name of the Person operator in Incident incident, within Model
    eg. find-i op/bill

  • Operator - Displays all incidents with the name of the Person operator in Incident incident matching the logged-in user’s name exactly, within Model
    eg. find-i self

  • Each parameter in find-i search commands can be combined in any order and quantity, returning only results that abide by all filtering by each parameter used

  • Search by keywords is case-insensitive

  • Each parameter in find-i accepts multiple keywords, and searches for matches containing any of these keywords

The incident search mechanism is facilitated by ModelManager, which implements abstract class Model. It contains a FilteredList<Incidents> filteredIncidents, which internally stores the list of displayed incidents in the GUI. Additionally, it implements the following key method: * updateFilteredIncidentsList(Predicate<Incident> predicate) - Updates the stored filtered incidents list with the new predicate

There are two possible commands within this set of searches. Firstly, we will consider when the user calls the command list-i in the application.

The following sequence diagram shows how the list-i command works:

ListIncidentsSequenceDiagram

As indicated in the diagram, the LogicManager instantiates a ListIncidentsCommand upon running command execute(list-i). It then calls ListIncidentsCommand#execute(), which runs Model#updateFilteredIncidentList with the predicate PREDICATE_SHOW_ALL_INCIDENTS. This Predicate<Incident> always evaluates to true. This Predicate<Incident> is passed to FilteredList<Incident> filteredList, as a parameter to run the method setPredicate(). This updates the list of visible incidents. CommandResult commandResult is also returned to the LogicManager to log the success/failure of the method.

Next, we will look at an example in which the user calls search to look for incidents written by an operator whose name contains Alex.

The execution of this method is a little more complex.

The following sequence diagram shows how the search command identifies the keyword and flag, and returns related incidents:

SearchIncidentsSequenceDiagram

The key difference is the utility of the SearchIncidentsCommandParser to parse the keyword after tag op\ in the command. It creates a NameKeywordsPredicate using the String "Alex", which is returned to be used in constructing a new instance of SearchIncidentsCommand, stored as a Predicate<Incident> predicate. From there, the process is similar, in that SearchIncidentsCommand#execute() is run, causing the Model to run Model#updateFilteredIncidentList(predicate) using the predicate stored in SearchIncidentsCommand. Upon updating the list similar to the incidents listing command above, SearchIncidentsCommand also calls Model#getFilteredIncidentList() to return ObservableList<Incident>. It obtains the size of this list, and returns it in CommandResult commandResult.

Design Considerations

Aspect: How incident search keyword is inputted
  • Current choice: Parse user input after flag (eg. op\ or desc\)

    • Pros: Easy to implement.

    • Cons: Have to parse keyword from command and flag, user has to follow style of flag for successful search.

  • Alternative: Prompt user for search input

    • Pros: Separates command from keyword for ease of reading and parsing.

    • Cons: Difficult to implement multi-command execution.

Aspect: How listing all incidents is called
  • Current choice: Utilise separate command incidents

    • Pros: Intuitive to use.

    • Cons: Similar code under different command.

  • Alternative: Utilise search command (eg. search unfiltered)

    • Pros: Less overlap in code.

    • Cons: Unintuitive to the user as no search is being made, even more keywords to remember.

Aspect: How predicate is added to SearchIncidentsCommand
  • Current choice: SearchIncidentsCommandParser class calls Model to create a new Predicate based on search string.

    • Pros: Abstracts the creation and management of predicates to the Model.

    • Cons: Requires greater level of coupling between classes.

  • Alternative: SearchIncidentsCommand or SearchIncidentsCommandParser directly create Predicate based on search string.

    • Pros: Less dependencies within the parser class.

    • Cons: Breaks abstraction flow.