TAA Developer Guide
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 delete i/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, 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 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("delete 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) and all Group objects (which are contained in a UniqueGroupList object).Group's assignments (all Assignment objects which are contained in a UniqueAssignmentList object within each Group).Person objects (e.g., results of a search query) as a separate 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.Person's session data (all Session objects, each containing a LocalDate, Attendance, and Participation, which are contained in a SessionList object within each Person), keyed by GroupName with one SessionList per group.Person's assignment grades as a mapping of GroupName to AssignmentName to grade, allowing for per-group assignment grade tracking.UserPrefs object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPrefs object.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 AddressBook, which Person references. This allows AddressBook to only require one Tag object per unique tag, instead of each Person needing their own Tag objects.
API : Storage.java
The sequence diagram below illustrates the interactions within the Storage component when data is loaded during initialization.
Note: The lifeline for JsonSerializableAddressBook should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
How the load works:
JsonAddressBookStorage delegates to JsonSerializableAddressBook#toModelType() to parse the JSON data into Model objects. During this process, each person and group entry is validated against the current group and assignment data.StorageManager#getLastLoadWarnings() and displayed to the user on startup.The Storage component,
AddressBookStorage 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 algorithm can be found here.
Format: Valid matric number has form of A, followed by 7 digits (
The checksum calculation is done by MatricNumber#calculateChecksum(String matricNumber).
The checksum letter is one of the following 13 letters: Y X W U R N M L J H E A B.
Step 1. Extract digits
Step 2. Compute the sum of the 6 digits above.
Step 3. Map the remainder to a checksum letter by computing remainder = sum % 13.
| remainder | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Letter | Y | X | W | U | R | N | M | L | J | H | E | A | B |
Examples:
The table below shows one matric number that produces each of the 13 possible check letters.
| Matric number | Digits d2–d7 | Digit sum | mod 13 | Check letter |
|---|---|---|---|---|
A0308002Y | 0,3,0,8,0,2 | 13 | 0 | Y |
A0308003X | 0,3,0,8,0,3 | 14 | 1 | X |
A0308004W | 0,3,0,8,0,4 | 15 | 2 | W |
A0308005U | 0,3,0,8,0,5 | 16 | 3 | U |
A0308006R | 0,3,0,8,0,6 | 17 | 4 | R |
A0308007N | 0,3,0,8,0,7 | 18 | 5 | N |
A0308008M | 0,3,0,8,0,8 | 19 | 6 | M |
A0308009L | 0,3,0,8,0,9 | 20 | 7 | L |
A0308019J | 0,3,0,8,1,9 | 21 | 8 | J |
A0308029H | 0,3,0,8,2,9 | 22 | 9 | H |
A0308039E | 0,3,0,8,3,9 | 23 | 10 | E |
A0308000A | 0,3,0,8,0,0 | 11 | 11 | A |
A0308001B | 0,3,0,8,0,1 | 12 | 12 | B |
The command tab completion feature provides real-time command suggestions and contextual parameter help as the user types, with the ability to accept suggestions via the TAB key.
The feature leverages three key components:
The architecture works as follows:
Step 1: Initialization
CommandBox is created, it extracts all command words from CommandRegistry.COMMAND_ATTRIBUTES and creates a sorted list of COMMAND_SUGGESTIONSStep 2: User Types
TextArea, a text change listener triggers two updates:
updateGhostText(): Finds and displays matching command suggestions as faded textupdateContextualHelp(): Shows command parameters in the result display panelStep 3: Ghost Text Generation
findSuggestion() method performs a prefix match against COMMAND_SUGGESTIONSghostTextLabel with semi-transparent stylingStep 4: TAB Key Completion
Step 5: Contextual Help
updateContextualHelp() method extracts the command word and looks up its parameters in CommandRegistry
Aspect: Where to store command metadata
Option 1 (current choice): Use a centralized CommandRegistry with a static COMMAND_ATTRIBUTES map
Option 2: Store parameters within each Command class
Aspect: Suggestion matching algorithm
Option 1 (current choice): Simple prefix matching (linear search through sorted list)
Option 2: Fuzzy matching with edit distance
The proposed undo/redo mechanism is facilitated by VersionedAddressBook. It extends AddressBook with an undo/redo history, stored internally as an addressBookStateList and currentStatePointer. Additionally, it implements the following operations:
VersionedAddressBook#commit() — Saves the current address book state in its history.VersionedAddressBook#undo() — Restores the previous address book state from its history.VersionedAddressBook#redo() — Restores a previously undone address book state from its history.These operations are exposed in the Model interface as Model#commitAddressBook(), Model#undoAddressBook() and Model#redoAddressBook() respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedAddressBook will be initialized with the initial address book state, and the currentStatePointer pointing to that single address book state.
Step 2. The user executes delete 5 command to delete the 5th person in the address book. The delete command calls Model#commitAddressBook(), causing the modified state of the address book after the delete 5 command executes to be saved in the addressBookStateList, and the currentStatePointer is shifted to the newly inserted address book state.
Step 3. The user executes add n/David … to add a new person. The add command also calls Model#commitAddressBook(), causing another modified address book state to be saved into the addressBookStateList.
Note: If a command fails its execution, it will not call Model#commitAddressBook(), so the address book state will not be saved into the addressBookStateList.
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the undo command. The undo command will call Model#undoAddressBook(), which will shift the currentStatePointer once to the left, pointing it to the previous address book state, and restores the address book to that state.
Note: If the currentStatePointer is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The undo command uses Model#canUndoAddressBook() to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
The following sequence diagram shows how an undo operation goes through the Logic component:
Note: The lifeline for UndoCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Similarly, how an undo operation goes through the Model component is shown below:
The redo command does the opposite — it calls Model#redoAddressBook(), which shifts the currentStatePointer once to the right, pointing to the previously undone state, and restores the address book to that state.
Note: If the currentStatePointer is at index addressBookStateList.size() - 1, pointing to the latest address book state, then there are no undone AddressBook states to restore. The redo command uses Model#canRedoAddressBook() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
Step 5. The user then decides to execute the command list. Commands that do not modify the address book, such as list, will usually not call Model#commitAddressBook(), Model#undoAddressBook() or Model#redoAddressBook(). Thus, the addressBookStateList remains unchanged.
Step 6. The user executes clear, which calls Model#commitAddressBook(). Since the currentStatePointer is not pointing at the end of the addressBookStateList, all address book states after the currentStatePointer will be purged. Reason: It no longer makes sense to redo the add n/David … command. This is the behavior that most modern desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: How undo & redo executes:
Alternative 1 (current choice): Saves the entire address book.
Alternative 2: Individual command knows how to undo/redo by itself.
delete, just save the person being deleted).Target user profile:
Value proposition: manage all student-related TA matters on one platform
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
The term contacts and students are used interchangeably in user stories and use cases.
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | user | add basic contact details | add students to my app |
* * * | user | delete contacts | remove students from my app |
* * * | user | list contact details within a tutorial group | see all contacts within a tutorial group |
* * * | user | find contacts based on a search field within a tutorial group | filter and narrow my search space to certain fields |
* * * | user | unmark attendance of a student for a tutorial session | correct mistakes in attendance records |
* * * | user | verify whether a matric number is valid | enter correct matric numbers |
* * * | user | create a tutorial group | keep track of new tutorial groups I am teaching |
* * * | user | switch between different tutorial groups | view different tutorial groups |
* * * | user | delete a tutorial group | delete tutorial groups I am no longer teaching |
* * * | user | list tutorial groups | see all tutorial groups I am teaching |
* * * | user | rename tutorial groups | update the tutorial group if it changes |
* * * | user | add students to tutorial groups | sort students into their respective tutorial groups |
* * * | user | remove students from tutorial groups | remove students that are no longer in a specified tutorial group |
* * * | user | add a participation score for a student for a tutorial session | keep track of student participation in tutorials |
* * * | user | delete a participation score for a student for a tutorial session | delete unwanted participation scores |
* * * | user | edit participation scores for a student for a tutorial session | amend a participation score if it is wrong |
* * * | user | create a tutorial session | mark attendance and add participation scores for a tutorial session |
* * * | user | add matric numbers of students | differentiate and add students with the same name |
* * | user | edit contacts | avoid wasting time recreating contacts if there’s a typo |
* * | user | enter information partially (e.g., only name without email) | add information progressively as I get it |
* * | user | mark attendance using ID and date of a tutorial session | keep track of attendance for tutorials |
* * | user | create new assignments for a tutorial group | keep track of assignments given to a tutorial group |
* * | user | mark an assignment as completed or uncompleted | keep track of the assignment progress of students |
* * | user | delete assignments for a tutorial group | remove assignments I no longer need to track |
* * | user | edit assignments for a tutorial group | update assignment information |
* * | user | view attendance for a tutorial session of a tutorial group | keep track of attendance for a tutorial session of a tutorial group |
* * | user | view participation scores for a tutorial session of a tutorial group | keep track of participation scores for a tutorial session of a tutorial group |
* * | first-time user | list the possible commands easily | use the product without worrying about remembering commands before jumping into it |
* * | first-time user | mass delete contacts | play around with the app using dummy data and easily clear it when I want to put in real data |
* * | long-term user | import existing contact data from this app | restore my previous backups |
* | user | have notes for certain contacts | pay specific attention to certain people |
* | user | track operation history | remember when things happen and amend previous mistakes |
* | user | identify unfinished contacts with a tag | ensure I remember to finish adding their details later |
* | user | view large amounts of information in an organised and clear way | easily find specific information at a glance |
* | user | do a fuzzy search for names | find information even if I do not remember their names fully |
* | user | autocorrect incomplete commands | save time typing and correcting mistakes |
* | user | view an individual student's attendance records | monitor their attendance history |
* | user | mark attendance with date and time | detect if students are late for class |
* | user | sort students alphabetically | view my student contacts in alphabetical order |
* | user | sort students by tutorial groups | view student contacts based on what tutorial group they are in |
* | user | view my students in a paginated list of 40 students per page | view students page by page without having to keep scrolling down |
* | user | undo my previous action | undo my most recent command |
* | user | redo my previous action | redo my most recent undo |
* | busy user | set a recurring weekly schedule for a tutorial group | be reminded of when my tutorial sessions are |
* | busy user | add a temporary tutorial session | keep track of additional tutorials like consultations or make-up classes |
* | busy user | view a list of my upcoming tutorials for the week | view how many remaining tutorial sessions I have for the week |
* | colour-blind user | change the colour scheme of the UI | use the app easily and accessibly |
* | first-time user | import existing contact data from elsewhere | migrate easily from a different app |
* | forgetful user | add profile pictures for each contact | remember and identify students better |
* | long-term user | export the program data as a backup | prevent losing all my data if I switch devices |
* | long-term user | make new shortcuts for commands or strings | use the app more efficiently |
(For all use cases below, the System is the Teacher Assistant's Assistant (TAA), referred to as TAA, and the Actor is the Teaching Assistant (TA), unless specified otherwise)
Use case: UC1 - Add a contact
MSS
Use case ends.
Extensions
Use case: UC2 - Delete a contact
MSS
Use case ends.
Extensions
Use case: UC3 - Edit a contact
MSS
Use case ends.
Extensions
Use case: UC4 - Create a group
MSS
Use case ends.
Extensions
Use case: UC5 - Delete a group
MSS
Use case ends.
Extensions
Use case: UC6 - Rename a group
MSS
Use case ends.
Extensions
Use case: UC7 - Add student to group
MSS
Use case ends.
Extensions
Use case: UC8 - Remove student from group
Preconditions: Student is added into group by UC7 - Add student to group.
MSS
Use case ends.
Extensions
Extensions are similar to Extensions 1a. and 1b. of UC7 - Add student to group.
Use case: UC9 - Switch to a group view
MSS
Use case ends.
Extensions
Use case: UC10 - Record class participation
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Use case: UC11 - Grade an assignment submission
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Use case: UC12 - Mark attendance
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Extensions for UC12 behave very similarly to UC10 - Record class participation, but does not involve Extension 3c.
Use case: UC13 - Unmark attendance
UC13 behaves similarly to UC12 - Mark attendance.
Use case: UC14 - Create a session for a group
MSS
Use case ends.
Extensions
Use case: UC15 - Delete session
MSS
Use case ends.
Extensions
Use case: UC16 - View attendance overview for a group
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Use case: UC17 - Export current view
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Use case: UC18 - Create an assignment for a group
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
1a. TAA detects an assignment with the same name in the group.
1b. TAA detects an invalid assignment name or max marks.
Use case: UC19 - Find contacts
MSS
Use case ends.
Extensions
Use case: UC20 - Edit session
MSS
Use case ends.
Extensions
Use case: UC21 - Edit assignment
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
Use case: UC22 - Delete assignment
Preconditions: User is in a group view by UC9 - Switch to a group view.
MSS
Use case ends.
Extensions
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.
TAA.jar file and copy it into a folder of your choice.java -jar TAA.jar.
add Invalid command format!... error message.add n/John Invalid command format!... error message.add n/John p/98764321 e/john@gmail.com m/A1234567X t/exchange A1234567X exists.add n/John p/98764321 e/john@gmail.com m/A1234567Y t/exchange The matric number checksum letter is incorrect. For the given digits, it should be 'X'. error message.add n/John p/98764321 e/john@gmail.com m/A1234567X t/exchange A1234567X already exists.A person with the same matric number already exists. error message.edit i/1 p/91234567 e/newemail@example.com 91234567 and newemail@example.com, respectively.edit i/1 t/ edit i/999 p/91234567 999 exists.The person index provided is invalid error message.edit i/1 At least one field to edit must be provided. error message.edit i/1 m/A1234567X A1234567X.A person with the same matric number already exists. error message.delete Invalid command format!... error message.delete i/1 delete i/0 Invalid command format!... error message.find n/Alex, then delete i/1 Alex exists, and he is index 1 after running find n/AlexAlex is deleted. Running list afterward confirms they are no longer present.Alex Yeoh with matric number A0102035A and another contact named Bernice exists with matric number A0294810A exists.find Invalid command format!... error message.find n/Alex Alex Yeoh is displayed.find m/A010 Alex Yeoh is listed.find n/Alex m/A0294810A Bernice appears as index 1, and Alex Yeoh appears as index 2.creategroup g/T09 T09 is created.creategroup g/T09 T09 already exists from the previous test case.This group already exists. error message.listgroups 2026-S1-T01 and 2026-S1-T02 exist from sample data.switchgroup g/2026-S1-T01 2026-S1-T01. The status bar updates to show 2026-S1-T01.switchgroup all No Group Selected.switchgroup g/T99 This group does not exist. error message.T09 exists. Sample data is loaded.addtogroup g/T09 m/A0102035A Alex Yeoh is added to group T09. The result display shows a success message.addtogroup g/T09 i/2,3 T09.addtogroup g/T09 m/A0102035A Alex Yeoh is already in T09 from the previous test case.Already in T09: Alex Yeoh. error message.Alex Yeoh is in group T09.removefromgroup g/T09 m/A0102035A Removed Alex Yeoh from T09. Contact will still exist in TAA, but is not in the group T09.removefromgroup g/T09 m/A0102035A Alex Yeoh is no longer in T09 from the previous test case.Not in T09: Alex Yeoh. error message.T09 exists. Sample data is loaded.renamegroup g/T09 new/T09-Renamed Renamed group T09 to T09-Renamed.renamegroup g/T09-Renamed new/2026-S1-T01 2026-S1-T01 already exists from sample data.Another group with that name already exists. error message.T09-Renamed exists.deletegroup g/T09-Renamed Deleted group: T09-Renamed. Contacts that were in the group still remain in TAA.deletegroup g/T99 This group does not exist. error message.view g/2026-S1-T01. No session on 2026-04-10 exists.addsession d/2026-04-10 2026-04-10 is created for all students in 2026-S1-T01.addsession d/2026-04-17 n/make-up 2026-04-17 is created with the note make-up.view d/2026-04-17 to see the created note.addsession d/2026-04-10 2026-04-10 already exists from the previous test case.Session 2026-04-10 already exists for all students in group 2026-S1-T01. error message.addsession d/2026-13-01 Invalid month: 13. Month must be between 01 and 12. error message.2026-04-10 exists in 2026-S1-T01.editsession d/2026-04-10 nd/2026-04-11 Updated session 2026-04-10 -> 2026-04-11 in group 2026-S1-T01.editsession d/2026-04-11 nn/tutorial 2026-04-11 from Test Case 2.Updated session 2026-04-11 (note "tutorial") in group 2026-S1-T01.editsession d/2026-04-11 nn/ Updated session 2026-04-11 (cleared note) in group 2026-S1-T01..editsession d/2026-04-11 Invalid command format!... error message.editsession d/2026-04-11 nd/2026-04-17 2026-04-11 and 2026-04-17.Cannot move session to 2026-04-17 because that date already exists in group 2026-S1-T01.2026-04-11 exists in 2026-S1-T01.deletesession d/2026-04-11 Deleted session 2026-04-11 from group 2026-S1-T01 and removed its attendance and participation records..deletesession d/2026-12-31 No session on 2026-12-31 was found in group 2026-S1-T01. error message.view g/2026-S1-T01. A session on 2026-04-10 exists.mark i/1 d/2026-04-10 PRESENT for 2026-04-10.unmark i/1 d/2026-04-10 ABSENT for 2026-04-10.mark i/1 d/2026-04-10 (outside group view)
switchgroup all first.Mark attendance from a group view only. Use switchgroup g/GROUP_NAME first. error message.mark i/999 d/2026-04-10 999 exists, switch to view using view g/2026-S1-T01.The person index provided is invalid.view g/2026-S1-T01. A session on 2026-04-10 exists.part i/1 d/2026-04-10 pv/4 4 is recorded for the first student on 2026-04-10.part i/1 d/2026-04-10 pv/6 Invalid command format!... error message.part i/1 d/2026-04-10 pv/abc Invalid command format!... error message.2026-S1-T01 using switchgroup g/2026-S1-T01. At least one session with attendance data exists.view view d/2026-04-10 2026-04-10 is highlighted in the overview.view absent d/2026-04-10 ABSENT on 2026-04-10 are shown.view from/2026-04-01 to/2026-04-30 view from/2026-04-30 to/2026-04-01 from/ date cannot be after to/ date. error message.view d/2026-04-10, then mark i/2, then part i/2 pv/3 2026-04-10 without needing to re-specify the date. The view updates after each command.2026-S1-T01 using switchgroup g/2026-S1-T01.createassignment a/Quiz 1 d/2026-05-01 mm/20 Created assignment Quiz 1 in 2026-S1-T01..createa a/Quiz 2 d/2026-05-08 mm/10 Created assignment Quiz 2 in 2026-S1-T01..createa is a shorthand that behaves like createassignment.createassignment a/Quiz 1 d/2026-06-01 mm/30 Quiz 1 already exists from the Test Case 2.An assignment with that name already exists in the current group. error message.createassignment a/Quiz 3 d/2026-05-15 mm/10 (outside group view)
switchgroup all first.Assignment commands can only be used when viewing a specific group. error message.2026-S1-T01 using switchgroup g/2026-S1-T01.lista 2026-S1-T01 are shown, including their due dates, max marks, and graded counts.Quiz 1 exists in 2026-S1-T01.editassignment a/Quiz 1 na/Midterm d/2026-05-10 mm/25 Edited assignment Midterm in 2026-S1-T01..editassignment a/NonExistent na/New d/2026-06-01 mm/10 This assignment does not exist in the current group. error message.Quiz 2 (max marks 10) exists in 2026-S1-T01. At least 3 students are in the group.gradea a/Quiz 2 i/1 gr/8.5 8.5 for Quiz 2.gradea a/Quiz 2 i/1-3 gr/7 7 for Quiz 2.gradea a/Quiz 2 m/A0102035A gr/10 A0102035A receives a grade of 10 for Quiz 2.A0102035A refers to Alex Yeoh.gradea a/Quiz 2 i/1 gr/100 Grade must be between 0 and 10 (the assignment's max marks) inclusive error messagegradea a/Quiz 2 i/1 gr/-1 Grade should be a non-negative number with at most 3 decimal places. error message.Quiz 2 exists in 2026-S1-T01.deleteassignment a/Quiz 2 Deleted assignment Quiz 2 from 2026-S1-T01.deletea a/NonExistent This assignment does not exist in the current group. error message.2026-S1-T01 using switchgroup g/2026-S1-T01.exportview [JAR file location]/view-export.csv, containing contacts in group 2026-S1-T01.Test case: exportview f/exports/t01-apr.csv
[JAR file location]/exports/t01-apr.csv.Test case: exportview f/t:est
The file name 't:est' is invalid because it contains illegal character(s): ':'. Please choose a different file name. error message.exportview (outside group view)
switchgroup all first.No group selected. Switch to a group before exporting the view. error message.help clear clear someExtraText exit add n/Test User p/81111111 e/test@example.com m/A0308002Y.exit.java -jar TAA.jar.
Test User is still present.The following tests require direct editing of TAA_savefile.json in the data folder.
Back up the file before each test if you intend to continue using the existing data in your save file.
TAA_savefile.json.java -jar TAA.jar.
TAA_savefile.json with invalid JSON (e.g., { "persons": [).TAA_savefile.json, add a contact whose groups array references a group name not present in the groups array.
groups array inside a person of sample data to reference a group that does not exist.2026-S1-T01 for Alex Yeoh to 2026-S1-T15.preservedSkippedPersons in the save file.matricNumber field to an invalid value (example: A0000000Z).Prerequisites: Ensure the contact's other fields are valid, otherwise the matric number error will be reported first (from Contact with an invalid matric number).
Edit a contact's grade for an assignment to a value greater than the assignment's maxMarks.
One major challenge was evolving AddressBook into a domain-specific application for TAs while still keeping the codebase maintainable. In particular, extending the model to support tutorial groups, per-group sessions, attendance, participation, and assignment grades required careful design to avoid tightly coupling unrelated features.
Another challenge was preserving a smooth CLI workflow while introducing richer group-based and date-based operations. Commands such as attendance marking, participation recording, session management, and view filtering required additional parser and model logic, while still needing to remain intuitive for users.
The team also had to ensure that invalid or partially corrupted saved data would not cause the entire application to fail. This required additional validation and recovery logic during loading, together with meaningful warnings for the user.
The project required substantial effort in both feature development and adaptation of the original architecture. Compared to the original AB3 codebase, TAA now supports tutorial-group management, attendance and participation tracking by session date, assignment management within groups, and filtered class views for teaching workflows.
The team also improved robustness by validating saved data during loading, preserving skipped invalid entries, and surfacing warnings to the user instead of failing silently. On the UI side, the app was adapted to support attendance-oriented views and clearer group/session context.
Overall, our team successfully transformed a generic contact-management application into a more task-focused teaching assistant management tool while preserving the strengths of the original CLI-based workflow.
Team size: 5
Improve session and assignment grade error reporting during save file loading: Currently, when a manually edited entry has multiple invalid session or assignment grade fields, only the first error among them is reported, requiring multiple fix-and-relaunch cycles to fully correct the entry. We plan to accumulate and report all such errors together in a single warning message, consistent with how basic field errors (name, phone, email, matric number, tags) are already reported together.
Use a leaner JSON representation for group sessions:
Currently, group sessions are serialized using the same JsonAdaptedSession class as person sessions, which includes attendance and participation fields. Group sessions are always constructed with UNINITIALISED attendance and 0 participation, so they carry no meaningful data.
We plan to have a dedicated JsonAdaptedGroupSession class that serializes only the date and note fields, producing a leaner save file and making the data model's intent clearer.
Validate person session dates against group sessions on load:
Currently, a person's session records are not cross-checked against the group's session list during loading. A manually edited save file could contain a person with a session date that does not exist in the group's session list, and TAA will load it without warning. view and exportview will still show all sessions (union of group's and student's sessions), but the group's session list in JSON does not capture the full picture of what sessions will be shown. Additionally, this inconsistency can cause addsession to treat an existing person-level session as newly created, resulting in a misleading partial-success message. A future enhancement would validate person session dates against the group's session list during load, and skip person-level session entries whose dates do not exist in the group's session list, reporting them as load warnings.