PROJECT: SocialCare


1. Overview

This portfolio documents my involvement in the SocialCare project that was developed under the CS2103T (Software Engineering) module taken in the National University of Singapore (NUS).

SocialCare is a desktop application designed to serve the volunteer and event management needs of social welfare organizations. The main aim of the project was to streamline manual and inefficient processes faced by administrators of such organizations. Users primarily interact with the application using a Command Line Interface (CLI) with elements of a Graphical User Interface (GUI) to display information.

My primary role as a developer for SocialCare involved implementing event management functions as well as handling extensive user interface improvements.

2. Summary of Contributions

  • Major enhancement: added the ability to manage and display event records

    • What it does: This feature allows the user to create and manage events that span a period of time.

    • Justification: This feature improves the product significantly because a user is able to display and keep track of events by the organisation. This is a core requirement to the application as volunteers have to be assigned to events for basic operations.

    • Highlights: This enhancement is one of the major building blocks of the system and affects majority of the other components. It required an in-depth analysis of design alternatives. The implementation too was challenging as other components are dependent on this component.

  • Minor enhancement: added an overview command that allows the user to have a statistical overview of existing volunteers and events.

  • Code contributed: Here is a link to my code on the Project Code Dashboard.

  • Other contributions:

    • Project management:

      • Managed releases v1.1 - v1.4 (4 releases) on GitHub

      • Applied upstream bug fix: #78

    • Enhancements to existing features:

      • Updated the user interface aesthetics and behaviour: #92, #158, #243

    • Documentation:

      • Did cosmetic tweaks to existing contents of the Developer Guide: #118, #128

    • Community:

      • PRs reviewed (with non-trivial review comments): #58, #232

      • Enquired about and resolved a team issue on the forum: #134

    • Tools:

      • Integrated a new Github plugin (Coveralls) to the team repository

3. Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

3.1. Event Management

The following commands can only be accessed after switching to the 'event' panel. (see [command-switch])

3.1.1. Adding new event: add

Adds an event to the system.

Format: add n/NAME l/LOCATION sd/START_DATE ed/END_DATE st/START_TIME et/END_TIME d/DESCRIPTION [t/TAG]…​

  • Start date and end date must be in 'DD-MM-YYYY format'.

  • Start time and end time must be in 'HH:MM format'.

  • An event can have any number of tags (including 0).

Example(s):

The figure below shows how the panel looks like before executing the example(s) below.

add command
Figure 1. Panel before adding an event
  • add n/Flag Day l/Yishun MRT sd/31-10-2018 ed/31-10-2018 st/09:00 et/15:00 d/For the children’s home

    Adds an event with the properties specified in the command above. The expected result is shown in the figure below.

    add command
    Figure 2. Result of add n/Flag Day l/Yishun MRT sd/31-10-2018 ed/31-10-2018 st/09:00 et/15:00 d/For the children’s home
  • add n/Fundraising l/Tampines Street 31 sd/15-11-2018 ed/17-11-2018 st/13:00 et/18:00 d/Raising funds t/fundraiser t/charity

    Adds an event with the properties specified in the command above. The expected result is shown in the figure below.

    add command
    Figure 3. Result of add n/Fundraising l/Tampines Street 31 sd/15-11-2018 ed/17-11-2018 st/13:00 et/18:00 d/Raising funds t/fundraiser t/charity

3.1.2. Listing all events : list

Lists all events in the system and display them in the panel.

Format: list
Displays all existing events in the system in the panel.
The figure below shows a panel displaying all existing events after executing the list command.

list command
Figure 4. Output of list

3.1.3. Editing event details : edit

Edit details of an existing event in the system when in the 'event' context.

Format: edit EVENT_INDEX [n/NAME] [l/LOCATION] [sd/START_DATE] [ed/END_DATE] [st/START_TIME] [et/END_TIME] [d/DESCRIPTION] [t/TAG]…​

  • Edits the event at the specified EVENT_INDEX. The index refers to the index number shown in the displayed event list. The index must be a positive integer 1, 2, 3, …​

  • At least one of the optional fields must be provided.

  • Existing values will be updated to the input values.

  • When editing tags, the existing tags of the event will be removed i.e adding of tags is not cumulative.

  • You can remove all the event’s tags by typing t/ without specifying any tags after it.

Example(s):

The figure below indicates the EVENT_INDEX and shows how the panel looks like before executing the example(s) below.

add command
Figure 5. Panel before editing an event, EVENT_INDEX is indicated in the circles
  • edit 1 n/Charity Fun Run t/
    Edits the name of event at index 1 and removes all tags. The expected result is shown in the figure below.

    Before edit
    Figure 6. Result of edit 1 n/Charity Fun Run t/

3.1.4. Deleting event: delete

Deletes an existing event in the system when in the 'event' context.

Format: delete EVENT_INDEX

Example(s):

The figure below indicates the EVENT_INDEX and shows how the panel looks like before executing the example(s) below.

add command
Figure 7. Panel before deleting an event, EVENT_INDEX is indicated in the circles
  • delete 3
    Deletes the event specified at index 3. The expected result is shown in the figure below.

    Before delete
    Figure 8. Result of delete 3

4. Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

4.1. Auto-incremented event ID

The auto-incremented event ID field is used by the Record class to identify unique events. An integer ID field is used because the alternative method of identifying unique events based on multiple Event attribute fields would be computationally inefficient.

Current implementation

The auto-incremented event ID field is facilitated by the Event class. The Event class keeps track of the highest ID in the system. Additionally, it implements two different constructors for different situations:

  • Event(Name name, Location location, Date startDate, Date endDate, Time startTime, Time endTime, Description description, Set<Tag> tags)

    This constructor is used when working with an event that does not yet exist in the system (e.g. adding a new event).

    It increments the current highest event ID in the system and assigns that value to the new event that is created. This behaviour is illustrated in the code snippet of the Event class below.

    public Event(Name name, Location location, Date startDate, Date endDate, Time startTime, Time endTime, Description description, Set<Tag> tags) {
            ...
            incrementMaxId();
            this.eventId = new EventId(maxId);
            ...
    }
    
    private void incrementMaxId() {
        maxId += 1;
    }
  • Event(EventId eventId, Name name, Location location, Date startDate, Date endDate, Time startTime, Time endTime, Description description, Set<Tag> tags)

    This constructor is used when working with an event that already exists in the system (e.g. loading data from XML file or editing an existing event).

    It checks whether the ID of the event being initialised is greater than the current highest ID in the system. If this condition is true, the current highest event ID value will be replaced by the ID of the event being initialised. This behaviour is illustrated in the code snippet of the Event class below.

    public Event(Name name, Location location, Date startDate, Date endDate, Time startTime, Time endTime, Description description, Set<Tag> tags) {
            ...
            if (isEventIdGreaterThanMaxId(eventId.id)) {
                replaceMaxIdWithEventId(eventId.id);
            }
            ...
    }
    
    private void replaceMaxIdWithEventId(int eventId) {
        maxId = eventId;
    }
Design considerations
Aspect: How event ID is generated
  • Alternative 1 (current choice): Increment from highest event ID

    Pros

    Implementation is easy.

    Cons

    Maintained highest event ID may be susceptible to overwrite and become desynchronised.

  • Alternative 2: Randomly generated unique event ID

    Pros

    Not dependent on a maintained highest event ID variable (single point of failure).

    Cons

    Requires keeping track of all existing event IDs to ensure uniqueness.

4.2. Overview command

The overview command is used in the 'event' or 'volunteer' context to show statistics for the number of types of events and volunteer distribution.

Current implementation

The overview command raises a OverviewPanelChangedEvent to start calculating statistical data and to update the UI.

Because of the volatile nature of the data (it can change when attributes of events or volunteers are changed), the data is not stored persistently in the ModelManager.

Instead, whenever the OverviewPanel UI class detects an OverviewPanelChangedEvent, it calls on the Overview to provide it with updated statistics.

The figure below is the sequence diagram to show how the overview command works when running from the 'event' context. Note that the OverviewPanel calls the calculateNumOfEvents and calculateVolunteerDemographics methods in Overview class.

overview SD
Figure 9. Simplified sequence diagram for overview command

In the calculateNumOfEvents method, events are categorised into 3 events types:

  • Upcoming (events that have yet to happen).

  • Ongoing (events that are currently happening).

  • Completed (events that have already happened).

The categorisation process can be found in the DateTimeUtil class in the getEventStatus method. The start to end period of each event is compared with the current date and time to determine its category. This behaviour is illustrated in the code snippet below.

public static int getEventStatus(Date startDate, Time startTime, Date endDate, Time endTime) {
    ...
    if (now.compareTo(start) < 0) {
        return UPCOMING_EVENT;
    } else if (now.compareTo(start) >= 0 && now.compareTo(end) <= 0) {
        return ONGOING_EVENT;
    } else {
        return COMPLETED_EVENT;
    }
    ...
}

In the calculateVolunteerDemographics method, the ages of volunteers are derived from their birthdates instead of being stored in the system.

Design considerations
Aspect: How statistics are aggregated
  • Alternative 1 (current choice): Calculate statistics from scratch using existing volunteers and events

    Pros

    No need to store and maintain volatile statistical data.

    Cons

    Requires heavier processing every time statistics are aggregated.

  • Alternative 2: Store and maintain statistics after each operation

    Pros

    No need for heavy computation as a result of building statistics from scratch.

    Cons

    Have to propagate changes to statistical data after changes to volunteers and events.