Skip to content

Repository files navigation

Conference Rooms API

A REST API for renting conference halls: search for available halls, book them, calculate the rental cost based on the time of day and selected services, and generate business reports.

Table of contents

Business problem

A company rents conference halls to businesses. The API lets clients:

  • manage halls (create, update, delete) and their additional services;
  • search for halls that are free for a given period and capacity;
  • book a hall and receive a full cost calculation;
  • view business reports (revenue, service popularity, hall occupancy).

Tech stack

  • .NET 10, ASP.NET Core Web API
  • Entity Framework Core + SQLite (the provider is easily swappable)
  • FluentValidation — input validation
  • Swagger / OpenAPI (Swashbuckle) — interactive documentation
  • xUnit + Moq — unit and integration tests

Architecture

The solution follows Clean Architecture with four layers, so the business logic depends neither on the database nor on the web framework. Dependencies point inward (toward the Domain) — the Dependency Inversion Principle.

Layer Responsibility
Domain Entities, domain rules, the pricing engine, domain exceptions. Depends on nothing.
Application Use-case services, DTOs, validation, repository abstractions. Depends only on Domain.
Infrastructure EF Core, repositories, database seeding. Implements Application's abstractions.
WebApi Controllers, middleware, authentication, Swagger, composition root.

Project structure

ConferenceRooms/
├── src/
│   ├── ConferenceRooms.Domain/          # Entities, pricing engine, domain exceptions
│   │   ├── Common/                      # Guard clauses
│   │   ├── Entities/                    # Hall, AdditionalService, Booking, BookingServiceItem
│   │   ├── Enums/                       # RatePeriod
│   │   ├── Exceptions/                  # Domain exceptions (mapped to HTTP codes)
│   │   └── Pricing/                     # IPricingRule, PricingEngine, Rules/
│   ├── ConferenceRooms.Application/      # Use cases, DTOs, validation, abstractions
│   │   ├── Abstractions/                # Service & repository interfaces
│   │   ├── Dtos/                        # Request/response models
│   │   ├── Mapping/                     # Entity <-> DTO mapping
│   │   ├── Services/                    # HallService, BookingService, ReportService
│   │   └── Validation/                  # FluentValidation validators
│   ├── ConferenceRooms.Infrastructure/  # EF Core, repositories, seeding
│   │   ├── Migrations/
│   │   └── Persistence/                 # DbContext, Configurations/, Repositories/, Seeding/
│   └── ConferenceRooms.WebApi/          # Controllers, middleware, auth, Swagger
│       ├── Controllers/
│       ├── Middleware/                  # Exception handling, API key
│       └── Security/                    # ApiKeyOptions
└── tests/
    └── ConferenceRooms.UnitTests/       # Unit, integration and end-to-end API tests
        ├── Api/                         # End-to-end tests (WebApplicationFactory)
        ├── Infrastructure/              # Repository integration tests
        ├── Pricing/                     # Pricing engine unit tests
        └── Services/                    # Booking service unit tests (Moq)

Data model

Database schema

AdditionalService and BookingServiceItem are owned by Hall and Booking respectively (cascade delete). A Booking references a hall by HallId (a plain column, not an enforced foreign key), and its service items are snapshots taken at booking time.

Key technical decisions

  • Pricing engine (Strategy pattern). The rate depends on overlapping time-of-day periods, so a booking is split into segments at rate boundaries and each segment is charged at its own rate. Each rate is a separate strategy (IPricingRule), so new rates can be added without changing the engine.
  • Service price snapshots: a booking copies each service's name and price at booking time, so later price changes never affect historical bookings or reports.
  • Soft delete for halls, enforced by a global EF query filter.
  • Domain exceptions mapped to HTTP status codes (404 / 409 / 400) by a single error-handling middleware; unexpected errors return 500 without leaking details.
  • Repository + Unit of Work over EF Core; Dependency Injection throughout.
  • API key authentication with a fixed-time comparison.

Pricing rules

The base hourly price is adjusted by the time of day. Overlapping periods are resolved by priority (Peak overrides Standard):

Period Time Adjustment
Morning 06:00–09:00 −10%
Standard 09:00–18:00 base price
Peak 12:00–14:00 +15%
Evening 18:00–23:00 −20%

Total cost = hall cost (summed per segment) + selected services. Bookings must fall within the operating hours 06:00–23:00.

Getting started

Prerequisites

  • .NET 10 SDK

Run

dotnet run --project src/ConferenceRooms.WebApi

The SQLite database is created and seeded (Halls A, B, C) automatically on first run. Open the URL shown in the console — the root redirects to Swagger.

Authentication

All /api/* endpoints require an API key in the X-Api-Key header. The demo key is set in appsettings.json:

X-Api-Key: dev-secret-key-change-me

In Swagger, click Authorize and paste the key.

For production the key should come from environment variables or a secret store, not from appsettings.json.

API overview

Method Endpoint Description
GET /api/halls List all halls
GET /api/halls/{id} Get a hall
POST /api/halls Create a hall
PUT /api/halls/{id} Update a hall
DELETE /api/halls/{id} Soft-delete a hall
POST /api/halls/{id}/services Add a service to a hall
DELETE /api/halls/{id}/services/{serviceId} Remove a service
GET /api/bookings/available Search available halls
POST /api/bookings Create a booking (returns full cost breakdown)
GET /api/reports/revenue Revenue report
GET /api/reports/popular-services Service popularity report
GET /api/reports/occupancy Hall occupancy report

Testing

dotnet test

Coverage includes:

  • Pricing engine — rate boundaries, overlapping periods, invalid times.
  • Booking service — cost calculation and 404/409 branches (unit tests with Moq).
  • Repositories — overlap detection, availability, soft-delete filter (integration tests against SQLite in-memory).
  • API endpoints — every endpoint end-to-end.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages