Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/marchena96/Paradigma-lab1/llms.txt

Use this file to discover all available pages before exploring further.

LibraryService API follows a classic layered (n-tier) design with no repository layer between the service and the database. Each layer has a single responsibility: controllers handle HTTP concerns, services own all business logic and data access, and EF Core’s LibraryContext bridges the .NET object world to PostgreSQL running on Supabase.

Request flow

Every HTTP request travels through exactly three code layers before touching the database:
HTTP Request → Controller → Service → LibraryContext (EF Core) → PostgreSQL (Supabase)
The controller parses and validates input, then delegates to a service. The service runs all queries and mutations through LibraryContext. EF Core translates those into SQL and executes them against the PostgreSQL instance hosted on Supabase.

Solution structure

Paradigma-lab1/
├── HackerRank1/                         # Web API (net8.0)
│   ├── Controllers/                     # HTTP handlers
│   ├── Services/                        # Business logic + data access
│   ├── Data/                            # EF Core DbContext + entities
│   ├── DTO/                             # Data transfer objects
│   ├── Entities/                        # Config entities (JwtSettings)
│   ├── Helpers/                         # TokenGenerator
│   ├── Migrations/                      # EF Core migration history
│   ├── Startup.cs                       # DI, middleware, JWT, Swagger
│   └── Program.cs                       # Host builder
└── LibraryService.Integration.Test/     # xUnit integration tests

Layer responsibilities

LayerKey typesResponsibility
ControllersLibrariesController, BooksController, AuthControllerParse HTTP input (route params, JSON body), call the appropriate service method, and return the correct HTTP status code (200 OK, 201 Created, 204 No Content, 404 Not Found, 401 Unauthorized)
ServicesILibrariesService, IBooksService, IAuthenticationServiceAll data-access logic — querying, inserting, updating, and deleting via LibraryContext; no HTTP knowledge
LibraryContextLibraryContext : DbContextMaps the Library and Book entities to the Libraries and Books PostgreSQL tables; owned by EF Core’s DbContext pool
DTOsBookForm, UserLightweight, camelCase JSON contract types serialized with System.Text.Json ([JsonPropertyName]); decoupled from the database entities

Startup and hosting model

The application uses the classic Program.cs + Startup.cs hosting model, not Minimal API. Program.cs creates the generic host and points it at Startup:
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
Startup.ConfigureServices registers services in the following order:
  1. JwtSettings binding — reads the JwtSettings section from configuration (or throws InvalidOperationException if absent) and registers the result as a singleton. Also registers IAuthenticationService → AuthenticationService (Scoped).
  2. JWT Bearer authentication — configures JwtBearerDefaults.AuthenticationScheme with issuer/audience/key validation and zero clock-skew.
  3. Authorization — calls services.AddAuthorization() to enable the [Authorize] attribute on controllers.
  4. CORS — adds a named "Frontend" policy that allows any header and method from the Vite dev server at http://localhost:5173.
  5. Business-service DI — registers ILibrariesService → LibrariesService (Transient) and IBooksService → BooksService (Transient).
  6. DbContextPool — registers LibraryContext with Npgsql, a pool size of 20, and retry-on-failure (max 1 retry, 5-second delay).
  7. Controllers and Swagger — calls services.AddControllers() and services.AddSwaggerGen().
An idempotency guard at the top of ConfigureServices checks whether JwtSettings is already registered and returns early if so. This prevents double-registration errors (e.g., "Scheme already exists: Bearer") when WebApplicationFactory and UseStartup<Startup> both invoke ConfigureServices during integration tests.

Middleware pipeline

Before the pipeline is mounted, Startup.Configure runs auto-migration: it resolves LibraryContext, checks for pending EF Core migrations, and calls db.Database.Migrate() — but only when the provider is not SQLite (SQLite is used in tests and manages its schema via EnsureCreated). The middleware pipeline is then assembled in the following order:
OrderMiddlewareRegistered via
1Routingapp.UseRouting()
2CORS ("Frontend" policy)app.UseCors("Frontend")
3Authentication (JWT Bearer)app.UseAuthentication()
4Authorizationapp.UseAuthorization()
5Endpointsapp.UseEndpoints(e => e.MapControllers())
In development, UseDeveloperExceptionPage() is prepended, and the Swagger middleware (UseSwagger / UseSwaggerUI) serves the interactive API explorer at /swagger.

Build docs developers (and LLMs) love