Webapp: https://main.d2onw2mh99c9sz.amplifyapp.com/
Server: https://vz3zbcpx7i3gxn3gtw4x46ikv40gcbpu.lambda-url.ap-southeast-1.on.aws/
This is Tan Jing Sheng's implementation of the SWE Take Home Assignment.
| Event | Date & Time |
|---|---|
| Received | = 5th March 2025, 4:48 PM |
| Started | ~ 5th March 2025, 5:00 PM |
| Completed | ~ 6th March 2025, 7:00 AM |
To set up and run the project, you need the following:
Ensure that these dependencies are installed before proceeding with the setup.
-
Clone the repository:
git clone https://github.com/tjingsheng/swe-take-home-assignment.git cd swe-take-home-assignment -
Copy .env.example to .env and edit it
cp .env.example .env vim .env # or use any text editor to fill in the required valuesNote: There are no required values for local development, but you should still have the .env file
-
Install dependencies using
pnpm:pnpm install
-
Seed the database:
pnpm run seed
This will populate the database with initial test data.
Note: This shoud run automatically after
pnpm install -
Start the development server:
pnpm run dev
This will run the application in development mode with live reload.
-
Sorting Criteria
Ambiguity: Sorting is only mentioned as NAME or SALARY, always in ascending order. There is no mention of whether sorting can be combined (e.g., sorting first by SALARY and then by NAME in case of ties).
Assumption: If more than one sort key is provided (e.g., ["SALARY", "NAME"]), we apply sorting in the order given, prioritising the first key before moving to the next.
e.g. /users?sort=NAME&sort=SALARY will sort by NAME then SALARY is there is a tie.
-
Salary Range Handling
Ambiguity: The default values are 0.0 for min and 4000.0 for max. However, it's not explicitly stated what happens if min > max (e.g., /users?min=5000&max=4000).
Assumption: If min > max, return an empty list ("results": []), not an error.
-
Offset and Limit Behaviour
Ambiguity: There is no mentioning of behaviour when the offset exceeds the number of available records.
Assumption: If offset is greater than the available results, return an empty list ("results": []), not an error.
-
Concurrency and Scaling
Ambiguity: The requirement states that concurrent uploads are desirable but does not specify the expected behaviour when two uploads update the same user.
Assumption: The last successful upload overwrites the previous one (last write wins).
-
HTTP Response Codes
Ambiguity: Which HTTP status codes should be used for specific failures?
Assumption:
200 OK→ Successful operations.404 Not Found→ Unknown Routes.500 Internal Server Error→ Unexpected failures.
-
Unique Name Handling
Ambiguity: The requirement does not specify whether user names should be unique or how case sensitivity is handled when determining uniqueness.
Assumption: User names are not required to be unique. Names are treated as case-sensitive, meaning "JohnDoe" and "johndoe" are considered different users.
You can fetch user data using the following curl command:
curl -G "http://localhost:3000/users" \
--data-urlencode "min=1000" \
--data-urlencode "max=5000" \
--data-urlencode "offset=10" \
--data-urlencode "limit=50" \
--data-urlencode "sort=NAME"This request retrieves users whose salary falls between 1,000 and 5,000, with pagination controls (offset=10, limit=50) and sorted by name.
To upload a CSV file containing user data, use:
curl -X POST http://localhost:3000/upload \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "file=name,salary%0AAlex,3000.0%0ABryan,3500.0"curl -X POST "http://localhost:3000/upload" \
-H "Content-Type: multipart/form-data" \
-F "file=@./server/data/test.csv"Note: modify the curl to use a file that exists on your system.
This sends a CSV file located at ./server/data/test.csv to the server for processing.
-
pnpm run dev:server- Runs the development server (
serverpackage).
- Runs the development server (
-
pnpm run dev:webapp- Runs the development environment for the web application (
webapppackage).
- Runs the development environment for the web application (
-
pnpm run dev- Runs all
devscripts in parallel using--streamfor better output handling.
- Runs all
-
pnpm run seed:server- Seeds the server database with test data.
-
pnpm run build:server- Builds the server package.
-
pnpm run build:webapp- Builds the web application package.
-
pnpm run build- Runs both
build:serverandbuild:webappin parallel using--stream.
- Runs both
-
pnpm run format- Formats the monorepo with prettier
-
pnpm run dev- Starts the web application using Vite.
-
pnpm run build- Builds the TypeScript and Vite project.
-
pnpm run lint- Runs ESLint to check for code issues.
-
pnpm run preview- Previews the built web application.
-
pnpm run start- Starts the production server with
tsx watch, enabling live reloading for TypeScript changes. - Uses
cross-envto setNODE_ENV=productionconsistently across operating systems.
- Starts the production server with
-
pnpm run dev- Starts the development server with
tsx watch, enabling live reloading for TypeScript changes. - Uses
cross-envto setNODE_ENV=developmentconsistently across operating systems.
- Starts the development server with
-
pnpm run seed- Runs
seed.tsto populate the database with fake user data for testing. - Uses
faker-jsto generate realistic test data.
- Runs
-
pnpm run postinstall- Automatically runs
seedafter dependencies are installed, ensuring the database is populated without manual intervention.
- Automatically runs
-
pnpm run build- (Optional) Add a build step for the server if needed (e.g., compiling TypeScript).
-
pnpm run postbuild- Automatically zips the build for easier deployment.
- @mantine/core: Fully featured React components library.
- @mantine/hooks: Useful React hooks for building UIs.
- @tabler/icons-react: React icon set for UI elements, recommended by Mantine.
- @tanstack/react-query: Powerful asynchronous state management for TS/JS.
- axios: Promise-based HTTP client for browser and Node.js.
- react: The library for building web and native UIs.
- react-dom: Entry point for the DOM and server renderers for React.
- react-router: A flexible and standards-focused router for React.
- express: Fast, unopinionated, minimalist web framework for Node.js.
- fast-csv: Library for parsing and formatting CSV files in Node.
- multer: Middleware for handling
multipart/form-datauploads. - serverless-http: Wraps an Express app for serverless deployment.
- zod: TypeScript-first schema validation with static type inference.
- @dotenvx/dotenvx: Improved environment variable management.
- axios: Also used on the server side.
- @eslint/js: ESLint configuration for JavaScript.
- @types/react: TypeScript types for React.
- @types/react-dom: TypeScript types for ReactDOM.
- @vitejs/plugin-react: React plugin for Vite.
- eslint: Pluggable linting utility for JavaScript and JSX.
- eslint-plugin-react-hooks: Enforces React Hooks rules.
- eslint-plugin-react-refresh: Ensures proper use of React Refresh.
- globals: Provides a list of global variables for linting.
- typescript: Static typing for JavaScript.
- typescript-eslint: ESLint plugin for TypeScript.
- vite: Fast development server and build tool for modern frontends.
- prettier: Code formatter for consistent style.
- @faker-js/faker: Generate realistic fake data for testing.
- @types/express: TypeScript types for Express.
- @types/multer: TypeScript types for Multer.
- @types/node: TypeScript types for Node.js.
- cross-env: Cross-platform environment variable management.
- esbuild: Fast JavaScript bundler and minifier for production.
- tsx: Runs TypeScript files without compilation.
- prettier: Code formatter for consistent style.
Fun assignment!