Welcome! This repository contains a small, partially implemented backend service designed for evaluating software engineering candidates.
Your task is to extend it, improve it, and demonstrate your ability to work within an existing codebase using modern development practices.
This project simulates contributing to a real internal system. Please treat it like production-quality work: readable code, tests, documentation, and thoughtful architecture all matter.
The base project includes:
- Node.js + TypeScript
- Express or Fastify
- Prisma ORM (PostgreSQL)
- Router β Controller β Service β Repository architecture
- Zod-based request validation
- JWT Authentication
- Role-Based Authorization (RBAC)
- Swagger/OpenAPI documentation
- Pino/Winston JSON logging
- Environment variable validation
- Dockerized local development
- Jest or Vitest test framework (unit + API tests)
- PostgreSQL (via Docker)
- Prisma migrations + seed script
A minimal Vue 3 scaffold may be provided, or you may build one yourself depending on the task assignment.
git clone <your-fork-url>
cd candidate-projectcp .env.example .envdocker-compose up --buildAPI available at:
http://localhost:3000
Swagger docs at:
http://localhost:3000/docs
backend/
src/
config/
db/
modules/
auth/
users/
...
middlewares/
common/
tests/
app.ts
server.ts
prisma/
docker-compose.yml
Dockerfile
README.md
- βοΈ Correctness
- βοΈ Code Quality
- βοΈ Testing coverage & quality
- βοΈ API design & documentation
- βοΈ Architecture alignment
- βοΈ Git hygiene & commits
Choose ONE task track that best aligns with your background and the position mentioned in your welcome email. For example, if applying for a Backend Developer role, choose track B or D.
(You may complete more than one if you want to demonstrate broader capability.)
Note: This is only for evaluation. None of this code you submit will be merged or used for current projects.
Build a Single Page Application (SPA) that interacts with this backend API.
- Use Vue 3 (recommended) or any modern JS framework
- Use a component library of your choice
- Implement:
- Registration (
POST /auth/register) - Login (JWT) (
POST /auth/login) - Store & persist JWT
/auth/meprofile page- User listing (
GET /users)
- Registration (
- Handle:
- Loading & error states
- Validation & API errors
- UI expectations:
- Clean and functional UI
- Router integration (Vue Router, React Router)
- Reusable component structure
- Search/filter users
/frontendfolder or separate repo- README explaining setup & architecture
Choose one of the DB tasks below.
You will:
- Update Prisma schema to support MySQL
- Add MySQL to Docker Compose
- Update migrations to new SQL engine
- Adapt enum behavior, relations, and indexes
- Validate full API functionality post-migration
This evaluates:
- SQL engine knowledge
- Prisma migration expertise
- Infrastructure adaptation skills
Examples:
ProjectsTeamsOrganizationsLocations
Your module must include:
- 1-to-many and many-to-many relationships
- Composite unique keys
- Cascading or restricted delete rules
- Paginated list APIs
- Integration tests validating constraints
Extend the API by adding a nested relational model tied to the User entity.
UserSettingsUserNotificationsUserSecurityLogsUserProfilesUserSessions
- Add new Prisma models + migration
- Create new module folder:
settings/ settings.router.ts settings.controller.ts settings.service.ts settings.repo.ts - Routes:
GET /users/:id/settingsPUT /users/:id/settings
- Zod validation
- Authorization rules:
- A user may only modify their own settings
- ADMIN may modify any user
- Add Swagger documentation
- Must include integration tests for:
- Access control (user vs admin)
- Upsert/update behavior
Implement a robust data seeding strategy for this project.
- Use Faker.js (or an equivalent library) to generate hundreds of fake users (for example 200β500).
- Include a mix of roles:
- At least 1
ADMIN - Some
MANAGERusers - Many
USERaccounts
- At least 1
- Ensure:
- Passwords are hashed using the existing auth/password utilities
- Emails are unique
- First/last names look realistic
Suggested file:
prisma/seed.dev.tsor
prisma/seed.tsand a corresponding npm script, for example:
"scripts": {
"prisma:seed": "ts-node prisma/seed.ts"
}Implement a separate seeding path suitable for production-like environments:
- Use a static file (JSON or CSV), for example:
prisma/seed.production.json- or
prisma/seed.production.csv
- Seed only a small, curated set of records, for example:
- One
ADMINaccount - A few demo
USERaccounts
- One
- Requirements:
- Seeding must be idempotent:
- Do not create duplicate records if seed is re-run
- Use
upsertor existence checks based on a stable key (e.g., email)
- Protect production from accidental bulk fake data:
- Use
NODE_ENVor a dedicated env var (e.g.SEED_MODE=development|production) - Ensure dev-only Faker-based seeding never runs in production
- Use
- Seeding must be idempotent:
- After seeding, log a summary:
- Number of users created
- Number of users updated (if using upsert)
- Role breakdown (e.g.,
ADMIN: 1, MANAGER: 5, USER: 300)
- Handle and log errors clearly.
- Seed additional related data once other modules exist (e.g., settings, projects).
- Integrate seeding into Docker Compose or CI in a safe way.
- Document how to run dev vs production seeding in the README.
- Seed script(s) under
prisma/ - Static data file(s) for production-style seeding
- Updated
package.jsonscripts section - Short documentation section in the README explaining:
- How to run dev seeding
- How to run production seeding
- Any assumptions or trade-offs
Implement full Zod-based validation for the existing User API endpoints.
This task evaluates your ability to:
- Apply strong API input validation
- Produce consistent error responses
- Use schemas to simplify controller logic
- Enforce real-world request constraints
Validate:
pageβ integer β₯ 1, default = 1pageSizeβ integer between 1 and 100, default = 20searchβ optional, trimmed string
Use:
z.coerce.number()for numeric coerciondefault()for fallback values.min()/.max()for constraintsvalidateQuery()middleware for enforcement
Schema must validate:
emailβ required, valid emailpasswordβ required, min length recommendedfirstNameβ optionallastNameβ optionalroleβ optional, must be one ofUSER | MANAGER | ADMIN
Validation must:
- Reject unexpected fields
- Produce structured JSON errors
- Ensure controllers only receive clean, typed data
- Create Zod schemas in:
src/modules/users/user.validation.ts - Integrate schemas into:
using:
user.router.tsvalidateQuery(listUsersQuerySchema)validateBody(createUserBodySchema)
- Refactor controller to rely on parsed input
- Ensure all validation errors return:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request",
"details": { ... }
}
}- Fork the repository
- Create a feature branch (
candidate/<your-name>) - Open a PR to your own fork
- Include a write-up describing:
- Architecture decisions
- Trade-offs you made
- Improvements you'd make with more time
- Add "mgtech-software" as a reviewer on your PR
- Reply to your initial email with a link to your PR
If any task feels ambiguous, conflicting, or incomplete, document your assumptions.
Thoughtful reasoning is part of the evaluation.
We look forward to reviewing your work.