Skip to content
CAI
Software that uses CAICheck a score

Tmaturano/Bookify

50.7

Adequate · 21 September 2026

2.8k

lines of production code

C#

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Bookify is a .NET 8 apartment booking platform built on Clean Architecture and CQRS principles, managing the lifecycle of apartments, users, and reservations. It provides RESTful endpoints for searching available apartments, reserving bookings with concurrency control, and handling user authentication via Keycloak. The system ensures data integrity through an outbox pattern for reliable event processing and optimizes performance using Redis caching and structured logging.

How it got here

2023 — Initial project scaffolding and core domain implementation

22 changes.

This period established the foundational architecture of the Bookify application, initializing the solution with Clean Architecture principles, .NET 8 dependencies, and Docker Compose for local development. It focused on implementing the core domain model for bookings and apartments, alongside the application layer's CQRS structure with MediatR behaviors for validation, logging, and caching. The work also covered the initial infrastructure setup, including Entity Framework Core persistence, Keycloak-based authentication, and the first API endpoints for user registration and apartment search.

2024 — Reliability and performance infrastructure

4 changes.

This period focused on enhancing system reliability and performance by implementing an outbox pattern for reliable domain event processing and introducing distributed Redis caching. The work also established a robust testing framework with comprehensive functional, integration, and architecture tests, alongside fine-grained permission-based authorization to improve security and access control.

Features

Add ability to retrieve a specific booking with user authorization and caching

Users can now fetch details of a specific booking by ID. The system verifies that the requesting user owns the booking before returning data, ensuring access control. The response includes comprehensive booking details such as pricing, currency, duration, and status. Additionally, this query result is cached to improve performance for subsequent requests.

src/Bookify.Application/Bookings/GetBooking · high confidence

Add apartment search capability with availability filtering

Users can now search for apartments by specifying a start and end date. The system returns a list of apartments that are not reserved, confirmed, or completed for the requested period, including details such as name, description, price, currency, and full address (country, state, zip code, city, street).

src/Bookify.Application/Apartments · high confidence

Add infrastructure repositories for domain entities

New repository implementations have been added to the infrastructure layer to provide data access for Apartments, Bookings, and Users. The BookingRepository includes logic to check for overlapping reservations based on active statuses, while the UserRepository handles entity attachment to prevent duplicate role inserts during creation. A generic base Repository class is also introduced to standardize common operations like GetById and Add across these entities.

src/Bookify.Infrastructure/Repositories · high confidence

Added CQRS messaging abstractions

The application layer now includes core interfaces for the Command Query Responsibility Segregation (CQRS) pattern, specifically defining ICommand, ICommandHandler, IQuery, and IQueryHandler within the Messaging abstraction namespace. These interfaces integrate with the MediatR library and the application's Result type, establishing the structural contract for how commands and queries are processed, which enables a more decoupled and consistent approach to handling application logic.

src/Bookify.Application/Abstractions/Messaging · high confidence

Added user registration, login, and profile retrieval endpoints

The application now supports core user lifecycle operations via new command and query handlers. Users can register with email, name, and password (validated for format and length), log in to receive a JWT access token, and retrieve their own profile details (ID, name, email) from the database. Registration delegates identity creation to an external authentication service, while login and profile retrieval rely on JWT services and SQL queries respectively.

src/Bookify.Application/Users · high confidence

Booking reservation capability with validation and conflict handling

Users can now reserve an apartment booking via a new command handler that validates input (ensuring user and apartment IDs are present and the start date precedes the end date), checks for overlapping existing bookings, and handles concurrency conflicts by returning an overlap error. Upon successful reservation, a domain event triggers an email notification to the user confirming the reservation with a 10-minute window to finalize.

src/Bookify.Application/Bookings/ReserveBooking · high confidence

Initial API project scaffolding with controllers, middleware, and configuration

