Overview
Coupon Stash is a desktop coupons manager that allows users to keep track of their coupons. The user interacts with it using a CLI, and it has a beautiful GUI created with JavaFX. It is written in Java, and has about 15kLoC.
Summary of contributions
-
Major enhancement: added the ability to use a coupon (Pull request #80, #98)
-
What it does: allows the user to keep track of his usage for each and every coupon.
-
Justification: This feature is essential in keeping track of coupons and also its generated savings.
-
Highlights: This enhancement ties in with other coupon fields to ensure the valid usage of a coupon. From the start date of the coupon, to the type of savings generated, this feature is critical to the functioning of Coupon Stash.
-
-
Major enhancement: added archiving mechanism (Pull Request #137)
-
What it does: automatically archive the coupon when it has expired or exhausted its usages.
-
Justification: This feature declutters the user’s visible list of active coupons, while retaining the ability to access the archived coupons if needed.
-
Highlights: Considerations were made on the design of the archiving system, where the initial phase focused on two separate data files for active and archived coupons. This was found to be highly coupled, and would increase complexity and maintainability of the application. This enhancement ties in with the Used and Expiring functionality of Coupons to ensure correct archiving of coupons.
-
-
Minor enhancement: Added shortcut (Ctrl + Q) to quit windows that do not have a CLI in Coupon Stash (e.g. Coupon, Remind Window), to maintain the ability to use Coupon Stash with only a keyboard (except scrolling of lists). (Pull Request #323)
-
Code contributed: [Functional & Test Code]
-
Other contributions:
-
UI Lead:
-
Project management:
-
Lead the project in terms of direction of product, defining and assigning tasks.
-
-
Documentation:
-
Community:
-
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. |
Using a coupon: used
Use a coupon if its usage has yet to reach its limit.
Requires an original amount of purchase if the coupon has savings in a
percentage value.
Format: used INDEX
or used INDEX MONETARY_AMOUNT
where MONETARY_AMOUNT
is a number prefixed by a user-defined currency
symbol e.g. ($4.50, where the currency symbol is "$").
Examples:
-
used 1
Uses the first coupon in the coupon list. -
used 1 $10.0
Uses the first coupon in the coupon list, which also has a percentage savings. The total savings of the coupon will be calculated, and can be seen with the commandsaved
.
Archiving a coupon: archive
Archives a coupon when you want to keep a record of it, without cluttering your current stash of coupons.
To view archived coupons, the user can run the
list a/ command to list all
archived coupons. Alternatively, the find command explained below will
search all archived coupons, thus displaying archives that match the supplied
keywords below unarchived coupons. Finally, the
expiring command will also
include all archived coupons that are expiring in its results.
Read the section on find and
expiring
respectively to find out more.
|
Format: archive INDEX
Examples:
-
archive 1
Archives the first coupon in the coupon list.
To keep your coupons more organized, Coupon Stash will automatically archive your coupons once their usage limit has been reached, or when they have expired. |
Unarchiving a coupon: unarchive
Unarchive a coupon, thus bringing it back to your active coupons list.
To unarchive a coupon, you have to make sure that the archived coupon is
visible in the Coupon Stash first. Read the section on the
archive command to find out the ways that
you can display archived coupons.
|
Format: unarchive INDEX
Examples:
-
unarchive 1
Unarchive the first coupon in the coupon list.
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. |
Coupon Archiving
When physical coupons are expired or exhausted, they would usually be thrown away, or kept in the archive. Coupon Stash simulates this archive, storing these coupons in the app so that the user can still keep track of it, and the savings they generated.
Current Implementation
The archiving of coupons is facilitated by the Archived
attribute of a
coupon. The following methods in the CouponStash
,
Coupon
, Usage
, UsedCommand
class and the Model
interface facilitates this feature:
-
CouponStash#archiveExpiredCoupons()
— Archives any coupon in theCouponStash
that has expired, and returns a new updatedCouponStash
. -
Coupon#increaseUsageByOne()
- Increases the usage of a coupon by one. -
Usage#isAtLimit
- Returns true if the current usage is at its limit (abstracted by theLimit
field). -
UsedCommand#execute()
- Executes theused
command input by the user. -
Model#PREDICATE_SHOW_ALL_ACTIVE_COUPONS
- APredicate
function that filters out archived coupons from a givenCouponStash
.
Given below is two example usage scenarios and how the archiving mechanism behaves at each step of each scenario. An activity diagram is provided first to describe the general events that will lead to an automatic archiving of coupons by Coupon Stash.
Archiving of Expired Coupons
Expired coupons are automatically archived by Coupon Stash upon start up of the application. The following steps describe how this behaviour is implemented.
Step 1. The user launches the application for the first time. The initiation of
ModelManager
will also trigger the
initiation of CouponStash
with any available saved data.
Step 2. The method CouponStash#archiveExpiredCoupons
will be called from the
newly initiated CouponStash
, and have its
UniqueCouponList
mapped to a function that archive coupons that has expired
before the date of opening the application, and returns a new updated CouponStash
.
This mapping function is facilitated by Coupon#hasExpired()
and Coupon#archive()
.
Step 3. The ModelManager
will proceed to filter out the archived coupons from
the newly updated CouponStash
, and return
a filtered list of active coupons. This filtering is facilitated by the
predicate Model#PREDICATE_SHOW_ALL_ACTIVE_COUPONS
.
Archiving of Exhausted Coupons
Coupons that have exhausted its usages will be automatically archived by the application. The following steps describe how this behaviour is implemented.
Step 1. The user uses a Coupon
in the current observable CouponStash
with the
command used 1
.
UsedCommand
is created with the parsed arguments, and executed. The particular Coupon
will then have its Usage
increased by one by calling Coupon#increaseUsageByOne()
.
Step 2. The Coupon
will then be checked if its Usage
has reached its Limit
, using
the Usage#isAtLimit()
method. For the purpose of this explanation, we assume that
the coupon being used has a usage Limit
of 1 and a previous Usage
value of 0,
with savings in MonetaryAmount
.
Step 3. The Coupon
will have a new Archived
value, which will be set to
true
if the Usage
has indeed reached its Limit
. This is facilitated by Coupon#archive()
.
Step 4. The CouponStash
will be updated with this used Coupon
with the
ModelManager#setCoupon()
method. Under the hood of
this method, the current FilteredList
will be updated to show active
Coupons
only, facilitated by the predicate
Model#PREDICATE_SHOW_ALL_ACTIVE_COUPONS
.
Design Considerations
Aspect: The implementation to store archived coupons
-
Alternative 1 (current choice):
Coupon
contains anArchived
field-
Pros: Easy to implement, lower maintainability.
-
Cons: Saved data may get get considerably huge after heavy usage of application.
-
-
Alternative 2: Archived
Coupon
s are stored in another separate data file.-
Pros: Separates the logic between the two different
CouponStash
, e.g. ability to limit the functions on archivedCoupon
s -
Cons: Sharply increases the maintainability and coupling of the application with two data files.
-
Alternative 1 was chosen, due to the cons of Alternative 2. While a separate
file is akin to having two separate stashes of coupons, this would increase
the overall complexity of the application. Logic
and Model
would have to
deal with another set of data, and Commands
may have to split up the logic
for different data sets. Furthermore, while saved data will be larger for
Alternative 1, it should only affect the performance of starting Coupon Stash
up, since most of the interactions with the program is with active coupons.
Overview
Package is a platform tailored to the needs of a specific food business, allowing for a seamless platform for both the business and its customers to use to order food packages. The platform manages food packages, menus, and the delivery area of customers, which can help save the business time and energy over using the conventional method of recording on paper and communicating over instant messaging.
Website: https://foodanatomy.herokuapp.com/
Summary of contributions
-
Communicated with business client
-
Planned functionality of the platform
-
Designed platform UI on Figma
-
Build both frontend and backend from scratch
Overview
chestersim.dev is meant to be a personal website for myself, but was also used intially for me to build something with my newfound knowledge for React. An updated version is coming up soon!
Overview
MoneyMove$ is a project born out of the Razer Fintech Hackathon (video here at the 1:10:18 mark!). It is a savings/Sub-Accounts app that provides a curated, personalized content experience which ties directly into savings goals and habits. The app relies on Mambu’s APIs to create sub-accounts - buckets - for each item, good, or service the user desires. The team intends to offer a plethora of content for the user to save up to, including gaming, food deals, movies, events and even personal banking services. The project won the prize for the top 2 in the hackathon!
Summary of contribtions
-
Main frontend engineer - build the entire app in React Native
Overview
Clique was a project done by me and my partner for Project Orbital (CP2106, and won the Judge’s Choice Award. It is a messaging-cum-calendar mobile app, where we try to integrate events into messaging. Read more about it in depth in the repo!
Summary of contributions
-
Designed majority of the UI using Sketch
-
Developed and build equal share of both the frontend and the backend.