|
1 | 1 | # GitHub Copilot Instructions |
2 | 2 |
|
3 | | -> **Token Budget**: Target 600, limit 650 (auto-loaded) |
4 | | -> Details: `#file:AGENTS.md` (~2,550 tokens, on-demand) |
5 | | -> Skills: `#file:SKILLS/<name>/SKILL.md` (on-demand) |
| 3 | +## Overview |
6 | 4 |
|
7 | | -## Quick Context |
| 5 | +REST API for managing football players built with ASP.NET Core 10. Implements CRUD operations with a layered architecture, EF Core + SQLite persistence, FluentValidation, AutoMapper, and in-memory caching. Part of a cross-language comparison study (Go, Java, Python, Rust, TypeScript). |
8 | 6 |
|
9 | | -ASP.NET Core 10 REST API with layered architecture |
10 | | -**Stack**: .NET 10 LTS, EF Core 10, SQLite, Docker, xUnit |
11 | | -**Pattern**: Repository + Service + AutoMapper + FluentValidation |
12 | | -**Focus**: Learning PoC emphasizing clarity and best practices |
| 7 | +## Tech Stack |
13 | 8 |
|
14 | | -## Core Conventions |
15 | | - |
16 | | -- **Naming**: PascalCase (public), camelCase (private) |
17 | | -- **DI**: Primary constructors everywhere |
18 | | -- **Async**: All I/O operations use async/await |
19 | | -- **Logging**: Serilog with structured logging |
| 9 | +- **Language**: C# (.NET 10 LTS) |
| 10 | +- **Framework**: ASP.NET Core (MVC controllers) |
| 11 | +- **ORM**: Entity Framework Core 10 |
| 12 | +- **Database**: SQLite |
| 13 | +- **Mapping**: AutoMapper |
| 14 | +- **Validation**: FluentValidation |
| 15 | +- **Caching**: `IMemoryCache` (1-hour TTL) |
| 16 | +- **Logging**: Serilog (structured, console + file) |
20 | 17 | - **Testing**: xUnit + Moq + FluentAssertions |
21 | 18 | - **Formatting**: CSharpier |
22 | | -- **Commits**: Conventional Commits with issue number suffix |
23 | | - - Format: `type(scope): description (#issue)` (max 80 chars) |
24 | | - - Types: feat, fix, chore, docs, test, refactor |
25 | | - - Example: `feat(api): add player search endpoint (#123)` |
26 | | - - Body lines ≤80 chars |
| 19 | +- **Containerization**: Docker |
27 | 20 |
|
28 | | -## Architecture |
| 21 | +## Structure |
29 | 22 |
|
30 | 23 | ```text |
31 | | -Controller → Service → Repository → Database |
32 | | - ↓ ↓ |
33 | | -Validation Caching |
| 24 | +src/Dotnet.Samples.AspNetCore.WebApi/ |
| 25 | +├── Controllers/ — HTTP handlers; minimal logic, delegate to services [HTTP layer] |
| 26 | +├── Services/ — Business logic + IMemoryCache caching [business layer] |
| 27 | +├── Repositories/ — Generic Repository<T> + specific implementations [data layer] |
| 28 | +├── Models/ — Player entity + DTOs |
| 29 | +├── Validators/ — FluentValidation (structure only; business rules in services) |
| 30 | +├── Profiles/ — AutoMapper profiles |
| 31 | +├── Data/ — DbContext + DbInitializer |
| 32 | +└── Storage/ — SQLite database file |
| 33 | +
|
| 34 | +test/Dotnet.Samples.AspNetCore.WebApi.Tests/ |
| 35 | +├── ControllersTests/ |
| 36 | +└── ServicesTests/ |
34 | 37 | ``` |
35 | 38 |
|
36 | | -Controllers: Minimal logic, delegate to services |
37 | | -Services: Business logic + `IMemoryCache` caching |
38 | | -Repositories: Generic `Repository<T>` + specific implementations |
39 | | -Models: `Player` entity + DTOs |
40 | | -Validators: FluentValidation (structure only, business rules in services) |
41 | | - |
42 | | -## Copilot Should |
| 39 | +**Layer rule**: `Controller → Service → Repository → Database`. Controllers must not access repositories directly. Business logic must not live in controllers. |
43 | 40 |
|
44 | | -- Generate idiomatic ASP.NET Core code with minimal controller logic |
45 | | -- Use EF Core async APIs with `AsNoTracking()` for reads |
46 | | -- Follow Repository + Service pattern consistently |
47 | | -- Write tests with xUnit/Moq/FluentAssertions |
48 | | -- Apply RFC 7807 Problem Details for errors |
49 | | -- Use primary constructors for DI |
50 | | -- Implement structured logging with `ILogger<T>` |
| 41 | +## Coding Guidelines |
51 | 42 |
|
52 | | -## Copilot Should Avoid |
| 43 | +- **Naming**: PascalCase (public members), camelCase (private fields) |
| 44 | +- **DI**: Primary constructors everywhere |
| 45 | +- **Async**: All I/O operations use `async`/`await`; no `ConfigureAwait(false)` (unnecessary in ASP.NET Core) |
| 46 | +- **Reads**: Use `AsNoTracking()` for all EF Core read queries |
| 47 | +- **Errors**: RFC 7807 Problem Details for all error responses |
| 48 | +- **Logging**: Structured logging via `ILogger<T>`; never `Console.Write` |
| 49 | +- **Tests**: xUnit + Moq + FluentAssertions; test naming mirrors method under test |
| 50 | +- **Avoid**: synchronous EF Core APIs, controller business logic, static service/repository classes |
53 | 51 |
|
54 | | -- Synchronous EF Core APIs |
55 | | -- Controller business logic (belongs in services) |
56 | | -- Static service/repository classes |
57 | | -- `ConfigureAwait(false)` (unnecessary in ASP.NET Core) |
| 52 | +## Commands |
58 | 53 |
|
59 | | -## Quick Commands |
| 54 | +### Quick Start |
60 | 55 |
|
61 | 56 | ```bash |
62 | | -# Run with hot reload |
63 | | -dotnet watch run --project src/Dotnet.Samples.AspNetCore.WebApi |
| 57 | +dotnet restore |
| 58 | +dotnet build |
| 59 | +dotnet run --project src/Dotnet.Samples.AspNetCore.WebApi # https://localhost:9000 |
| 60 | +dotnet watch run --project src/Dotnet.Samples.AspNetCore.WebApi # hot reload |
| 61 | +dotnet test --settings .runsettings # with coverage |
| 62 | +docker compose up |
| 63 | +``` |
64 | 64 |
|
65 | | -# Test with coverage |
66 | | -dotnet test --settings .runsettings |
| 65 | +### Pre-commit Checks |
67 | 66 |
|
68 | | -# Docker |
69 | | -docker compose up |
| 67 | +1. Update `CHANGELOG.md` `[Unreleased]` section (Added / Changed / Fixed / Removed) |
| 68 | +2. `dotnet build --configuration Release` — must succeed |
| 69 | +3. `dotnet test --settings .runsettings` — all tests must pass |
| 70 | +4. Verify code formatting with CSharpier |
| 71 | +5. Commit message follows Conventional Commits format (enforced by commitlint) |
70 | 72 |
|
71 | | -# Swagger: https://localhost:9000/swagger |
72 | | -``` |
| 73 | +### Commits |
| 74 | + |
| 75 | +Format: `type(scope): description (#issue)` — max 80 chars |
| 76 | +Types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf` |
| 77 | +Example: `feat(api): add player search endpoint (#123)` |
73 | 78 |
|
74 | | -## Load On-Demand Files |
| 79 | +## Agent Mode |
75 | 80 |
|
76 | | -**Load `#file:AGENTS.md` when:** |
77 | | -- "How do I run tests with coverage?" |
78 | | -- "CI/CD pipeline setup or troubleshooting" |
79 | | -- "Database migration procedures" |
80 | | -- "Publishing/deployment workflows" |
81 | | -- "Detailed troubleshooting guides" |
| 81 | +### Proceed freely |
82 | 82 |
|
83 | | -**Load `#file:SKILLS/<skill-name>/SKILL.md` (planned):** |
84 | | -- Docker optimization: `docker-containerization/SKILL.md` |
85 | | -- Testing patterns: `testing-patterns/SKILL.md` |
| 83 | +- Route handlers and controllers |
| 84 | +- Service layer logic and caching |
| 85 | +- Repository implementations |
| 86 | +- Unit and integration tests |
| 87 | +- Documentation and CHANGELOG updates |
| 88 | +- Bug fixes and refactoring within existing patterns |
86 | 89 |
|
87 | | -**Human-readable overview**: See `README.md` (not auto-loaded) |
| 90 | +### Ask before changing |
88 | 91 |
|
89 | | ---- |
| 92 | +- Database schema (entity fields, migrations) |
| 93 | +- Dependencies (`*.csproj`, `global.json`) |
| 94 | +- CI/CD configuration (`.github/workflows/`) |
| 95 | +- Docker setup |
| 96 | +- Application configuration (`appsettings.json`) |
| 97 | +- API contracts (breaking DTO changes) |
| 98 | +- Caching strategy or TTL values |
90 | 99 |
|
91 | | -**Why this structure?** Base instructions (~600 tokens) load automatically. On-demand files (~2,550 tokens) load only when needed, saving 80% of tokens per chat. |
| 100 | +### Never modify |
| 101 | + |
| 102 | +- Production configurations or deployment secrets |
| 103 | +- `.runsettings` coverage thresholds |
| 104 | +- Port configuration (9000) |
| 105 | +- Database type (SQLite — demo/dev only) |
| 106 | + |
| 107 | +### Key workflows |
| 108 | + |
| 109 | +**Add an endpoint**: Add DTO in `Models/` → update `PlayerMappingProfile` in `Mappings/` (AutoMapper) → add repository method(s) in `Repositories/` → add service method in `Services/` → add controller action in `Controllers/` → add validator in `Validators/` → add tests → run pre-commit checks. |
| 110 | + |
| 111 | +**Modify schema**: Update `Player` entity → update DTOs → update AutoMapper profile → reset `Storage/players.db` → update tests → run `dotnet test`. |
| 112 | + |
| 113 | +**After completing work**: Suggest a branch name (e.g. `feat/add-player-search`) and a commit message following Conventional Commits including co-author line: |
| 114 | + |
| 115 | +```text |
| 116 | +feat(scope): description (#issue) |
| 117 | +
|
| 118 | +Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
| 119 | +``` |
0 commit comments