Skip to content

Commit 388c72d

Browse files
authored
Merge pull request #449 from nanotaboada/docs/448-normalize-readme-structure
docs: normalize README structure and add RELEASES.md
2 parents ed03238 + 50b31b4 commit 388c72d

3 files changed

Lines changed: 119 additions & 179 deletions

File tree

.markdownlint.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"MD013": false,
3+
"MD024": {
4+
"siblings_only": true
5+
}
6+
}

README.md

Lines changed: 40 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,14 @@
1414

1515
Proof of Concept for a RESTful API built with .NET 10 (LTS) and ASP.NET Core. Manage football player data with SQLite, Entity Framework Core, Swagger documentation, and in-memory caching.
1616

17-
## Table of Contents
18-
19-
- [Features](#features)
20-
- [Tech Stack](#tech-stack)
21-
- [Project Structure](#project-structure)
22-
- [Architecture](#architecture)
23-
- [Architecture Decisions](#architecture-decisions)
24-
- [API Reference](#api-reference)
25-
- [Prerequisites](#prerequisites)
26-
- [Quick Start](#quick-start)
27-
- [Testing](#testing)
28-
- [Containers](#containers)
29-
- [Releases](#releases)
30-
- [Environment Variables](#environment-variables)
31-
- [Command Summary](#command-summary)
32-
- [Contributing](#contributing)
33-
- [Legal](#legal)
34-
3517
## Features
3618

3719
- 🏗️ **Clean layered architecture** - Repository pattern, dependency injection, and async operations throughout
3820
- 📚 **Interactive API exploration** - Swagger UI documentation with health monitoring endpoints
3921
-**Performance optimizations** - In-memory caching, rate limiting, and efficient database queries
4022
- 🧪 **High test coverage** - xUnit tests with automated reporting to Codecov and SonarCloud
41-
- 📖 **Token-efficient documentation** - Custom instructions with coding guidelines, architecture rules, and agent workflows for AI-assisted development
4223
- 🐳 **Full containerization** - Multi-stage Docker builds with Docker Compose orchestration
4324
- 🔄 **Complete CI/CD pipeline** - Automated testing, code quality checks, Docker publishing, and GitHub releases
44-
- 🏟️ **Stadium-themed semantic versioning** - Memorable, alphabetical release names from World Cup venues
4525

4626
## Tech Stack
4727

@@ -58,51 +38,6 @@ Proof of Concept for a RESTful API built with .NET 10 (LTS) and ASP.NET Core. Ma
5838
| **Testing** | [xUnit](https://github.com/xunit/xunit), [Moq](https://github.com/devlooped/moq), [FluentAssertions](https://github.com/fluentassertions/fluentassertions) |
5939
| **Containerization** | [Docker](https://github.com/docker) & [Docker Compose](https://github.com/docker/compose) |
6040

61-
## Project Structure
62-
63-
```text
64-
src/Dotnet.Samples.AspNetCore.WebApi/
65-
├── Program.cs # Entry point: DI setup, middleware pipeline
66-
├── Controllers/ # HTTP handlers (request/response logic)
67-
│ └── PlayerController.cs
68-
├── Services/ # Business logic + caching layer
69-
│ ├── IPlayerService.cs
70-
│ └── PlayerService.cs
71-
├── Repositories/ # Data access abstraction
72-
│ ├── IPlayerRepository.cs
73-
│ ├── IRepository.cs
74-
│ ├── PlayerRepository.cs
75-
│ └── Repository.cs
76-
├── Models/ # Domain entities and DTOs
77-
│ ├── Player.cs
78-
│ ├── PlayerRequestModel.cs
79-
│ └── PlayerResponseModel.cs
80-
├── Data/ # EF Core DbContext and migrations
81-
│ └── PlayerDbContext.cs
82-
├── Mappings/ # AutoMapper profiles
83-
│ └── PlayerMappingProfile.cs
84-
├── Validators/ # FluentValidation rules
85-
│ └── PlayerRequestModelValidator.cs
86-
├── Configurations/ # Swagger, rate limiting config
87-
├── Enums/ # Domain enumerations (e.g. Position)
88-
├── Extensions/ # Service registration extensions
89-
├── Middlewares/ # Custom ASP.NET Core middleware
90-
├── Utilities/ # Helper classes
91-
├── Migrations/ # EF Core migrations
92-
└── storage/ # Pre-seeded SQLite database
93-
94-
test/Dotnet.Samples.AspNetCore.WebApi.Tests/
95-
├── Unit/ # Unit tests with xUnit
96-
│ ├── PlayerControllerTests.cs
97-
│ ├── PlayerServiceTests.cs
98-
│ └── PlayerValidatorTests.cs
99-
└── Utilities/ # Shared test helpers
100-
├── DatabaseFakes.cs
101-
├── PlayerFakes.cs
102-
├── PlayerMocks.cs
103-
└── PlayerStubs.cs
104-
```
105-
10641
## Architecture
10742

10843
Layered architecture with dependency injection via constructors and interface-based contracts.
@@ -196,47 +131,27 @@ graph RL
196131
class AspNetCore,EFCore,MemoryCache feat;
197132
```
198133

199-
### Arrow Semantics
200-
201-
Arrows follow the injection direction: `A --> B` means A is injected into B. Solid arrows (`-->`) represent active ASP.NET Core dependencies — services registered with the IoC container and invoked at runtime. Dotted arrows (`-.->`) represent test dependencies — test classes reference the types they exercise but are not injected into them.
202-
203-
### Composition Root Pattern
204-
205-
`Program` is the composition root: it registers all services, repositories, DbContext, mappers, validators, and middleware with the ASP.NET Core IoC container, which resolves them at runtime via constructor injection.
206-
207-
### Layered Architecture
208-
209-
Four layers: Initialization (`Program`), HTTP (`Controllers`, `Validators`), Business (`Services`, `Mappings`), and Data (`Repositories`, `Data`).
210-
211-
Framework and third-party packages are placed inside the subgraph of the layer that uses them — `Serilog` and `Swashbuckle` in Initialization, `ASP.NET Core` and `FluentValidation` in HTTP, `AutoMapper` in Business, `EF Core` in Data.
212-
213-
`Models` is a cross-cutting type concern — shared entities and DTOs consumed across all layers, with no logic of its own.
214-
215-
### Color Coding
216-
217-
Blue = core application packages, yellow = Microsoft platform packages, red = third-party libraries, green = tests.
218-
219-
*Simplified, conceptual view — not all components or dependencies are shown.*
220-
221-
## Architecture Decisions
222-
223-
See [Architecture Decision Records (ADRs)](adr/README.md) for documented decisions about this project's architecture, technology choices, and development practices.
134+
> *Arrows follow the injection direction (A → B means A is injected into B). Solid = runtime dependency, dotted = structural. Blue = core domain, red = third-party, green = tests. Controllers call Services; Services call Repositories — bypassing layers is not permitted.*
135+
>
136+
> *Significant design decisions are documented as ADRs in [`adr/`](adr/README.md).*
224137
225138
## API Reference
226139

227140
Interactive API documentation is available via Swagger UI at `https://localhost:9000/swagger/index.html` when the server is running.
228141

229142
> 💡 Swagger documentation is only available in development mode for security reasons.
230143
231-
**Quick Reference:**
144+
| Method | Endpoint | Description | Status |
145+
| ------ | -------- | ----------- | ------ |
146+
| `GET` | `/players` | List all players | `200 OK` |
147+
| `GET` | `/players/{id:Guid}` | Get player by ID *(requires authentication)* | `200 OK` |
148+
| `GET` | `/players/squadNumber/{squadNumber:int}` | Get player by squad number | `200 OK` |
149+
| `POST` | `/players` | Create new player | `201 Created` |
150+
| `PUT` | `/players/squadNumber/{squadNumber:int}` | Update player by squad number | `200 OK` |
151+
| `DELETE` | `/players/squadNumber/{squadNumber:int}` | Remove player by squad number | `204 No Content` |
152+
| `GET` | `/health` | Health check | `200 OK` |
232153

233-
- `GET /players` - List all players
234-
- `GET /players/{id:Guid}` - Get player by ID (requires authentication)
235-
- `GET /players/squadNumber/{squadNumber:int}` - Get player by squad number
236-
- `POST /players` - Create new player
237-
- `PUT /players/squadNumber/{squadNumber:int}` - Update player
238-
- `DELETE /players/squadNumber/{squadNumber:int}` - Remove player
239-
- `GET /health` - Health check
154+
Error codes: `400 Bad Request` (validation failed) · `404 Not Found` (player not found) · `409 Conflict` (duplicate squad number on `POST`)
240155

241156
For complete endpoint documentation with request/response schemas, explore the [interactive Swagger UI](https://localhost:9000/swagger/index.html).
242157

@@ -275,24 +190,6 @@ The server will start on `https://localhost:9000`.
275190
- Swagger Documentation: `https://localhost:9000/swagger/index.html`
276191
- Health Check: `https://localhost:9000/health`
277192

278-
## Testing
279-
280-
Run the test suite with xUnit:
281-
282-
```bash
283-
# Run all tests
284-
dotnet test
285-
286-
# Run tests with coverage report
287-
dotnet test --results-directory "coverage" --collect:"XPlat Code Coverage" --settings .runsettings
288-
289-
# View coverage report
290-
dotnet tool install --global dotnet-reportgenerator-globaltool
291-
reportgenerator -reports:coverage/**/coverage.cobertura.xml -targetdir:coverage -reporttypes:Html
292-
```
293-
294-
Tests are located in the `test/` directory and use xUnit for unit testing. Coverage reports are generated for controllers and services only.
295-
296193
## Containers
297194

298195
This project includes full Docker support with multi-stage builds and Docker Compose for easy deployment.
@@ -327,56 +224,7 @@ docker compose down -v
327224

328225
The containerized application runs on port 9000 and includes health checks that monitor the `/health` endpoint.
329226

330-
## Releases
331-
332-
This project uses **stadium-themed release names** inspired by famous football stadiums that hosted FIFA World Cup matches. Each release is named after a stadium (A-Z alphabetically), making versions memorable and fun.
333-
334-
### Release Naming Convention
335-
336-
Releases follow the pattern: `v{SEMVER}-{STADIUM}` (e.g., `v1.0.0-azteca`)
337-
338-
- **Semantic Version**: Standard versioning (MAJOR.MINOR.PATCH)
339-
- **Stadium Name**: Alphabetically ordered codename from the [stadium list](CHANGELOG.md#stadium-release-names)
340-
341-
### Create a Release
342-
343-
To create a new release, follow this workflow:
344-
345-
#### 1. Update CHANGELOG.md
346-
347-
First, create a `release/` branch and document your changes in [CHANGELOG.md](CHANGELOG.md):
348-
349-
```bash
350-
git checkout -b release/1.0.0-azteca
351-
# Move items from [Unreleased] to new release section
352-
# Example: [1.0.0 - azteca] - 2026-01-22
353-
git add CHANGELOG.md
354-
git commit -m "docs: prepare changelog for v1.0.0-azteca release"
355-
git push origin release/1.0.0-azteca
356-
# Open a PR, get it reviewed, and merge into master
357-
```
358-
359-
#### 2. Create and Push Tag
360-
361-
Then create and push the version tag:
362-
363-
```bash
364-
git tag -a v1.0.0-azteca -m "Release 1.0.0 - Azteca"
365-
git push origin v1.0.0-azteca
366-
```
367-
368-
#### 3. Automated CD Workflow
369-
370-
This triggers the CD workflow which automatically:
371-
372-
1. Validates the stadium name
373-
2. Builds and tests the project in Release configuration
374-
3. Publishes Docker images to GitHub Container Registry with three tags
375-
4. Creates a GitHub Release with auto-generated changelog from commits
376-
377-
> 💡 Always update CHANGELOG.md before creating the tag. See [CHANGELOG.md](CHANGELOG.md#how-to-release) for detailed release instructions.
378-
379-
### Pull Docker Images
227+
### Pull Docker images
380228

381229
Each release publishes multiple tags for flexibility:
382230

@@ -391,8 +239,6 @@ docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:azteca
391239
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:latest
392240
```
393241

394-
> 💡 See [CHANGELOG.md](CHANGELOG.md) for the complete stadium list (A-Z) and release history.
395-
396242
## Environment Variables
397243

398244
The application can be configured using environment variables for different scenarios:
@@ -427,6 +273,29 @@ STORAGE_PATH=/storage/players-sqlite3.db
427273

428274
> 💡 Additional environment variables (`ASPNETCORE_ENVIRONMENT=Production` and `ASPNETCORE_URLS=http://+:9000`) are set in the `Dockerfile`.
429275
276+
## Contributing
277+
278+
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduct and the process for submitting pull requests.
279+
280+
**Key guidelines:**
281+
282+
- Follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
283+
- Ensure all tests pass (`dotnet test`)
284+
- Keep changes small and focused
285+
- Review [.github/copilot-instructions.md](.github/copilot-instructions.md) for architectural patterns
286+
287+
**Testing:**
288+
289+
Run the test suite with xUnit:
290+
291+
```bash
292+
# Run all tests
293+
dotnet test
294+
295+
# Run tests with coverage report
296+
dotnet test --results-directory "coverage" --collect:"XPlat Code Coverage" --settings .runsettings
297+
```
298+
430299
## Command Summary
431300

432301
| Command | Description |
@@ -443,17 +312,9 @@ STORAGE_PATH=/storage/players-sqlite3.db
443312
| `docker compose up` | Start Docker container |
444313
| `docker compose down` | Stop Docker container |
445314
| `docker compose down -v` | Stop and remove Docker volume |
446-
447-
## Contributing
448-
449-
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduct and the process for submitting pull requests.
450-
451-
**Key guidelines:**
452-
453-
- Follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
454-
- Ensure all tests pass (`dotnet test`)
455-
- Keep changes small and focused
456-
- Review [.github/copilot-instructions.md](.github/copilot-instructions.md) for architectural patterns
315+
| **AI Commands** | |
316+
| `/pre-commit` | Runs linting, tests, and quality checks before committing |
317+
| `/pre-release` | Runs pre-release validation workflow |
457318

458319
## Legal
459320

RELEASES.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Releases
2+
3+
Releases follow the pattern `v{SEMVER}-{STADIUM}` (e.g., `v1.0.0-azteca`). Codenames are drawn alphabetically from the [stadium list](CHANGELOG.md#stadium-release-names) of famous football stadiums that hosted FIFA World Cup matches.
4+
5+
## Workflow
6+
7+
### 1. Create a Release Branch
8+
9+
Branch protection prevents direct pushes to `master`, so all release prep goes through a PR:
10+
11+
```bash
12+
git checkout master && git pull
13+
git checkout -b release/v1.0.0-azteca
14+
```
15+
16+
### 2. Update CHANGELOG.md
17+
18+
Move items from `[Unreleased]` to a new release section in [CHANGELOG.md](CHANGELOG.md):
19+
20+
```bash
21+
# Move items from [Unreleased] to new release section
22+
# Example: [1.0.0 - azteca] - 2026-01-22
23+
git add CHANGELOG.md
24+
git commit -m "docs: prepare changelog for v1.0.0-azteca release"
25+
git push origin release/v1.0.0-azteca
26+
# Open a PR, get it reviewed, and merge into master
27+
```
28+
29+
### Pre-release Checklist
30+
31+
Before creating the tag, verify all of the following:
32+
33+
- [ ] `CHANGELOG.md` `[Unreleased]` section is moved to a new versioned release entry
34+
- [ ] `dotnet build --configuration Release` passes
35+
- [ ] `dotnet test --settings .runsettings` passes
36+
- [ ] Stadium name is valid and follows alphabetical order (see [stadium list](CHANGELOG.md#stadium-release-names))
37+
- [ ] All CI checks on `master` are green
38+
39+
### 3. Create and Push Tag
40+
41+
After the PR is merged, create and push the version tag from `master`:
42+
43+
```bash
44+
git checkout master && git pull
45+
git tag -a v1.0.0-azteca -m "Release 1.0.0 - Azteca"
46+
git push origin v1.0.0-azteca
47+
```
48+
49+
### 4. Automated CD Workflow
50+
51+
Pushing the tag triggers the CD workflow which automatically:
52+
53+
1. Validates the stadium name
54+
2. Builds and tests the project in Release configuration
55+
3. Publishes Docker images to GitHub Container Registry with three tags
56+
4. Creates a GitHub Release with auto-generated changelog from commits
57+
58+
> 💡 Always update CHANGELOG.md before creating the tag. See [CHANGELOG.md](CHANGELOG.md) for the complete stadium list (A-Z) and release history.
59+
60+
## Docker Pull
61+
62+
Each release publishes multiple tags for flexibility:
63+
64+
```bash
65+
# By semantic version (recommended for production)
66+
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:1.0.0
67+
68+
# By stadium name (memorable alternative)
69+
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:azteca
70+
71+
# Latest release
72+
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:latest
73+
```

0 commit comments

Comments
 (0)