A comprehensive backend REST API for managing all HR operations including employee management, attendance, leave, payroll, tasks, notifications, and real-time communication — built with Flask and PostgreSQL.
| Technology | Purpose |
|---|---|
| Flask | Python web framework |
| SQLAlchemy | ORM |
| PostgreSQL | Primary database |
| Flask-Migrate (Alembic) | Database migrations |
| Flask-SocketIO | Real-time notifications & chat |
| Cloudinary | File & document storage |
| JWT | Authentication & authorization |
| OTP Utils | Two-factor / OTP verification |
| psycopg2 | PostgreSQL adapter |
hrms-backend/
│
├── User_Data/ # User-uploaded files & documents
├── controllers/ # Business logic controllers
├── migrations/ # Alembic database migrations
├── static/
│ └── uploads/
│ └── chat_files/ # Real-time chat file attachments
│
├── .env # Environment variables
├── config.py # App configuration (DB, Cloudinary, JWT etc.)
├── models.py # SQLAlchemy database models
├── middleware.py # JWT auth middleware
├── server.py # Flask app entry point
├── socket_instance.py # Flask-SocketIO instance
├── leaves.py # Leave management routes
├── masteradmin.py # Master admin routes
├── superadmin_routes.py # Super admin routes
├── user_route.py # Employee/user routes
├── new.py # Additional routes
├── otp_utils.py # OTP generation & verification
└── clear # DB clear utility script
MasterAdmin
└── Company / Organisation
├── SuperAdmin (HR Manager)
└── Employee
├── Attendance (daily punch-in/out)
├── Leave
│ ├── LeaveType
│ └── LeaveBalance
├── Payroll
│ ├── Salary Structure
│ ├── Allowances
│ ├── Deductions
│ └── PaySlip (auto-generated)
├── Task
│ ├── TaskAssignment
│ └── TaskComment
├── Notification
└── ChatMessage
└── ChatFile (Cloudinary)
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/hrms_db
# JWT
SECRET_KEY=your_jwt_secret_key
JWT_EXPIRY_DAYS=7
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# OTP / Email
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your_email@gmail.com
MAIL_PASSWORD=your_app_password
# App
FLASK_ENV=development
FLASK_DEBUG=1# 1. Clone the repository
git clone <repo-url>
cd hrms-backend
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Set up environment variables
cp .env.example .env
# Edit .env with your credentials
# 5. Initialize database
flask db init
flask db migrate -m "initial migration"
flask db upgrade
# 6. Run the server
python server.py
# or with gunicorn (production)
gunicorn --worker-class eventlet -w 1 server:app --bind 0.0.0.0:5000
⚠️ Useeventletworker with gunicorn for Flask-SocketIO support.
MasterAdmin
└── SuperAdmin (HR / Company Admin)
└── Employee (Staff)
| Role | Access |
|---|---|
| MasterAdmin | Full system access, manage companies, super admins |
| SuperAdmin | Manage employees, approve leaves, run payroll, assign tasks |
| Employee | View own profile, apply leave, view payslip, chat, tasks |
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/login |
Login (all roles) |
| POST | /auth/send-otp |
Send OTP to email/phone |
| POST | /auth/verify-otp |
Verify OTP |
| POST | /auth/reset-password |
Reset password via OTP |
| POST | /auth/logout |
Logout |
| Method | Endpoint | Description |
|---|---|---|
| GET | /masteradmin/dashboard |
System-wide stats |
| POST | /masteradmin/company |
Create company |
| GET | /masteradmin/companies |
List all companies |
| PUT | /masteradmin/company/:id |
Update company |
| DELETE | /masteradmin/company/:id |
Delete company |
| POST | /masteradmin/superadmin |
Create super admin |
| GET | /masteradmin/superadmins |
List all super admins |
| DELETE | /masteradmin/superadmin/:id |
Remove super admin |
| Method | Endpoint | Description |
|---|---|---|
| GET | /superadmin/dashboard |
HR dashboard stats |
| POST | /superadmin/employee |
Add employee |
| GET | /superadmin/employees |
List all employees |
| GET | /superadmin/employee/:id |
Employee detail |
| PUT | /superadmin/employee/:id |
Update employee |
| DELETE | /superadmin/employee/:id |
Remove employee |
| GET | /superadmin/attendance |
All attendance records |
| GET | /superadmin/attendance/:employee_id |
Employee attendance |
| GET | /superadmin/leaves |
All leave requests |
| PUT | /superadmin/leave/:id/approve |
Approve leave |
| PUT | /superadmin/leave/:id/reject |
Reject leave |
| POST | /superadmin/payroll/run |
Run monthly payroll |
| GET | /superadmin/payroll |
All payroll records |
| GET | /superadmin/payslip/:id |
View payslip |
| POST | /superadmin/task |
Create task |
| GET | /superadmin/tasks |
All tasks |
| PUT | /superadmin/task/:id |
Update task |
| DELETE | /superadmin/task/:id |
Delete task |
| POST | /superadmin/notification |
Send notification |
| Method | Endpoint | Description |
|---|---|---|
| GET | /user/profile |
Own profile |
| PUT | /user/profile |
Update profile |
| POST | /user/attendance/punch-in |
Punch in |
| POST | /user/attendance/punch-out |
Punch out |
| GET | /user/attendance |
Own attendance history |
| POST | /user/leave/apply |
Apply for leave |
| GET | /user/leaves |
Own leave history |
| GET | /user/leave/balance |
Remaining leave balance |
| GET | /user/payslips |
Own payslip history |
| GET | /user/payslip/:id |
View specific payslip |
| GET | /user/tasks |
Assigned tasks |
| PUT | /user/task/:id/status |
Update task status |
| GET | /user/notifications |
Own notifications |
| PUT | /user/notification/:id/read |
Mark as read |
Salary is automatically calculated every month based on:
Gross Salary
├── Basic Salary
├── HRA (House Rent Allowance)
├── DA (Dearness Allowance)
├── Travel Allowance
└── Other Allowances
Deductions
├── PF (Provident Fund) — 12% of Basic
├── ESI (if applicable)
├── TDS (Tax Deducted at Source)
├── Leave Deductions (unpaid leaves)
└── Other Deductions
Net Salary = Gross Salary − Total Deductions
Auto-calculation triggers:
- Monthly payroll run by SuperAdmin
- Late attendance deductions
- Unpaid leave deductions
- Overtime additions (if configured)
Payslip includes:
- Employee details
- Month/Year
- Attendance summary
- Earnings breakdown
- Deductions breakdown
- Net payable amount
- Company stamp/logo (via Cloudinary)
| Type | Days |
|---|---|
| Casual Leave (CL) | 12/year |
| Sick Leave (SL) | 12/year |
| Earned Leave (EL) | 15/year |
| Maternity/Paternity | As per policy |
| Unpaid Leave | Unlimited (salary deducted) |
Employee applies → SuperAdmin notified → Approve/Reject
→ Leave balance updated → Employee notified
→ Payroll reflects unpaid leaves automatically
- SuperAdmin creates and assigns tasks to employees
- Each task has: title, description, priority, due date, status
- Task statuses:
Pending → In Progress → Review → Completed - Employees update task status in real time
- Task comments supported
- File attachments via Cloudinary
- SuperAdmin gets notified on status change
- Real-time notifications via Flask-SocketIO
- Triggered by: leave approval/rejection, task assignment, payroll generation, announcements
- Employees see unread notification count badge
- Mark as read individually or all at once
- Notification history stored in database
- Built with Flask-SocketIO
- Employee-to-employee direct messaging
- File sharing in chat (stored in
static/uploads/chat_files/+ Cloudinary) - Online/offline status indicators
- Message history persisted in database
| Resource | Usage |
|---|---|
| Employee profile photos | Profile management |
| Company logo | Payslip generation |
| Document uploads | Offer letters, ID proofs |
| Chat file attachments | Real-time chat |
| Payslip PDFs | Auto-generated payslips |
- JWT tokens with 7-day expiry
- OTP-based password reset via email/SMS
- Role-based access control (MasterAdmin / SuperAdmin / Employee)
- Middleware validates token and injects
g.useron every protected route - Sensitive credentials managed via
.env(never committed)
pip install gunicorn eventlet
gunicorn --worker-class eventlet -w 1 \
--bind 0.0.0.0:5000 \
--timeout 120 \
server:appserver {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
⚠️ WebSocket support (Upgradeheaders) is required for Flask-SocketIO to work behind Nginx.
- Total employees
- Present today / Absent today
- Pending leave requests
- Tasks by status (Pending / In Progress / Completed)
- Monthly payroll total
- Recent activity feed
- Department-wise headcount
Flask
Flask-SQLAlchemy
Flask-Migrate
Flask-JWT-Extended
Flask-SocketIO
Flask-Mail
psycopg2-binary
cloudinary
python-dotenv
eventlet
PillowThis project is proprietary software developed by Aditya Sharma.
All rights reserved © 2025 Aditya Sharma.
Built with ❤️ in Bhilai, Chhattisgarh