# Repository Guidelines ## Hard Rules — Always Enforced 1. **Never call `uow.SaveChangesAsync()` in any repository or service.** Only `uow.CommitAsync()` (or `BeginAsync`/`CommitAsync`/`RollbackAsync` for transactions) may be called, and only from the service layer. 2. **Never use `DateTime.UtcNow`.** Use `DateTime.Now` (server time) everywhere. 3. **Never build a feature that was not explicitly requested.** Confirm with the user before creating any new entity, endpoint, service, or infrastructure component. --- ## Project Structure & Module Organization The repository contains one solution file, `Distribution.slnx`, and one ASP.NET Core 10 Web API project in `Distribution/`. The intended folder layout is: ``` Distribution/ ├── Controllers/ # Thin HTTP endpoints — no business logic, no UoW calls ├── Data/ │ └── AppDBContext.cs # EF Core DbContext — add DbSets here ├── Domain/ │ └── Entities/ # Plain POCO entities; one file per entity ├── Infra/ │ ├── UoW/ # IUnitOfWork + EFUnitOfWork (already implemented) │ └── Repositories/ # IRepository, EFRepository, and per-aggregate repos ├── Application/ │ └── Services/ # Business logic; owns the uow.CommitAsync() call └── DTOs/ # Request/Response DTOs per module ``` Core entrypoint: `Distribution/Program.cs`. Configuration: `appsettings.json` / `appsettings.Development.json`. Launch profiles: `Distribution/Properties/launchSettings.json`. Do not commit build output from `Distribution/bin/` or `Distribution/obj/`. ## UoW Call-Chain Rule ``` Controller → Service → Repository (EF change tracking only) ↓ uow.CommitAsync() ← only the service calls this ``` - Repositories call `AddAsync`, `Update`, `Remove` on the DbSet — nothing more. - Services call `_uow.CommitAsync(ct)` to flush and commit. - For multi-step operations, services call `BeginAsync` → work → `CommitAsync` (or `RollbackAsync` in catch). - `uow.SaveChangesAsync()` exists on the interface but must never appear in repo or service code. --- ## Build, Test, and Development Commands Run commands from the repository root unless noted otherwise. - `dotnet restore Distribution.slnx`: restore NuGet packages. - `dotnet build Distribution.slnx`: compile the solution. - `dotnet run --project Distribution/Distribution.csproj`: start the API locally. - `dotnet watch run --project Distribution/Distribution.csproj`: run with hot reload during development. - `dotnet test`: run automated tests once a test project is added. The default development URLs are defined in `launchSettings.json`, currently `http://localhost:5089` and `https://localhost:7025`. ## Coding Style & Naming Conventions Use standard C# conventions: 4-space indentation, PascalCase for public types and members, camelCase for local variables and parameters, and one class per file. Name controllers with the `*Controller.cs` pattern and keep route names explicit. Nullable reference types are enabled, so handle nullability deliberately rather than suppressing warnings. ## Testing Guidelines There is no test project in the repository yet. Add new tests in a sibling project such as `Distribution.Tests/` and include it in the solution. Prefer xUnit for .NET API coverage. Name test files after the subject under test, for example `OrdersControllerTests.cs`, and use method names like `Get_ReturnsNotFound_WhenIdIsMissing`. ## Commit & Pull Request Guidelines The current branch has no commit history yet, so use a clean convention from the start: short imperative subjects such as `Add orders controller` or `Configure OpenAPI in development`. Keep commits focused on one change. Pull requests should include a brief summary, impacted endpoints or config files, test evidence (`dotnet build`, `dotnet test`), and sample request or response details when API behavior changes. ## Configuration Notes Keep secrets out of `appsettings.json`; use environment variables or user secrets for local development. Restrict `appsettings.Development.json` to non-sensitive machine-local defaults.