Developer Guide
- Setting up, getting started
- Introduction
- Purpose
- Target User Profile
- Value Proposition
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
- Appendix: Instructions for manual testing
- Appendix: Effort
Setting up, getting started
Refer to the guide Setting up and getting started.
Introduction
Pawbook is a desktop application for dog school managers to facilitate their bookkeeping of puppies and dogs in the school, optimized for input via a Command Line Interface (CLI) which caters to fast-typers who prefer to use a keyboard. You can navigate the application with ease and execute instructions by typing text-based commands in the command box provided without ever having to reach for your mouse!
Purpose
This document aims to serve as a guide for developers, testers and designers who are interested in working on Pawbook. It describes both the design and architecture of Pawbook.
Target User Profile
The target user profile are dog school managers that own and manage the daily operations of the dog schools. They handle a wide range of operations such as keeping track of the dogs under their care, arranging programs and taking care of the dogs on a daily basis. They need a systematic way of maintaining their handle on the operations of their school at all times.
Value Proposition
In Singapore, dog schools are popular among dog owners. Besides day care, they also provide training, grooming and workshops. With many moving parts daily, managing operations can get overwhelming. Pawbook is an all-in-one management system to help dog school managers to maintain organization of their dog schools. Besides keeping track of all the dogs under their care, it also allows dog school managers to plan their schedule and manage programs and classes. At present, there is no such application that helps dog school managers organize and manage their school. This application serves to increase the efficacy of dog schools.
Design
Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
Main
has two classes called Main
and MainApp
. It is responsible for:
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the local persistent storage.
Each of the four components,
- defines its API in an
interface
with the same name as the Component. - exposes its functionality using a concrete
{Component Name}Manager
class (which implements the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class which implements the Logic
interface.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete owner 1
.
The sections below give more details of each component.
UI component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, EntityListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- Executes user commands using the
Logic
component. - Listens for changes to
Model
data so that the UI can be updated with the modified data.
Logic component
API :
Logic.java
-
Logic
uses thePawbookParser
class to parse the user command. - This results in a
Command
object which is executed by theLogicManager
. - The command execution can affect the
Model
(e.g. adding an owner). - The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. - In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete owner 1")
API call.
DeleteOwnerCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Model component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the pawbook database data.
- exposes an unmodifiable
ObservableList<Entity>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - does not depend on any of the other three components.
Storage component
API : Storage.java
The Storage
component,
- can save
UserPref
objects in json format and read it back. - can save the Pawbook Database data in json format and read it back.
Common classes
Classes used by multiple components are in the pawbook.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Entities: Owner/Dog/Program
Despite having three closely related entities in Pawbook, the actual implementation does not couple the 3 entities together in any ways. Instead of storing a reference between an Owner and their Dog, a symbolic ID number is used to represent these links. This ensures that data objects continue to only store information and leave the control/manipulation of data to the logic side of the application. It is therefore possible for all the various entities to remain immutable as well.
This necessitates that an unique ID number is assigned to every entity during its creation and remain constant throughout its lifetime in the application. A simple numbering system is used here whereby the ID is generated by incrementing from 1 until an unused number is found, gaps between numbers will only be filled after a restart of the application to simplify the code.
The ID system replaces the original implementation that uses the index of every Person in the visible list. This gives the advantage of being able to reference to any entity on any screen, which can be useful since different entities are not displayed together.
The UniqueEntityList
contains pairs of ID and entity. This attempts to mimic a map/dictionary while keeping possible to continue using the original UI components with minimal changes to the code. Every entity does not store its ID as an internal attribute due to the fact that ID is dynamically generated, usually after the instantiation of the entity itself. The ability to set or change the ID during the lifetime of the entity will violate the immutability of the entities. Furthermore, there is no need for the any entity to be aware of its ID.
Alternative Implementation: Using a Hashmap as container for unique entities
A hashmap was briefly considered as a candidate for storing the unique entities as it was a natural fit.
Benefits:
- Much faster lookup when retrieving an entity by its ID or to check for ID clashes.
Drawbacks:
- Hashmaps have no inherent order, it will be quickly become expensive to maintain order whenever there are data changes.
- There is no
FilteredList
equivalent for maps in JavaFX, filtering cannot be simply achieve withinModel
and will need to be done on the GUI side.
This current implementation though not ideal, avoid many potential rewrites since there is no ListView
equivalent for maps in JavaFX. Switching to using a hashmap as underlying data structure will mean that a table will need to be used to display all the entries, adding unnecessary complication to the code as filtering and sorting will no longer as be simple. Most of these changes are under-the-hood and does not improve user experience significantly.
Adding/Deleting feature
What it is
Pawbook manages more than one type of entity, each with their own unique attributes. An OOP approach is used here whereby both the AddCommand
and DeleteCommand
are generic classes that extends the Command
class. This way any number of other classes extending entity
can be added/deleted as well.
Implementation details
The actual execution of the different add commands are highly similar and often differ only by the extra entity-specific checks, e.g. verifying that the owner ID refers to an actual owner instead of taking in an arbitrary number. The same applies to delete commands as well.
In order to generate the respective commands, the raw input needs to be parsed first. It is required that the user provide a second keyword right after the add
/delete
command keyword to indicate the correct entity type to be added. Using this information, the arguments can be forwarded to the correct parser from within PawbookParser
to generate the actual add/delete commands.
Given below is an example usage scenario and how the add command behaves at each step.
Step 1. The user launches the application and executes add owner n/BRUCE p/92019201 e/bruce@example.com a/BLK 123 Adam Road t/friendly
to save an owner.
Step 2. The owner is added to the model.
Below is an example activity diagram for a valid delete command from the user.
The activity diagram for both add and delete commands are mirrored. Based on the name of the entity type supplied, the correct parser will be instantiated to parse the arguments and generate the executable command.
To further illustrate how an actual deletion of an entity is performed, below is an example sequence diagram for a valid delete command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
identifies the user command and creates aDeleteDogCommandParser
object. It then calls theDeleteDogCommandParser
’sparse()
method with user input as the parameter. - In the
parse()
method, theDeleteDogCommandParser
will then generate theDeleteDogCommand
object. This is then returned all the way back to theLogicManager
. - The
LogicManager
will then proceed to call theexecute()
method. - The
execute()
method is further explored below. The high level understanding is that a CommandResult is returned and finally passed back toLogicManager
.
This is how the DeleteDogCommand
works upon execution:
- The
Dog
to be deleted will first be retrieved from theModel
. - Using the ID stored in the
Dog
, theOwner
can be retrieved fromModel
as well. - A new
Owner
with the same details except without the currentDog
’s ID will be created to replace the currentOwner
instance in theModel
. - A list of
Program
that theDog
is enrolled in will be generated. - For each of these
Program
, it will be edited to remove the currentDog
’s ID. - With no more entities referring to the current
Dog
, it is safe to callModel#deleteEntity(...)
to delete theDog
.
The deletion of any entity will typically affect other related entities as well. The various add commands will similarly perform the reverse of the delete command.
Edit feature
What it is
Pawbook allows the user to edit
an entity. For instance, the user may want to edit
some attributes of an owner. By entering the edit command with the target owner ID, the attributes of the owner will be modified accordingly.
Implementation details
In order to generate the edit command, the user indicates the entity type to be edited, followed by the ID number. Using this information, the arguments can be forwarded to the correct parser from within PawbookParser
to be further processed.
Below is an example activity diagram for a valid edit command from the user.
Below is the sequence diagram for the Edit Command.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
identifies the user command and creates aEditOwnerCommandParser
object. It then calls theEditOwnerCommandParser
’sparse()
method with user input as the parameter. - In the
parse()
method, theEditOwnerCommandParser
will then generate theEditOwnerCommand
object. This is then returned all the way back to theLogicManager
. - The
LogicManager
will then proceed to call theexecute()
method. - The
execute()
method is further explored below. The high level understanding is that aCommandResult
is returned and finally passed back toLogicManager
.
Find feature
What it is
Pawbook allows the users to find
an entity based on keyword searches. The find
function allows for multiple keyword
searches and reveals the entire list of entities that match one or more of the results.
Implementation details
When the user enters a valid command with the search keywords, the arguments are parsed by the FindCommmandParser
which
converts the string of arguments into a list. The list is subsequently passed on to a NameContainsKeywordsPredicate
object
that uses the list of keywords to find the search results based on the supplied keywords. Take note that Find Command supports
substring searching, so for example if there is an Alice in the program, searching “Ali” will also return Alice as result.
Below is an example activity diagram for a valid find command from the user.
Below is an example sequence diagram for a valid find command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
identifies the user command and creates aFindCommandParser
object. It then calls theFindCommandParser
’sparse()
method with user input as the parameter. - In the
parse()
method, theFindCommandParser
will then generate theFindCommand
object. This is then returned all the way back to theLogicManager
. - The
LogicManager
will then proceed to call theexecute()
method. - The
execute()
method is further explored below. The high level understanding is that a CommandResult is returned and finally passed back toLogicManager
.
Here is a more specific breakdown of the command’s execute method.
- Upon calling the
execute()
method, theFindCommand
updates the filtered entity list inModel
using aNameContainsKeywordsPredicate
as parameter. - It then sorts the entity using the
sortEntities()
in increasing order by using aCOMPARATOR_ID_ASCENDING_ORDER
comparator that orders entities in increasing ID order. - From here, Find Command creates a command result and returns it to the
LogicManager
.
List feature
What it is
Pawbook allows the users to list
an entity based on keyword searches. The list
function responds to the current available
entities, which are owner
, dog
and program
, and returns a list of all the entries of the respective entity.
Implementation details
When the user enters a valid command with the entity keyword, the arguments are parsed by PawbookParser
, which uses Predicate
to identify which entity owner
, dog
or program
it is. ListCommand
is then generated with the predicate to return
a list of all the entries of that entity type.
List command supports the plural forms of the entity keywords.
Below is an example activity diagram for a valid list command from the user.
Below is an example sequence diagram for a valid list command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - In
PawbookParser
, aPredicate
is created based on which entity keyword was given by the user. There are only 3 cases here,owner
,dog
, orprogram
. - A
ListCommand
object will be created based on thePredicate
. - The
LogicManager
will then proceed to call theexecute()
method. - The
execute()
method is further explored below. The high level understanding is that a CommandResult is returned and finally passed back toLogicManager
.
Here is a more specific breakdown of the command’s execute method.
- Upon calling the
execute()
method, theListCommand
updates the filtered entity list inModel
using apredicate
and anentityType
as parameters. - It then sorts the entity using the
sortEntities()
in increasing order by using aCOMPARATOR_ID_ASCENDING_ORDER
comparator that orders entities in increasing ID order. - From here, List Command creates a command result and returns it to the
LogicManager
.
View feature
What it is
Pawbook allows the user to view
an entity and all its related entities. For instance, the user may want to view
all the dogs of one particular owner or all the dogs enrolled in a program. By entering the correct view command with the correct identification number, the entire list will be generated.
Implementation detail
When the user enters a valid command with the target entity ID, the ViewCommandParser will firstly parse the command and store the ID as an integer that is then passed on to as a parameter into the constructor method of a new ViewCommand instance.
Subsequently, once the new ViewCommand
instance has been created, in its execute method, it will retrieve the entity via the ID that was passed in, from the ModelManager
. With a handle on the target entity now, we build a list consisting of the entity IDs that are to be shown as search results.
Based on the class type of the target entity, we will reveal the search results accordingly. If the target entity is a Dog
, then we will show the relevant owner profile. If the target entity is a Owner
, then we will list out all of the owner’s dogs. Similar to owner, for Program
, we will reveal the full list of dogs enrolled in that program.
This list is subsequently passed on to the RelatedEntityPredicate
that will later be used in the ModelManager’s updatefilteredEntityList())
method to finally reveal the search results.
Take note that this is the order in which results will be displayed, based on target entity searched:
- View Dog: Dog > Owner > Programs enrolled in
- View Owner: Owner > Dogs owned
- View Program: Program > Dogs enrolled
Below is an example activity diagram for a valid view command from the user.
Below is an example sequence diagram for a valid view command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
identifies the user command and creates aViewCommandParser
object. It then calls theViewCommandParser
’sparse()
method with user input as the parameter. - In the
parse()
method, theViewCommandParser
will then generate theViewCommand
object. This is then returned all the way back to theLogicManager
. - The
LogicManager
will then proceed to call theexecute()
method. - The
execute()
method is further explored below. The high level understanding is that a CommandResult is returned and finally passed back toLogicManager
.
Here is a more specific breakdown of the command’s execute method.
- In the execute method of
ViewCommand
, it first generates a list of related entity IDs by calling thegenerateRelatedIdList()
which accesses the data in the model. - This list is then passed into the constructor method of
IdMatchPredicate
and is then passed intoupdateFilteredEntityList()
method. TheupdateFilteredEntityList()
updates the filtered entity list in model. - Next,
ViewCommand
creates aViewCommandComparator
and uses it to sort the ordering of the filtered entity list. - From there,
ViewCommand
generates theCommandResult
based on the filtered entity list. This portion is not shown here as it is trivial.
Schedule feature
What it is
Pawbook allows the user to display the schedule
of all programs.
For instance, the user may want to view the schedule
of all programs on a specific date. By entering the correct schedule command with the correct date, the entire list of programs on the specific date will be generated.
Implementation details
When the user enters a valid command with the date, the arguments are parsed by the ScheduleCommandParser
that converts
the argument string into a Date that is subsequently passed on to a ProgramOccursOnDatePredicate
object.
Using the IsEntityPredicate
for program and the ProgramOccursOnDatePredicate
, the list of programs is retrieved via
the ModelManager
using the updateFilteredEntityList()
method.
Below is an example activity diagram for a valid schedule command from the user.
Below is an example sequence diagram for a valid schedule command from the user.
Here is a more specific breakdown of the command’s execute method.
- In the execute method of
ScheduleCommand
, it first creates aProgramOccursOnDatePredicate
object. - The
IsEntityPredicate
of Program and theProgramOccursOnDatePredicate
is then passed intoupdateFilteredEntityList()
method. TheupdateFilteredEntityList()
updates the filtered entity list in model. - From there,
ScheduleCommand
generates theCommandResult
based on the filtered entity list. This portion is not shown here as it is trivial.
Enrol feature
What it is
Pawbook supports the enrolling of specific dogs into specific programs.
Implementation details
In order to enrol a dog into a program, the raw input needs to be parsed first. It is required that the user provides 2 parameters, namely dogId
and programId
. These inputs have the prefix /d
and /p
, and is followed by an integer. Using this information, the arguments will be forwarded to the EnrolCommandParser
from within PawbookParser
, which converts the String input to int.
Below is an example activity diagram for a valid enrol command from the user.
Below is an example sequence diagram for a valid enrol command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
will identify the command given by the user based on the first command word and pass the user input down toEnrolDropCommandParser
. - The
EnrolDropCommandParser
will then create anenrolCommand
object with the user inputdogIdSet
andprogramIdSet
as input parameters, in this case,dogIdSet
will be[2]
andprogramIdSet
will be[3]
. - The
EnrolDropCommandParser
will then return anenrolCommand
object. - The
LogicManager
will now call theexecute
method in theenrolCommand
object. - The
EnrolCommand
will now call theupdateFilteredEntityList
method of the existingModel
object. - The high level understanding is that a
CommandResult
is returned and finally passed back toLogicManager
.
Here is a more specific breakdown of the command’s execute method.
- The
LogicManager
will call the execute method in theEnrolCommand
object. - The
EnrolCommand
will then call thecheckIdValidity
method of the existingModel
object. - If the ID is valid, the
EnrolCommand
will create anIdMatchPredicate
object. - The
EnrolCommand
will call theupdateFilteredEntityList
method of the existingModel
object update theIdMatchPredicate
object into Pawbook. - The
EnrolCommand
then creates aCommandResult
object and returns it, indicating the successful updating of theIdMatchPredicate
object.
Drop feature
What it is
While Pawbook allows the enrolling of dogs into programs, conversely it supports dropping previously-enrolled dogs from the programs.
Implementation details
To drop a dog from a program, the raw input is parsed and goes through several checks to ensure that the provided dog and program IDs are both valid and are indeed referring to dog and program objects respectively. Subsequently, the arguments will be forwarded to DropCommandParser
followed by PawbookParser
where they are converted from the String input to int.
Below is an example activity diagram for a valid drop command from the user.
Below is an example sequence diagram for a valid drop command from the user.
- The
LogicManager
uses thePawbookParser
to parse the given user input. - The
PawbookParser
will identify the command given by the user based on the first command word and pass the user input down toEnrolDropCommandParser
. - The
EnrolDropCommandParser
will then create adropCommand
object with the user inputdogIdSet
andprogramIdSet
as input parameters, in this case,dogIdSet
will be [2] andprogramIdSet
will be [3]. - The
EnrolDropCommandParser
will then return aenrolCommand
object. - The
LogicManager
will now call the execute method in thedropCommand
object. - The
DropCommand
will now call theupdateFilteredEntityList
method of the existingModel
object. - The high level understanding is that a
CommandResult
is returned and finally passed back toLogicManager
.
Here is a more specific breakdown of the command’s execute
method.
- The
LogicManager
will call the execute method in theDropCommand
object. - The
DropCommand
will then call thecheckIdValidity
method of the existingModel
object. - If the ID is valid, the
DropCommand
will create anIdMatchPredicate
object. - The
DropCommand
will call theupdateFilteredEntityList
method of the existingModel
object update theIdMatchPredicate
object into Pawbook. - The
DropCommand
then creates aCommandResult
object and returns it, indicating the successful updating of theIdMatchPredicate
object.
Alternate Implementation: Enrol/Drop features
As dogs and programs can also be identified by their respective names instead of IDs, another implementation could be replacing the parameters of dogId
and programId
with their respective names.
However, this requires there to be no duplicate dog or program names.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product Scope
Target user profile:
- Has a need to manage a significant number of dogs and owners
- Prefers desktop apps over other types
- Is a fast typist
- Prefers typing to mouse interactions
- Is reasonably comfortable using CLI apps
- Prefers a portable and lightweight application
Value proposition:
- Manages customer data faster than a typical mouse/GUI driven app
- Saves significant time for the business owner, who beforehand had to manage the details of dogs and owners
- Consolidates information on dogs, owners and programs into one place
- Clutter-free user interface
- Application is optimized for keyboard navigation
User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
Dog school manager | Have a list of dogs, owners, and programs in the school | Keep track of the operations and dogs we are responsible for |
* * * |
Dog school manager | Easily switch between the different lists for dogs, owners and programs | Quickly view all the profiles of one entity type |
* * * |
Dog school manager | Add dog/owner/program profiles | Keep track of the operations and parties involved in the school |
* * * |
Dog school manager | Delete dog/owner/program profiles | Keep track of the operations and parties involved in the school |
* * * |
Dog school manager | Edit a dog/owner/program profile | Correct/update a profile when needed |
* * * |
Dog school manager | View a dog/owner/program profile | Easily find out information on the target entity |
* * * |
Dog school manager | Find profiles using keywords instead of ID | Easily find a target dog/owner/program very quickly |
* * * |
Dog school manager | Enrol dogs into a specific dog program | Add dogs who recently joined a program to the class list |
* * * |
Dog school manager | Drop dogs out of a specific dog program | Remove dogs that have left a program from the class list |
* * * |
Dog school manager | See the schedule for any day | Easily view my schedule to know what programs are happening on that day |
* * |
Dog school manager | Autosave the data after every command | Regularly save the data and protect sensitive data in the event that the system crashes |
* * |
Advanced user | Edit in bulk quickly | Save time and effort when making changes to multiple profiles/programs |
* * |
Beginner user | Have a help command with a command summary available | Refer to it when I am unsure of the command |
Use Cases
(For all use cases below, the System is the Pawbook
and the Actor is the user
, unless specified otherwise)
Use case: UC01 - Add a dog/owner profile or program
MSS
- User requests to add a dog/owner profile or program to the list.
-
Pawbook adds the dog/owner.
Use case ends.
Extensions
- 1a. Missing mandatory dog/owner/program details.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies missing details.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. Entity already exists in the program.
- 1b1. Pawbook shows an error message.
-
1b2. User supplies an entity with different details.
Steps 1b1-1b2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC02 - Delete a dog/owner profile or program
MSS
- User requests to delete a specific dog/owner profile or program in the list.
-
Pawbook deletes the dog/owner profile or program.
Use case ends.
Extensions
- 1a. The given dog/owner/program ID is invalid or not specified.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies the corrected dog/owner/program ID.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. The given dog/owner/program ID does not match the entity specified.
- 1b1. Pawbook shows an error message, indicating the entity expected.
-
1b2. User supplies the corrected dog/owner/program ID.
Steps 1b1-1b2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC03 - Edit a dog/owner profile or program
MSS
- User requests to edit a specific dog/owner/program in the list.
-
Pawbook edits the dog/owner/program.
Use case ends.
Extensions
- 1a. The given dog/owner/program ID is invalid or does not correspond to the entity specified.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies the corrected dog/owner/program ID.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. The user failed to provide any mandatory details to be edited.
- 1b1. Pawbook shows an error message.
-
1b2. The user provides one or more mandatory details to be edited. Steps 1b1-1b2 are repeated until the command entered is correct.
Use case resumes at step 2.
Use case: UC04 - Show the specified entity list
MSS
- User requests to list dogs/owners/programs.
-
Pawbook lists the related dogs/owners/programs.
Use case ends.
Extensions
- 1a. User requests to list something that is none of the three entities.
- 1a1. Pawbook shows an error message, suggesting the accepted entities.
-
1a2. User supplies the corrected dog/owner/program parameter.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case UC05 - View an entity and all its related entities
MSS
- User types in view command with the target ID.
-
Pawbook supplies the results of all the related entities of that ID.
Use case ends.
Extensions
- 1a. The ID is not provided.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies a valid ID.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. The ID is invalid (negative, out of bounds, not in database etc.).
- 1b1. Pawbook shows an error message.
-
1b2. User supplies a valid ID.
Steps 1b1-1b2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case UC06 - Find entity by keyword(s)
MSS
- User types in find command with one or more keywords.
-
Pawbook supplies the results matching the keyword(s).
Use case ends.
Extensions
- 1a. The keyword is not provided.
- 1a1. Pawbook shows an error message and requests keyword.
-
1a2. User supplies keywords.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC07 - Enrol dog to a program
MSS
- User requests to enrol dog to program.
-
Pawbook enrols the dog to the correct program.
Use case ends.
Extensions
- 1a. The dog/program ID is invalid/not specified.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies correct dog/program ID.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. The user requests to enrol multiple dogs to multiple programs.
- 1b1. Pawbook shows an error message.
-
1b2. User changes request to either enrolling one dog to one program, one dog to multiple programs, or multiple dogs to one program.
Steps 1b1-1b2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC08 - Drop dog from program
MSS
- User requests to drop dog from program.
-
Pawbook drops dog from the correct program.
Use case ends.
Extensions
- 1a. The dog/program ID is invalid/not specified.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies correct dog/program ID.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
- 1b. The user requests to drop multiple dogs from multiple programs.
- 1b1. Pawbook shows an error message.
-
1b2. User changes request to either dropping one dog from one program, one dog from multiple programs, or multiple dogs from one program.
Steps 1b1-1b2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC09 - View schedule
MSS
- User requests to view schedule with a specified date.
-
Pawbook shows the schedule.
Use case ends.
Extensions
- 1a. The date is invalid/not specified.
- 1a1. Pawbook shows an error message.
-
1a2. User supplies correct date.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC10 - View Help Window
MSS
- User enters
help
command into the command box and presses enter. -
Pawbook opens a help window containing the link to the user guide and also a command summary for the user.
Use case ends.
Extensions
- 1a. The given command/format is invalid.
- 1a1. Pawbook shows an error message to the user.
-
1a2. User supplies the correct command.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
Use case: UC11 - Exit Pawbook
MSS
- User enters the
exit
command into the command box and presses enter. - Pawbook shows goodbye message.
-
Pawbook terminates.
Use case ends.
Extensions
- 1a. The given command/format is invalid.
- 1a1. Pawbook shows an error message to the user.
-
1a2. User supplies the correct command.
Steps 1a1-1a2 are repeated until the command entered is correct.Use case resumes at step 2.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has
Java 11
or above installed. - Should be able to hold up to 100000 dogs, owners and dog programs without a noticeable sluggishness in performance for typical usage.
- Should be usable by a tech novice who is not familiar with CLI.
- Should respond within 2 seconds.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- A simple interface that is easy to navigate.
- Not required to handle finance-related bookkeeping.
- Pawbook does not require internet connection to run.
- Able to work in all different time zones, regardless of where the system is operated in the world.
- Features should be implemented such that they can undergo automated testing.
- Pawbook data should be saved locally. Not possible to be hacked from external machines. Only way to access is through the local machine.
- Only one Pawbook program can run on a local machine at any time.
- Pawbook program file size should not exceed beyond 1GB.
- Pawbook should be able to recover from exceptions and error handling and not freeze on the user.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- JSON: JSON is short for JavaScript Object Notation which is a lightweight format for data storage
Appendix: Instructions for manual testing
Given below are instructions to test the app manually. These instructions should be complemented with the user guide for comprehensive testing. The state of the application is assumed to contain the sample data from when the application is first launched.
To empty the database and reset the state (ID goes back to 1) for testing, try deleting all the entities and restart the program. Remember to switch different list views using the list command to look at different lists and ensure all entities have been removed.
Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file.
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
-
Exiting the app
- With the application still open, enter
exit
in the command box or click on the close window button [X].
Expected: Application terminates.
- With the application still open, enter
-
For the sake of all manual testing, we will be using the preset typical entities loaded from Pawbook database.
Add Command
-
Adding a dog
-
Prerequisites: Pawbook is launched and running. Ensure that an owner with ID 1 is present.
-
Test case:
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
Expected: If database does not already contain a Bruce, a successful command result should show. -
Test case:
add dog o/1 b/Chihuahua d/12-02-2019 n/Bruce s/Male t/playful t/active
Expected: Similar to previous. -
Test case :
add dog o/1 b/Chihuahua d/12-02-2019 n/Bruce t/playful t/active
Expected: Missing parameters, status message indicates invalid command format.
-
-
Adding an owner
-
Prerequisites: Pawbook is launched and running.
-
Test case:
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
Expected: If database does not already contain a John Doe, a successful command result should show. -
Test case:
add owner n/John Doe a/311, Clementi Ave 2, #02-25 e/johnd@example.com p/98765432 t/friends t/owesMoney
Expected: Similar to previous. -
Test case :
add owner n/John Doe e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
Expected: Missing parameter, status message indicates invalid command format.
-
-
Adding a program
-
Prerequisites: Pawbook is launched and running.
-
Test case:
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
Expected: If database does not already contain a Bruce, a successful command result should show. -
Test case:
add program s/01-02-2021 18:00 n/Obedience Training t/puppies
Expected: Similar to previous. -
Test case :
add program t/puppies
Expected: Missing parameters, status message indicates invalid command format.
-
Delete Command
-
Deleting an owner while all owners are being shown
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
. Ensure Bruce has ID 2. -
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
. Ensure program has ID 3. -
List owners using
list owner
.
-
-
Test case:
delete owner 1
Expected: Owner with ID 1 is deleted from the list. All the dogs belonging to the first owner is also deleted. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete owner 0
Expected: No owner is deleted. Error details shown in the status message. Status bar remains the same. -
Test case:
delete owner 2
Expected: No owner is deleted as ID 2 is not an owner. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete owner
,delete owner x
,delete owner -x
(where x is larger than list size or negative)
Expected: Similar to previous. -
Prerequisites: Refer to above. List dogs using
list dog
. -
Test case:
delete dog 2
Expected: Dog with ID 2 is deleted from the list. The dogs will also be removed from all programs they were previously enrolled in. -
Test case:
delete dog 0
Expected: No dog is deleted. Error details shown in the status message. Status bar remains the same. -
Test case:
delete dog 1
Expected: No dog is deleted as ID 1 is not a dog. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete dog
,delete dog x
,delete dog -x
(where x is larger than list size or negative)
Expected: Similar to previous.
-
-
Deleting a program while all programs are being shown
-
Prerequisites: Refer to above. List programs using
list program
. -
Test case:
delete program 3
Expected: Program with ID 3 is deleted from the list. The dogs that were enrolled in the program will no longer be enrolled in that program. -
Test case:
delete program 0
Expected: No program is deleted. Error details shown in the status message. Status bar remains the same. -
Test case:
delete program 1
Expected: No program is deleted as ID 1 is not a program. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete program
,delete program x
,delete program -x
(where x is larger than list size or negative)
Expected: Similar to previous.
-
Edit Command
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
-
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
-
Add another sample owner with
add owner n/James Bond p/90139122 e/jamesbond@example.com a/322, Clementi Ave 2, #02-25 t/friends t/owesMoney
Ensure James Bond has ID 4.
-
-
Editing a dog
-
Test case:
edit dog 2 n/Milo
Expected: Successfully renamed Bruce to Milo. -
Test case:
edit dog 2 n/Bruce o/4
Expected: Successfully renamed Milo to Bruce and changed owner from John Doe to James Bond. -
Test case:
edit dog 3 n/Milo o/4
Expected: Error status message shown, indicating dog ID provided is invalid.
-
-
Editing an owner
-
Test case:
edit owner 1 p/91234567
Expected: Successfully changes John Doe’s number. -
Test case:
edit owner 1 p/97538642 e/ilovedogs@sample.com
Expected: Successfully changed John Doe’s number and updated his email. -
Test case:
edit owner 3 n/Keith
Expected: Error status message shown, indicating owner ID provided is invalid.
-
-
Editing a program
-
Test case:
edit program 3 n/Kennel Training
Expected: Successfully renamed Obedience Training to Kennel Training. -
Test case:
edit program 3 n/Kennel Training s/01-02-2021 17:00
Expected: Successfully renamed Obedience Training to Kennel Training and changes the session date to 1700 from 1800. -
Test case:
edit program 4 n/Kennel Training s/01-02-2021 17:00
Expected: Error status message shown, indicating program ID provided is invalid.
-
Find Command
-
Find valid entities
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
-
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
-
Add another sample owner with
add owner n/James Bond p/90139122 e/jamesbond@example.com a/322, Clementi Ave 2, #02-25 t/friends t/owesMoney
Ensure James Bond has ID 4.
-
-
Test case:
find John
Expected: Alice with ID 1 is shown on the display list. Status message says “1 entity listed!” -
Test case:
find Jo
Expected: Similar to previous. -
Test case:
find John James
Expected: John and James are displayed on the list. Status messages says: “2 entities listed!”
-
-
Finding invalid entities
-
Test case:
find InvalidName
Expected: Zero entities listed. -
Test case:
find 12345
Expected: Zero entities listed.
-
List Command
-
Listing dogs
- Test case:
list dog
Expected: All the dogs in the school listed.
- Test case:
-
Listing owners
- Test case:
list owner
Expected: All the owners in the school listed.
- Test case:
-
Listing program
- Test case:
list program
Expected: All the programs in the school listed.
- Test case:
-
Invalid List commands
-
Test case:
list
Expected: Error message indicates unknown entity, shows supported entities. -
Test case:
list invalidEntity
Expected: Similar to previous.
-
View Command
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
-
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
-
Enrol Bruce into Obedience Training with
enrol d/2 p/3
-
Ensure that Bruce is successfully added to the Obedience Training program.
-
-
Viewing owner
- Test case:
view 1
Expected: John’s and Bruce’s contacts are listed. John Doe’s contact is at the top, followed by Bruce.
- Test case:
-
Viewing dog
- Test case:
view 2
Expected: John, Bruce and Obedience Training program is listed. Bruce’s contact is at the top, followed by John, followed by Obedience Training.
- Test case:
-
Viewing program
- Test case:
view 3
Expected: Bruce and Obedience Training program is listed. Obedience training details are at the top, followed by Bruce’s details.
- Test case:
-
Invalid view ID
-
Test case:
view 4
Expected: Error status message is provided, indicating invalid ID. -
Test case:
view -1
Expected: Error status message is provided, indicating ID must be positive.
-
Schedule Command
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample program with
add program n/Obedience Training 1 s/[TODAY'S DATE] 18:00 t/puppies
. Fill in today’s date in the[TODAY'S DATE]
field in dd-mm-yyyy format. -
Add a sample program with
add program n/Obedience Training 2 s/01-02-2021 18:00 t/puppies
-
Ensure that sample programs are successfully added.
-
-
Viewing schedules on a valid day
-
Test case:
schedule
Expected: Successful status message, shows the sample Obedience Training 1 happening today. -
Test case:
schedule 01-02-2021
Expected: Successful status message, shows the sample Obedience Training 2 happening on 01-02-2021.
-
-
Viewing schedules on an invalid day
-
Test case:
schedule 31-02-2021
Expected: Error status message thrown, indicating day of the month does not exist. -
Test case:
schedule 031-02-2021
Expected: Error status message thrown, indicating that date format should be in dd-MM-yyyy format.
-
Enrol Command
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
Ensure Bruce has ID 2. -
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
Ensure Obedience Training has ID 3.
-
-
Enrol valid dog into valid program
- Test case:
enrol d/2 p/3
Expected: Bruce is successfully added to the Obedience Training program.
- Test case:
-
Enrol valid dog into invalid program
- Test case:
enrol d/2 p/4
Expected: Error status message stating program ID is invalid.
- Test case:
-
Enrol invalid dog into valid program
- Test case:
enrol d/3 p/3
Expected: Error status message stating dog ID is invalid.
- Test case:
-
Enrol multiple valid dogs into valid program
-
Repeat Pre-requisites
-
Add another sample dog with
add dog n/Apple b/Golden Retriever d/28-04-2020 s/Female o/1 t/friendly
Ensure Apple as ID 4. -
Test case:
enrol d/2 d/4 p/3
Expected: Bruce and Apple are successfully added to the Obedience Training program. Remember to drop Bruce from the program if he was enrolled previously!
-
-
Enrol one valid dog into multiple valid programs
-
Repeat Pre-requisites
-
Add another sample program with
add program n/Potty Training s/14-03-2021 12:00 t/puppies
Ensure Potty Training has ID 4. -
Test case:
enrol d/2 p/3 p/4
Expected: Bruce is successfully added to the Obedience Training program and the Potty Training program. Remember to drop Bruce from the program if he was enrolled previously!
-
-
Enrol multiple valid dogs into multiple valid programs
-
Repeat Pre-requisites
-
Add another sample dog with
add dog n/Apple b/Golden Retriever d/28-04-2020 s/Female o/1 t/friendly
Ensure Apple has ID 4. -
Add another sample program with
add program n/Potty Training s/14-03-2021 12:00 t/puppies
Ensure Potty Training has ID 5. -
Test case:
enrol d/2 d/4 p/3 p/5
Expected: Error messaging stating that enrollment of multiple dogs into multiple programs is not supported.
-
-
Invalid enrol command
- Test case:
enrol invalidCommand
Expected: Error status message indicating wrong command format.
- Test case:
Drop Command
-
Pre-requisites
-
Start with an empty database by deleting all entities.
-
Add a sample owner with
add owner n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney
. Ensure John Doe has ID 1. -
Add a sample dog with
add dog n/Bruce b/Chihuahua d/12-02-2019 s/Male o/1 t/playful t/active
. Ensure Bruce has ID 2. -
Add a sample program with
add program n/Obedience Training s/01-02-2021 18:00 t/puppies
Ensure Obedience Training has ID 3.
-
-
Drop valid dog from valid program
-
Enrol dog into program with:
enrol d/2 p/3
-
Test case:
drop d/2 p/3
Expected: Bruce is successfully dropped from Obedience Training program.
-
-
Drop valid dog from invalid program
-
Enrol dog into program with:
enrol d/2 p/3
-
Test case:
drop d/2 p/4
Expected: Error status message stating program ID is invalid.
-
-
Drop invalid dog from valid program
-
Enrol dog into program with:
enrol d/2 p/3
-
Test case:
drop d/3 p/3
Expected: Error status message stating dog ID is invalid.
-
-
Drop multiple valid dogs from valid program
-
Repeat Pre-requisites
-
Add another sample dog with
add dog n/Apple b/Golden Retriever d/28-04-2020 s/Female o/1 t/friendly
Ensure Apple as ID 4. -
Enrol dogs into program with:
enrol d/2 d/4 p/3
-
Test case:
drop d/2 d/4 p/3
Expected: Bruce and Apple are successfully added to the Obedience Training program.
-
-
Drop one valid dog from multiple valid programs
-
Repeat Pre-requisites
-
Add another sample program with
add program n/Potty Training s/14-03-2021 12:00 t/puppies
Ensure Potty Training has ID 4. -
Enrol dog into programs with:
enrol d/2 p/3 p/4
-
Test case:
drop d/2 p/3 p/4
Expected: Bruce is successfully added to the Obedience Training program and the Potty Training program.
-
-
Drop multiple valid dogs from multiple valid programs
-
Repeat Pre-requisites
-
Add another sample dog with
add dog n/Apple b/Golden Retriever d/28-04-2020 s/Female o/1 t/friendly
Ensure Apple has ID 4. -
Add another sample program with
add program n/Potty Training s/14-03-2021 12:00 t/puppies
Ensure Potty Training has ID 5. -
Enrol dog into program with:
enrol d/2 p/3
andenrol d/4 p/5
-
Test case:
drop d/2 d/4 p/3 p/5
Expected: Error messaging stating that dropping of multiple dogs from multiple programs is not supported.
-
-
Invalid drop command
- Test case:
drop invalidCommand
Expected: Error status message indicating wrong command format.
- Test case:
Help Command
- Opening the help window
- Test case:
help
Expected: Opens a pop-up window that shows the command summary and provides a link to the user guide.
- Test case:
Exit Command
- Test case:
exit
Expected: The program should exit and close.
Appendix: Effort
Throughout the development, our team wanted to make Pawbook easy to use, intuitive and presentable. After countless group discussions, physical meetings and additional effort leading up to submission, we managed to pull through and present a usable and functioning product that we are proud of. Amassing over 14,000 lines of code combined, we had to stick to strict internal deadlines, manage conflicts and maintain a culture of open communication and transparency. We also took the liberty to call for group meetings whenever needed, going beyond just the usual meetings to make sure everyone is in sync.
The first step of development was abstracting the “entity” that was used in AddressBook. Instead of just a Person entity, we realized that we needed to create three entities: Dog, Owner and Program. This included a great deal of refactoring and involved the abstraction of an Entity class that is inherited by all three classes. The alternative was a simple solution would be to duplicate the Person
class 3 times and have 3 separate containers alongside 3 different GUI components. However, this naive implementation is only good as a proof-of-concept, as it greatly violated the DRY principle.
The second challenge was deciding what type of data structure we wanted to use for storing all the entities. Because of the relationship between owners, dogs and programs, we knew that there must be a way for the entities to call on each other. However, we did not want to store the related objects directly in each entity as that would lead to very high coupling. We came up with an ID system that allows us to refer to each entity by ID. However, we were stuck when trying to implement the hashmap data structure that we were initially thinking of using. This was because changing the internal data structure would greatly impact all aspects of the application, including UI, testing and functionality. We then decided to refactor the internal list structure to accept a Pair
class, containing the ID as the key and the object as the value. This was yet another huge refactoring that we had to work through to migrate from the index-based system over to an ID-based one.
Once the bottleneck on the underlying data structure was finally completed, we had to think of how to refactor the functions such that they were able to accept all three entities. Additionally, we had to think of all the features that we wanted to accomplish to help us achieve our target proposition. With all of us taking one or more commands, we worked in parallel to push out new commands such as list
, view
, schedule
, enrol
, drop
while heavily refactoring existing commands and improving on them to not just work with the three new entities, but also change the way the results were displayed. We decided that we wanted the display results not to follow numerical ordering, but in order of relevance and sense from the user perspective.
In terms of testing, we are proud to say that our test coverage is over the 77% mark, above the original coverage of AB3 which was 72%. This was because the team really pulled together to bring our coverage up leading to the final submission, ensuring that our tests were comprehensive enough to not only cover majority of the functional code, but also the possible corner cases.
We also placed emphasis on GUI, making sure that our GUI was suitable and aesthetically pleasing for users. Through the process, we also had to learn a great deal of FXML syntax as we did away with SceneBuilder which we thought was hard to use and inflexible. Hence, we directly edited the code instead. It was also necessary to edit the CSS to change the theme of the application.
While Pawbook inherited a GUI from AddressBook, we made a conscious effort to not revolve the product too heavily on the GUI. Instead of having separate tabs for each of the entities, we decided to make use of the existing ListView
to display the various types of entities, allowing the user to switch between them using the list
command rather than requiring that the user leave their keyboard to reach for their mouse in order to perform a trivial task like this.
Finally, the team made additional effort into making sure that the documentation was organised, comprehensive and easy to read. We all had to pick up PlantUML notation to create the UML diagrams such as activity diagrams and sequence diagram. Before submission, we made sure to standardize and make the formatting consistent, positioning of diagrams and overall flow and logic of the User Guide and this Developer Guide.