During the development of this application, the following AI tools were utilized:
These AI tools primarily contributed to:
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 del 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, PersonListPanel, 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 Person 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("del 1") API call as an example.
Note: The lifeline for DeleteCommandParser 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 AddressBookParser object which in turn creates a parser that matches the command (e.g., DeleteCommandParser) and uses it to parse the command.Command object (more precisely, an object of one of its subclasses e.g., DeleteCommand) which is executed by the LogicManager.Model when it is executed (e.g. to delete a person).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:
AddressBookParser class creates an XYZCommandParser (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 a XYZCommand object (e.g., AddCommand) which the AddressBookParser returns back as a Command object.XYZCommandParser classes (e.g., AddCommandParser, DeleteCommandParser, ...) inherit from the Parser interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model component,
Person objects (which are contained in a UniquePersonList object), all Job objects (which are contained in a UniqueJobList object) and all Application objects (which are contained in a UniqueApplicationList).Person, Job, Application objects (e.g., results of a search query) as a separate stackable filtered_ list which is exposed to outsiders as an unmodifiable ObservableList<Person> 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 Skill list in the TalentMatch, which Person references. This allows TalentMatch to only require one Skill object per unique skill, instead of each Person needing their own Skill objects.
API : Storage.java
The Storage component,
AddressBookStorage, ApplicationsManagerStorage 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.
Target user profile:
Value proposition:
TalentMatch enables HR recruiters to manage the full recruitment lifecycle more efficiently than typical mouse/GUI driven applications by:
These features combine to provide HR recruiters with a comprehensive tool for managing the entire recruitment process from job creation to final candidate selection.
Priorities:
* * ** **| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | HR Recruiter | add a new person with their details | keep track of potential candidates for internship positions |
* * * | HR Recruiter | edit a person's information | update their details when they provide new information |
* * * | HR Recruiter | delete a person | remove entries of candidates no longer under consideration |
* * * | HR Recruiter | find persons by various criteria | quickly locate specific candidates without going through the entire list |
* * * | HR Recruiter | see a list of all persons | get an overview of all potential candidates |
* * * | HR Recruiter | add a job with title, rounds, and required skills | create new internship positions for candidates to apply to |
* * * | HR Recruiter | edit job details | update job requirements or descriptions as needed |
* * * | HR Recruiter | delete a job | remove positions that are no longer available |
* * * | HR Recruiter | find jobs by keywords | quickly locate specific job positions without browsing through all listings |
* * * | HR Recruiter | list all jobs | get an overview of all available positions |
* * * | HR Recruiter | create an application linking a person to a job | track which candidates are applying for which positions |
* * * | HR Recruiter | delete an application | remove incorrect applications or those no longer being considered |
* * * | HR Recruiter | advance an application to the next interview round | track a candidate's progress through the interview process |
* * * | HR Recruiter | find applications by status | quickly locate applications at specific stages in the recruitment process |
* * * | HR Recruiter | switch between person view and job view | focus on different aspects of the recruitment process as needed |
* * | HR Recruiter | view detailed information of a specific job | see its requirements and applicant distribution across interview rounds |
* * | HR Recruiter | view detailed information of an applicant from job view | see their qualifications and application progress without switching views |
* * | HR Recruiter | use command history | recall and reuse previous commands without retyping them |
* * | HR Recruiter | see a visual representation of application progress | quickly gauge where each candidate stands in the interview process |
* * | HR Recruiter | find applications for a specific job | focus on managing candidates for a particular position |
* * | HR Recruiter | find applications with a specific status for a specific job | manage candidates at the same stage in the interview process for a particular role |
* * | HR Recruiter | have context-specific commands | have a more intuitive workflow based on whether I'm in person view or job view |
* * | HR Recruiter | specify skills for both jobs and persons | match candidates to positions based on skill requirements |
* * | HR Recruiter | view all applications for a job | see all candidates being considered for a specific position |
* * | HR Recruiter | clear all data from the system | start fresh when beginning a new recruitment cycle |
* | HR Recruiter | have data automatically saved | not worry about losing information if the application closes unexpectedly |
* | HR Recruiter | view help information | understand how to use the commands in the system |
* | HR Recruiter | see a graphical representation of interview round distribution | quickly understand the distribution of applications across different stages |
* | HR Recruiter | continue searches based on previously filtered results | gradually narrow down my search to find exactly what I'm looking for |
* | HR Recruiter | have case-insensitive search for most fields | find results regardless of letter casing used |
(For all use cases below, the System is TalentMatch and the Actor is the HR manager (HR), unless specified otherwise)
Use case: Remove a person
MSS
User requests to list all persons.
TalentMatch shows a list of all persons with their indices.
User requests to delete a specific person in the list by their index.
TalentMatch deletes the person.
Use case ends.
Extensions
1a. User is in Job View.
2a. The given index is invalid.
Use case: Add a job
MSS
Extensions
3a. User provides invalid job details (missing required fields/ wrong format).
3b. TalentMatch finds an existing job with identical job title.
Use case: Create an application
MSS
Extensions
3a. The person doesn't exist in the system.
3b. The job doesn't exist in the system.
4a. TalentMatch detects an existing application for the same person and job.
Use case: List all jobs
MSS
Extensions
Use case: Delete an application
MSS
User requests to delete an application.
TalentMatch prompts user for job index and application index.
User selects the job index and application index in the list.
TalentMatch deletes the application.
Use case ends.
Extensions
1a. User is in Person View.
3a. User provides invalid job index or application index.
Use case: Find a job
MSS
User requests to list jobs.
TalentMatch shows a list of jobs.
User requests to find a job by a keyword.
TalentMatch filters and list any jobs that contain the full keyword.
Use case ends
Extensions
1a. User is in Person View.
3a. User mistypes the keyword.
17 or above installed.Mainstream OS: Windows, Linux, macOS - the operating systems that TalentMatch is designed to run on.
HR Recruiter: The main user of TalentMatch; a professional responsible for managing the application timeline and recruitment process for job candidates.
Applicant/Candidate: A prospective university student who is applying for a job opening.
Person: An entity in the TalentMatch system representing a potential job candidate with attributes such as name, phone number, email, address, university, and skills.
Job: An entity in the TalentMatch system representing an available position with attributes such as job title, required number of interview rounds, and required skills.
Application: A relationship entity linking a Person to a Job, tracking the progress of a candidate through the recruitment process for a specific position.
Interview Round: A stage in the recruitment process that a candidate must progress through, represented by a numerical value in the Application status.
Skill: A capability or technical knowledge that can be possessed by a Person or required by a Job, used for matching candidates to positions.
Person View: A UI mode that focuses on listing and managing Person entities.
Job View: A UI mode that focuses on listing and managing Job entities and their associated applications.
Application Status: A numerical value indicating a candidate's progress through the interview process:
UniquePersonList: A data structure in the Model component that stores all Person objects without duplicates.
UniqueJobList: A data structure in the Model component that stores all Job objects without duplicates.
UniqueApplicationList: A data structure in the Model component that stores all Application objects without duplicates.
Brownfield Project: A software development project that builds upon existing code rather than starting from scratch (as opposed to a greenfield project).
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
Saving window preferences
Shutdown
Adding a person
list command.add n/John Doe p/98765432 e/john@example.com a/123 Jurong Street s/NUS d/CSadd n/John Doeadd, add n/, add p/12345678Deleting a person
list command. Multiple persons in the list.del 1del 0delete, del x, ... (where x is larger than the list size)Finding a person
list command.find Johnfind 98765432find john@example.comAdding a job
listjob command.addjob jt/Software Engineer jr/3 k/Java k/Pythonaddjob t/Software Engineeraddjob, addjob t/, addjob s/JavaDeleting a job
listjob command. Multiple jobs in the list.deljob 1deljob 0deletejob, deljob x, ... (where x is larger than the list size)Finding a job
listjob command.findjob Softwarefindjob JavaCreating an application
list and listjob commands.addapp ij/1 ip/1addapp ij/0 ip/1addapp, apply ij/x ip/y, ... (where x or y is larger than the list size)Deleting an application
listjob command. Each job card contains multiple applications in the list.delapp ij/1 ia/1delapp ij/0 ia/1delapp, delapp ij/x ia/y, ... (where x is larger than the list size and y is larger than the number of applications for the said job)Finding applications
listjob command.findapp as/3findapp as/1findapp ij/1 as/1Switching views
switchswitchDealing with missing/corrupted data files
data/addressbook.json filedata/applicationsmanager.json filedata/addressbook.json file by adding invalid JSONdata/applicationsmanager.json file by adding invalid JSONAccessing help
helpTeam Size: 4
Improve duplicate person detection
Currently, duplicate detection for Person only uses the Person.name fields for comparison, which can inconvenience users wanting to add multiple contacts with the same name. It also results in issues like multiple people being able to be added to the address book with different names but the same contact details, which may not reflect a real-world scenario faithfully. We plan to extend duplicate detection to become more robust, comparing multiple fields (such as names, phone numbers, emails etc.), only considering a contact duplicate if multiple fields match. This logic is non-trivial.
Fix multiple window display issue
When using multiple screens, if users move the application to a secondary screen, and later switch to using only the primary screen, the GUI opens off-screen. We plan to implement logic to detect and remedy this scenario by ensuring the application window always appears within the bounds of available screens, eliminating the need for users to manually delete the preferences.json file.
Improve data recovery for corrupted storage files
Currently, when storage files (applicationsmanager.json and addressbook.json) are detected to have corruption or incorrect formatting, the application wipes user data and starts with a clean slate, resulting in complete data loss even from minor formatting errors. We plan to implement a more robust data recovery mechanism that attempts to salvage uncorrupted portions of the files, creates automatic backups before wiping data, and provides users with options to restore from previous states rather than immediately discarding all data.
Improve UI pie chart Currently, a bug in the legend and the pie chart component makes it such that past 33 jobs with applicants, the legend of the pie chart fails to render. We believe this is due to a CSS bug. We intend to fix this in a future iteration.
Improve skill tag validation and parsing
Currently, the skill tag with prefix k/ is limited through input validation to single words with no spaces, and with only . and / as special characters allowed. We plan to expand the input validation and parsing such that skills can accept multi-word inputs and more special characters, in a manner that is meaningful.
Improve parser to avoid misdetection of prefixes
Currently, our prefixes are detected through a pattern similar to (simplified for brevity here) <SPACE>/<PREFIX><CONTENT>. However, in fields such as Address and Name that accept multi-word inputs and special characters, sometimes a misdetection of prefixes can be triggered (e.g. inputting a name with s/o will detect a school prefix). We intend to fix this by employing more robust input validation and checking as well as possibly moving to a less ubiquitous character to demarcate a prefix, such as a backslash, which should greatly reduce such conflicts.
Better warnings for incorrect usage of edit/editjob commands.
Due to the manner in which both edit commands detect changes to the Person or Job, error handling is not specific to the point where we can give targeted warnings or error messages to the end user based on the actual error; instead, our warnings are quite general at the moment. We intend to improve this by improving upon the shared backend code that the edit commands use to detect and catch exceptions.
Improve UI bar chart: Currently, a bug in the legend and the bar chart component makes it such that past 5 schools with applicants, or past 4 applicants per school, the legend of the bar chart fails to render requisite schools or applicants. We believe this is due to a CSS bug. We intend to fix this in a future iteration.
We felt that the difficulty of the project was quite high, especially as took on quite ambitious features. We implemented a significant number of features, including, but not limited to
Application and ApplicationManager, which served as a way for us to manage the relationship between Person and Job in an immutable, side-effect free mannerOn the project management aspect, we often faced significant merge conflicts in the earlier iterations. Since the features we were implementing were often so large, the way the core API of the application was modified by individual group members to implement their respective features was often incongruent, leading to near irreconcilable merge conflicts. We learnt our lesson and started discussing broad-level implementation plans for our features at the start of the later iterations, ensuring that there were no breaking changes introduced by any of the team members.
Furthermore, on the technical side of things, since the UI features that we wanted to implement were quite involved and our experience with JavaFX was limited, we were often stuck at times. However, AI auto-complete tools like GitHub Copilot and Cursor were often able to provide us with direction when we were unfamiliar with syntax or the inner workings of JavaFX.
The effort required was quite significant. By functional code, we are ranked #3 in the cohort. Everyone dedicated a significant amount of time to the project, especially in the later iterations, when we started implementing features and bug fixes at a rapid pace.
We think that we have made an application that is quite functional and one which extends upon the base AB3 significantly, while also exploring JavaFX UI styling and capabilities quite far. It is clear that a lot of work and effort has gone into the application, and we are very proud of it. In particular, our key achievements are:
Job and Person reliably