From f26ad1744eb8b0a40b15e75a8e74aedceb24a0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ty=C5=84ski?= Date: Sat, 3 Oct 2026 18:30:43 +0200 Subject: [PATCH] feat(backend): scaffold ASP.NET Core Web API with health endpoint --- backend/AGENTS.md | 82 +++++++++++++++++++++++++ backend/Controllers/HealthController.cs | 16 +++++ backend/Program.cs | 27 ++++++++ backend/Properties/launchSettings.json | 14 +++++ backend/TarninaHub.csproj | 13 ++++ backend/appsettings.Development.json | 8 +++ backend/appsettings.json | 9 +++ 7 files changed, 169 insertions(+) create mode 100644 backend/AGENTS.md create mode 100644 backend/Controllers/HealthController.cs create mode 100644 backend/Program.cs create mode 100644 backend/Properties/launchSettings.json create mode 100644 backend/TarninaHub.csproj create mode 100644 backend/appsettings.Development.json create mode 100644 backend/appsettings.json diff --git a/backend/AGENTS.md b/backend/AGENTS.md new file mode 100644 index 0000000..656b8db --- /dev/null +++ b/backend/AGENTS.md @@ -0,0 +1,82 @@ +# AGENTS.md — Standardy warstwy Controller + +Dotyczy projektu `backend` (ASP.NET Core Web API, .NET 10). + +## Język nazewnictwa + +- Wszystkie nazwy zmiennych, parametrów, pól, metod, klas i plików są **wyłącznie w języku angielskim**. +- Zakaz używania polskich nazw w kodzie (np. `uzytkownik`, `zamowienie`), w tym w parametrach tras i modelach. +- Komentarze i dokumentacja opisowa mogą być w języku polskim, ale identyfikatory w kodzie — tylko po angielsku. + +## Organizacja kontrolerów + +- Każdy kontroler w osobnym pliku w katalogu `Controllers/`, nazwa pliku zgodna z nazwą klasy. +- Nazwa klasy: `Controller` (np. `CustomersController`), dziedziczy po `ControllerBase`. +- Stosuj atrybut `[ApiController]` oraz jawne trasy `[Route("api/")]` (np. `[Route("api/health")]`) — nie używaj tokenu `[controller]`. +- Katalog `Controllers/` grupuje wyłącznie kontrolery — logika biznesowa trafia do serwisów. + +## Konwencje akcji + +- Metody akcji w czasie teraźniejszym, opisujące operację: `GetById`, `GetAll`, `Create`, `Update`, `Delete`. +- Używaj atrybutów HTTP: `[HttpGet]`, `[HttpGet("{id}")]`, `[HttpPost]`, `[HttpPut("{id}")]`, `[HttpDelete("{id}")]`. +- Parametry tras w `{camelCase}` (np. `{customerId}`), zgodnie z nazwami w kodzie. +- Zwracaj typy wyników `ActionResult` lub `IActionResult` z jawnymi kodami statusu: + - `200 OK` — pobranie/zaktualizowanie, + - `201 Created` — utworzenie (`CreatedAtAction`), + - `204 NoContent` — usunięcie, + - `400 BadRequest`, `404 NotFound` — błędy. +- Kontroler nie zawiera logiki biznesowej ani dostępu do bazy — deleguje do serwisów/repozytoriów. +- Używaj wstrzykiwania zależności przez konstruktor (tylko `readonly` pola). + +## Modele i DTO + +- Wejście i wyjście kontrolera stanowią dedykowane DTO, nie modele encji. +- Nazwy DTO: `Request`, `Response`. +- Walidacja wejścia przez adnotacje (`[Required]`, `[StringLength]`, `[Range]`). +- Nie zwracaj encji bazy bezpośrednio z akcji. + +## Asynchroniczność + +- Wszystkie operacje I/O (baza, HTTP) jako `async` z sufiksem `Async` i zwrotem `Task<...>`. +- Akceptuj `CancellationToken cancellationToken` i przekazuj go dalej. + +## Przykład + +```csharp +[ApiController] +[Route("api/customers")] +public class CustomersController : ControllerBase +{ + private readonly ICustomerService _customerService; + + public CustomersController(ICustomerService customerService) + { + _customerService = customerService; + } + + [HttpGet("{customerId:int}")] + public async Task> GetById( + int customerId, + CancellationToken cancellationToken) + { + var customer = await _customerService.GetByIdAsync(customerId, cancellationToken); + + return customer is null + ? NotFound() + : Ok(customer); + } + + [HttpPost] + public async Task> Create( + CreateCustomerRequest request, + CancellationToken cancellationToken) + { + var createdCustomer = await _customerService.CreateAsync(request, cancellationToken); + + return CreatedAtAction( + nameof(GetById), + new { customerId = createdCustomer.Id }, + createdCustomer); + } +} +``` diff --git a/backend/Controllers/HealthController.cs b/backend/Controllers/HealthController.cs new file mode 100644 index 0000000..c395a5e --- /dev/null +++ b/backend/Controllers/HealthController.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc; + +namespace TarninaHub.Controllers; + +[ApiController] +[Route("api/health")] +public class HealthController : ControllerBase +{ + [HttpGet] + public ActionResult Get() + { + return Ok(new HealthResponse("ok")); + } +} + +public record HealthResponse(string Status); diff --git a/backend/Program.cs b/backend/Program.cs new file mode 100644 index 0000000..f28b2c2 --- /dev/null +++ b/backend/Program.cs @@ -0,0 +1,27 @@ +var builder = WebApplication.CreateBuilder(args); + +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); + +builder.Services.AddControllers(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} +else +{ + app.UseHttpsRedirection(); +} + +app.UseDefaultFiles(); +app.UseStaticFiles(); + +app.MapControllers(); + +app.MapFallbackToFile("index.html"); + +app.Run(); diff --git a/backend/Properties/launchSettings.json b/backend/Properties/launchSettings.json new file mode 100644 index 0000000..03aa453 --- /dev/null +++ b/backend/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7080", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/backend/TarninaHub.csproj b/backend/TarninaHub.csproj new file mode 100644 index 0000000..0268d75 --- /dev/null +++ b/backend/TarninaHub.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + enable + enable + + + + + + + diff --git a/backend/appsettings.Development.json b/backend/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/backend/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/backend/appsettings.json b/backend/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/backend/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}