Develop a production-ready Customer Relationship Management (CRM) system implementing Domain-Driven Design (DDD), Command Query Responsibility Segregation (CQRS), and Clean Architecture principles. This document outlines the technical specifications, architectural patterns, and implementation requirements.
The system must provide:
- Complete Customer management functionality (CRUD operations)
- Strict enforcement of business rules for data integrity
- Event-driven architecture for system extensibility
- Soft-deletion mechanism for data retention
- Clean separation of concerns across architectural layers
- RESTful API endpoints for all customer operations
- Appropriate error handling and validation
-
Backend:
- .NET 9.0
- Entity Framework Core 9.0
- Dapper for queries
- SQL Server (or PostgreSQL with minimal changes)
- MediatR for CQRS implementation
- FluentValidation for validation
- Serilog for logging
- xUnit, Moq, and FluentAssertions for testing (for integration or end-to-end tests use TestContainers on docker)
-
Development Tools:
- Visual Studio or JetBrains Rider
- Deployment using Docker for containerization or .NET ASPIRE
- Git for version control
The solution must strictly adhere to a clean, onion architecture with the following layers:
Implement the domain layer with the following components:
-
Aggregate Roots:
- Create a
Customeraggregate root that inherits from a genericAggregateRoot<TId>base class - Implement soft-delete capability via
ISoftDeleteinterface - Encapsulate all domain logic and state changes in the aggregate
- Create a
-
Value Objects:
- Create strongly-typed, immutable value objects for all customer properties:
FirstName: String with appropriate validationLastName: String with appropriate validationDateOfBirth: Date type with age validationPhoneNumber: Complex type with country code and number partsEmail: String with email format validationBankAccountNumber: String with appropriate format validation
- Implement
ValueObjectbase class with equality comparison based on property values
- Create strongly-typed, immutable value objects for all customer properties:
-
Domain Events:
- Implement the following domain events:
CustomerCreatedDomainEventCustomerUpdatedDomainEventCustomerDeletedDomainEventCustomerRestoredDomainEvent
- Events must capture all relevant state changes
- Implement the following domain events:
-
Business Rules:
- Implement validation rules as separate classes adhering to
IBusinessRuleinterface:CustomerEmailMustBeUniqueRule: Ensures email uniquenessCustomerPersonalInfoMustBeUniqueRule: Ensures no duplicate customers with same name and birth date
- Rules must be checked during both creation and updates
- Implement validation rules as separate classes adhering to
-
Domain Services:
- Implement
ICustomerUniquenessCheckerServicefor validating customer uniqueness constraints - Domain services must be abstracted through interfaces
- Implement
Implement the application layer with these components:
-
Commands:
CreateCustomerCommand: Creates a new customerUpdateCustomerCommand: Updates an existing customerDeleteCustomerCommand: Soft-deletes a customerRestoreCustomerCommand: Restores a soft-deleted customer- All commands must include appropriate validation
-
Command Handlers:
- Implement handlers for each command
- Handlers must orchestrate domain operations and persistence
-
Queries:
GetCustomerByIdQuery: Gets customer by IDGetCustomersListQuery: Gets paginated list of customersGetCustomerByEmailQuery: Gets customer by email
-
Query Handlers:
- Implement handlers for each query
- Return appropriate DTO models, not domain entities
-
DTOs:
- Create data transfer objects for all API responses
- DTOs must not expose domain implementation details
-
Behaviors:
- Implement cross-cutting concerns as MediatR behaviors:
ValidationBehavior: For FluentValidation integrationLoggingBehavior: For command/query execution logging
- Implement cross-cutting concerns as MediatR behaviors:
Implement the infrastructure layer with these components:
-
Persistence:
- Entity Framework Core DbContext
- Repository implementations
- Entity configurations and mappings
- Migration scripts
-
Processing:
- Domain event dispatching
- Background jobs (if needed)
-
Resilience:
- Retry policies for external service calls
- Circuit breaker patterns
-
Serialization:
- JSON serialization configuration
Implement the presentation layer with these components:
- API Controllers:
- RESTful endpoints for all customer operations
- Proper status codes and error responses
- API documentation via Swagger
The Customer aggregate must:
- Be implemented as a rich domain model with encapsulated business logic
- Have private setters for all properties to enforce invariants
- Use factory methods for creation with full validation
- Implement the following public methods:
Create: Static factory method that validates and creates a new customerChangeAttribute: Updates customer properties with full validationDelete: Implements soft-deletionRestore: Reverts soft-deletion
Example signature for the Create method:
public static Customer Create(
FirstName firstName,
LastName lastName,
DateOfBirth dateOfBirth,
PhoneNumber phoneNumber,
Email email,
BankAccountNumber bankAccountNumber,
ICustomerUniquenessCheckerService customerUniquenessCheckerService
);Domain events must:
- Inherit from a common
DomainEventBaseclass - Be raised during appropriate state changes in the aggregate
- Contain all relevant information about the state change
- Be handled by separate event handlers in the application layer
Business rules must:
- Be implemented as separate classes implementing
IBusinessRuleinterface - Have an
IsBroken()method that returns a boolean - Provide a meaningful error message when broken
- Be checked during domain operations using a
CheckRulemethod
CQRS implementation must:
- Strictly separate commands (write operations) from queries (read operations)
- Use MediatR as the mediator pattern implementation
- Implement commands as request objects with validators
- Implement queries as request objects with handlers
- Return Result objects from command handlers
- Return DTOs from query handlers
Validation must be implemented at multiple levels:
- Domain-level validation through business rules
- Application-level validation through FluentValidation
- API-level validation through ModelState validation
- Infrastructure-level validation through database constraints
Implement comprehensive test suite including:
-
Unit Tests:
- Domain logic testing
- Command and query handler testing
- Validation testing
-
Integration Tests:
- Repository testing
- API controller testing
-
End-to-End Tests:
- Complete API flow testing
- Complete .NET solution with all components described above
- Database initialization and migration scripts
- Docker containerization
- Comprehensive test suite
- API documentation with Swagger
- Deployment instructions
- Code documentation
The solution will be accepted when:
- All CRUD operations for customers function correctly
- All business rules are properly enforced
- All tests pass with >90% code coverage
- The solution follows the specified architecture
- The API is properly documented
- The solution can be deployed using the provided instructions
- Day 1: Core domain models and business rules
- Day 2: Application layer and CQRS implementation
- Day 3: Infrastructure layer implementation
- Day 4: API and presentation layer
- Day 5: Testing
- Day 6: Deployment
- Day 7: Refactoring and documentation
The solution should adhere to this architectural structure:
src/
├── Core/
│ ├── Domain/
│ │ ├── Aggregates/
│ │ │ └── Customer/
│ │ │ ├── Entities/
│ │ │ ├── ValueObjects/
│ │ │ ├── Events/
│ │ │ ├── Rules/
│ │ │ ├── Services/
│ │ │ └── Specifications/
│ │ ├── SeedWork/
│ │ │ ├── Primitives/
│ │ │ ├── Events/
│ │ │ └── Specification/
│ │ └── SharedKernel/
│ └── Application/
│ ├── Features/
│ │ └── Customer/
│ │ ├── Commands/
│ │ ├── Queries/
│ │ └── Models/
│ └── Behaviors/
├── Infrastructure/
│ └── Persistence/
│ ├── Context/
│ ├── Repositories/
│ └── EntityConfiguration/
└── Presentation/
└── API/
├── Controllers/
└── Filters/
This project follows strict contribution guidelines to maintain code quality and consistency. See CONTRIBUTION.md for full details.
- Create an Issue
- Create a Branch
- Make Changes & Commit
- Create Pull Request
- Address Reviews
- Merge & Release
All branches should follow this format:
<type>([optional-scope])/descriptive-name
Example branch names:
feat/user-authfix/login-errordocs/api-guiderefactor/auth-flow
We follow Conventional Commits with the following format:
type(scope): <emoji> <description>
- feat:
feat: 🚀 implement user authentication - fix:
fix: 🐛 resolve login timeout issue - docs:
docs: 📄 update API documentation - refactor:
refactor: ♻️ simplify authentication flow - test:
test: 🧪 add integration tests - chore:
chore: 🧰 clean unused code - style:
style: 🎨 format JavaScript files - perf:
perf: ⚡️ optimize database queries - build:
build: 🏗️ update webpack configuration - ci:
ci: 👷 setup GitHub Actions - revert:
revert: ⏪️ revert user authentication
- Major (1.x.x): Breaking changes (with
breaking-changeslabel or!notation) - Minor (x.1.x): New features (
feattype) - Patch (x.x.1): Bug fixes and other changes
- Keep commits atomic and focused
- Follow existing code style
- Add tests for new features
- Update documentation
- Use
dotnet formatanddotnet csharpier .before committing
As a developer implementing this project, follow these steps to submit your work:
-
Clone the repository:
git clone <repository-url> cd <repository-name>
-
Create a new branch for your implementation:
git checkout -b feat/customer-management-implementation
-
Implement the project following all the requirements specified in this document.
-
Make regular commits following the commit convention documented in the Contribution Guidelines:
git add . git commit -m "feat: 🚀 implement customer aggregate"
-
Push your changes to the remote repository:
git push origin feat/customer-management-implementation
-
Once implementation is complete, create a pull request to the main branch:
- Go to the repository on GitHub
- Click "Pull requests" > "New pull request"
- Set base branch to
mainand compare branch to yourfeat/customer-management-implementation - Click "Create pull request"
-
In the pull request description:
- Provide a summary of the implemented features
- Mention any design decisions or trade-offs made
- List any pending items or known issues
-
Add
pouryanoufallah96as a reviewer for your pull request -
Be prepared to address any feedback or requested changes from the reviewer
- The reviewer will assess your implementation against the requirements and acceptance criteria.
- You may need to make additional changes based on feedback.
- Once approved, your implementation will be merged into the main branch.