Skip to content

YieldStudio/technical-test-node-typescript

Repository files navigation

Introduction

Prerequisites

  1. IDE / code editor
  2. SQLite compatible database GUI
  3. API testing client tool (Postman, HTTPie, ...)

Initialize the project

npm install
npm run prisma:generate

Run the server

npm run dev
open http://localhost:3000

Run tests

npm test

Defaulted in watch mode

Instructions

Important

  1. Please turn off any AI helping tool.
  2. For the entire test, you are asked to improve the architecture of the codebase to enhance readability and provide the best solutions for each exercise.
  3. We don't expect you to know prisma (ORM), feel free to ask whatever you want about it.
  4. For simplicity purpose, we don't expect any operation to be transactional.

Timing This test is designed to be completed in approximately 45 minutes to 1 hour. Each part includes a time estimate to help you manage your time. If you run out of time on a part, explain in a comment what you would have done.

Evaluation criteria We evaluate the clarity of your code, your architectural choices, and your ability to justify them. We value quality over quantity — a well-structured partial solution is better than a rushed complete one.


1. Add validation for Recipe and Ingredients creation (~15 min)

Add rules to validate the format of the provided input before persisting it.

a. A Recipe must have at least 1 ingredient. b. prepTime cannot be null or 0. c. cookingTime cannot be null but can be 0.

Validation errors should be returned to the client in a clear and exploitable way.

Think about where in the architecture this validation logic should live.


2. Test recipe creation (~20 min)

Implement a unit test to verify recipe creation and persistence. The test should not rely on any prisma related code. The tested module should be the createRecipeUseCase, do not bother calling the endpoint.

The current code is not testable in isolation — you will need to refactor CreateRecipeUseCase to make it testable. This refactoring is expected and part of the exercise.

An interface RecipeRepository is already defined in src/repositories/recipe/index.ts. Write an InMemoryRecipeRepository that implements this interface and stores recipes in a simple array. Use it in your tests instead of mocking.

Your tests should cover:

  • A successful recipe creation (the recipe is correctly persisted with all its data).
  • Validation errors from part 1 (if you completed it).

3. Build a Recipe class (~25 min)

We want to add a totalTime property to each recipe. This property should be a computation such as totalTime = prepTime + cookingTime.

Build a Recipe class so that each instance is guaranteed to be a valid recipe (with valid values).

  1. Implement the class and include totalTime as a computed property.
  2. The class should enforce the validation rules from part 1 — it should be impossible to instantiate an invalid Recipe.
  3. Test the class behavior (valid creation, rejection of invalid data, totalTime computation).
  4. Update CreateRecipeUseCase to use the Recipe class. You don't need to refactor the routes or the repository — focus on the domain and use case layers.

4. Refactor a React component (~20 min)

The recipe page (frontend/) is already split into components (RecipePage / RecipeList / RecipeListItem / RecipeForm), and the fetching is already extracted into useRecipes / useCreateRecipe (frontend/hooks/) — you don't need to touch those.

RecipeForm (react-hook-form) currently does everything in one place: the form wiring, the validation rules (inline in register), the transformation of the form values into the API payload, and the rendering.

The exercise is the refactoring. Pull this logic apart so the component is easier to maintain — for instance a custom hook for the form (state/validation/submit) and a place for the validation rules — and leave RecipeForm focused on rendering. There is no single "right" decomposition; make choices and own them.

A behaviour test is provided in frontend/recipeForm.test.tsx. It drives the form through the DOM, so it asserts on what the user sees rather than on the internals — it should stay green throughout your refactoring (treat it as a safety net). The happy path is already written; fill in the it.todo cases for the validation rules (title required, prepTime > 0, cookingTime >= 0, at least one ingredient).

zod + @hookform/resolvers are installed if you want to use a schema for the validation, but that's up to you.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors