Skip to content
klinkbyPublic

About

Booqr backend.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Klinkby.Booqr

Build+Push Docker image codecov CodeQL License Up?

An AOT (Ahead-of-Time) enabled ASP.NET 10 Web API, designed to serve as a robust backend for an application requiring efficient and secure booking management with a PostgreSQL database. The service is designed on a minimalist clean architecture emphasizing performance and maintainability without ceremony.

It is multi-tenant: many businesses share one PostgreSQL database, each seeing only its own data, with isolation enforced by the database itself.

Features

  • AOT Compilation: Leverages .NET 10's Native AOT with aggressive trimming.
  • Build-time OpenAPI: Compile-time generated OpenAPI spec with zero runtime overhead.
  • Source Generators: Extensive use of compile-time code generation:
  • IAsyncEnumerable Streaming: Unbuffered streaming for collection endpoints with async iteration
  • Channels: Async pipelines for immediate response with deferred processing.
  • Background Services: In-process email processing on the API; cross-tenant scheduled jobs (reminder delivery, refresh-token flush) run in a dedicated worker run-mode container that holds only the BYPASSRLS batch credential.
  • Activity Tracking: Historic audit logging.
  • Problem Details: Structured error responses using RFC 7807 (ProblemDetails) standard with detailed validation errors.
  • CLEF structured logging via NLog: Compact Log Event Format for efficient json log sink.
  • Container Security: Runs rootless in tiny Alpine Linux images (~17MB image) with immutable filesystem.
  • Password handling: Email-verified user accounts with BCrypt password hashing and timing attack mitigation.
  • PostgreSQL Backend: Reliable data storage in Npgsql 18 container with schema bootstrapping.
  • JWT Authentication: Secure API authentication with Microsoft.AspNetCore.Authentication.JwtBearer.
  • Refresh Token Rotation: Opaque refresh tokens with 240-bit cryptographic entropy, family-based tracking for reuse detection, and automatic revocation on compromise.
  • HttpOnly Cookies: Secure refresh token storage with HttpOnly, Secure, SameSite=Strict, and path-scoped attributes to prevent XSS and CSRF attacks.
  • Token Management: SHAKE128 hashing for database storage, transactional token rotation, and automated daily cleanup of expired tokens.
  • Role-based Authorization: Fine-grained access control using ASP.NET Core's built-in authorization policies.
  • Multi-Tenancy: One shared PostgreSQL database isolated by FORCE ROW LEVEL SECURITY plus one login role per tenant (t_<id>). The RLS policy keys on the connected role (current_user), so isolation is DB-enforced and unforgeable — no per-request session variable. The API resolves each tenant from its subdomain (<slug>.booqr.dk); the API image's admin run-mode provisions tenants, roles, and migrations. Per-tenant role passwords are HMAC-derived; cross-tenant scheduled jobs run in a separate worker container as a dedicated BYPASSRLS role, decoupled from the tenant master secret so the internet-facing API never carries the batch credential.
  • Docker Compose: Wraps the service with HAProxy gateway in the front, PostgreSQL in the back, a long-running internal-only worker container for cross-tenant scheduled jobs, an internal-only admin container for provisioning/migrations, and efficient UNIX sockets for inter-container communication.

Known Limitations

  • bigint id truncation on bookings/calendar: The bookings.id and calendar.id columns are bigint in the database (see Migrations/0001_baseline.sql — "bigint promotion"), but the C# domain represents entity ids as int via the shared Audit.Id / IId (and int-keyed shared request/route types ByIdRequest, {id:int}). BookingRepository.Add narrows the returned identity with Convert.ToInt32, which throws OverflowException once an identity value exceeds int.MaxValue (~2.1 billion). A full fix requires threading long through the shared id types and the booking/calendar endpoints; it is deferred because those types are shared by every entity and widening them changes the wire contract for int-keyed entities too.

Project Structure

The Klinkby.Booqr solution is organized into several projects, each responsible for a distinct aspect of the application:

  • Core: Defines core domain models, interfaces, and common utilities used across all layers.
  • Application: Contains the application's business logic and orchestrates operations between the API and infrastructure layers.
  • Infrastructure: Manages data access (e.g., interaction with PostgreSQL) and external service integrations. Includes Klinkby.Booqr.Infrastructure.Generators for code generation.
  • Api: The entry point of the application, containing middleware configuration and all things HTTP. Run-mode is chosen by a leading arg: the web/API host (default), the control-plane admin CLI (Admin/, admin --migrate|--provision|--deprovision|--rotate), and the scheduled worker (Worker/). The admin and worker modes run as the same image in separate internal containers; admin holds the elevated provisioning credentials and never starts the web pipeline.
  • Tests: Contains unit and integration tests for various components of the solution, including Klinkby.Booqr.Api.Tests, Klinkby.Booqr.Application.Tests, and Klinkby.Booqr.Infrastructure.Tests using test containers to spin up a live PostgreSQL instance.

Minimal Runtime Dependencies

Licensed under AGPL-3.0

Copyright (C) 2026 Mads Klinkby (https://www.kli.dk)

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/.

About

Booqr backend.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages