Files
Hy2026/backend/AGENTS.md
T

3.2 KiB

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: <Resource>Controller (np. CustomersController), dziedziczy po ControllerBase.
  • Stosuj atrybut [ApiController] oraz jawne trasy [Route("api/<resource>")] (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<T> 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: <Resource>Request, <Resource>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

[ApiController]
[Route("api/customers")]
public class CustomersController : ControllerBase
{
    private readonly ICustomerService _customerService;

    public CustomersController(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    [HttpGet("{customerId:int}")]
    public async Task<ActionResult<CustomerResponse>> GetById(
        int customerId,
        CancellationToken cancellationToken)
    {
        var customer = await _customerService.GetByIdAsync(customerId, cancellationToken);

        return customer is null
            ? NotFound()
            : Ok(customer);
    }

    [HttpPost]
    public async Task<ActionResult<CustomerResponse>> Create(
        CreateCustomerRequest request,
        CancellationToken cancellationToken)
    {
        var createdCustomer = await _customerService.CreateAsync(request, cancellationToken);

        return CreatedAtAction(
            nameof(GetById),
            new { customerId = createdCustomer.Id },
            createdCustomer);
    }
}