Developer Guide
Table of Contents
- Table of Contents
- Glossary
- Setting up, getting started
- Design
- Implementation
- Appendix: Requirements
- Appendix: Instructions for manual testing
- Appendix: Effort
- Appendix: Planned Enhancements
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Opening: Item representing an internship opening
- Keydate: Item representing a event tied to a particular date or deadline
Setting up, getting started
Refer to the guide Setting up and getting started.
Design

.puml
files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
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
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 hard disk.
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 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class which follows the corresponding APIinterface
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.
UI 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
, OpeningListPanel
, 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,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysOpening
object residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
How the Logic
component works:
- When
Logic
is called upon to execute a command, it uses theUltronParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add an opening). - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
The Sequence Diagram below illustrates the interactions within the Logic
component for the execute("delete 1")
API call.

DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
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:
- When called upon to parse a user command, the
UltronParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theUltronParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
The Model
component,
- stores Ultron data i.e., all
Opening
objects (which are contained in aUniqueOpeningList
object). - stores the currently ‘selected’
Opening
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Opening>
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. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Storage component
API : Storage.java
The Storage
component,
- can save both Ultron data and user preference data in json format, and read them back into corresponding objects.
- inherits from both
UltronStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the seedu.ultron.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add remark feature
The RemarkCommandParser
class parses the user input and returns a RemarkCommand
object. The RemarkCommand
object then accesses the Model
component to get its filteredOpenings.
The RemarkCommand
object accesses the filteredOpenings to get the opening at the specified index. It then uses the details of the retrieved opening along with a new remark to create a new opening.

RemarkCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The RemarkCommand
object then calls setOpening()
on Model
, passing in the openingToEdit and editedOpening. The Model
will then set the opening at the index specified to be the editedOpening.
Once the opening in the model has been changed, the result indicating the command’s success will be returned to LogicManager
and MainWindow
Show opening details feature
The show
command was outlined with existing commands which take in indexes. It is similar to both the delete
and edit
commands, accessing the displayed list in the Model
component.
The ShowCommandParser
class parses the user input and returns a ShowCommand
object. The ShowCommand
object then accesses the Model
component to get the opening at the specified index from the openings list.

ShowCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
An Index
is tracked by the model component and updated on every ShowCommand
execution. A CommandResult
object is then returned to the LogicManager
.
The MainWindow
class then receives the CommandResult
object and calls the handler handleShow
. The method gets the opening at the specified index from the LogicManager
which in turn accesses the ModelManager
.
A new OpeningDetailsPanel
is created and displayed to the user. The OpeningDetailsPanel
is a UiPart
which is a JavaFX
component. The OpeningDetailsPanel
is created with the retrieved opening.
A simplified sequence was employed for mouse clicks. The OpeningListPanel
class handles the mouse click event and calls the logic component to set the selected opening. The MainWindow
class then calls the handleShow
method to recreate the OpeningDetailsPanel
with the selected opening.
Design considerations:
Aspect: How show command executes:
-
Alternative 1 (current choice): Access the opening at the specified index from the displayed list in the
Model
component.- Pros:
- Easy to implement.
- Meets the basic requirement of the feature.
- Simple to understand.
- Cons: May not be very useful if the user wants to see the details of an opening that is not displayed in the current list.
- Pros:
-
Alternative 2: Access the opening at the specified index from the full list in the
Model
component.- Pros:
- More useful as the user can see the details of any opening in Ultron.
- Flexible usage.
- Follows the
find
command which also accesses the full list.
- Cons: We must ensure that the index is still valid even if the list is filtered or sorted, which may be difficult to implement.
- Pros:
Upcoming keydates feature
Implementation
The upcoming
feature takes in a positive integer as the argument. This integer represents the number of days to consider, excluding today. The feature will filter openings based on whether their keydate falls between today and the specified number of days in the future, including today. It also filters out openings without any keydates.
Given below is an example usage scenario and ow the upcoming feature’s mechanisms behaves in steps.
Step 1. The user launches the application with pre-existing openings added, each with certain keydates, such as Interview: 2023-10-10
. The user decides to only want to focus on openings that has key events coming up in the next 5 days. The user executes upcoming 5
to filter the openings to only show openings with keydates within 5 days.

