A Modern HR Workflow Platform for seamless candidate management, intelligent offer letter generation, and comprehensive workspace controls.
HrLetterPlus streamlines the entire HR workflow—from candidate tracking through offer generation to employee onboarding—with an intuitive, modern interface and powerful backend APIs.
- Frontend: React 19 + TypeScript + Vite for rapid, type-safe development
- Backend: Node.js + Express with PostgreSQL persistence
- Authentication: Secure JWT-based access control
- APIs: RESTful endpoints for all core HR operations
- Secure user registration and login with bcrypt hashing
- JWT-based authentication for all protected endpoints
- Role-based access control
- Session management and logout
- Real-time offer status statistics and distribution
- Activity timeline for tracking workflow progress
- Interactive charts for candidate and offer analytics
- Quick insights into recruitment metrics
- Complete CRUD operations for candidate profiles
- Advanced search and filtering capabilities
- Candidate data enrichment (department, designation, source tracking)
- Bulk candidate operations support
- Reusable offer letter templates with dynamic placeholders
- Rich HTML support for professional formatting
- Version control for template iterations
- Template soft-delete for audit trails
- One-click offer creation from templates
- Complete offer versioning and change history
- Intelligent status workflow (Draft → Sent → Accepted/Rejected)
- PDF generation for professional offer documents
- Offer status tracking and update logs
- Personalized profile management (name, title, team)
- Granular notification preferences
- Theme and appearance customization
- Security settings (2FA, session timeout)
- Integration configuration (email, storage)
- Search across candidates, offers, templates, and users
- Real-time results with relevance ranking
- Advanced filtering by multiple criteria
- Full-text search support
- In-app help center with quick links
- Frequently asked questions
- Workflow tutorials and best practices
| Technology | Purpose |
|---|---|
| React 19 | Modern UI framework with hooks and concurrent features |
| TypeScript 6 | Type-safe development with full IDE support |
| Vite | Lightning-fast build tool and dev server |
| Tailwind CSS | Utility-first styling framework |
| Shadcn/ui | High-quality, unstyled component library |
| React Router 7 | Client-side routing and navigation |
| Recharts | Composable charting library |
| Technology | Purpose |
|---|---|
| Node.js 18+ | JavaScript runtime environment |
| Express 5 | Minimal and flexible web framework |
| PostgreSQL | Reliable, powerful relational database |
| jsonwebtoken | JWT generation and verification |
| bcryptjs | Secure password hashing |
| CORS | Cross-origin resource sharing |
| Dotenv | Environment variable management |
HrLetterPlus/
├── backend/ # Express API server
│ ├── config/
│ │ └── db.js # PostgreSQL connection pool
│ ├── controllers/ # Request handlers
│ │ ├── auth.controller.js
│ │ ├── candidate.controller.js
│ │ ├── offer.controller.js
│ │ ├── template.controller.js
│ │ ├── settings.controller.js
│ │ ├── search.controller.js
│ │ └── help.controller.js
│ ├── routes/ # API endpoints
│ │ ├── auth.routes.js
│ │ ├── candidate.routes.js
│ │ ├── offer.routes.js
│ │ ├── template.routes.js
│ │ ├── settings.routes.js
│ │ ├── search.routes.js
│ │ └── help.routes.js
│ ├── middleware/
│ │ └── auth.middleware.js # JWT verification
│ ├── index.js # Express app entry point
│ └── package.json
│
├── frontend/ # React + Vite application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ │ ├── app-sidebar.tsx
│ │ │ ├── site-header.tsx
│ │ │ ├── nav-user.tsx
│ │ │ └── ui/ # Shadcn component library
│ │ ├── pages/ # Route pages
│ │ │ ├── auth/
│ │ │ ├── candidates/
│ │ │ ├── dashboard/
│ │ │ ├── offers/
│ │ │ ├── templates/
│ │ │ ├── settings/
│ │ │ ├── search/
│ │ │ └── help/
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utility functions
│ │ ├── App.tsx # Main app component
│ │ └── main.tsx # Entry point
│ ├── vite.config.ts
│ ├── tsconfig.json
│ └── package.json
│
└── .gitignore
- Node.js 18+ (Download)
- npm 9+ (included with Node.js)
- PostgreSQL 12+ (Download)
- A modern web browser (Chrome, Firefox, Safari, Edge)
node --version # Should be v18.0.0 or higher
npm --version # Should be 9.0.0 or higher
psql --version # Should be 12.0 or higher# Server Configuration
PORT=5000 # API server port (default: 5000)
NODE_ENV=development # Environment mode
# JWT Security
JWT_SECRET=your_super_secret_jwt_key_min_32_chars_recommended
# Database Connection
DB_HOST=localhost # PostgreSQL host
DB_PORT=5432 # PostgreSQL port (default: 5432)
DB_USER=postgres # Database user
DB_PASSWORD=your_secure_password # Database password
DB_NAME=hrletterplus_db # Database nameSecurity Tips:
- Generate a strong JWT secret:
openssl rand -base64 32 - Never commit
.envto version control - Use different secrets for development and production
- Rotate secrets regularly
# API Configuration
VITE_API_URL=http://localhost:5000 # Backend API base URL
VITE_APP_NAME=HrLetterPlus # Application name# Clone the repository
git clone https://github.com/Jaykumar122/Hrletterplus.git
cd hrletterplus
# Create environment files
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env# Create PostgreSQL database
psql -U postgres -c "CREATE DATABASE hrletterplus_db;"
# Update backend/.env with your database credentials# Install backend dependencies
cd backend
npm install
# Install frontend dependencies (in new terminal)
cd ../frontend
npm installTerminal 1 - Backend:
cd backend
npm start✅ Backend running on http://localhost:5000
Terminal 2 - Frontend:
cd frontend
npm run dev✅ Frontend running on http://localhost:5173
Open your browser and navigate to:
http://localhost:5173
Default test credentials (if seed data exists):
- Email:
admin@hrletterplus.com - Password:
password123
cd frontend
npm run build # Create optimized production bundle
npm run preview # Preview the production build locallyBase URL: http://localhost:5000
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
API health check |
GET |
/health |
Server status |
POST |
/api/auth/register |
Register new user |
POST |
/api/auth/login |
Login and get JWT token |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/logout |
Logout current user |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/dashboard/stats |
Offer statistics |
GET |
/api/dashboard/activity |
Recent activity feed |
GET |
/api/dashboard/chart |
Chart data (time-series) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/candidates |
List all candidates |
POST |
/api/candidates |
Create new candidate |
GET |
/api/candidates/:id |
Get candidate details |
PUT |
/api/candidates/:id |
Update candidate |
DELETE |
/api/candidates/:id |
Delete candidate |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/templates |
List all templates |
POST |
/api/templates |
Create new template |
GET |
/api/templates/:id |
Get template details |
PUT |
/api/templates/:id |
Update template |
DELETE |
/api/templates/:id |
Soft-delete template |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/offers |
List all offers |
POST |
/api/offers |
Create new offer |
GET |
/api/offers/:id |
Get offer details |
PUT |
/api/offers/:id |
Update offer |
PATCH |
/api/offers/:id/status |
Update offer status |
GET |
/api/offers/:id/history |
Get offer version history |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/settings |
Get user settings |
PUT |
/api/settings |
Update user settings |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/search?q=query |
Search all resources |
GET |
/api/help |
Get help center data |
All protected endpoints require a Bearer token in the Authorization header:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:5000/api/candidatesAll API responses follow a consistent JSON format:
Success (2xx):
{
"data": { /* response data */ },
"message": "Operation successful"
}Error (4xx, 5xx):
{
"message": "Error description",
"error": "error details"
}- ✅ Auto-migrations: The backend automatically creates the
user_settingstable on startup - ✅ CORS Configuration: Frontend origin
http://localhost:5173is whitelisted - ✅ JWT Expiry: Tokens expire after 7 days
⚠️ Database: Ensure PostgreSQL is running before starting the backend⚠️ Port Conflicts: ChangePORTin.envif port 5000 is already in use
We welcome contributions! Please follow these steps:
-
Fork the repository
git clone https://github.com/jaykumar122/hrletterplus.git cd hrletterplus -
Create a feature branch
git checkout -b feature/your-feature-name
-
Commit your changes
git commit -m "feat: Add your feature description" -
Push to your fork
git push origin feature
-
Open a Pull Request
- Include a clear description of your changes
- Reference any related issues
- Ensure all tests pass
- Follow existing code style and patterns
- Write meaningful commit messages
- Test your changes locally before submitting
- Keep PRs focused on a single feature/fix
This project is licensed under the ISC License. See LICENSE file for details.
Built with ❤️ by the HrLetterPlus team