The Bookify.API project is introduced, providing the HTTP entry point for the application. It exposes REST endpoints for Apartments, Bookings, and Users (including registration and login) via standard ASP.NET Core controllers, alongside a parallel minimal-API implementation for Bookings. The API supports versioning (v1 and v2) and Swagger documentation. Operational features include a custom global exception handler that returns standardized ProblemDetails, structured logging with Serilog and Seq (including correlation ID support), database migration application in development, and health check endpoints. Configuration for Keycloak authentication, Redis caching, and database connections is provided via appsettings.

src/Bookify.API · high confidence

Initial Entity Framework Core mapping configurations for domain entities

This change introduces the initial set of Entity Framework Core \IEntityTypeConfiguration\ implementations for the application's core domain models, including Apartment, Booking, Review, User, Role, Permission, and OutboxMessage. These configurations define the database schema mappings, such as table names, primary keys, property constraints (e.g., max lengths), owned value objects (e.g., Price, Address), and relationships (e.g., Booking to Apartment and User). Notably, the Apartment configuration includes optimistic concurrency support via a \Version\ row version property, and the Role/Permission configurations seed initial data for the 'Registered' role and 'UsersRead' permission to establish a baseline for the authorization system.

src/Bookify.Infrastructure/Configurations · high confidence

Initial domain model for bookings, apartments, and users

The Bookify.Domain layer now contains the core domain entities, value objects, and abstractions required to support the application's business logic. This includes the Booking entity with its reservation, confirmation, and cancellation workflows, alongside Apartment and Review entities. The domain also introduces a strongly-typed ID pattern, a Result type for handling operation outcomes, and a domain event system to track state changes such as booking reservations and user creation. Additionally, it defines the User entity with role-based permissions and a PricingService to calculate costs based on apartment amenities and date ranges.

src/Bookify.Domain · high confidence

Initial infrastructure implementations for clock and email services

The new Bookify.Infrastructure project introduces concrete implementations for core application abstractions. It provides a DateTimeProvider that returns the current UTC time, and a stub EmailService that currently completes immediately without sending actual messages, allowing the application to compile and run while email functionality is deferred.

src/Bookify.Infrastructure/Clock, src/Bookify.Infrastructure/Email · high confidence

Initial infrastructure setup with persistence, authentication, and background jobs

The application now includes a new infrastructure layer that configures Entity Framework Core with Npgsql for database persistence, Dapper with a custom DateOnly type handler for data access, and a Redis-based distributed caching service. Authentication is established via JWT and Keycloak integration, while authorization uses a permission-based policy provider. The system also introduces an outbox pattern for reliable domain event publishing, Quartz-based background job scheduling, API versioning, and health checks for the database, cache, and Keycloak service.

src/Bookify.Infrastructure · high confidence

Initial project scaffolding with Docker Compose and Clean Architecture structure

The repository has been initialized with a Clean Architecture solution structure, including domain, application, infrastructure, and API projects, alongside a comprehensive test suite (unit, integration, and architecture tests). A Docker Compose configuration is now provided to spin up the entire application stack locally, including the API, a PostgreSQL database, Keycloak for identity management, Seq for structured logging, and Redis for distributed caching. This allows users to run the application and its dependencies with a single command.

(repo-wide) · high confidence

Introduce Keycloak-based authentication and user management

The application now integrates with Keycloak for identity management. This change adds infrastructure components to handle JWT authentication, including a service to acquire access tokens via the Keycloak protocol, an HTTP delegating handler for admin API calls, and configuration options for the identity provider. It also introduces a user registration service that creates users in Keycloak and a user context implementation that extracts user identity and ID from JWT claims, enabling role-based and resource-based authorization throughout the system.

src/Bookify.Infrastructure/Authentication · high confidence

Introduction of IDateTimeProvider abstraction

A new IDateTimeProvider interface has been added to the application's abstractions layer, exposing a single UtcNow property. This change introduces a dependency-injection-friendly abstraction for time, allowing the application to decouple time-dependent logic from the system clock.

src/Bookify.Application/Abstractions/Clock · high confidence

Introduction of IDbConnection factory abstraction