The following sequence diagram shows how the status operation works:
Step 2. The UltronParser
class parses the user input of upcoming 5
and returns a UpcomingCommand
object with a OpeningsBeforeDaysPredicate
representing the 5
portion of the input.
Step 3. The LogicManager
then calls the execute()
of the UpcomingCommand
object, which accesses the Model
component to update the current list of openings to be displayed. This new list will be filtered based on the OpeningsBeforeDaysPredicate
, checking through the full list of openings for openings within 5
days.
Step 4. The MainWindow
class receives the CommandResult
object and the new filtered list is displayed for the user.
Design considerations:
Aspect: Allow for inputs in months, weeks and days rather than days
-
The benefit to split inputs might not be so apparent since users would usually only use this command nearer to the event dates.
-
Alternative 1 (current choice): Allow only input in terms of days.
- Pros:
- Easier to implement.
- Efficient for users since they usually want to look for events close to the current date.
- Cons:
- Less efficient if users want to find events which are further into the future.
- Pros:
-
Alternative 2: Allow for input in terms of months, weeks and days.
- Pros:
- Users can give inputs without converting the period to days.
- Cons:
- Increased complexity in terms of parsing
- Longer command line with more fields increases the amount the user has to type to use the command.
- Pros:
Status filtering feature
Implementation
The status
feature command was outlined with an existing command which takes in keywords. It is similar to the find
command, filtering based on the full list in the Ultron
component. Unlike find
, it only accepts one keyword at a time.
Given below is an example usage scenario and how the status feature’s mechanisms behaves in steps.
Step 1. The user launches the application with pre-existing openings added, each with different status values, such as APPLIED
or INTERVIEWING
. The user decides to only want to focus on openings that he has only just applied to. The user executes status applied
to filter the openings to only show openings with APPLIED
status.

The following sequence diagram shows how the status operation works:

