Skip to content

Repository files navigation

Workplace Booking Platform

Responsive web application for booking open workspaces, closed offices, and meeting rooms. Built with Clean Architecture, React + TypeScript + Material UI, .NET 8, PostgreSQL 16, and Microsoft Entra ID.

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        PRESENTATION LAYER                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   React Frontend    β”‚    β”‚   .NET 8 Web API            β”‚   β”‚
β”‚  β”‚  (Material UI)      β”‚    β”‚   (API Endpoints)           β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      APPLICATION LAYER                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Use Cases / Application Services / DTOs / Validators   β”‚   β”‚
β”‚  β”‚  (BookingPlatform.Application)                          β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       DOMAIN LAYER                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Entities / Value Objects / Domain Events / Interfaces  β”‚   β”‚
β”‚  β”‚  (BookingPlatform.Domain)                               β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   INFRASTRUCTURE LAYER                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ EF Core      β”‚ β”‚ Identity     β”‚ β”‚ Email    β”‚ β”‚ Backgroundβ”‚ β”‚
β”‚  β”‚ Repositories β”‚ β”‚ (Entra ID)   β”‚ β”‚ Service  β”‚ β”‚ Workers   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        DATA LAYER                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              PostgreSQL 16 (booking schema)             β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Technology Stack

Layer Technology Version
Frontend React + TypeScript + Material UI React 18, TS 5, MUI 5
Backend .NET 8 Web API .NET 8.0 LTS
Database PostgreSQL 16
Auth Microsoft Entra ID OIDC/OAuth 2.0
Infrastructure Ubuntu + Docker Compose + Nginx 24.04 LTS
CI/CD GitHub Actions Latest

πŸ“ Project Structure

workplace-booking-platform/
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ architecture/
β”‚   β”‚   β”œβ”€β”€ ARCHITECTURE.md      # Complete architecture documentation
β”‚   β”‚   β”œβ”€β”€ DIAGRAMS.md          # Mermaid diagrams (C4, sequences, ER)
β”‚   β”‚   β”œβ”€β”€ TECHNICAL_DECISIONS.md
β”‚   β”‚   └── DEPENDENCIES.md
β”‚   └── adr/                     # Architecture Decision Records (18 ADRs)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ backend/
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ BookingPlatform.Domain/       # Domain layer (pure C#)
β”‚   β”‚   β”‚   β”œβ”€β”€ BookingPlatform.Application/  # Application layer (CQRS)
β”‚   β”‚   β”‚   β”œβ”€β”€ BookingPlatform.Infrastructure/ # Infrastructure (EF Core, Entra ID)
β”‚   β”‚   β”‚   └── BookingPlatform.Api/          # API layer (Controllers)
β”‚   β”‚   └── tests/                           # Unit, Integration, API tests
β”‚   β”œβ”€β”€ frontend/
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ components/      # Reusable UI components
β”‚   β”‚   β”‚   β”œβ”€β”€ pages/           # Route-level components
β”‚   β”‚   β”‚   β”œβ”€β”€ hooks/           # Custom React hooks
β”‚   β”‚   β”‚   β”œβ”€β”€ services/        # API clients, auth
β”‚   β”‚   β”‚   β”œβ”€β”€ contexts/        # React contexts (Auth, Theme)
β”‚   β”‚   β”‚   β”œβ”€β”€ types/           # TypeScript interfaces
β”‚   β”‚   β”‚   β”œβ”€β”€ utils/           # Helpers, formatters
β”‚   β”‚   β”‚   β”œβ”€β”€ theme/           # MUI theme configuration
β”‚   β”‚   β”‚   β”œβ”€β”€ layouts/         # Page layouts
β”‚   β”‚   β”‚   └── assets/          # Static assets
β”‚   β”‚   └── tests/               # Unit, E2E tests
β”‚   └── ...
β”œβ”€β”€ infrastructure/
β”‚   β”œβ”€β”€ docker/                  # Docker Compose files
β”‚   β”œβ”€β”€ nginx/                   # Nginx configurations
β”‚   └── database/
β”‚       └── migrations/          # SQL migrations / EF Core
└── ...

