This document tracks key things I've learned while building this project, focusing on Node.js, TypeScript, backend architecture, and best practices.
- How to use tsconfig.json to control compilation.
- How to structure a modular project using
src/logic,src/config, andinterfaces. - Use of
tsyringefor dependency injection to decouple logic. - Using environment variables and
dotenvfor config separation.
- Built a secure authentication flow with:
- Hashed passwords using
bcrypt(with a SHA-256 pre-hash for long tokens), - JWT-based access tokens,
- Refresh token sessions stored in DB and rotated on use.
- Hashed passwords using
- Implemented middleware for:
- Input validation with Joi,
- Logging and structured error handling,
- Authentication via access tokens using Express middleware.
- Created schemas using Joi and extracted request types from them.
- Centralized validation logic and reused it across routes.
- Used Jest and Supertest for Integration and Unit tests
- Logged requests using a custom middleware.
- Interfaces vs types in modeling request/response DTOs.
- Integrated
swagger-jsdocandswagger-ui-express. - Learned how to:
- Annotate routes with OpenAPI specs.
- Auto-generate docs and serve them with Express.
- Used DI to inject services.
- Split code into layers:
- Controller
- Service
- Repository
- Followed Separation of Concerns and Single Responsibility Principle.
- Add role-based access control (RBAC).
- Explore caching with Redis for session tokens.
- Dockerize the app for deployment.
- Vitest is better than Jest (better integration with TS and Dev Experience)
- Zod over Joi (also a typescript library, not js like Joi)
- Biome combines prettier and eslint and is simpler to configure
- Remove try/catch from controllers - middleware already handles this
- Add reasons why I used specific library/framework and provide alternatives
- Add autogenerated API docs for consistency