Skip to content

Latest commit

 

History

History
76 lines (49 loc) · 3.25 KB

File metadata and controls

76 lines (49 loc) · 3.25 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

All commands run from backend/.

# Build
dotnet build TaskManagement.sln

# Run API (requires SQL Server on localhost:1433)
dotnet run --project TaskManagement.Api

# Run all tests
dotnet test TaskManagement.sln --nologo

# Run a single test project
dotnet test TaskManagement.Domain.Tests --nologo
dotnet test TaskManagement.Api.Tests --nologo

# Run a single test by name filter
dotnet test TaskManagement.Domain.Tests --filter "FullyQualifiedName~Constructor_WithEmptyTitle"

# Apply EF Core migrations
dotnet ef database update --project TaskManagement.Infrastructure --startup-project TaskManagement.Api

# Add a new migration
dotnet ef migrations add <MigrationName> --project TaskManagement.Infrastructure --startup-project TaskManagement.Api

The API starts at https://localhost:7xxx with Swagger UI at /swagger.

Database connection (SQL Server via Docker or localdb):

Server=localhost,1433;Database=TaskManagementDb;User Id=sa;Password=admin@123;TrustServerCertificate=True

Architecture

Clean Architecture with four projects:

Domain → Application → Infrastructure
                   ↘ Api ↙
  • DomainTaskItem entity, TaskItemStatus/TaskPriority enums, DomainException/DomainValidationException. No external dependencies. All validation and domain rules live here.
  • ApplicationITaskItemService / TaskItemService, ITaskItemRepository (interface only), request/response DTOs (C# records). Depends on Domain only.
  • InfrastructureTaskManagementDbContext, TaskItemRepository, EF Core entity configuration, migrations, and 10-row seed data. Depends on Application.
  • ApiTasksController, GlobalExceptionHandler, Swagger wiring. Depends on Application; references Infrastructure only for DI registration.

Key patterns

Domain modelTaskItem is a rich entity. Mutations go through named methods (UpdateDetails, ChangeStatus, ChangePriority, Reassign, SoftDelete). All mutators call EnsureNotDeleted() first and stamp ModifiedDate. Never set properties directly from outside the entity.

Soft deleteIsDeleted flag. EF Core global query filter on TaskManagementDbContext excludes deleted rows automatically. The DELETE /api/tasks/{id} endpoint calls SoftDelete(), not a database delete.

Exception → HTTP mappingGlobalExceptionHandler (implements IExceptionHandler) maps domain exceptions:

  • DomainValidationException → 400
  • DomainException → 409
  • KeyNotFoundException → 404
  • Default → 500

All error responses use the ErrorResponse record: { Status, Title, Detail, TraceId }.

Summary endpointGET /api/tasks/summary uses a raw SQL query (not EF) in TaskItemRepository.GetSummaryAsync() to return task counts grouped by status and priority.

Repository orderingGetAllAsync orders results: Priority DESC → Status ASC → CreatedDate DESC.

Testing

Tests use NUnit 3 with [TestFixture] / [Test] / [TestCase]. The single test project TaskManagement.Domain.Tests covers only the Domain layer. Use Assert.Multiple when asserting several independent properties in one test.