A new ISqlConnectionFactory interface has been added to the application's data abstractions, providing a CreateConnection method that returns an IDbConnection. This interface serves as the foundational contract for database connectivity within the application layer, enabling decoupled access to SQL resources.

src/Bookify.Application/Abstractions/Data · high confidence

Introduction of core authentication abstractions

The application layer now exposes three new interfaces to support user identity and access management: IAuthenticationService for registering new users, IJwtService for obtaining access tokens via email and password, and IUserContext for retrieving the current user's ID and identity provider identifier. These interfaces define the contract for authentication operations within the application.

src/Bookify.Application/Abstractions/Authentication · high confidence

Introduction of distributed caching infrastructure

The application now supports distributed caching via Redis, replacing or augmenting previous caching mechanisms. This change introduces an abstraction layer (ICacheService) and a concrete implementation (CacheService) that serializes and deserializes objects using System.Text.Json for storage in a distributed cache. It also defines ICachedQuery to mark queries that should be cached, along with CacheOptions to manage default expiration times (set to 1 minute). Users will experience faster response times for cached queries as data is now stored in a distributed cache rather than potentially in-memory or not cached at all.

src/Bookify.Application/Abstractions/Caching, src/Bookify.Infrastructure/Caching · high confidence

Introduction of email sending capability

The application now includes an abstraction for sending emails via the new IEmailService interface, which defines a SendAsync method accepting a recipient, subject, and body. This change enables the system to send email notifications, such as those related to booking reservations, by providing a standardized contract for email delivery.

src/Bookify.Application/Abstractions/Email · high confidence

Outbox pattern implementation for reliable domain event processing

The system now persists domain events to an outbox table to ensure they are reliably delivered even if the initial transaction fails. A background Quartz job periodically picks up unprocessed messages from the database, deserializes them, and publishes them via MediatR, marking them as processed or recording errors upon completion. This change guarantees that domain events are not lost during application restarts or transient failures, providing eventual consistency for downstream consumers.

src/Bookify.Infrastructure/Outbox · high confidence

Behavioural changes

Add concurrency and validation exception types

The application now includes specific exception classes to handle concurrency conflicts and validation failures. A new ConcurrencyException has been added to support optimistic concurrency checks, while ValidationException and its associated ValidationError record allow for structured reporting of property-level validation errors.

src/Bookify.Application/Exceptions · high confidence

Added pipeline behaviors for logging, validation, and query caching

The application now includes three new MediatR pipeline behaviors to enhance request handling. LoggingBehavior adds structured logging for commands, recording success, errors, and exceptions via Serilog. ValidationBehavior automatically validates command requests using FluentValidation and throws a ValidationException if constraints are violated. QueryCachingBehavior intercepts cached queries, returning results from the cache when available and storing new results to improve performance.

src/Bookify.Application/Abstractions/Behaviors · high confidence

Application layer now includes MediatR behaviors for logging, validation, and query caching

The application layer now automatically applies cross-cutting concerns to all MediatR requests. Commands and queries are validated using FluentValidation, logged via a logging behavior, and queries are cached via a new QueryCachingBehavior. This ensures consistent validation, observability, and performance optimization for API requests without requiring manual implementation in individual handlers.

src/Bookify.Application · high confidence

Database schema evolution for initial data model, outbox, roles, and permissions

This update applies a series of Entity Framework Core migrations to the PostgreSQL database. It begins by creating the core tables for apartments, users, bookings, and reviews, then adds an identity link to users and introduces an outbox message table to support distributed transaction persistence. Subsequent changes make foreign keys in bookings and reviews nullable, introduce a roles table with a many-to-many relationship to users (seeding a 'Registered' role), and add a permissions table structure.

src/Bookify.Infrastructure/Migrations · high confidence

Introduces permission-based authorization with role caching

The application now supports fine-grained, permission-based authorization in addition to role-based checks. A new AuthorizationService retrieves user roles and permissions from the database, caching the results via ICacheService to reduce database load. CustomClaimsTransformation enriches the user's identity with role claims, while a custom PermissionAuthorizationHandler and PolicyProvider allow controllers to enforce specific permissions using the new HasPermissionAttribute.

