Ngejoblist
Overview
Ngejoblist was built as a technical requirement for an internship application. The task was to build a job platform backend using NestJS, demonstrating production-style API structure, authentication, and business logic. This project pushed me beyond coursework into building something that resembled a real product.
Problem
- The internship application required a technical demonstration — not just a resume, but a working backend system
- I needed to prove I could build production-style APIs with authentication, authorization, and complex business logic
- The job platform domain required handling multiple entities: companies, jobs, applications, and users
Goal
- Build a job platform backend that demonstrates NestJS best practices
- Implement JWT authentication with role-based access control
- Add Cloudinary integration for image uploads
- Document every endpoint with Swagger
Role
I built the entire backend independently.
Team: Achmad Raihan Fahrezi Effendy (Backend Developer)
Architecture
| Layer | Technology | Purpose |
|---|---|---|
| Framework | NestJS 10 | Modular backend structure |
| Auth | JWT (passport-jwt) | Authentication and authorization |
| ORM | Prisma | Schema-driven data access |
| Database | PostgreSQL | Persistent storage |
| Uploads | Cloudinary | Image storage and optimization |
| Logging | Winston + daily-rotate-file | Structured logging with rotation |
| Docs | Swagger (@nestjs/swagger) | Interactive API documentation |
| Rate Limiting | @nestjs/throttler | API rate limiting |
| Validation | Zod | Schema validation |
| Testing | Jest + Supertest | Unit and integration tests |
Key Features
- JWT Authentication — Register, login, and token refresh with bcrypt password hashing
- Role-Based Access — Separate permissions for job seekers, companies, and administrators
- Job Management — CRUD operations for job postings with filtering and search
- Application System — Job seekers can apply, companies can review applications
- Image Uploads — Cloudinary integration for company logos and job images
- Rate Limiting — Throttler middleware to prevent abuse
- Structured Logging — Winston with daily log rotation
- Swagger Docs — Interactive API documentation for every endpoint
Technical Decisions
- NestJS was chosen because the internship required it — this was the project that made me proficient with the framework
- Prisma was used for schema-first development and type-safe database queries
- Cloudinary was chosen for image uploads to avoid managing file storage infrastructure
- Winston with daily rotation was added for production-ready logging
Challenges
- Understanding NestJS modules, providers, and dependency injection took significant time
- Designing the application flow between job seekers and companies required careful schema planning
- Building something that felt “production-ready” without actual production deployment was a mental shift
Outcome
The project was submitted as part of the internship application and demonstrated production-style backend skills. It became the foundation for my NestJS proficiency and influenced how I approach API design.
Final Thoughts
Ngejoblist taught me that building for a requirement is different from building for yourself. When the stakes are higher, the code needs to be cleaner, the decisions need to be more deliberate, and the documentation needs to be more thorough. That discipline carried into every project after.