StatusCommand
and ContainsStatusPredicate
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Step 2. The UltronParser
class parses the user input of status applied
and returns a StatusCommand
object with a ContainsStatusPredicate
representing the applied
portion of the input.
Step 3. The LogicManager
then calls the execute()
of the StatusCommand
object, which accesses the Model
component to update the current list of openings to be displayed. This new list will be filtered based on the ContainsStatusPredicate
, checking through the full list of openings for openings with the status APPLIED
.
Step 4. The MainWindow
class receives the CommandResult
object and the new filtered list is displayed for the user.
Design considerations
Aspect: How many keywords status command allows:
- There is not much benefit to allowing more than one keyword at a time and users can avoid needless clutter.
-
Alternative 1 (current choice): Only allow one keyword.
- Pros:
- Easier to implement.
- Largely meets needs of users in a typical setting.
- Users can avoid needless clutter.
- Cons:
- Less flexibility for user if they ever want to filter based on two keywords.
- Pros:
-
Alternative 2: Allow one or more keywords.
- Pros:
- More flexibility for user.
- Cons:
- Increased complexity in terms of parsing, validation and logic.
- Need to add-on sorting functionality to sort filtered openings by status to prevent disorganisation.
- Pros:
Appendix: Requirements
Product scope
Target user profile:
- has a need to manage a significant number of internship applications
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition: manage openings faster than a typical mouse/GUI driven app
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I can … | So that I can… |
---|---|---|---|
* * * |
potential user exploring the app | see the app populated with sample openings | easily see how the app will look when it is in use. |
* * * |
user | add an opening regarding the internship I am interested in | keep note of it |
* * * |
user | delete an opening | remove unwanted openings |
* * * |
user | see all applications | track my progress |
* * * |
user | add multiple keydates | store all important dates for each opening |
* * * |
user | link certain key events of an opening to a date | remember which event happens on what date |
* * * |
user | sort my keydates in order | see which keydate of which opening to focus on |
* * * |
user | see openings of a specific status | view specific kinds of openings at once |
* * * |
user | see what keydates are nearing | avoid missing any keydates of any openings |
* * |
user | add remarks to my openings | add any addtional details tied to specific openings |
* * |
user | see submission deadlines | check them |
* |
user | see the total number of accepted applications | celebrate my success |
* |
user | see all the outcomes of my application | properly assess my options |
Use cases
(For all use cases below, the System is Ultron
and the Actor is the user
, unless specified otherwise)
Use case: UC 1 - Adding an opening
MSS
- User enters a command to add an opening
- Ultron adds the opening to its list of openings Use case ends.
Extensions
1a. Ultron detects an error in the entered data. 1a1. Ultron informs the user that the data is invalid Use case ends
Use case: UC 2 - Deleting an opening
MSS
- User enters a command to delete an opening
- Ultron deletes the opening from its list of openings Use case ends.
Extensions
1a. Ultron detects an error in the entered data. 1a1. Ultron informs the user that the data is invalid Use case ends
Use case: UC 3 - Editing an opening
MSS
- User enters a command to edit an opening
- Ultron edits the opening based on the user input parameters Use case ends.
Extensions
1a. Ultron detects an error in the entered data. 1a1. Ultron informs the user that the data is invalid Use case ends
Use case: UC 4 - See all openings
MSS
- User enters a command to list all openings
- Ultron shows the user a list of all the openings that the user has added Use case ends.
Extensions
1a. List is empty 1a1. Ultron informs the user that the list is currently empty Use case ends
Use case: UC 5 - See all openings with a specific status
MSS
- User enters a command to list all openings of a specific status
- Ultron shows the user a list of all the openings that match the status given by the user Use case ends.
Extensions
1a. No opening contains the status specified by the user 1a1. Ultron informs the user that no openings of that status exist Use case ends
Use case: UC 6 - List openings with upcoming keydates
MSS
- User enters a command to list all openings by keydates in ascending order, specifying a number of days
- Ultron shows the user a list of openings that contain keydates, sorted by keydates in ascending order Use case ends.
Extensions
1a. No opening contains relevant keydates 1a1. Ultron informs the user that no openings contain keydates Use case ends
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - The app should be fast and respond within 100ms when users input commands.
- The app should start up and load the list from a saved file within 1 second of opening.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.

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 openings. 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 via command line
- Test case:
exit
Expected: App exits with no issues and window closes
- Test case:
Adding an opening
-
Adding an opening that does not already exist in the list
-
Prerequisites: Openings that are being added do not already exist in the list. Meaning that the opening does not share both the company name and position name with another opening
-
Test case:
add p/position c/company e/example@example.com s/applied
Expected: An opening is added to the end of the list. Success message shown in the status message. Opening added contains fields that match those given in the command line. -
Test case:
add p/position c/company s/applied
Expected: No opening is added. Error details shown in the status message. Command line remains the same. -
Other incorrect add commands to try:
add
Expected: Similar to previous.
-
-
Trying to add an opening that already exists in the list
-
Prerequisites: Openings that are trying to be added already exist in the list. Meaning that the opening shares both the company name and position name with another opening
-
Test case:
add p/position c/company e/example@example.com s/applied
Expected: No opening is added. Error details shown in the status message. Command line remains the same.
-
Editing an opening
-
Editing an opening to change a field
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
edit 1 p/new position
Expected: First opening gets edited. Success message shown in the status message. First opening now has “new position” in its position field. -
Test case:
edit 0 p/new position
Expected: No opening is edited. Error details shown in the status message. Command line remains the same. -
Other incorrect edit commands to try:
edit
,edit x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Editing an opening to add a deadline
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
edit 1 d/Online Assessment@2023-04-01
Expected: First opening gets edited. Success message shown in the status message. First opening now contains a deadline named “Online Assessment” due 2023-04-01.
-
-
Editing an opening to replace a deadline
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. First opening contains a deadline -
Test case:
edit 1 d/Interview@2023-04-05
Expected: First opening gets edited. Success message shown in the status message. First opening now contains a deadline named “Interview” due 2023-04-05.
-
-
Editing an opening to remove a deadline
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. First opening contains a deadline -
Test case:
edit 1 d/
Expected: First opening gets edited. Success message shown in the status message. First opening now contains no deadlines
-
Showing an opening
-
Viewing the details of an opening while all openings are being shown
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
show 1
Expected: Details of first opening is shown in the right panel. Details of the shown opening shown in the status message. -
Test case: click on an opening on the left panel
Expected: Details of clicked opening is shown in the right panel. -
Test case:
show 0
Expected: No new opening is shown. Error details shown in the status message. Command line remains the same. -
Other incorrect show commands to try:
show
,show x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
Adding, editing or deleting a remark
-
Adding a remark
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
remark x r/3 rounds of interviews
(where x is the index of an opening without an existing remark)
Expected: Opening gets edited. Success message shown in the status message. Opening now has “3 rounds of interviews” in its remark field, visible after using the show command. -
Test case:
remark 0 r/3 rounds of interviews
Expected: No opening is edited. Error details shown in the status message. Command line remains the same. -
Other incorrect remark commands to try:
remark
,remark x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting a remark
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
remark x r/
(where x is the index of an opening with an existing remark)
Expected: Opening gets edited. Success message shown in the status message. Opening now has no remarks in its remark field.
-
-
Editing a remark
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. First opening contains a deadline -
Test case:
remark x r/Has difficult online assessment
(where x is the index of an opening with an existing remark)
Expected: Opening gets edited. Success message shown in the status message. Opening now has “Has difficult online assessment” in its remark field, visible after using the show command.
-
Deleting an opening
-
Deleting an opening while all openings are being shown in list
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. -
Test case:
delete 1
Expected: First opening is deleted from the list. Details of the deleted opening shown in the status message. -
Test case:
delete 0
Expected: No opening is deleted. Error details shown in the status message. Command line remains the same. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting an opening currently being shown in the right panel
-
Prerequisites: List all openings using the
list
command. Multiple openings in the list. Show the opening to be deleted usingshow x
command (where x is index of opening to be deleted) -
Test case:
delete x
Expected: Opening with index x is deleted from the list. Details of the deleted opening shown in the status message. Right panel is now empty.
-
Clearing all openings
-
Clearing all openings
- Test case:
clear
Expected: All openings are deleted from the list. Success message shown in status message.
- Test case:
Finding an opening by company or position
-
Finding an opening by keyword
-
Prerequisites: At least one opening with the word “developer” in its position or company name exists in the list
-
Test case:
find developer
Expected: List filters out all openings that do not have the word “developer” in its position or company name. Number of found openings is shown in the status message. Command line remains the same
3.Test case:
find
Expected: List remains the same. Error details shown in the status message. Command line remains the same. -
Finding an opening by status
-
Finding an opening by status
-
Prerequisites: At least one opening with “interviewing” as its status
-
Test case:
status interviewing
Expected: List filters out all openings that do not have “interviewing” as its status. Number of found openings is shown in the status message. Command line remains the same.
3.Test case:
status
Expected: List remains the same. Error details shown in the status message. Command line remains the same. -
Getting openings with upcoming deadlines
-
Getting openings with upcoming deadlines
-
Prerequisites: Multiple openings in the list. Openings contain deadlines not passed due within 5 days of today.
-
Test case:
upcoming 5
Expected: List shows openings that contain deadlines not passed within 5 days of today. Openings are sorted in order, with the openings with the closer deadlines on top. Number of found openings is shown in the status message. -
Test case:
upcoming
Expected: List remains the same. Error details shown in the status message. Command line remains the same.
-
Appendix: Effort
Evaluation of Implementation
This table summarises the difficulty level and effectiveness of each feature on a scale of 1 to 5.
Feature | Difficulty | Effectiveness |
---|---|---|
Keydates | 3 | 5 |
Keydate sorting | 3 | 4 |
Status command | 2 | 3 |
Remark | 1 | 2 |
Upcoming command | 4 | 4 |
UI enhancements | 4 | 3 |
Difficulties faced
-
Keydates
-
Keydates were implemented using the existing ‘Tag’ class as a baseline. Refactoring was done to both the ‘Tag’ model and ‘TagParser’ to allow for the creation of keydates.
-
There were more issues with the ‘Tag’ model than expected, since the key and date had to be further extracted from the input arguments. This lead to multiple separator characters being tested out before settling on the current implementation. The tokenisation of the input arguments was also haphazardly inserted, since the alternative would require a complete overhaul of the ‘ArgumentTokenizer’ class.
-
Input validation was often overlooked and only discovered during testing. Empty or untrimmed keys were initially accepted and dates were not checked for validity. This was fixed by adding additional checks in the parser.
-
Date validation for certain invalid dates in our keydates, such as 29 February in a non-leap year or 31 November, was missed out due to not realising our implementation would not account for it. Initial implementations of date validation using LocalDate and DateTimeFormatter does not check for such invalid dates. Afterwards, we had find a new method of parsing and validation in the form of SimpleDateFormat that sufficiently validates input dates.
-
-
Sorting of keydates
-
The initial collection of keydates was implemented using a HashSet, which does not allow for ordering. This was changed an ArrayList, which allowed for ordering of keydates. There are further issues with the logic component and its use of a filtered list which we eventually identified and replaced with an observable list.
-
Comparison of keydates was initially implemented with a custom comparator. This was changed to implementing the ‘Comparable’ interface and defining a ‘compareTo’ method, which allowed for the sorting of keydates to be done in the ‘Keydate’ class itself.
-
-
Status command
- The status command was rather straightforward and made use of existing Predicate classes. The only issue was the lack of a ‘Status’ class, which was rectified by creating a new class.
-
Remark command
- The existing implementation from our team project tutorial was used as a baseline. Minor changes were made hence did not pose any major issues.
-
Upcoming command
-
This command required the most effort to implement. The initial proposal was to have a sorting command and an upcoming command, but this was changed to a single upcoming command.
-
A opening predicate and a opening comparator had to be implemented for the two-step process of filtering and sorting
-
-
UI enhancements
-
The initial list view limited the amount of information that could be displayed. A details panel was added to display more information about the opening.
-
This required restructuring of the UI components and the logic components. The logic components had to be modified to allow for the details panel to be updated when a new opening is selected.
-
Achievements
A large part of the project was spent on refactoring the codebase and ensuring practical design. Many features were remade after testing and discussion concluded that the current implementation was not ideal. We also invested significant time into improving the UI, which was not a requirement of the project.
Appendix: Planned Enhancements
Enhancement 1: Optional Contact Field
-
The current email field for each opening is not optional. This is not ideal as some openings do not require an email address and users may find it inconvenient to have to enter a dummy email address. An email address might also not be the most appropriate contact information for some openings.
-
We propose to replace the email field with an optional contact field. This field can be used to store any contact information, e.g. phone number, email address, LinkedIn profile link, career portal link. This will allow users to store any contact information they wish to have for each opening.
Enhancement 2: Keydates should accept time
-
The current keydate field that can be added to openings only accept dates in the format of YYYY-MM-DD. This means that users cannot add the time of deadlines to keydates. For example, a user might want to include the time of his interview in the keydate.
-
We propose to include the option for keydates to include a time. The format for a keydate, which used to be “Event@YYYY-MM-DD”, will now become “Event@YYYY-MM-DD[hh:mm]” Adding a time to a keydate will not be compulsory, meaning that users can continue to add keydates without a timing.
Enhancement 3: Position should allow for special characters
-
The current position field that can be added to openings only accept positions that are alphanumeric with whitespace. This means that users cannot add special characters to their position. For example, a user might want to add a position for
UI/UX designer
. -
We propose to add additional parsing functionality to allow users to include special characters in the position field when adding or editing an opening, like
edit 1 p/UI/UX designer
. We will also need to adjust our parsing for our prefixes such asp/
, such that it does not introduce any bugs when the field value also includes the special character/
.
Enhancement 4: Addition of keydates should be accumulative
-
The current keydates field can be changed using the
edit
command. This change overwrites the current keydates of the opening being edited. This means that users have to re-enter every single past keydate when adding a new one to maintain the history. For example, a user might already have a keydateOA@2023-11-11
and wants to addInterview@2023-11-13
, the user will have to enter the commandedit 1 d/OA@2023-11-11 d/Interview@2023-11-13
. -
We propose to allow edit to still overwrite the keydates, but we add new commands
addkeydate
anddeletekeydate
. These two commands will take in an index and keydates as parameters to add new keydates or delete existing keydates for the indexed opening. Example usages would beaddkeydate 1 Interview@2023-11-13
anddeletekeydate 1 OA@2023-11-11
. It will also be able to take in multiple keydates and function accordingly (all input keydates fordeletekeydate
must be valid, ie if one of them do not exist, command fails).