A quick guide on how to start the project & a look into possible next.
The Frontend & Backend are both in src folder for your convenience. Have fun looking around! ✨
- Navigate to the
commsdirectory:
cd src/comms
npm run start:dev- Navigate to the welcome-page directory:
cd src/welcome-page
npm start-
Testing:
- Write more unit tests using Jest, for full coverage.
- Write integration tests to ensure the correct inputs give the correct outputs for the frontend and backend.
-
Separation of Concerns:
- Backend: Refactor the code with the MVC design pattern for scalability.
- Frontend: Make sure components follow the Single Responsibility Principle and use Redux/useContext for more robust & scalable state management.
-
API Optimizations:
- Use
async/awaitto handle asynchronous calls and improve performance. - Optimise reads/writes with
map()orreduce()to handle large datasets.
- Use
Please take your time to thoroughly read through this README. If anything is unclear or you think there is a mistake somewhere, please let us know via email. We recommend you spend around an hour or so on this test. Submission instructions are at the bottom of this README.
This test is split into two parts - a backend REST API section, and a frontend section. If you struggle to do the backend section, then please do the frontend section to the best of your ability by either faking/stubbing or not doing any API calls.
We suggest you spend around 60-90 minutes on this in total, and do as much as you can. Do not worry if you do not finish everything. We also encourage you to:
- Use Google, Stackoverflow, online documentation, ChatGPT as much as you require.
- Write tests if you think they are beneficial, but only if you think they are within reason of the time limit.
- Install and use any third party packages if you see fit
- Think about what you would do if you had more time, or if this was a real-world production project. We may ask further questions about your solution in further interviews.
- Readability and how well-typed your code is
- The code should be written in Typescript and must compile and run, on Node 18 or later.
- We take into account your previous experience with TypeScript.
- Don't implement anything unnecessary - i.e. authentication, database, containerization. We won't give additional credit for that.
As a highly personalized service, communications to our customers must be tailored purr-fectly and personalized to each and every customer. As we have multiple channels of communications (i.e. emails, SMS, landing pages), we like to keep the templating logic for this channel-agnostic and in a dedicated REST API service.
For example, calling GET /comms/welcome-fresh/<USER-ID> might return
{
"message": "Welcome to KatKin, <full-name>! We're super excited for <cat1> and <cat2> to join the KatKin club and start loving fresh!"
}with the interpolated values populated with that specific customer's (and cat's) data. This endpoint could then be used to generate content for SMSs, emails, or personalized web pages.
A skeletal backend has already been setting up for you, using TypeScript and NestJS - the language and framework we use at KatKin. To run this backend, you can do yarn start.
There is no frontend setup - you are free to setup one of your own React-based one as you choose, either within the same repository or in a different repository.
There is a data.json file containing user data in this repository, which you should read from in place of a database.
Within this codebase, create an endpoint /comms/your-next-delivery/<USER-ID>, that looks up the corresponding user's data, and returns a JSON payload of the following shape:
{
"title": "Your next delivery for <cat names, separated by comma or 'and'>",
"message": "Hey <firstName>! In two days' time, we'll be charging you for your next order for <cat names, formatted as described below>'s fresh food.",
"totalPrice": <total price, calculated via the formula shown in a later section in this README>,
"freeGift": <true if the total price exceeds 120 pounds, otherwise false>
}Cat names should be formatted in a grammatically correct manner, i.e. just A if there's a single cat named A, A and B if there's two cats, A, B and C if there's three or more cats.
For example, with the following user:
{
"id": "ff535484-6880-4653-b06e-89983ecf4ed5",
"firstName": "Kayleigh",
"lastName": "Wilderman",
"email": "Kayleigh_Wilderman@hotmail.com",
"cats": [
{
"name": "Dorian",
"subscriptionActive": true,
"breed": "Thai",
"pouchSize": "C"
},
{
"name": "Ocie",
"subscriptionActive": true,
"breed": "Somali",
"pouchSize": "F"
},
{
"name": "Eldridge",
"subscriptionActive": false,
"breed": "Himalayan",
"pouchSize": "A"
}
]
}hitting /comms/your-next-delivery/ff535484-6880-4653-b06e-89983ecf4ed5 should return the following body:
{
"title": "Your next delivery for Dorian and Ocie",
"message": "Hey Kayleigh! In two days' time, we'll be charging you for your next order for Dorian and Ocie's fresh food.",
"totalPrice": 134.00,
"freeGift": true
}Cats come in different shapes and sizes. Bigger cats need more food, and vice versa. Our food is delivered in pouches, hence we use the term pouch size to refer to how much food a cat needs. Therefore, every cat in the dataset will have a pouchSize attributed to them - between A to F. Every pouch size will have its own price.
A user's order price is there calculated as the sum of their active cats' pouch size prices. The pouch size prices are described below:
A -> 55.50 GBP
B -> 59.50 GBP
C -> 62.75 GBP
D -> 66.00 GBP
E -> 69.00 GBP
F -> 71.25 GBP
So for example, if a user had 3 cats, each on pouch size A, B, C, but only the first two cats (on A and B) currently have an active subscription, then their price would be 55.50 + 59.50 = £115.00 pounds.
Using React (or your favourite React-based metaframework of choice), create a frontend with just one page - /welcome/<USER-ID>, which calls the API endpoint described in the previous step and renders the message in a style similar to the figma file provided here.
You can:
- Create a separate folder/repository to do this if you choose.
- Use any libraries/frameworks you want, i.e. Tailwind, styled components (or not - feel free to just use regular styling/CSS as well).
- Use any project generators you want (i.e.
create-next-app,create-react-app,create-vite-app)
Note: We aren't expecting an exact 1-to-1 copy of the design, i.e. exact fonts, spacing, or colors. Just get roughly close enough. Use any random image of a cat that you can find.
Either:
- Make your solution publicly available in a Git repository(s) and send us the URL(s). You can have a separate frontend/backend repository if you want. Please make sure to name the repository something inconspicuous, i.e, don't put
KatKinin the name. Do not fork this repository as your solution will be visible to all other candidates. - Or, if option 1 is unfeasible, zip up all your code (please do not include
node_modules!) and send it via email to tech@katkin.com
We would also appreciate it if you can write a sentence or two about what you think of this test and/or and how we could improve it.