Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HRLite — Employee Management System

A Full-stack portfolio project demonstrating Clean Architecture, CQRS, multi-tenancy, containerisation, and CI/CD.


Goal

Build a scalable, maintainable platform that showcases:

  • Backend engineering with .NET 9 and Clean Architecture
  • Frontend engineering with Angular 17 and Signals
  • Cloud-native patterns (multi-tenancy, audit logging, blob storage)
  • Infrastructure as code (Docker, GitHub Actions)
  • Test-driven quality (43 unit tests)

Tech Stack

Backend

Layer Technology
Runtime .NET 9 Web API
Architecture Clean Architecture (Domain → Application → Infrastructure → API)
CQRS MediatR 14
ORM Entity Framework Core 9
Database SQL Server / Azure SQL
Validation FluentValidation 12
Mapping AutoMapper 16
Auth JWT Bearer + RBAC (Admin, HR, Manager)
Audit Logging Azure Cosmos DB
File Storage Azure Blob Storage
Logging Serilog
API Docs Swagger / Swashbuckle

Frontend

Layer Technology
Framework Angular 17 (standalone components)
State Angular Signals
HTTP RxJS + custom ApiService
UI Angular Material
Auth JWT interceptor + role-based guards

Infrastructure

Concern Technology
Containerisation Docker + Docker Compose
CI GitHub Actions (PR validation)
Cloud Target Azure App Service + Azure Static Web Apps

Architecture

HRLite/
├── backend/
│   ├── src/
│   │   ├── HRLite.Domain/          # Entities, Enums, Interfaces
│   │   ├── HRLite.Application/     # CQRS Handlers, DTOs, Validators, Mappings
│   │   ├── HRLite.Infrastructure/  # EF Core, Repos, JWT, Cosmos, Blob
│   │   └── HRLite.API/             # Controllers, Middleware, Program.cs
│   └── tests/
│       ├── HRLite.Domain.Tests/    # Entity unit tests (xUnit)
│       └── HRLite.Application.Tests/ # Handler & validator tests (xUnit + NSubstitute)
├── frontend/
│   └── hrlite-ui/                  # Angular 17 app
├── docker-compose.yml              # SQL Server + API + Frontend
└── .github/workflows/ci.yml        # PR validation pipeline

Key Patterns

  • Clean Architecture — strict layer boundaries; Domain has zero external dependencies
  • CQRS via MediatR — every use case is an isolated command or query handler
  • Repository patternIRepository<T> abstracts all data access
  • Pipeline behaviours — logging and validation run automatically before every handler
  • Multi-tenancyTenantId on every entity, enforced via EF Core global query filters
  • Soft deleteIsDeleted flag + global query filter; no hard deletes
  • JWT + RBAC — three roles (Admin, HR, Manager) enforced at controller and route level

Features

Module Capabilities
Authentication Login, JWT token, role-based access
Employees Create, read, update, soft delete; auto-generated employee code
Departments CRUD with employee count
Leave Management Apply, approve/reject, track status
Attendance Mark daily attendance, duplicate prevention
Documents Upload to Azure Blob, store metadata in SQL

Prerequisites

Tool Version
Docker Desktop Latest (WSL2 backend on Windows)
.NET SDK 9.0 (for local development only)
Node.js 20+ (for local development only)

Docker is the only requirement to run the full stack.


Running Locally with Docker

1. Clone the repository

git clone https://github.com/YOUR_USERNAME/HRLite.git
cd HRLite

2. Start all services

docker-compose up --build

This will:

  1. Start SQL Server and wait for it to be healthy
  2. Start the .NET API — runs EF migrations and seeds demo data automatically
  3. Start the Angular frontend served via nginx

3. Access the app

Service URL
Frontend http://localhost:4200
API Swagger http://localhost:5217/swagger
SQL Server localhost,1433

4. Demo credentials

Tenant: tenant-demo

Role Email Password
Admin admin@hrlite.com Admin@123
HR hr@hrlite.com Hr@12345
Manager manager@hrlite.com Manager@123

Useful Docker commands

# Run in background
docker-compose up --build -d

# View API logs
docker-compose logs -f api

# Stop everything
docker-compose down

# Wipe database and start fresh
docker-compose down -v

Running Locally without Docker

Backend

cd backend
dotnet restore
dotnet run --project src/HRLite.API

Update appsettings.Development.json with a valid SQL Server connection string before running.

Frontend

cd frontend/hrlite-ui
npm install
ng serve

App will be available at http://localhost:4200.


Running Tests

cd backend
dotnet test --verbosity normal
Project Tests Coverage
HRLite.Domain.Tests 14 Entity defaults, invariants
HRLite.Application.Tests 29 Command handlers, validators

Configuration

Environment variables (Docker)

Sensitive values are passed as environment variables in docker-compose.yml. Before deploying to production, replace all placeholder values:

Variable Description
ConnectionStrings__DefaultConnection SQL Server connection string
Jwt__Key JWT signing key (min 32 chars)
CosmosDb__ConnectionString Azure Cosmos DB connection string
AzureBlob__ConnectionString Azure Blob Storage connection string

Important: The credentials in appsettings.Development.json and docker-compose.yml are for local development only. Never use them in production. Use Azure Key Vault or environment-specific secrets management instead.

Azure services (optional)

Cosmos DB and Azure Blob Storage are optional for local development. If connection strings contain placeholder values (REPLACE), the application automatically falls back to a no-op audit logger and will skip blob operations.


CI/CD

A GitHub Actions workflow runs on every pull request to main:

Job What it does
backend Restore → Build → Test
frontend npm ci → ng build --production
docker docker compose build (image validation)

Roadmap

  • Azure deployment (App Service + Static Web Apps)
  • OpenTelemetry tracing
  • Redis caching for frequently read data
  • Refresh token support
  • Pagination filters on all list endpoints

About

Demonstrate full-stack engineering skills, cloud deployment, and production-ready architecture.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages