Skip to content

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

Leave Management

An enterprise backend system for leave management built with Laravel. It includes CRUD operations for leave requests, an approval pipeline (HR → Manager → CEO), audit logging, and a scalable daily reporting/aggregation mechanism.

⸻

Table of Contents

  • Quick Start
  • Architecture
  • Authentication
  • General Routes / Endpoints
  • Approval Pipeline Rules
  • Aggregation / Reporting
  • Request / Response Examples
  • Execution, Queues & Scheduling
  • Testing & Linting
  • Error Codes
  • OpenAPI / Swagger
  • Developer Notes / Contributing
  • License

⸻

Quick Start

Requirements: PHP 8.x, Composer, Database (MySQL/Postgres/SQLite), Docker (optional)

git clone https://github.com/Alibaghaee/leave-management.git cd leave-management cp .env.example .env composer install php artisan key:generate php artisan migrate --seed php artisan serve

Get a Sanctum Token

php artisan tinker $user = \App\Models\User::first(); $token = $user->createToken('api')->plainTextToken;

Send the token with your requests:

Authorization: Bearer

⸻

Architecture

  • Layered architecture: Controllers → DTOs → Services → Repositories → Models
  • API responses are based on JsonResource with the { data, meta, links } format
  • Approval stages are configured using order, role, and min_days
  • Logs are used for:
    • auditing
    • idempotency
    • multi-stage approval/rejection tracking

Models:

  • Employee
  • LeaveRequest
  • Stage
  • LeaveLog

Reporting is handled through summary tables:

  • daily
  • monthly
  • yearly

⸻

Authentication

The entire API under /api/v1 is protected by the following middleware:

auth:sanctum

Clients must provide a Bearer Token.

⸻

General Routes / Endpoints

GET /api/v1/employees POST /api/v1/employees GET /api/v1/employees/{id} PUT /api/v1/employees/{id} DELETE /api/v1/employees/{id} GET /api/v1/leave-requests POST /api/v1/leave-requests GET /api/v1/leave-requests/{id} PUT /api/v1/leave-requests/{id} DELETE /api/v1/leave-requests/{id} POST /api/v1/leave-requests/{id}/approve POST /api/v1/leave-requests/{id}/reject GET /api/v1/stages POST /api/v1/stages GET /api/v1/stages/{id} PUT /api/v1/stages/{id} DELETE /api/v1/stages/{id} GET /api/v1/leave-logs POST /api/v1/leave-logs GET /api/v1/employee-leave-summaries/daily POST /api/v1/employee-leave-summaries/daily/aggregate

⸻

Approval Pipeline Rules

Roles and Restrictions

  • HR → can always approve
  • Manager → can only approve requests for employees where employee.manager_id == manager.id
  • CEO → can only approve when days_count >= min_days configured for the CEO stage

Error Types According to Tests

  • If the user is completely unauthorized → 403 Forbidden
  • If a manager attempts to approve a request belonging to an employee who is not their subordinate → 422 Unprocessable Entity

Stages

Each stage contains:

  • name
  • role
  • order
  • min_days
  • next_stage_id

Idempotency

idempotency_key is used to prevent duplicate approve/reject operations.

If the same key has already been consumed, the operation returns without making any changes.

⸻

Aggregation / Reporting

  • Aggregation tables → daily/monthly/yearly
  • Manual execution:

php artisan leave:aggregate-employee-leave-daily --date=2025-11-16

API:

POST /api/v1/employee-leave-summaries/daily/aggregate

Query:

GET /api/v1/employee-leave-summaries/daily?employee_id=1&date=2025-12-01

Aggregation is designed to be safe, idempotent, and queue-based.

⸻

Request / Response Examples

Create a Daily Leave Request

POST /api/v1/leave-requests { "leave_type": "annual", "start_date": "2025-12-01", "end_date": "2025-12-03", "reason": "Vacation" }

Response:

{ "data": { "id": 12, "employee_id": 3, "employee_name": "Ali", "leave_type": "annual", "days_count": 3, "status": "pending_hr", "current_stage_id": 1 } }

Create an Hourly Leave Request (Half Day)

{ "leave_type": "hourly", "start_date": "2025-12-10", "end_date": "2025-12-10", "start_time": "09:00", "end_time": "13:00", "reason": "Doctor appointment" }

days_count = (hours / 8) → the example above = 0.5

Multi-Stage Approval

POST /api/v1/leave-requests/12/approve { "comment": "OK", "idempotency_key": "hr-12-approve" }

⸻

Execution, Queues & Scheduling

Queue Worker

php artisan queue:work

Cron for Scheduler

          • cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1

Recommendation: Use two separate Docker services for the worker and scheduler.

⸻

Testing & Linting

php artisan test php artisan test --parallel

If available:

composer cs-check composer phpstan

⸻

Error Codes

Status Description 200 Success 201 Created 204 Deleted 401 Authentication failed 403 Insufficient permissions 422 Validation / business rule error 500 Server error

Example 422 error:

{ "message": "The given data was invalid.", "errors": { "start_date": ["required"] } }

⸻

OpenAPI / Swagger

Main file:

openapi.yaml

Compatible with Swagger UI / Redoc.

Includes:

  • Bearer token security scheme
  • Complete schema definitions
  • Routes for all resources

⸻

Developer Notes / Contributing

  • Follow PSR-12
  • Create Pull Requests with accompanying tests
  • Do not change approval pipeline behavior without updating tests
  • Run the complete test suite before merging:

php artisan test

⸻

License

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages