Skip to content

03k64/tech-test

Repository files navigation

Engineer Tech Test Submission

Thanks for allowing me to complete your tech test - I really enjoyed it. I was familiar with Fastify, Jest and TypeScript going in. TypeBox was new to me, I've tried to use it correctly but I'm sure my usage of it could be improved. I hit a couple of issues with it around fast-json-stringify (for serialisation of responses) and jest-json-schema (for validation in tests). As far as I could tell this seems to relate to my usage of a Union type where the variants were an array of objects, or null.

The original instructions requested the ability to get product entities by brand ID and store entities by product ID. I have provided the following:

  • an endpoint to get brands, with optional pagination, product ID and search parameters
    • search is performed via case-insensitive substring match against the brand name field
  • an endpoint to get a single brand by ID
  • an endpoint to get products, with optional pagination, brand ID and search parameters
    • search is performed via case-insensitive substring match against the product label field
  • an endpoint to get stores, with optional pagination, product ID, and search parameters
    • search is performed via case-insensitive substring match against the store name field
  • an endpoint serving a simple health status, e.g., of the type that might be used to perform pod healthchecks in Kubernetes
  • a Swagger UI endpoint serving interactive API documentation
  • a metrics endpoint serving Prometheus-compatible HTTP server request duration metrics for all non-health, non-Swagger endpoints

Usage Instructions

I've used pnpm as my package manager - apologies if this causes issues. If you would like to run the application natively you should be able to do so with:

  1. pnpm i
  2. pnpm start

Alternatively, as you also mentioned Docker, I've provided a Dockerfile and a docker-compose file. You can run the application in Docker with:

  1. docker compose up -d app

Irrespective of whether you run it natively or in Docker, the application should be available on: http://localhost:3000. Additionally, metrics covering HTTP response time are available in Prometheus-compatible format on: http://localhost:3001/metrics.

Documentation

I've added Swagger documentation, this is available on: http://localhost:3000/documentation. Unfortunately there is a slight issue due to my use of TypeBox modules which means some invalid references are generated in the schema used by Swagger. This is visible in the documentation UI via an error alert (at the top of the page) and when looking at the response schema for each route (where the incorrectly referenced entry is shown as "string"). This issue has been raised on the @fastify/swagger repository as a bug.

Testing

I've provided unit tests (co-located with modules being tested) and end-to-end (E2E) tests (in the test directory).

You can run the unit tests with: pnpm t.

The E2E tests require the application to be running. If you're running it natively then you can run the E2E tests with: pnpm test:e2e:run. Alternatively you can run: pnpm test:e2e - this will start the application using Docker, run the tests, and stop the application again when they exit successfully.

Code Structure

I've treated the provided brands.json file as a "database". From that decision I've structured my code as though it was a normal three-layered web application:

  • route handlers (controllers) are in src/routes
  • services (business logic) are in src/services
  • database (repositories) are in src/database

I've also provided an error handler and not found handler in src/fastify-handlers. I favour consistent response shapes and providing these handlers enables that for most use-cases.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published