Refer to the guide Setting up and getting started.
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main (consisting of classes Main and MainApp) is in charge of the app launch and shut down.
The bulk of the app's work is done by the following 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 hard disk.Commons represents a collection of classes used by multiple other components.
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 deleteContact 1.
Each of the four main components (also shown in the diagram above),
interface with the same name as the Component.{Component Name}Manager class (which follows the corresponding API interface mentioned in the previous point.For example, the Logic component defines its API in the Logic.java interface and implements its functionality using the LogicManager.java class which follows the Logic interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
The API of this component is specified in Ui.java
The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, ContactListPanel, StatusBarFooter etc. All these, including the MainWindow, inherit from the abstract UiPart class which captures the commonalities between classes that represent parts of the visible GUI.
The UI component uses the 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,
Logic component.Model data so that the UI can be updated with the modified data.Logic component, because the UI relies on the Logic to execute commands.Model component, as it displays Contact object residing in the Model.API : Logic.java
Here's a (partial) class diagram of the Logic component:
The sequence diagram below illustrates the interactions within the Logic component, taking execute("deleteContact 1") API call as an example.
Note: The lifeline for DeleteContactCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
How the Logic component works:
Logic is called upon to execute a command, it is passed to an ContactBookParser object which in turn creates a parser that matches the command (e.g., DeleteContactCommandParser) and uses it to parse the command.Command object (more precisely, an object of one of its subclasses e.g., DeleteContactCommand) which is executed by the LogicManager.Model when it is executed (e.g. to delete a contact).Model) to achieve.CommandResult object which is returned back from Logic.Here are the other classes in Logic (omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
ContactBookParser class creates an XYZCommandParser (XYZ is a placeholder for the specific command name e.g., AddContactCommandParser) which uses the other classes shown above to parse the user command and create a XYZCommand object (e.g., AddContactCommand) which the ContactBookParser returns back as a Command object.XYZCommandParser classes (e.g., AddContactCommandParser, DeleteContactCommandParser, ...) inherit from the Parser interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model component,
Contact objects (which are contained in a UniqueContactList object).Contact objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Contact> 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.UserPref object that represents the user's preferences. This is exposed to the outside as a ReadOnlyUserPref objects.Model represents data entities of the domain, they should make sense on their own without depending on other components)Note: An alternative (arguably, a more OOP) model is given below. It has a Tag list in the ContactBook, which Contact references. This allows ContactBook to only require one Tag object per unique tag, instead of each Contact needing their own Tag objects.
API : Storage.java
The Storage component,
ContactBookStorage and UserPrefStorage, which means it can be treated as either one (if only the functionality of only one is needed).Model component (because the Storage component's job is to save/retrieve objects that belong to the Model)Classes used by multiple components are in the seedu.address.commons package.
This section describes some noteworthy details on how certain features are implemented.
The Trip management system allows travel agents to create, edit, delete, and list trips, which are essential for organizing travel plans for customers. Below are the details of its implementation.
In the current implementation, there is intentionally no direct relationship between Trip and Contact entities. This design decision was made to provide:
This approach supports the current use case where a travel agent might quickly create a trip record with customer names before fully registering those customers as contacts in the system.
Both Contact and Trip entities support notes through the nts/ parameter prefix. When parsing commands like addContact, editContact, addTrip, and editTrip, developers should be aware of the following important behavior:
n/, p/, e/, a/, t/, acc/, i/, d/, c/) appear within the note content, they will be interpreted as separate parameters rather than part of the note text.addTrip n/Europe Trip acc/Grand Hotel i/Sightseeing d/1/6/2024 nts/Remember to book n/train tickets, the text "n/train tickets" would not be part of the note - instead, "n/train tickets" would be treated as a separate name parameter.
The implementation follows these steps:
AddressBookParser identifies that the command type is addTrip based on the command word and creates an instance of AddTripCommandParser to parse the user input.
AddTripCommandParser extracts values corresponding to the required prefixes:
n/ must contain a non-empty trip name.a/ must contain a non-empty accommodation.i/ must contain a non-empty itinerary.d/ must contain a valid trip date in the format d/M/YYYY.cn/ is optional and can be specified multiple times.note/ is optional and contains additional information about the trip.
kjIf any of the required prefixes are missing or invalid, AddTripCommandParser throws a ParseException. Otherwise, it creates a new instance of AddTripCommand based on the parsed input.
When executed, AddTripCommand:
CommandExceptionNOTE: TravelHub identifies a trip as duplicate if their trip names match (case-insensitive) with an existing trip in the trip book.
The delete trip feature allows users to remove trips from the trip book by specifying the trip's index in the displayed list.
AddressBookParser identifies that the command type is deleteTrip based on the command word and creates an instance of DeleteTripCommandParser to parse the user input.
DeleteTripCommandParser extracts the index from the command arguments and ensures:
If the index is invalid, DeleteTripCommandParser throws a ParseException. Otherwise, it creates a new instance of DeleteTripCommand based on the user input.
Upon execution, DeleteTripCommand:
CommandExceptionmodel.deleteTrip(tripToDelete) to remove the trip from the trip bookCommandResult with a success messageThe edit trip feature allows users to modify the details of an existing trip by specifying the trip's index in the displayed list and the new details.
AddressBookParser identifies that the command type is editTrip based on the command word and creates an instance of EditTripCommandParser to parse the user input.
EditTripCommandParser extracts the index and provided fields from the command arguments and ensures:
If the input is invalid, EditTripCommandParser throws a ParseException. Otherwise, it creates a new instance of EditTripCommand based on the user input.
Upon execution, EditTripCommand:
CommandExceptionTrip instance with the updated detailsCommandException if a duplicate is foundCommandResult confirming the successful editThe list trip feature allows users to view all trips or filter trips by date.
AddressBookParser identifies that the command type is listTrip based on the command word and creates an instance of ListTripCommandParser to parse the user input.
ListTripCommandParser checks if additional arguments are provided:
ListTripCommand that will show all tripsListTripCommand with the filter dateUpon execution, ListTripCommand:
CommandResult indicating the trips are listedTrips are stored in a JSON format similar to contacts. The TripBook class maintains a list of trips in an UniqueTripList, which ensures that there are no duplicate trips. The Storage component handles saving and loading of trips from disk.
Each Trip object contains:
TripName that uniquely identifies the tripAccommodation specifying where customers will stayItinerary describing the planned activitiesTripDate in the format d/M/YYYYNote containing additional information about the tripAll trip data is automatically saved when changes are made and loaded when the application starts.
Target User Profile:
Value Proposition:
TravelHub addresses these challenges by providing:
Scope boundaries:
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | travel agent | add contacts along with comprehensive details | profile and contact them |
* * * | travel agent | delete contacts | remove invalid or non-existent contacts |
* * * | travel agent | add trips with information like dates, customers, accommodation and itineraries | check all the consolidated information for a trip |
* * * | travel agent | delete trips | remove outdated or irrelevant information |
* * * | travel agent | tag contacts | know whether they are a customer or service |
* * * | travel agent | add notes to customer profiles or trips | keep track of special requests or important details |
* * | travel agent | update contact information | keep up-to-date information when their details change |
* * | travel agent | update trip information | keep up-to-date information when trip details change |
* * | travel agent | search for specific contacts | quickly locate the information I need |
* * | travel agent | change the date of the trip | accommodate flexibility in plans |
* * | travel agent | refer to all possible commands | refer to instructions when I forget how to use the app |
* * | travel agent | view the list of trips for a specific date | get information in a accesible and organised manner |
* | potential travel agent | see the app populated with sample customer profiles and trips | understand how the data is organized and what I can achieve with the system |
* | new travel agent | clear the sample data with a single command | start with a clean slate for my customer data and trip records |
* | long-time travel agent | remove completed trips and inactive customer profiles | keep my workspace uncluttered and focused on current travel plans |
* | clumsy travel agent | change my previous actions | correct my mistakes |
* | travel agent | view my customers by their tags | easily compare contacts of the same tag with one another |
(For all use cases below, the System is the TravelHub and the Actor is the Travel Agent, unless specified otherwise)
Use case: See Usage Instructions
MSS
Travel Agent requests to see usage instructions.
System displays a list of available commands and their formats.
Travel Agent reads the instructions.
Use case ends.
Extensions
Use case: Add a Contact
MSS
Travel Agent requests to add a new contact with details (name, phone number, email, address, tag and notes).
System validates the contact details.
System adds the contact to the contact list.
System displays a success message for adding the contact.
Use case ends.
Extensions
Use case: Add a Trip
MSS
Travel Agent requests to add a new trip with details (trip name, accommodation, itinerary, date, customer names and notes).
System validates the trip details.
System adds the trip to the trip list.
System displays a success message for adding the trip.
Use case ends.
Extensions
Use case: Delete a Contact
MSS
Travel Agent requests to delete a specific contact by index.
System deletes the contact.
System displays a success message for deleting the contact.
Use case ends.
Extensions
Use case: Delete a Trip
MSS
Travel Agent requests to delete a specific trip by index.
System deletes the trip.
System displays a success message for deleting the trip.
Use case ends.
Extensions
Use case: Edit a Contact
MSS
Travel Agent requests to list all contacts.
TravelHub shows a list of contacts.
Travel Agent requests to edit a specific contact via an index.
System validates the index and new contact details.
System updates the contact with the new details.
System displays a success message for editing the contact.
Use case ends.
Extensions
Use case: Edit a Trip
MSS
Travel Agent requests to list all trips.
TravelHub shows a list of trips.
Travel Agent requests to edit a specific trip via an index.
System validates the index and new trip details.
System updates the trip with the new details.
System displays a success message for editing the trip.
Use case ends.
Extensions
Use case: Find a Contact
MSS
Travel Agent find for contacts using a keyword.
System searches for matching contacts and trips.
System displays a list of matching results.
Use case ends.
Use case: Clear All Data
MSS
Travel Agent enters the clear command to remove all contacts and trips.
System displays a confirmation pop-up asking if the user really wants to clear all data.
Travel Agent confirms by clicking "Yes".
System clears all contact and trip data from the application.
System displays a success message: "Address book and trip book have been cleared!"
Use case ends.
Extensions
17 or above installed.This section defines key terms used in the user guide to ensure clarity and understanding.
| Term | Definition |
|---|---|
| CLI | Command Line Interface. A text-based interface where users interact with the application by typing commands. |
| GUI | Graphical User Interface. A visual interface where users interact with the application through graphical elements like buttons and menus. |
| Mainstream OS | Operating systems that are widely used, such as Windows, Linux, Unix, and macOS. |
| JSON | JavaScript Object Notation. A lightweight data format used for storing and transferring data in a human-readable format. |
| API | Application Programming Interface. A set of rules and protocols that allow different software components to communicate with each other. |
| OOP | Object-Oriented Programming. A programming paradigm based on the concept of "objects," which can contain data and code to manipulate that data. |
| Model | A component in the application that manages the data and business logic. |
| UI | User Interface. The part of the application that users interact with, including screens, buttons, and other visual elements. |
| Storage | A component in the application responsible for saving and retrieving data, such as contact information and user preferences. |
| Command | An instruction given by the user to the application to perform a specific action, such as adding or deleting a contact. |
| Parser | A component that interprets user input and converts it into commands that the application can execute. |
| ObservableList | A list that allows external components to observe changes to its contents, typically used in the UI to automatically update when data changes. |
| UserPref | User Preferences. Settings or configurations that the user can customize, such as the application's appearance or behavior. |
| Customer Contact | A contact tagged as "customer," representing an individual who is a client of the travel agency. |
| Service Contact | A contact tagged as "service," representing a business or service provider (e.g., hotels, resorts, restaurants and attractions). |
| Trip | A planned journey or vacation, including details such as trip name, start date, customers, accommodation, itineraries and notes |
| Note | Additional information or details added to a customer profile or trip, such as special requests or important reminders. |
Currently, there is no relationship between Trip and Contact entities. In future iterations, we plan to implement a proper relationship between these entities to enhance data integrity and enable more powerful features.
Proposed Implementation:
Benefits:
Implementation Challenges:
Currently, if parameter prefixes (e.g., n/, p/, e/, a/, t/, acc/, i/, d/, c/) appear within note content, they are treated as separate parameters rather than as part of the note. To allow users to include these prefix patterns in their notes, we plan to implement an escape character mechanism.
Proposed Implementation:
\) that users can place before parameter prefixes in notesnts/Remember to call \p/12345678 would include "p/12345678" as part of the note textBenefits:
Implementation Challenges:
Currently, trips only have a start date. To better support trip planning and tracking, we plan to enhance the Trip model to include an end date.
Proposed Implementation:
TripEndDate class similar to the existing TripDate classed/5/6/2024)Benefits:
Implementation Challenges:
Currently, all commands must be entered in exact camelCase format (e.g., addTrip, editContact, help), which can be error-prone for users. Typing ADDTRIP or Addtrip or addtrip, which hurts usability—especially for new users or CLI users accustomed to case-insensitive input.
Proposed Implementation:
COMMAND_WORD constants in command classes to lowercase (e.g., COMMAND_WORD = "addtrip";)addtrip, AddTrip, ADDTRIP, AdDtRiP — all should work)Benefits:
Implementation Challenges:
Given below are instructions to test the app manually.
Note: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.
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.
Deleting a contact while all contacts are being shown
Prerequisites: List all contacts using the listContact command. Multiple contacts in the list.
Test case: deleteContact 1
Expected: First contact is deleted from the list. Command Output Box displays the details of the deleted contact.
Test case: deleteContact 0
Expected: No contact is deleted. Error message shown: The contact index provided is invalid.
Other incorrect delete commands to try: deleteContact, deleteContact x, ... (where x is larger than the list size)
Expected: Similar to previous.
Simulating a corrupted data file
TravelHub.jar file.data/ folder and open the addressbook.json file."phone" : "98765432Z",Expected: Application starts up with an empty address book.