Backend APIs
Overview
PeopleHub backend consists of three Node.js-based API services handling different domains: core HRMS functionality, candidate onboarding, and external integrations.
PeopleHub API (Main Backend)
Overview
Core backend API providing all HRMS functionality via RESTful HTTP endpoints.
Technical Stack
- Runtime: Node.js 22.x
- Framework: Fastify 5.5.0
- Language: TypeScript 5.9.2
- ORM: Drizzle ORM 0.44.4
- Database: PostgreSQL 17.5 (RDS Multi-AZ)
- Validation: Zod 4.1.3
- Auth: JWT (@fastify/jwt 10.0.0)
- Deployment: AWS Lambda via Serverless Framework 4.21.0
Architecture
Deployment: Single Lambda function with Fastify routing Package Size: ~1.5MB (optimized with esbuild) Memory: 1024 MB Timeout: 10 seconds Region: ap-south-1
Endpoints
Total: 150+ REST API endpoints
Modules:
- Employee Management:
/api/employees/* - Recruitment:
/api/jobs/*,/api/candidates/* - Leave:
/api/leave/* - Attendance:
/api/attendance/* - Performance:
/api/performance/*,/api/okr/* - Separation:
/api/separation/* - Talent:
/api/talent/*,/api/demands/* - Settings:
/api/settings/*,/api/master-data/* - Users & Roles:
/api/users/*,/api/roles/* - Documents:
/api/documents/* - Support:
/api/tickets/*
Authentication
Endpoints:
POST /api/auth/loginPOST /api/auth/refreshPOST /api/auth/logout
Token Handling:
- Access token: 4 hours (JWT)
- Refresh token: 7 days (HTTP-only cookie)
- Password hashing: bcrypt (10 rounds)
Authorization
- JWT validation on all protected routes
- Permission-based access control (RBAC) at endpoint level
- Data filtering based on user's org hierarchy and permissions
Database Access
- Connection Pooling: 10 connections per Lambda instance
- ORM: Drizzle (type-safe SQL queries)
- Migrations: Drizzle Kit for schema changes
File Handling
Pattern: Presigned S3 URLs
- Frontend requests presigned URL from API
- API generates URL (valid 15 minutes)
- Frontend uploads directly to S3
- API stores file metadata in database
API Documentation
- Interactive Docs:
/docsendpoint (Scalar UI) - Format: OpenAPI/Swagger
- Accessibility: Available in all environments
Performance
- Cold Start: <500ms
- Warm Execution: 10-50ms
- Database Queries: <10ms (indexed queries)
- API Response Time: <200ms p95
Candidate Onboarding API
Overview
Isolated backend API for candidate onboarding workflows, separated from main system for security.
Purpose
Handles all pre-joining activities for candidates who don't yet have employee status:
- Personal information collection
- Document uploads
- Background verification (BGV)
- Policy acknowledgment and e-signature
- Onboarding task tracking
Technical Stack
- Runtime: Node.js 18.x
- Framework: Fastify 5.5.0
- Language: TypeScript 5.9.2
- ORM: Drizzle ORM 0.44.4
- Database: Same PostgreSQL RDS (limited access)
- Deployment: AWS Lambda (separate from main API)
Architecture
Deployment: Separate Lambda function Package Size: ~1.5MB Memory: 1024 MB Timeout: 10 seconds Domain: Separate subdomain for security isolation
Key Endpoints
- Candidate Profile:
/api/candidate/profile - Documents:
/api/candidate/documents/* - Background Verification:
/api/candidate/bgv/* - Policies:
/api/candidate/policies/* - E-Signature:
/api/candidate/esign/* - Tasks:
/api/candidate/tasks/*
Security Isolation
Why Separate? Candidates are external users (not yet employees) handling sensitive PII data before employment relationship is established.
Isolation Measures:
- Separate Lambda: Independent deployment and scaling
- Limited Database Access: Only onboarding-related tables
- Separate Credentials: Different database user with restricted permissions
- Separate Domain: Different subdomain/endpoint
- No Access to Employee Data: Cannot query employee tables
Data Migration: Once candidate is hired:
- HR initiates "migrate to employee" action in main app
- Main API creates employee record
- Copies relevant candidate data
- Candidate record marked as "migrated"
- Candidate loses access to onboarding portal
Authentication
- Token-Based: Unique token sent via email
- No Password: Candidates authenticate with email token only
- Session Duration: 24 hours
- One-Time Links: Secure links for document uploads
Integrations
Digio (E-Signature):
- Create signature requests
- Receive webhook callbacks
- Update policy signature status
Notifications:
- Onboarding welcome email
- Document upload reminders
- Policy signature reminders
- HR notifications on completion
Integration API
Overview
Backend service handling all external system integrations and scheduled background jobs.
Purpose
Centralized integration layer for:
- Webhook endpoints for external systems
- Scheduled data sync jobs
- Third-party API integrations
- Background processing tasks
Technical Stack
- Runtime: Node.js 20.x
- Framework: Fastify 5.5.0
- Language: TypeScript 5.9.2
- ORM: Drizzle ORM 0.44.4
- Database: Shared PostgreSQL RDS
- Deployment: AWS Lambda
Architecture
Deployment: Single Lambda function Timeout: Extended (30 seconds for long-running syncs) Memory: 1024 MB Triggers: HTTP endpoints + CloudWatch Events (cron)
Webhook Endpoints
Digio (E-Signature):
- Endpoint:
POST /webhooks/digio - Events: Signature requested, signed, failed, expired
- Processing: Validate signature → Parse event → Update database → Trigger notification
Future Webhooks: ATS candidate updates, Payroll sync, BGV results
Scheduled Jobs (Cron)
Trigger: CloudWatch Events (EventBridge)
Daily Jobs:
- Clean up expired tokens
- Archive old logs
- Sync data from external systems (when implemented)
Weekly Jobs:
- Generate integration health reports
- Data reconciliation checks
Configuration Example (serverless.yml):
yaml
events:
- schedule: cron(0 2 * * ? *) # Daily at 2 AM ISTExternal API Clients
Digio API Client:
- Create e-signature requests
- Check signature status
- Download signed documents
Future Integrations: TalentRecruit (ATS), Payroll system, BGV providers
Data Sync Pattern
- Cron job triggers Lambda
- Fetch data from external system (API call)
- Transform data to PeopleHub format
- Compare with existing records
- Insert/update database
- Log sync status and errors
- Send summary email (if errors)
Security
Webhook Validation:
- Signature verification using shared secret
- Timestamp validation (prevent replay attacks)
- IP whitelisting (where supported)
API Credentials:
- Stored in AWS Secrets Manager
- Automatic rotation every 30 days
- Never logged or exposed
Error Handling
- Exponential backoff for API failures
- Max 3 retries for transient errors
- Dead Letter Queue (DLQ) for failed webhook events
- Comprehensive logging for investigation
Common Deployment Details
Deployment
Tool: Serverless Framework Command: serverless deploy --stage devDuration: ❤️ minutes per service Strategy: Blue/green deployment (new version, test, cutover)
Environment Variables
Stored in AWS Secrets Manager and injected at deployment:
- Database credentials
- JWT secrets
- AWS S3 bucket names
- External API keys (Digio, notifications, etc.)
Logging & Monitoring
Logging:
- Destination: AWS CloudWatch Logs
- Format: Structured JSON logs
- Retention: 90 days
Monitoring:
- Lambda invocations, duration, errors, throttles
- Database query performance
- API response times
- External API call latency
Alarms:
- Error spikes (>5% error rate)
- High latency (>500ms p95)
- API timeouts
- Integration failures
Error Handling
Standard Error Format:
json
{
"statusCode": 400,
"error": "Bad Request",
"message": "Detailed error message"
}Status Codes: 200, 201, 400, 401, 403, 404, 500