Documentation Index Fetch the complete documentation index at: https://mintlify.com/Rampop01/HR-Platform/llms.txt
Use this file to discover all available pages before exploring further.
Overview
HCMatrix uses a proxy-based API architecture to avoid CORS issues and centralize backend communication. All API requests flow through Next.js API routes that proxy to the backend server.
The API proxy is implemented in /app/api/proxy/[...path]/route.ts and automatically forwards requests to the configured backend.
Architecture
Why Use a Proxy?
CORS Prevention Eliminates cross-origin request issues
Centralized Config Single point for API configuration
Security Hide backend URLs from client
Request Control Modify requests/responses as needed
Configuration
Backend URL Setup
Configure the backend API URL in .env.local:
API_BASE_URL = https://apitest.hcmatrix.co
This is a server-side only variable. It is not exposed to the browser, keeping your backend URL private.
Default Configuration
From app/api/proxy/[...path]/route.ts:3:
const API_BASE_URL = process . env . API_BASE_URL || 'https://apitest.hcmatrix.co'
If API_BASE_URL is not set, requests default to https://apitest.hcmatrix.co.
API Proxy Implementation
The proxy route handles all HTTP methods and forwards them to the backend. From app/api/proxy/[...path]/route.ts:5-58:
async function proxyRequest ( req : NextRequest ) {
// Extract the path after /api/proxy/
const url = new URL ( req . url )
const pathSegments = url . pathname . replace ( '/api/proxy/' , '' )
const targetUrl = ` ${ API_BASE_URL } / ${ pathSegments }${ url . search } `
const headers : HeadersInit = {
'Accept' : 'application/json' ,
}
// Forward the Authorization header if present
const authHeader = req . headers . get ( 'Authorization' )
if ( authHeader ) {
headers [ 'Authorization' ] = authHeader
}
const fetchOptions : RequestInit = {
method: req . method ,
headers ,
}
// Forward the body for POST/PUT/PATCH requests
if ([ 'POST' , 'PUT' , 'PATCH' ]. includes ( req . method )) {
headers [ 'Content-Type' ] = 'application/json'
try {
const body = await req . json ()
fetchOptions . body = JSON . stringify ( body )
} catch {
// No body or invalid JSON — that's fine
}
}
try {
const response = await fetch ( targetUrl , fetchOptions )
const contentType = response . headers . get ( 'content-type' )
let data : any
if ( contentType ?. includes ( 'application/json' )) {
data = await response . json ()
} else {
const text = await response . text ()
data = { message: text }
}
return NextResponse . json ( data , { status: response . status })
} catch ( error ) {
console . error ( 'Proxy error:' , error )
return NextResponse . json (
{ message: 'Failed to connect to API server' },
{ status: 502 }
)
}
}
Supported HTTP Methods
The proxy supports all standard HTTP methods from route.ts:60-78:
export async function GET ( req : NextRequest ) {
return proxyRequest ( req )
}
Using the API Client
HCMatrix provides a centralized API client in lib/api.ts for all backend communication.
API Client Setup
From lib/api.ts:1-110:
const PROXY_BASE = '/api/proxy'
async function apiCall < T >(
endpoint : string ,
method : 'GET' | 'POST' = 'GET' ,
body ?: Record < string , unknown >,
token ?: string
) : Promise < T > {
const url = ` ${ PROXY_BASE }${ endpoint } `
const headers : HeadersInit = {
'Accept' : 'application/json' ,
}
if ( token ) {
headers [ 'Authorization' ] = `Bearer ${ token } `
}
if ( body ) {
headers [ 'Content-Type' ] = 'application/json'
}
const response = await fetch ( url , {
method ,
headers ,
body: body ? JSON . stringify ( body ) : undefined ,
})
const contentType = response . headers . get ( 'content-type' )
let responseData : any
if ( contentType ?. includes ( 'application/json' )) {
responseData = await response . json ()
} else {
const text = await response . text ()
throw new Error ( `API returned non-JSON response: ${ response . status } ` )
}
if ( ! response . ok ) {
const errorMessage =
responseData ?. message ||
responseData ?. error ||
`API error: ${ response . status } `
throw new Error ( errorMessage )
}
return responseData as T
}
Available API Methods
Authentication
Dashboard
Employees
Login Authenticate a user and receive a token: import { api } from '@/lib/api'
const response = await api . login ( 'user@example.com' , 'password123' )
// Returns: { user: {...}, token: "..." }
Logout End user session: Get Dashboard Data Fetch dashboard statistics: const data = await api . getDashboard ( token )
// Returns:
// {
// total_employees: number
// new_hire_count: number
// upcoming_event: number
// open_positions: number
// }
List Employees Fetch paginated employee list: const employees = await api . getEmployees ( token , 1 , {
department: 'Engineering' ,
status: 'active'
})
// Returns:
// {
// data: Employee[]
// current_page: number
// per_page: number
// total: number
// next_page_url: string | null
// prev_page_url: string | null
// }
Get Employee Details Fetch single employee: const employee = await api . getEmployee ( token , 123 )
// Returns full EmployeeDetail object
Search Employees Search with filters: const results = await api . searchEmployees (
token ,
{ name: 'John' , department: 'Sales' },
1
)
Type Definitions
The API client includes comprehensive TypeScript types for type safety.
Authentication Types
export interface LoginRequest {
email : string
password : string
}
export interface LoginResponse {
user : {
id : number
name : string
email : string
[ key : string ] : any
}
token : string
}
Employee Types
export interface Employee {
id : number
name : string
email : string
job_title : string
department : string
location : string
employment_type : string
status : string
start_date : string
avatar ?: string
}
export interface EmployeeDetail extends Employee {
phone : string
date_of_birth : string
address : string
salary : number
manager : string
manager_id : number
next_of_kin_name : string
next_of_kin_relationship : string
next_of_kin_phone : string
tenure_years : number
tenure_months : number
spouse : string | null
}
Authentication
Session Management
Authentication is handled via lib/auth.ts:1-41 using localStorage:
export interface AuthSession {
token : string
user : {
id : number
name : string
email : string
}
}
const SESSION_KEY = 'hcmatrix_session'
export const auth = {
saveSession ( session : AuthSession ) : void {
if ( typeof window !== 'undefined' ) {
localStorage . setItem ( SESSION_KEY , JSON . stringify ( session ))
}
},
getSession () : AuthSession | null {
if ( typeof window !== 'undefined' ) {
const session = localStorage . getItem ( SESSION_KEY )
return session ? JSON . parse ( session ) : null
}
return null
},
clearSession () : void {
if ( typeof window !== 'undefined' ) {
localStorage . removeItem ( SESSION_KEY )
}
},
isAuthenticated () : boolean {
return this . getSession () !== null
},
getToken () : string | null {
return this . getSession ()?. token || null
},
}
Authentication Flow
User Login
Call api.login() with credentials: const response = await api . login ( email , password )
Save Session
Store the session in localStorage: auth . saveSession ({
token: response . token ,
user: response . user
})
Use Token
Include token in subsequent API calls: const token = auth . getToken ()
const data = await api . getDashboard ( token )
Logout
Clear session on logout: await api . logout ( token )
auth . clearSession ()
Protected Routes
Protect pages by checking authentication status:
'use client'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
import { auth } from '@/lib/auth'
export default function ProtectedPage () {
const router = useRouter ()
useEffect (() => {
if ( ! auth . getToken ()) {
router . push ( '/auth/login' )
}
}, [ router ])
// Page content...
}
Error Handling
The API client includes comprehensive error handling:
Connection Errors
When the backend is unreachable:
{
"message" : "Failed to connect to API server" ,
"status" : 502
}
API Errors
When the API returns an error:
try {
await api . login ( email , password )
} catch ( error ) {
// Error message from API or generic error
console . error ( error . message )
}
Non-JSON Responses
If the API returns non-JSON content:
throw new Error ( `API returned non-JSON response: ${ response . status } ` )
Best Practices
Always Use Types Leverage TypeScript interfaces for type safety and autocomplete
Handle Errors Wrap API calls in try/catch blocks and provide user feedback
Check Authentication Verify token exists before making authenticated requests
Normalize Data Use mapper functions to normalize API responses
Testing API Integration
Local Testing
Test the proxy with curl:
curl http://localhost:3000/api/proxy/api/auth/login \
-X POST \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password"}'
Using Different Backends
Switch between environments:
Development
Staging
Production
API_BASE_URL = https://apitest.hcmatrix.co
Troubleshooting
Cause : Backend server is unreachableSolutions :
Verify API_BASE_URL is correct
Check backend server is running
Test backend URL directly in browser
Cause : Invalid or expired tokenSolutions :
Check token is being sent in Authorization header
Verify token hasn’t expired
Re-authenticate user
Cause : Bypassing the proxySolutions :
Always use /api/proxy/ prefix
Never call backend URL directly from frontend
Use the api client from lib/api.ts
Cause : API response doesn’t match TypeScript interfaceSolutions :
Check API documentation
Update type definitions
Use mapper functions to normalize data
Next Steps
Environment Setup Complete environment configuration guide
Settings Configure platform settings and preferences