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 theCouponStashthat 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 theLimitfield). -
UsedCommand#execute()- Executes theusedcommand input by the user. -
Model#PREDICATE_SHOW_ALL_ACTIVE_COUPONS- APredicatefunction 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):
Couponcontains anArchivedfield-
Pros: Easy to implement, lower maintainability.
-
Cons: Saved data may get get considerably huge after heavy usage of application.
-
-
Alternative 2: Archived
Coupons are stored in another separate data file.-
Pros: Separates the logic between the two different
CouponStash, e.g. ability to limit the functions on archivedCoupons -
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.