src/Bookify.Infrastructure/Authorization · high confidence

Test coverage

Added functional, integration, unit, and architecture test suites

Added comprehensive test coverage across the application, including functional tests for the API (e.g., user registration), integration tests for application services (e.g., apartment search, booking reservation) using Testcontainers for PostgreSQL, Redis, and Keycloak, unit tests for domain logic and application handlers using NSubstitute, and architecture tests to enforce layering and naming conventions.

test · high confidence

Dependencies

Initial project structure and dependency configuration for .NET 8

The Bookify solution is established with a multi-project architecture (API, Application, Infrastructure, Domain) and a comprehensive test suite, all targeting .NET 8. This change introduces the foundational dependency graph, including MediatR and Dapper for the application layer, ASP.NET Core Health Checks, JWT Authentication, and Redis caching for infrastructure, and xUnit with NSubstitute and Testcontainers for functional, integration, and unit testing.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 53 → 51 (-2.2)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 76 → 76 (+0.3)
  • Architecture 75 → 75 (+0.0)
  • Maturity 46 → 46 (+0.0)
  • Readiness 46 → 40 (-6.2)
  • Security 64 → 63 (-1.3)
  • Domain Modelling 70 → 89 (+19.7)
  • Event-Driven 100 → 100 (+0.0)

Resolved (11)

  • Bounded contexts not declared
  • High CVE: System.Text.Json 8.0.0
  • High CVE: System.Text.Json 8.0.0
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • No exposed public API
  • Secret: generic-api-key (.files/bookify-realm-export.json)
  • Secret: generic-api-key (.files/bookify-realm-export.json)
  • Secret: generic-api-key (src/Bookify.API/appsettings.Development.json)
  • Secret: generic-api-key (src/Bookify.API/appsettings.Development.json)
  • single-maintainer — knowledge-concentration (bus factor) risk

New (25)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (13–14 lines × 2) (src/Bookify.Infrastructure/Configurations/ApartmentConfiguration.cs)
  • High CVE: SSH.NET 2023.0.0
  • High CVE: System.Text.Json 8.0.0
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High IaC: WD-COMPOSE-0002 (docker-compose.yml)
  • High secret: WD-SECRET-0002 (.files/bookify-realm-export.json)
  • High secret: WD-SECRET-0002 (.files/bookify-realm-export.json)
  • High secret: WD-SECRET-0002 (src/Bookify.API/appsettings.Development.json)
  • High secret: WD-SECRET-0002 (src/Bookify.API/appsettings.Development.json)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Inconsistent naming for monetary value properties in the response DTO. Some properties use the suffix 'Amount' (e.g., PriceAmount, TotalPriceAmount, CleaningFeeAmount), while others use 'Currency' for the currency code. However, the property 'AmenitiesUpChargeAmount' follows the 'Amount' pattern, but there is no corresponding 'AmenitiesUpChargeCurrency' property visible in the list, whereas 'PriceCurrency' and 'TotalPriceCurrency' exist. More critically, the naming convention for the monetary values is inconsistent: 'PriceAmount' vs 'TotalPriceAmount' vs 'CleaningFeeAmount'. While 'Amount' is used for the value, the lack of a parallel 'Currency' property for 'AmenitiesUpCharge' suggests an incomplete implementation or naming drift compared to 'Price' and 'TotalPrice'.
  • Leaked secret: high-entropy-secret (.files/bookify-realm-export.json)
  • Medium IaC: WD-DOCKER-0003 (src/Bookify.API/Dockerfile)
  • Medium IaC: WD-DOCKER-0003 (src/Bookify.API/Dockerfile)
  • Medium: security finding (details withheld)
  • …and 5 more

API surface

  • Unchanged — 8 HTTP endpoints

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

Tmaturano/Bookify was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 425d1981ed9b7e81ede9a9dfb367ff75c0cff3ed — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.