Skip to main content

Architecture Overview

SGRH (Sistema de Gestión de Reservas Hoteleras) follows Clean Architecture principles with clear separation of concerns across multiple layers. The system is designed to be maintainable, testable, and scalable.

Architectural Principles

Dependency Inversion

Dependencies point inward: Infrastructure and API depend on Domain, never the reverse

Domain-Driven Design

Business logic is encapsulated in rich domain entities with behavior

CQRS Pattern

Commands for writes and Queries for reads are separated in the Application layer

Repository Pattern

Data access is abstracted through repository interfaces defined in Domain

Layer Structure

The system is organized into the following layers:
SGRH.Api/              # Presentation Layer - REST API Controllers
SGRH.Application/      # Application Layer - Use Cases (CQRS)
SGRH.Domain/           # Domain Layer - Business Logic & Entities
SGRH.Infrastructure/   # Infrastructure - External Services (S3, SES)
SGRH.Persistence/      # Persistence - EF Core & Repositories
SGRH.Auth/             # Authentication & Authorization
The Domain layer has no dependencies on other projects. All other layers depend on Domain.

Dependency Flow

Core Entities

The domain model includes the following core entities:
  • Reserva: Main reservation aggregate root with state machine (Pendiente → Confirmada → Finalizada)
  • DetalleReserva: Room details within a reservation with pricing snapshot
  • ReservaServicioAdicional: Additional services attached to reservations

Domain-Driven Patterns

Entity Base Class

All entities inherit from EntityBase which provides identity equality:
public abstract class EntityBase
{
    protected abstract object GetKey();

    public override bool Equals(object? obj)
    {
        if (obj is not EntityBase other) return false;
        if (ReferenceEquals(this, other)) return true;
        if (GetType() != other.GetType()) return false;
        return GetKey().Equals(other.GetKey());
    }

    public override int GetHashCode() => GetKey().GetHashCode();
}

Guard Clauses

Domain validation is enforced through guard clauses:
public static class Guard
{
    public static void AgainstNullOrWhiteSpace(string? value, string name, int maxLength)
    {
        if (string.IsNullOrWhiteSpace(value))
            throw new ValidationException($"{name} no puede estar vacío.");

        if (value.Length > maxLength)
            throw new ValidationException($"{name} supera el máximo de {maxLength} caracteres.");
    }

    public static void AgainstOutOfRange(int value, string name, int minExclusive)
    {
        if (value <= minExclusive)
            throw new ValidationException($"{name} debe ser mayor a {minExclusive}.");
    }
}

Domain Policies

Complex business rules are encapsulated in policy interfaces:
public interface IReservaDomainPolicy
{
    int? GetTemporadaId(DateTime fechaEntrada);
    void EnsureHabitacionDisponible(int habitacionId, DateTime fechaEntrada, 
                                     DateTime fechaSalida, int? reservaId);
    void EnsureHabitacionNoEnMantenimiento(int habitacionId, DateTime fechaEntrada, 
                                           DateTime fechaSalida);
    decimal GetTarifaAplicada(int habitacionId, DateTime fechaEntrada);
    void EnsureServicioDisponibleEnTemporada(int servicioAdicionalId, int? temporadaId);
    decimal GetPrecioServicioAplicado(int reservaId, int servicioAdicionalId);
}

Technology Stack

.NET 8

Modern C# features and performance improvements

Entity Framework Core

ORM for data access with SQL Server

ASP.NET Core

Web API framework for REST endpoints

Database Strategy

  • ORM: Entity Framework Core
  • Database: SQL Server / MySQL (configurable)
  • Migrations: Code-first approach
  • Configuration: Fluent API in Persistence layer
The connection string in Program.cs references "Default" - ensure your appsettings.json has this configured.

Next Steps

Domain Layer

Explore entities, value objects, and domain logic

Application Layer

Learn about CQRS commands and queries

Infrastructure Layer

Understand repository implementations

API Layer

Review REST API controllers and endpoints

Build docs developers (and LLMs) love