PROJECT: Club Connect


Overview

Club Connect is a desktop application targeted at club members who are students at the National University of Singapore (NUS). It aims to make the tedious process of club management easier and more effective.

The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.

Purpose

This project portfolio serves as a document to showcase my aptitude as a developer to potential employers. The features I added to Club Connect shows my strong understanding in programming concepts. The documentation I added shows my ability to write clearly.

Summary of contributions

  • Major enhancement: Added voting system

    • What it does: Allows Exco members to add/delete polls and view/hide results of polls. It also allows any member to vote in polls, but only once for each poll

    • Justification: This feature improves the product significantly because the Exco members can accurately determine the views of other members so that they can take the best path of action for the club.

  • Minor enhancement: Improved navigability of member list by adding compress/decompress mechanism and making Find command able to search by field or by all fields instead of just name.

    • Justification: This feature improves the product significantly since it saves time when looking for information of other members. More time can be spent on doing more important actions such as adding polls and assigning tasks.

  • Code contributed: Functional code Test code

  • Other contributions:

    • Project management:

      • Managed release Peer Testing on GitHub

    • Enhancements to existing features:

      • Replaced Address field of members to Matriculation Number #67

    • Community:

      • PRs reviewed (with non-trivial review comments): #168, #167, #149, #125

      • Fixed bug that caused most System tests to fail #154

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.

Adding a poll: addpoll (Since v1.3)

Adds a poll to Club Connect.
Format: addpoll q/QUESTION ans/ANSWER [ans/ANSWER]…​
Aliases: addp, poll

  • A poll must have 1 question, and at least 1 answer.

  • Questions and answers must be non-empty.

  • Answers must be distinct, else the duplicates will be removed.

Examples:

  • addpoll q/Which day should be Free Ice-Cream Day? ans/Monday ans/Wednesday ans/Friday
    Creates a poll asking members to vote for which day Free Ice-Cream Day should be held on. The options to choose from are Monday, Wednesday and Friday.

  • addpoll q/Where should the annual sports meeting be held? ans/I-Cube ans/LT7
    Creates a poll asking members to vote for where the annual sports meeting should be held. The answers to choose from are I-Cube and LT7.

This command is for Exco members only.

Figure 10 shows the a sample poll.

samplepoll
Figure 1. Sample poll created using the addpoll command.

Voting in a poll : vote (Since v1.4)

Votes for the specified answer in the specified poll in Club Connect .
Format: vote POLL_INDEX ANSWER_INDEX
Alias: vpoll

  • The POLL_INDEX refers to the index number shown in the most recent poll listing.

  • The ANSWER_INDEX refers to one of the index number of the answers of the specified poll.

  • The indices must be positive integers 1, 2, 3, …​

  • Polls voted by current logged in member will not be visible in the poll list unless logged in as an Exco member

Examples:

  • vote 1 2
    Votes for the 2nd answer in the 1st poll of the poll listing

  • vote 5 1
    Votes for the 1st answer in the 5th poll of the poll listing

Figure 27 shows the output of the vote command.

samplevote
Figure 2. Output of the vote command.

Locating members: find (Since v1.2)

Finds members whose details contain any of the given keywords.
Format: find [PREFIX] KEYWORD [MORE_KEYWORDS]
Aliases: f, search
Allowed PREFIX:
n/ = NAME
p/ = PHONE NUMBER
e/ = EMAIL
m/ = MATRIC NUMBER
g/ = GROUP
t/ = TAG

  • An additional PREFIX can be stated after find to narrow search to a particular field. e.g e/ for email

  • A maximum of 1 PREFIX should be stated. Additional prefixes are considered as keywords

  • If no PREFIX is stated, all member fields will be searched.

  • The search is case insensitive. e.g hans will match Hans.

  • The order of the keywords does not matter. e.g. Hans Bo will match Bo Hans.

  • Partial matches will be matched e.g. Han will match Hans.

  • Members matching at least one keyword will be returned (i.e. OR search). e.g. Hans Bo will return Hans Gruber, Bo Yang.

Examples:

  • find n/Betsy Tim John
    Returns all members having names containing Betsy, Tim, or John.

  • find g/logistics
    Returns all members in the logistics group

  • find p/123
    Returns any member having phone number containing 123.

  • find 9119
    Returns all members containing 9119 in any field (e.g. phone number or email)

Figure 21 shows the output of the find command.

findoutput
Figure 3. Output of find command.

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.

Polls-feature

