@@ -250,11 +250,119 @@ return player; // Let caller handle null
250250- Use route parameters for resource identification
251251- Apply validation before processing requests
252252
253+ ## 🛠️ Essential Commands & Workflows
254+
255+ ### Build & Run
256+ ``` bash
257+ # Build the solution
258+ dotnet build
259+
260+ # Run the API (hot reload enabled)
261+ dotnet watch run --project src/Dotnet.Samples.AspNetCore.WebApi/Dotnet.Samples.AspNetCore.WebApi.csproj
262+
263+ # Access Swagger UI (Development only)
264+ # https://localhost:9000/swagger/index.html
265+
266+ # Health check endpoint
267+ # https://localhost:9000/health
268+ ```
269+
270+ ### Testing
271+ ``` bash
272+ # Run all tests
273+ dotnet test
274+
275+ # Run tests with coverage
276+ dotnet test --results-directory " coverage" --collect:" XPlat Code Coverage" --settings .runsettings
277+
278+ # Run specific test category
279+ dotnet test --filter " Category=Unit"
280+ ```
281+
282+ ### Database Migrations
283+ ``` bash
284+ # Create a new migration
285+ dotnet ef migrations add < MigrationName> --project src/Dotnet.Samples.AspNetCore.WebApi
286+
287+ # Apply migrations
288+ dotnet ef database update --project src/Dotnet.Samples.AspNetCore.WebApi
289+
290+ # Regenerate database with seed data
291+ ./scripts/run-migrations-and-copy-database.sh
292+ ```
293+
294+ ** Important** : The ` run-migrations-and-copy-database.sh ` script:
295+ - Resets the placeholder database file
296+ - Runs all migrations
297+ - Copies the generated database from ` bin/Debug/net8.0/Data/ ` to ` Data/ `
298+ - Requires ` dotnet ef ` CLI tool installed globally
299+
300+ ### Docker Operations
301+ ``` bash
302+ # Build the image
303+ docker compose build
304+
305+ # Start the app (with persistent volume)
306+ docker compose up
307+
308+ # Stop the app (preserve data)
309+ docker compose down
310+
311+ # Reset database (removes volume)
312+ docker compose down -v
313+ ```
314+
315+ ** Important** : The SQLite database is stored in a Docker volume for persistence. First run copies a pre-seeded database from the image to the volume.
316+
317+ ### Rate Limiting
318+ - Configured via ` RateLimiter ` section in ` appsettings.json `
319+ - Default: 60 requests per 60 seconds (fixed window)
320+ - Queue limit: 0 (immediate rejection when limit reached)
321+
322+ ## 🚨 Common Issues & Workarounds
323+
324+ ### Database Path Issues
325+ - ** SQLite database location** : ` storage/players-sqlite3.db ` relative to binary output
326+ - ** Container storage** : ` /storage/players-sqlite3.db ` (mounted volume)
327+ - ** Environment variable** : ` STORAGE_PATH ` can override the default path in containers
328+
329+ ### Validation Patterns
330+ - ** FluentValidation** runs in the validator class for input format/structure
331+ - ** Business rule validation** (e.g., unique squad number check) happens in the service layer
332+ - This separation is intentional to keep validators focused on data structure, not business logic
333+
334+ ### Locking & Caching
335+ - ** DbContextPool** is used for performance - don't manually dispose DbContext
336+ - ** IMemoryCache** is cleared on data modifications using ` Remove(CacheKey_RetrieveAsync) `
337+ - Cache keys use ` nameof() ` for type safety
338+
339+ ### Test Configuration
340+ - Test coverage excludes test projects via ` .runsettings ` configuration
341+ - Coverage reports merge multiple Cobertura files into one
342+ - ` FluentAssertions ` and ` Moq ` are standard testing libraries
343+
344+ ## 📝 Commit Message Conventions
345+
346+ Follow ** Conventional Commits** (< https://www.conventionalcommits.org/ > ):
347+ - ` feat: ` - New features
348+ - ` fix: ` - Bug fixes
349+ - ` chore: ` - Maintenance tasks
350+ - ` docs: ` - Documentation changes
351+ - ` test: ` - Test additions or modifications
352+ - ` refactor: ` - Code restructuring without behavior change
353+
354+ ** Constraints** :
355+ - Header max length: 80 characters
356+ - Body max line length: 80 characters
357+ - Enforced via ` commitlint.config.mjs ` in CI/CD
358+
253359## 🚀 Future Evolution Considerations
254360
255- - ** Database Migration** : SQLite → PostgreSQL transition path
256- - ** Authentication** : JWT Bearer token implementation ready
257- - ** API Versioning** : URL-based versioning strategy
258- - ** OpenAPI** : Comprehensive Swagger documentation
259- - ** Monitoring** : Health checks and metrics endpoints
260- - ** Containerization** : Docker multi-stage builds optimized
361+ See open issues on GitHub for planned enhancements:
362+ - ** Clean Architecture Refactoring** ([ #266 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/266 ) ) - Migrate to Clean Architecture-inspired structure
363+ - ** PostgreSQL Support** ([ #249 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/249 ) ) - Add PostgreSQL to Docker Compose setup
364+ - ** .NET Aspire Integration** ([ #256 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/256 ) ) - Evaluate Aspire for dev-time orchestration and observability
365+ - ** JWT Authentication** ([ #105 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/105 ) ) - Implement Client Credentials Flow for protected routes
366+ - ** Global Exception Handling** ([ #184 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/184 ) ) - Add middleware with RFC 7807 Problem Details
367+ - ** Optimistic Concurrency** ([ #65 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/65 ) ) - Handle conflicts with application-managed tokens
368+ - ** Database Normalization** ([ #125 ] ( https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi/issues/125 ) ) - Extract Position, Team, League into separate tables
0 commit comments