A backend API built with ASP.NET Core, focusing on authentication, transactional consistency, and pragmatic domain-driven design. This project is intentionally backend-only and emphasizes architectural clarity over feature breadth.
This project addresses common real-world backend concerns:
- Stateless authentication using JWT
- Avoiding fat controllers and anemic domain models
- Ensuring domain side effects are consistent with database transactions
Constraints considered:
- No UI layer
- Single database (no microservices, no distributed transactions)
- Focus on correctness and maintainability rather than premature optimization
The solution follows Clean Architecture with a DDD‑lite approach:
TaskMind
├─ Domain Layer
│ ├─ TaskMind.Domain.Commons
│ ├─ TaskMind.Domain.Entities
│ ├─ TaskMind.Domain.Events
│ ├─ TaskMind.Domain.ObjectValue
│ └─ TaskMind.Domain.Enums
├─ Application Layer
│ ├─ TaskMind.Application.Commons
| | ├─ Interfaces
| | └─ Results
│ ├─ TaskMind.Application.Events
│ └─ TaskMind.Application.Services
| └─ Users
| ├─ IRequests
| ├─ IHandlers
| └─ Dtos
├─ Infrastructure Layer
│ ├─ Persistence (EF Core)
│ └─ Implementations
└─ Presentation Layer
├─ TaskMind.Auth.APIS
| ├─ Controllers
| ├─ Middlewares
| └─ Config
└─ TaskMind.Cases.APIS
├─ Controllers
├─ Middlewares
└─ Config
Layering rules:
- Domain has no dependency on any framework
- Application orchestrates use cases
- Infrastructure provides implementations
- Presentation is a thin HTTP layer
The domain layer contains:
- Rich entities encapsulating business rules
- Explicit domain events representing meaningful state changes
Example intentions:
UserLoggedInEventUserChangePasswordEvent
Domain entities do not depend on MediatR or EF Core. Events are simple C# objects.
Domain events are used to:
- Capture business-relevant occurrences
- Decouple side effects from core domain logic
Design decisions:
- Domain events are raised inside entities
- Events are collected during the transaction
- Event dispatching is orchestrated in the Application layer after persistence succeeds.
This prevents:
- Sending notifications for failed transactions
- Logging or auditing inconsistent state
The application layer:
- Implements use cases via command/query handlers
- Coordinates domain entities and repositories
- Dispatches domain events through MediatR
Rules:
- MediatR exists only in the Application layer
- Handlers may interact with infrastructure via interfaces
- No business logic in controllers
Authentication is implemented using:
- Short‑lived JWT access tokens
Key behaviors:
- Login issues access + token
Security considerations:
- Swagger UI is configured to reflect authentication behavior correctly
Persistence is handled with EF Core:
- Explicit Unit of Work abstraction
- Single transaction per request
- Domain events dispatched post‑commit
This ensures:
- Consistent state changes
- No side effects on failed database operations
API behavior is standardized:
- Global exception middleware
- Explicit handling for authentication / authorization failures
- Predictable HTTP response shapes
Controllers are intentionally thin and delegate all logic to the application layer.
This project intentionally does NOT include:
- Frontend or UI concerns
- CQRS read‑model optimizations
- Distributed caching
- Microservices or message brokers
These are postponed to avoid unnecessary complexity.
This project demonstrates:
- Clean Architecture in a real ASP.NET Core API
- Practical use of domain events
- JWT & refresh token security design
- Transactional consistency with EF Core
- Pragmatic DDD (non‑dogmatic)
dotnet restore
dotnet ef database update
dotnet run