The task is to refactor two endpoints implemented in the legacy codebase that can be used to list and create memberships:
GET /legacy/memberships (src/legacy/routes/membership.routes.js)
POST /legacy/memberships (src/legacy/routes/membership.routes.js)
The new implementation should be accessible through new endpoints in the modern codebase that are already prepared:
GET /memberships (src/modern/routes/membership.routes.ts)
POST /memberships (src/modern/routes/membership.routes.ts)
When refactoring, you should consider the following aspects:
- The response from the endpoints should be exactly the same. Use the same error messages that are used in the legacy implementation.
- You write read- and maintainable code
- You use Typescript instead of Javascript to enabled type safety
- Your code is separated based on concerns
- Your code is covered by automated tests to ensure the stability of the application
- existing packages in package-lock.json had some critical vulnerabilities that were needed to be addressed
- in the
GET /legacy/membershipsendpoint. There is a wrong filtering:p.membershipId === membership.id, but data frommemberships.jsonhasmembershipproperty resulting in memberships not having any related periods. weeklybilling interval is invalidbillingInterval, according to validation, but in the code this interval is handled.- providing any other
billingIntervalthat is notyearlyormonthlyis causing validation error with the messageinvalidBillingPeriods. Probably the error message should beinvalidBillingInterval - when
billingIntervalisyearlythere is a wrong handling ofbillingPeriods < 3billingPeriods > 3responds with validation errorbillingPeriodsLessThan3YearsbillingPeriods > 10responds with validation errorbillingPeriodsMoreThan10Years
- creating the membership periods is always creating ids starting from 1, which would be wrong in the real life API.
useris hardcoded to 2000, which limits the endpoint to only one user.- Issues with
GET /membershipsandPOST /membershipsrespond payload inconsistencies which are not recommended:GETendpoint responds withmemberships + periodscollection, butPOST /membershipsresponds withmembership + membershipPeriodsGETendpoint response displays dates in a date format, butPOSTin timestamp formatGETendpoint respond payload hasuserIdproperty, butPOSThasuser
- periods are not calculated in UTC. Therefore result it can make variations like: "2023-07-31T23:00:00.000Z" and "2023-08-01T00:00:00.000Z"
validFromdoesn't need to be valid datebillingPeriods < 6validation is not handled properly and it was never triggered- The API does not check existing memberships, allowing membership creation with the same dates or overlapping memberships for the same user
Taking into account that the scope of modern implementation should be only refactoring, leads me to the conclusion that the changes in the new implementation can't have any breaking change. Therefore, to avoid breaking changes, only the following changes and bugfixes are done
GET /membershipsendpoint responds with correctly attached periodsweeklybilling interval is supported and handledvalidFromneeds to be a valid date string
All the other changes would cause a breaking change that would not match the given scope and would be needed to represent the new major version according to semantic versioning