Task Management REST API
Advanced Project — Clean Architecture, JWT Auth, EF Core, Testing
🧠 Project Overview
Build a production-grade task management REST API using ASP.NET Core with Clean Architecture. This project demonstrates every core backend skill: authentication, database access, business logic, validation, and testing.
🎯 Requirements
- • CRUD operations for tasks with filtering and pagination
- • JWT authentication — register, login, refresh tokens
- • Role-based authorization (Admin vs User)
- • EF Core with repository pattern and migrations
- • Input validation with FluentValidation
- • Unit tests for all use case handlers
- • Swagger/OpenAPI documentation
Step 1: Domain Entity
Start with the domain entity — it enforces business rules and is independent of any framework.
TodoItem Entity
Domain entity with factory method, validation, and state transitions.
// Domain/Entities/TodoItem.cs
public class TodoItem
{
public Guid Id { get; private set; }
public string Title { get; private set; } = "";
public string? Description { get; private set; }
public bool IsCompleted { get; private set; }
public Priority Priority { get; private set; }
public DateTime CreatedAt { get; private set; }
public DateTime? CompletedAt { get; private set; }
public string UserId { get; private set; } = "";
public static TodoItem Create(str
...Step 2: API Controller
The controller is thin — it delegates to use case handlers via MediatR and extracts the user ID from the JWT claims.
TodoController
Thin API controller with JWT-based user identification.
// Api/Controllers/TodoController.cs
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class TodoController : ControllerBase
{
private readonly IMediator _mediator;
public TodoController(IMediator mediator) => _mediator = mediator;
[HttpGet]
public async Task<IActionResult> GetAll([FromQuery] TodoFilter filter)
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
var result = await _mediator.Send(
new GetTodosQuery(userId
...Step 3: Unit Tests
Test every use case handler with Moq. Verify that domain rules are enforced and repositories are called correctly.
Unit Tests with Moq
Test the CreateTodo handler with mocked repository.
// Tests/TodoServiceTests.cs
using Moq;
using Xunit;
public class CreateTodoHandlerTests
{
private readonly Mock<ITodoRepository> _mockRepo;
private readonly CreateTodoHandler _handler;
public CreateTodoHandlerTests()
{
_mockRepo = new Mock<ITodoRepository>();
_handler = new CreateTodoHandler(_mockRepo.Object);
}
[Fact]
public async Task Handle_ValidCommand_CreatesTodo()
{
var command = new CreateTodoCommand(
"Buy groceries",
...Challenge Complete Checklist
- ☐ All CRUD endpoints work with Swagger
- ☐ JWT auth protects all endpoints
- ☐ Admin role can see all tasks; users see only their own
- ☐ 80%+ unit test coverage
- ☐ Published to GitHub with README