A scalable, maintainable, and type-safe backend for the HiredWithAndi ecosystem. Built with Node.js, Express, and PostgreSQL.
- Runtime: Node.js (v20+)
- Framework: Express.js (ESM)
- Language: TypeScript
- Database: PostgreSQL
- ORM: Prisma
- Validation: Zod
- Authentication: JWT & Bcrypt
- Storage: Cloudinary (via Base64 upload)
This guide assumes a fresh Ubuntu 22.04/24.04 LTS server.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git nginx postgresql postgresql-contribLog into PostgreSQL and create the database/user:
sudo -u postgres psqlCREATE DATABASE hiredwithandi;
CREATE USER hwa_user WITH PASSWORD 'your_strong_password';
GRANT ALL PRIVILEGES ON DATABASE hiredwithandi TO hwa_user;
\qcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 20git clone https://github.com/alvianzf/hiredwithandi-be.git
cd hiredwithandi-be
npm installCreate .env file:
cp .env.example .env
nano .envUpdate DATABASE_URL to: postgresql://hwa_user:your_strong_password@localhost:5432/hiredwithandi?schema=public
Push schema and build:
npx prisma db push
npm run buildnpm install -g pm2
pm2 start dist/server.js --name hwa-backend
pm2 save
pm2 startupsudo nano /etc/nginx/sites-available/hwa-backendAdd configuration:
server {
listen 80;
server_name your_domain_or_ip;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}Enable and restart:
sudo ln -s /etc/nginx/sites-available/hwa-backend /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxhttps://your-api-domain.com/api
Login Flow:
- The frontend first calls
/auth/check-emailto see if the user exists. - If
exists: true, prompt for password and call/auth/login. - If
exists: false, prompt for name/password and call/auth/register.
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /auth/check-email |
Check if email exists in system | None |
| POST | /auth/register |
Register new user | None |
| POST | /auth/login |
Login and get JWT | None |
| POST | /auth/refresh |
Refresh access token using RT | None |
| Method | Endpoint | Description | Auth | Role |
|---|---|---|---|---|
| GET | /organizations |
List all organizations | JWT | Superadmin |
| POST | /organizations |
Create organization | JWT | Superadmin |
| Method | Endpoint | Description | Auth | Role |
|---|---|---|---|---|
| GET | /students |
List organization students | JWT | Admin/Superadmin |
| GET | /stats |
Global system stats | JWT | Superadmin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /jobs |
List all user jobs | JWT |
| POST | /jobs |
Create new job post | JWT |
| PATCH | /jobs/:id/status |
Update job status/order | JWT |
| PATCH | /jobs/:id |
Update job details | JWT |
| DELETE | /jobs/:id |
Delete job application | JWT |
Sample Response / Request Body
{
"id": "u-u-i-d",
"company": "Google",
"position": "Software Engineer",
"url": "https://careers.google.com/jobs/...",
"salary": "10k - 15k",
"notes": "Referral from Andi",
"workType": "Remote",
"location": "Jakarta, Indonesia",
"jobFitPercentage": 85,
"status": "applied",
"boardPosition": 1.0,
"dateApplied": "2024-03-20T10:00:00Z",
"statusChangedAt": "2024-03-20T10:00:00Z"
}Sample Response
{
"id": "u-u-i-d",
"email": "[email protected]",
"name": "Alvian Azfa",
"role": "STUDENT",
"status": "ACTIVE",
"orgId": "org-u-u-i-d",
"bio": "Passionate developer",
"avatarUrl": "https://..."
}Sample Response (POST /auth/login)
{
"data": {
"token": "eyJhbGci...",
"user": {
"id": "u-u-i-d",
"email": "[email protected]",
"name": "User Name",
"role": "STUDENT",
"orgId": "org-uuid"
}
}
}Note: The backend CORS policy allows requests from all localhost and 127.0.0.1 ports to ease local frontend development.
# Watch mode
npm run dev
# Generate Prisma Client
npx prisma generate
# Database Migration (Push)
npx prisma db push
# Seed Database (Creates default Superadmin based on .env)
# SUPERADMIN_EMAIL and SUPERADMIN_PASSWORD
npx prisma db seed