πŸš€ Quick Start

Prerequisites

  • Docker Desktop 4.0+
  • .NET 8 SDK (for local backend development)
  • Node.js 20 LTS (for local frontend development)
  • Git

Development with Docker Compose

# Clone and navigate
cd workplace-booking-platform

# Start all services (PostgreSQL, API, Frontend, Nginx, SMTP dev)
docker-compose -f infrastructure/docker/docker-compose.yml \
               -f infrastructure/docker/docker-compose.override.yml up -d

# Access applications
# Frontend: http://localhost:3000 (Vite dev server with HMR)
# API: http://localhost:8080
# Swagger: http://localhost:8080/scalar
# Hangfire: http://localhost:8080/hangfire
# pgAdmin: http://localhost:5050 (admin@booking.local / admin)
# SMTP UI: http://localhost:2500

Local Development (without Docker)

Backend:

cd src/backend
dotnet restore
dotnet ef database update --project src/BookingPlatform.Infrastructure --startup-project src/BookingPlatform.Api
dotnet run --project src/BookingPlatform.Api

Frontend:

cd src/frontend
npm ci
npm run dev

πŸ” Authentication

  • Provider: Microsoft Entra ID (Azure AD)
  • Flow: Authorization Code + PKCE (SPA)
  • Tokens: JWT Access Tokens + Refresh Tokens (HttpOnly cookies)
  • Claims: email, name, jobTitle, department, groups β†’ roles

πŸ“Š Database Schema

The database uses schema booking with key tables:

  • resources - 91 bookable spaces (60 open, 24 closed, 7 meeting rooms)
  • reservations - Time-based bookings with exclusion constraints
  • checkins - QR-based check-ins for offices
  • notification_outbox - Transactional outbox for emails
  • audit_logs - Immutable audit trail
  • app_users, business_profiles, application_roles - RBAC/ABAC

See FRD Document for complete schema.

🎨 Design System

  • Primary: #FFD800 (Yellow)
  • Primary Dark: #0E0E0E (Near Black)
  • Backgrounds: #FFFFFF, #F5F5F5, #F6F0CB
  • Text: #0E0E0E, #2A2A2A
  • Breakpoints: xs(0), sm(600), md(900), lg(1200), xl(1536)
  • Accessibility: WCAG AA minimum

πŸ§ͺ Testing

# Backend tests
cd src/backend
dotnet test --configuration Release --collect:"XPlat Code Coverage"

# Frontend tests
cd src/frontend
npm run test:unit          # Unit tests (Vitest + RTL)
npm run test:coverage      # With coverage
npm run test:e2e           # E2E tests (Playwright)
npm run lint               # ESLint
npm run typecheck          # TypeScript check

πŸ“¦ CI/CD Pipeline

GitHub Actions workflow includes:

  1. Build & Test - Backend + Frontend
  2. Security - CodeQL (SAST), Dependabot (SCA), OWASP ZAP (DAST)
  3. Docker Build - Multi-stage, multi-arch images
  4. Deploy - Staging (auto), Production (manual approval)

πŸ“š Documentation

Document Description
Architecture Complete system architecture
Diagrams Mermaid diagrams (C4, sequences, ER)
Technical Decisions 25 key decisions with rationale
Dependencies Full dependency catalog
ADRs 18 Architecture Decision Records

πŸ”’ Security

  • OWASP Top 10 mitigated
  • HTTPS everywhere (Nginx TLS termination)
  • JWT validation with JWKS
  • Rate limiting (Nginx + ASP.NET Core)
  • CSP, HSTS, security headers
  • No secrets in repo (Docker secrets / Key Vault)
  • Audit logging on all mutations

πŸ“ˆ Observability

  • Logging: Serilog β†’ Console/Seq (structured JSON)
  • Metrics: Prometheus /metrics endpoint
  • Tracing: OpenTelemetry β†’ Tempo/Jaeger
  • Health: /health, /health/live, /health/ready

πŸ“„ License

Internal use only - Confidential.


Built with Clean Architecture principles for maintainability, testability, and scalability.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages