Welcome to the CodeConnect Developer Guide!
Thank you to the developers of the original addressbook-level3 for creating the brownfield project that served as the basis for CodeConnect!
Code Reused:
Before you begin your development journey in CodeConnect, make sure that you meet the minimum requirements needed to run CodeConnect on your development device!
CodeConnect uses Java 11 with JavaFX. If you are not sure how to install Java 11 and JavaFX, refer to this section in our User Guide to install and start CodeConnect.
Now that you have installed Java 11 and JavaFX, you are all ready to get started on introducing new features or fix bugs in CodeConnect!
Want to start introducing new ideas to CodeConnect or contemplating on how to integrate your new features? Refer to the Design section for more information on how CodeConnect was built!
Want to know more about our existing features? Refer to the Implementation section to kickstart your understanding of how CodeConnect works!
Want to integrate our best practices into your own project? Refer to the Documentation, Logging, Testing, Configuration and DevOps section for more information on how we documented, tested and developed CodeConnect!
Want to understand our motivation behind developing CodeConnect? Refer to the Appendix: Requirements section for a clearer picture on how we tailored and scoped CodeConnect for our target audience!
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
(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.
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),
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
.The API of this component is specified
in 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("delete 1")
API
call as an example.
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 a CodeConnectParser
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 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:
CodeConnectParser
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 CodeConnectParser
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.The API of this component is specified
in 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 changes.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)Tag
list in the CodeConnect
,
which Contact
references. This allows CodeConnect
to only require one Tag
object per unique tag, instead of
each Contact
needing their own Tag
objects.The API of this component is specified
in Storage.java
The Storage
component,
CodeConnectStorage
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.
The Contact class is a fundamental component of the contact management system within the application. It represents an individual contact entry, encapsulating various details such as name, contact information, address, GitHub username, associated tech stack, tags, and a profile picture.
Take note that while contacts may not always have all valid details, such as a missing profile picture, these null cases should be handled separately within each Attribute's class (in this context, the ProfilePicture class). A contact's attribute should never be left null. This ensures that such invalid cases are always handled in that separate class, keeping the Contact class lean.
The Team class is another fundamental component of the contact management system. Teams are created to keep track of groups of contacts, and hold aggregate data about these contacts. These teams are used by the user to keep track of hackathon teams. Multiple teams are kept track by ModelManager.
UniqueTeamList
, each contact in a team is guaranteed to be unique. However, each contact
may belong in more than one team.
Every time a new contact is added to a team, team aggregate statistics is recalculated and TeamStats is replaced.
ModelManager keeps track of all Contacts and Teams. Only existing contacts can be added to a Team. They are added to a team by passing the reference of an existing contact.
This section describes some noteworthy details on how certain features are implemented.
General commands follow the same flow, with only differences deep within the execute
method of each command.
In this section, we will focus on the FindCommand
as an example.
The following sequence diagram models the interactions between the different components of CodeConnect for the execution of the Find Command.
Details:
FindCommandParser
parses the user input.FindCommand
object is created.FindCommandParser
returns the FindCommand
object.LogicManager
invokes the execute
method of FindCommand
, which finds the contacts containing the word "John" and returns these contacts.Team commands follow either one of the two sequences stated below, depending on the command type. Within each flow, the only differences lie in the execute
method of each command.
In this section, we will focus on the AddTeamCommand
as an example.
The following sequence diagram models the interactions between the different components of CodeConnect for the execution of the AddTeamCommand
.
Details:
TeamCommandParser
and AddTeamCommandParser
parses the user input.AddTeamCommand
object is created.TeamCommandParser
and AddTeamCommandCommandParser
return the AddTeamCommand
object.LogicManager
invokes the execute
method of AddTeamCommand
, which creates a new team called "NUS HACKERS".In this section, we will focus on the ExportTeamCommand
as an example.
The following sequence diagram models the interactions between the different components of CodeConnect for the execution of the ExportTeamCommand
.
Details:
TeamCommandParser
parses the user input.ExportTeamCommand
object is created.TeamCommandParser
return the ExportTeamCommand
object.LogicManager
invokes the execute
method of ExportTeamCommand
, which copies the details of the team members of the team specified at index 1.This feature saves previously entered commands so that the user can easily view them again.
The following sequence diagram shows what happens as the user requests to view the command history, and what happens after the command is executed:
Details:
updateCommandInput()
saves the currently edited command to the command buffer.next()
/previous()
in CommandHistoryView
is called and if a next/previous command exists, the command text field is updated.This feature enables the user to simply click on a contact's email address to send him/her an email.
The following sequence diagram shows what happens as the user double-clicks on the email address:
Details:
handleEmailClicked()
method of the MailApp class is invoked.openDefaultMailApp()
method is called with the email address as a parameter.openDefaultMailApp()
method attempts to open the default mail application with a new email composition window
addressed to the recipient's email address.Target user profile:
Value proposition:
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * | Student | save the contacts of student developers | remember them |
* * * | Student | see the contacts of student developers | reach out to them |
* * * | Student | delete the contacts of student developers | remove entries that I no longer need |
* * * | Student | search for the contacts of student developers | locate details of contacts without having to go through the entire list |
* * * | Student | update the details of contacts that I already have in my address book | keep my contact details up to date |
* * | Student | search for contacts by tags | locate a category of student developers easily |
* * | Student | categorise the contacts I have saved into the projects I am working on | have an organised address book |
* * | Forgetful Student | add profile pictures for each contact | know who I am contacting |
* * * | Student | search for contacts based on their technical skills | form teams for hackathons more easily |
* * | Student | rate technical skills of my contacts | get apt members for my hackathon team |
* | Student | view my most used commands while typing | save time typing out the full command |
* * * | Student | create teams of contacts | keep track of my teammates when participating in hackathons |
* * * | Student | add contacts to a team | can update my team as it changes |
* | Student signing up for a hackathon | export the contact details of my team | easily sign up for events |
* | Student | place reminders for meetings with my contacts | keep track of them |
* * | New user | import existing contacts into this application | reuse contacts that I have saved previously |
* * * | Student | add notes to different contacts | remember specific details |
* * | Student | integrate my contacts with calendar events | schedule meetings directly from the application |
* | Student | tag contacts based on their time zone | take note of different time zones when scheduling meetings |
* * * | Student | link GitHub profiles or personal portfolio websites to contacts | easily access their projects and contributions |
* | Student | be given smart suggestions for potential contacts based on my current network and interests | find new like-minded student developers |
* | Student | integrate messaging apps to initiate conversations directly from the application | interact with new contacts that I have made |
* | New user | have a tutorial feature that shows me how to use the app | |
* * | Student attending conferences or events | quickly exchange contact information with fellow attendees through QR codes | quickly add new contacts |
* * | Team Lead | have access to integrated online learning platforms to track the courses or certificates completed by my contacts | understand their evolving skills |
* * * | Student | endorse or rate the skills of my contacts | keep track of their expertise and choose the right team members |
(For all use cases below, the System is the CodeConnect
and the Actor is the user
, unless specified otherwise)
Use case: UC01 - Delete a contact
MSS
Extensions
1a. The list is empty.
1b. The given index does not exist in CodeConnect.
Use case: UC02 - Add a contact
MSS
Extensions
1a. The contact already exists in the system.
1b. No fields are entered.
Use case: UC03 - Update a contact
MSS
Extensions
1a. The given index to identify contact is invalid.
1b. No fields are entered.
1c. Updated value does not follow format of the specific field.
1d. Updated contact matches another existing contact
Use case: UC04 - View all contacts
MSS
Use case: UC05 - Search a contact by name
MSS
Extensions
1a. No substring is given.
1b. There are no contacts in the list that match the criteria.
Use case: UC06 - Search a contact by tags
MSS
Extensions
1a. No tag is given.
1b. There are no contacts in the list that match the criteria.
Use case: UC07 - Search a contact by tech stack
MSS
Extensions
1a. No tech stack is given.
1b. There are no contacts in the list that match the criteria.
Use case: UC08 - Rate a tech stack of a contact
MSS
Extensions
1a. No tech stack is given.
1b. No rating is given.
1c. No index is given.
1d. The specified contact does not have specified tech stack.
Use case: UC09 - Sending an email to a specific contact
MSS
Extensions
Use case: UC10 - Viewing command history
MSS
Extensions
Use case: UC11 - Export team members' details
MSS
Extensions
2a. An invalid index is passed into the command.
2b. CodeConnect does not find any team members in the team.
Use case: UC12 - Adding a team
MSS
Extensions
1a. No name is provided.
2a. Another team with the same name already exists in CodeConnect.
Use case: UC13 - Delete a team
MSS
Extensions
Use case: UC14 - List a team's members
MSS
Extensions
Use case: UC15 - Add a contact to a team
MSS
Extensions
1a. The given contact index does not exist in CodeConnect.
1b. The given team index does not exist in CodeConnect.
Use case: UC16 - Delete a contact from a team
MSS
Extensions
1a. The given contact index does not exist in CodeConnect.
1b. The given team index does not exist in CodeConnect.
{More to be added}
11
or above installed.Team size: 5
delete-contact
is runWhen the members of a team are shown in the contacts list, deleting a member of that team does not update the contact list.
A known workaround is to run the command to list the members of the team again, which will show the updated members of the team.
In the future, the delete-contact
command should be enhanced to detect if the contact list is showing the current members of the
team, and automatically update the contact list to show the updated team if necessary.
Currently, CodeConnect does not allow for special characters to be used in names. For example, s/o
cannot be used in
names even though it would be a valid name because it contains the special character /
. Other examples include .
in Harry S. Truman
,
or -
in T-Pain
.
In the future, we plan to expand the restrictions on names to also include special characters such as /
, .
and -
.
The parser in CodeConnect already should be able to parse most special characters without issue, except for /
,
since it is used to separate prefixes from their values. To solve this problem, we could either use another character instead of /
for the prefixes, or use a delimiter to mark the start and end of names so that the parser can ignore any occurrences of special characters in them.
Currently, CodeConnect does not allow for contacts to share the same names. However, different people can have the same names. Since GitHub usernames already need to be unique, we can use them to prevent duplicate contacts from being added into CodeConnect, instead of requiring both names and GitHub usernames to unique.
Currently, CodeConnect does not check if tags with the same name but with different capitalisation exist.
For example, t/friend
and t/Friend
can both be added to a contact, which should not be allowed.
In these situations, CodeConnect should treat these two tags as identical. For example, adding t/friend
and t/Friend
to a contact should display an error saying that identical tags cannot be added to a contact.
To achieve this, the Tag::equals
method can be modified to use String::equalsIgnoreCase
instead of String::equals
to compare tags.
When displaying tags, they should all be displayed either in upper or lower case, to show to the user that
tags are treated with case-insensitivity.
Currently, CodeConnect does not check if tech stacks with the same name but with different capitalisation exist.
For example, ts/C
and ts/c
can both be added to a contact, which should not be allowed.
In these situations, CodeConnect should treat these two tech stacks as identical. For example, adding ts/C
and ts/c
to a contact should display an error saying that identical tech stacks cannot be added to a contact.
To achieve this, the TechStack::equals
method can be modified to use String::equalsIgnoreCase
instead of String::equals
to compare tech stacks.
We can also consider saving tech stacks in upper case, which shows a consistent style and prevents the problem of one contact having
ts/Javascript
but another contact having ts/JaVaScRipT
. Instead, both contacts would show that they have ts/JAVASCRIPT
.
INDEX
For commands such as edit
, delete
, and rate
, inputting an invalid INDEX
gives a generic error message, which is
unhelpful for the user. For example, delete 0
returns Invalid command format!
.
The command parsers for all commands that take in INDEX
as an argument should be enhanced to detect when an invalid
input has been given, and output a more specific error message such as
INDEX should be a positive non-zero integer and not greater than the index of the last contact in the list
.
The current implementation allows a user to add/edit phone numbers with lengths greater than 15 digits. Additionally, there's ambiguity regarding the format of phone numbers, especially for Singaporean and International contexts.
Since CodeConnect is an application that can be used by anyone around the world, we will ensure that the number of digits a phone number can contain is between 3 and 15. This gives the user the flexibility to add contacts from anywhere across the world, which presents especially useful when he/she would like to invite the recipient to join an online hackathon.
rate
command errorsThe current implementation allows a user to input an Integer rating only, not a Double or a Long etc. Hence, the error
messages for the different numbers vary.
When the user inputs large numbers, such as 100000000
(an Integer) and 10000000000
(a Long), error messages, Rating should be between 0 and 10.
and Invalid command format!
are displayed respectively.
We intend to enhance the rate
feature by separating the error handling for ParseException and NumberException into two
with respective error messages.
Our current implementation supports users to add and edit contacts with email addresses and phone numbers that already exist in the contact list. However, we understand that this is not applicable in the real life scenario, as every email address and phone number has to be unique.
We intend to enhance the add
and edit
features by implementing a check within the contact list. This check will verify
whether the email address and phone number intended for addition or modification already exists within the contact list.
Given below are instructions to test the app manually.
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.
Adding a contact to empty list
Prerequisites: Clear the contact list using the clear
command.
Test case: add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01 g/johnDoee ts/Java
Expected: Contact is added to the contact list with correct details. Details of added contact shown in status message.
Adding contact to non-empty list
Prerequisites: List all contacts using the list
command. Contact list must be non-empty.
Test case: add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 g/betBetty t/criminal ts/Flutter
Expected: Contact is added to the end of the contact list with correct details. Details of added contact shown in status message.
Adding invalid contact to empty list
Prerequisites: Clear the contact list using the clear
command.
Test case: add n/John Doe
Expected: Contact is not added to the contact list. Error message shown in status message.
Adding invalid contact to non-empty list
Prerequisites: List all contacts using the list
command. Contact list must be non-empty.
Test case: add n/Betsy Crowe
Expected: Contact is not added to the contact list. Error message shown in status message.
Deleting a contact while all contacts are being shown
Prerequisites: List all contacts using the list
command. Multiple contacts in the list.
Test case: delete 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message.
Test case: delete 0
Expected: No contact is deleted. Error details shown in the status message. Contact list remains the same.
Other incorrect delete commands to try: delete
, delete -1
, delete x
, (where x is larger than the list size)
Expected: Similar to previous.
Deleting a contact when list is empty
Prerequisites: No contacts shown in filtered list. Use find command e.g. find someonethatdoesntexist
to show empty contact list.
Test case: delete 1
Expected: No contact is deleted. Error details shown in the status message. Contact list remains the same.
Editing a contact while all contacts are being shown
Prerequisites: List all contacts using the list
command. Multiple contacts in the list.
Test case: edit 1 ts/C ts/Java
Expected: First contact's tech stacks are updated to contain C
and Java
. Details of edited contact shown in status message.
Test case: edit 0 ts/C ts/Java
Expected: No contact is edited. Error details shown in the status message. Contact list remains the same.
Other incorrect edit commands to try: edit
, edit 0
, edit 1 invalid/field
Expected: Similar to previous.
Edited contact matches another existing contact in CodeConnect.
Prerequisites: List all contacts using the list
command. Multiple contacts in the list.
Test case: edit 2 n/SAME_NAME
(where SAME_NAME is the name of the first contact)
Expected: No contact is edited. Error details shown in the status message. Contact list remains the same.
Searching for a contact with a single keyword
Prerequisites: List all contacts using the list
command. Multiple contacts in the list. In the following test
cases, we assume we have contacts named Alex
, Bernice
, David
, and John
.
Test case: find John
Expected: The search should return contacts matching the keyword John
. The search is case-insenstive and matches
only the name.
Test case: find XYZ
Expected: The search should return no contacts since there are no matches for the keyword XYZ
.
Test case: find BERNICE
Expected: The search should return contacts matching the keyword BERNICE
in a case-insensitive manner. It should
match contacts with names like Bernice
, bernice
, BERNICE
, etc.
Test case: find Dav
Expected: The search should return no contacts because the search only matches full keywords. Partial matches
like Dav
won't match David
.
Searching for contacts with multiple keywords
Prerequisites: List all contacts using the list
command. Multiple contacts in the list.
Test case: find alex david
Expected: The search should return contacts matching either of the keywords alex
or david
. The order of the
keywords do not matter, and partial matches will not be considered.
Finding a contact by tag while all contacts are shown
Prerequisites: List all contacts using the list
command. Multiple contacts in the list. In the following test
cases, we assume we have contacts containing only the tag friend
.
Test case: find-tags friend
Expected: All contacts with tag friend
are shown in list. The search is case-insenstive and matches
only the tag.
Test case: find-tags doesnotexist
Expected: No contacts are shown in list.
Other incorrect find tags command to try: find-tags
, find-tags
Expected: No contact is found. Error details shown in the status message.
Finding a contact by tech stack while all contacts are shown
Prerequisites: List all contacts using the list
command. Multiple contacts in the list. In the following test
cases, we assume we have contacts containing only the tech stack Java
.
Test case: find-ts Java
Expected: All contacts with tech stack Java
are shown in list. The search is case-insenstive and matches
only the tech stack.
Test case: find-ts doesnotexist
Expected: No contacts are shown in list.
Other incorrect find tech stack command to try: find-ts
, find-ts
Expected: No contact is found. Error details shown in the status message.
Rating a contact's tech stack while all contacts are shown
Prerequisites: List all contacts using the list
command. Multiple contacts in the list.
Test case: rate 1 ts/Java r/8
Expected: Tech stack Java
of contact at index 1
is rated with a rating 8
.
Test case: rate 0 ts/Java r/8
Expected: Given tech stack of given contact is not rated. Error details shown in the status message.
Other incorrect rate tech stack command to try: rate -1 ts/Java r/8
, rate 1 ts/Java r/18
, rate 1 ts/Java r/-8
Expected: Given tech stack of given contact is not rated. Error details shown in the status message.
Rating a contact's tech stack when contact list is empty
Prerequisites: No contacts shown in filtered list. Use find command e.g. find someonethatdoesntexist
to get empty list showing.
Test case: rate 1 ts/Java r/8
Expected: Given tech stack of given contact is not rated. Error details shown in the status message.
Adding a team
Prerequisites: Added team should not already exist in CodeConnect.
Test case: team add n/NUS HACK 2024
Expected: Team is added to the team list. Details of team shown in status message.
Adding an invalid team
Prerequisites: Should be run after test case Adding a team
. Team NUS HACK 2024
should exist in the team list.
Test case: team add n/NUS HACK 2024
Expected: No team is added. Error details shown in the status message. Team list remains the same.
Other incorrect commands to try: team add
, team add NUS
.
Expected: Similar to previous.
Adding a contact to a team
Prerequisites: Ensure there are several contacts and teams in the list. A contact that needs to be added to a team should not already be a member of that team.
Test case: team 1 add-contact 1
Expected: The contact at index 1 of the contact list should be added to the first team in the team list. After
executing the command, verify that the contact is added to the team by entering team 1
.
Test case: team 0 add-contact 1
Expected: This command will return an error message indicating that the index is not a non-zero unsigned
integer. The contact will not be added to the team.
Test case: team add-contact 1
Expected: This command will return an error message indicating that the team index provided is invalid as it does
not exist.
Adding a contact that is already in the team
Prerequisites: View the members of the team with the team INDEX
command. Ensure that the contact already exists
in the team. We assume contact 2 already exists in team 2 for the test case below.
Test case: team 2 add-contact 2
Expected: A message indicating that the contact already exists in the team is displayed.
List members of a team
Prerequisites: Team list contains one or more teams. First team in list should have > 0 members.
Test case: team 1
Expected: Contact list shows the members of the team. Team name correctly shown in status message.
Test case: team 0
Expected: Contact list does not change. Error details shown in the status message.
Test case: team X
(where X is greater than the last team's index)
Expected: Similar to previous.
Deleting a contact from a team
Prerequisites: Enter the command team INDEX
to ensure that there are serveral contacts in a team. A contact that
needs to be deleted should already be a member of that team.
Test Case: team 1 delete-contact 1
Expected: The contact at index 1 of the team's member list should be deleted from the first team in the team list.
After executing the command, enter team 1
to ensure that the contact has been removed from the team.
Test case: team 0 delete-contact 1
Expected: This command will return an error message indicating that the index is not a non-zero unsigned
integer. The contact will not be deleted from the team.
Other incorrect commands to try: team 1 delete-contact 0
.
Test case: team X delete-contact 1
(where X is greater than the last team's index)
Expected: This command will return an error message indicating that the team index provided is invalid as it does
not exist.
Similar incorrect commands to try: team 1 delete-contact 0
, team 1 delete-contact X
, (where X is greater than
the last team's index)
Expected: Similar to previous.
Exporting team details
Prerequisites: Team list contains one or more teams. First team in list should have > 0 members.
Test Case: team 1 export
Expected Outcome: All team details are exported successfully to clipboard
Deleting a team
Prerequisites: Team list contains one or more teams.
Test case: team 1 delete
Expected: Team is deleted from the team list. Contact list does not change. Status message shows team name and its members.
Test case: team 0 delete
Expected: Team list does not change. Contact list does not change. Error details shown in the status message.
Test case: team X delete
(where X is greater than the last team's index)
Expected: Similar to previous.
Dealing with missing/corrupted data files
Prerequisites: Add a contact. Access addressbook.json and remove the name field from a address book. This simulates corrupt data. Restart the program to run into error.
Test Case: Delete addressbook.json and restart the app. Expected Outcome: A new addressbook.json is created.
Throughout the development of our project, we encountered several significant challenges that tested our problem-solving skills and collaboration abilities.
One of the foremost hurdles we faced was gaining a comprehensive understanding of the underlying implementation of AddressBook Level 3. As we inherited the codebase from a previous developer, we needed considerable time to unravel the complexities within AddressBook. We meticulously dissected each component, deciphering its role in the application, and strategised on how to extend, modify, or replace existing features to tailor it for our CodeConnect application.
Another major challenge arose during the refactoring process of the pre-existing codebase. The codebase exhibited multiple layers of nesting, making it extremely difficult to refactor classes and methods. This extended into the test cases as well - making changes to one class meant that many of the original tests would have to be refactored to accommodate to modifications. Despite leveraging IntelliJ IDE’s intelligent refactoring features, we encountered difficulties in properly detecting and renaming some classes and methods. This led to instances of broken code, necessitating extensive debugging and testing efforts to rectify.
Additionally, we encountered learning curves as we navigated working together as a cohesive team utilising a Version Control System (GitHub). Merge conflicts were a recurring obstacle, resulting in inadvertent overwrites of previously implemented code. The culmination of these challenges peaked during the integration phase for V1.3, where merging our individually assigned features into the team repository's master branch demanded meticulous coordination and communication.
Despite these formidable challenges, our team persevered with determination and resourcefulness. Each hurdle became an opportunity for growth, reinforcing our collaboration skills, technical acumen, and adaptability in the face of complexity. Through tenacity and a shared commitment to excellence, we successfully navigated these challenges, emerging stronger and more capable as a unified team.
Developing CodeConnect demanded a significant allocation of effort from each team member. In addition to our regular weekly meetings, every developer was tasked with traversing through the meticulous stages of analysis, design, development, testing, and documentation for every new feature integrated into the application.
Given that we inherited a brownfield project, a considerable amount of time and resources were dedicated to understanding the intricate architecture of AB3. Ensuring compatibility and stability remained at the forefront of our efforts, prompting numerous brainstorming sessions and thorough evaluations of how each new feature would seamlessly integrate.
Furthermore, as not all team members were well-versed in utilising a Version Control System (VCS) within a collaborative setting, considerable effort was expended. Guided by the more experienced members of our team, these individuals diligently worked towards acquiring the necessary proficiency with the VCS. This learning curve should be acknowledged, as mastering a VCS is a substantial step for future software professionals and bears significant importance.
Approximately 10% of our project's effort was conserved through the judicious reuse of existing components and libraries, particularly in the realm of commands and parsers. Leveraging the established practices of previous developers when modifying the application provided us with a valuable foundation, expediting the implementation of new functionalities.