A poll contains a question and any number of answers. Any member can vote in a poll but only once. Only 'Exco' members are allowed to add/delete polls and view/hide poll results. Polls are displayed in the poll ListView GUI of Club Connect.

Current Implementation

The poll feature is facilitated by the command classes below:

  • AddPollCommand

  • DeletePollCommand

  • VoteCommand

  • ViewResultsCommand

  • HideResultsCommand

Since all the commands above require the user be logged in, the statements below are present in their execute methods.

requireToSignUp();
requireToLogIn();

To restrict the commands that only Exco members can execute, the AddPollCommand, DeletePollCommand, ViewResultsCommand and HideResultsCommand will have the statement below in their execute methods.

requireExcoLogIn();

Figure 49 below shows the UML diagram of the Poll class.

PollUML

Figure 49. Poll UML Diagram

A Poll consists of the following:

  • Question: Represents the question of the poll.

  • ObservableList<Answer>: Represents the answers of the poll.

  • Set<MatricNumber>: Represents all members that have voted in the poll.

Figure 50 below shows the UML diagram of the Answer class.

AnswerUML

Figure 50. Poll UML Diagram

An Answer consists of the following:

  • String: Represents the sequence of characters making up the answer

  • int: Represents the number of members who voted for this answer

Voting in Polls

Voting in polls is facilitated by the VoteCommand which inherits from UndoableCommand to make voting undoable.

The input of the command is the POLL_INDEX of a poll and ANSWER_INDEX of the answer of the poll

Figure 53 shows the flow of voting in a poll:

width]"550"

Figure 53. Sequence Diagram for voting in a poll

The execution of the command invokes Model#voteInPoll(). The following code snippet shows the implementation:

@Override
public String voteInPoll(Poll poll, Index answerIndex)
        throws PollNotFoundException, AnswerNotFoundException, UserAlreadyVotedException {
    requireAllNonNull(poll, answerIndex);
    String voteDetails = clubBook.voteInPoll(poll, answerIndex, getLoggedInMember().getMatricNumber());
    indicateClubBookChanged();
    return voteDetails;
}

After successful execution, the voteCount of the answer in the poll will increment by 1. If the user is not an Exco member the poll will be removed from the poll ListView GUI, otherwise it will remain in the GUI for Exco members to monitor the results.

Viewing/Hiding All Poll Results

Viewing and Hiding Poll Results is facilitated by the ViewResultsCommand and HideResultsCommand.

By default poll results are not shown(Figure 54), but when ViewResultsCommand is executed, results consisting of how many people voted in a poll and how many voted for each answer will be shown(Figure 55).

PollWithoutResults

Figure 54. Poll Without Results

PollWithResults

Figure 55. Poll With Results

Since viewing and hiding results of polls are similar in implementation, only viewing results of polls will be discussed.

When an Exco member inputs 'viewresults', the sequence diagram (Figure 56) below shows how the different components interact to post a ViewResultsRequestEvent.

HighLevelSDforViewResultsToEventsCenter

Figure 56. Sequence Diagram to EventsCenter for viewing poll results .

Then, the PollListPanel which contains the poll ListView, will handle the event (Figure 57) by showing results of results of all polls (Figure 46).

HighLevelSDforViewResultsFromEventsCenter

Figure 57. Sequence Diagram from EventsCenter for viewing poll results.

The following code snippet shows the implementation:

@Subscribe
private void handleViewResultsEvent(ViewResultsRequestEvent event) {
    logger.info(LogsCenter.getEventHandlingLogMessage(event));
    showPollResults();
}

Hiding results of polls will be done in a similar manner except HideResultsRequestEvent is posted and handled instead of ViewResultsRequestEvent.

Design Considerations

Aspect: Keeping track of how many members voted for each answer of a poll and who has voted in a poll
  • Alternative 1 (current choice): Make each Answer keep track of how many votes it has received and each Poll keep track of who has voted in it using a Set<MatricNumber>

    • Pros: Voters are not tied to any specific answer hence ensuring anonymity

    • Cons: Harder to ensure sum of vote count of all Answer`s in a `Poll must equal to size of Set<MatricNumber> in the poll

  • Alternative 2: Make each Answer contain a Set<MatricNumber>. It’s size is the number of voters and to keep track of who voted, check user’s MatricNumber with all MatricNumber in all Answer of a Poll

    • Pros: Easy to implement

    • Cons: No anonymity since information of who voted for which Answer is stored inside Set<MatricNumber> of an Answer