An inventory management system built with .NET 10 and Angular, following clean architecture principles with CQRS.
Ivan is a full-stack inventory management application that tracks containers and items. The system is built using:
- Backend: ASP.NET Core Web API
- Frontend: Angular 19 with Bootstrap 5
- Database: SQL Server with Entity Framework Core
- Caching: Redis
- Messaging: RabbitMQ
- Testing: NUnit, Jasmine/Karma, Testcontainers
- .NET 10 SDK
- Node.js 18+ (with npm)
- Docker Desktop
- Google Chrome (for Angular tests)
- PowerShell
-
Clone the repository
git clone <repository-url> cd inventory-management
-
Install development tools
.\scripts\install_tools.ps1
This installs EF Core tools and Angular dependencies.
-
Start infrastructure services
cd environments\local .\provision.ps1
This starts SQL Server, Redis, RabbitMQ, and Redis Insight via Docker Compose.
-
Build and run tests
.\scripts\private_build.ps1
Backend API:
dotnet run --project src\Presentation\WebAPIThe API will be available at https://localhost:5000.
Frontend (Angular):
cd src\Presentation\webapp
npm startThe Angular app will be available at http://localhost:4200.
When modifying domain entities or database mappings, create a new EF Core migration:
.\scripts\add_migration.ps1 -MigrationName <MigrationName>Migrations are generated in src/Infrastructure/SQLServer/Migrations/. The migration is automatically applied when the application starts.
| Script | Description |
|---|---|
scripts\install_tools.ps1 |
Install EF Core tools and Angular dependencies |
scripts\private_build.ps1 |
Build Angular app, build solution, and run all tests |
scripts\add_migration.ps1 -MigrationName <name> |
Add a new EF Core migration |
environments\local\provision.ps1 |
Start local infrastructure via Docker |
After running provision.ps1, these services are available:
| Service | URL/Port | Credentials |
|---|---|---|
| SQL Server | localhost:1433 |
sa / (see local.config.json) |
| RabbitMQ | localhost:5672 |
admin / (see local.config.json) |
| RabbitMQ Management | localhost:15672 |
admin / (see local.config.json) |
| Redis | localhost:6379 |
- |
| Redis Insight | localhost:5540 |
- |
The project follows clean/onion architecture with CQRS (Command Query Responsibility Segregation).
src/
├── Core/
│ ├── Domain/ # Domain entities (no dependencies)
│ └── Application/ # Features, DTOs, interfaces (depends on Domain)
│
├── Infrastructure/
│ ├── Bootstrap/ # Dependency injection configuration
│ ├── SQLServer/ # EF Core repository implementation
│ ├── Redis/ # Cache implementation
│ └── RabbitMQ/ # Event hub implementation
│
├── Presentation/
│ ├── WebAPI/ # ASP.NET Core Web API
│ └── webapp/ # Angular application
│
└── Tests/
├── UnitTests/ # Isolated unit tests with mocks (NUnit)
└── IntegrationTests/ # Component tests with Testcontainers (NUnit)
The Angular application includes its own component tests using Jasmine/Karma.
Dependencies point inward—outer layers depend on inner layers:
Presentation → Infrastructure → Application → Domain
Features are organized by domain concept with commands and handlers:
Application/Features/{Entity}/
├── {Entity}s.cs # Facade
├── I{Entity}s.cs # Facade interface
└── {Action}{Entity}/
├── {Action}{Entity}Command.cs # Command request
├── {Action}{Entity}CommandHandler.cs
└── I{Action}{Entity}CommandHandler.cs
Request flow:
API Request → Command/Query → Handler → DTO → API Response
The Angular frontend communicates with the .NET WebAPI via HTTP:
- Development: Angular uses the API URL configured in
src/environments/environment.ts - Production: Configure the API URL in
src/environments/environment.prod.ts
Configuration is layered by environment:
environments/
├── global.config.json # Shared settings (project name, database name)
└── local/
├── local.config.json # Local environment settings
├── docker-compose.yml # Infrastructure services
└── init-db.sql # Database initialization
The Angular app is located at src/Presentation/webapp/ and uses:
- Angular 19 with standalone components
- Bootstrap 5 for styling
- RxJS for reactive programming
- Jasmine/Karma for component testing
Key directories:
src/app/components/- UI components (nav, home, modals)src/app/services/- HTTP services for API communicationsrc/app/models/- TypeScript interfaces for API contractssrc/environments/- Environment-specific configuration
The project uses a layered testing strategy:
Located in src/Tests/UnitTests/. Test isolated behavior using mocks.
dotnet test src/Tests/UnitTestsLocated in src/Tests/IntegrationTests/. Test components with real infrastructure using Testcontainers.
dotnet test src/Tests/IntegrationTestsLocated alongside components in src/Presentation/webapp/src/app/. Test UI components with Jasmine/Karma.
cd src/Presentation/webapp
npm test -- --watch=false --browsers=ChromeHeadless.\scripts\private_build.ps1This runs all test suites: .NET unit tests, .NET integration tests, and Angular component tests.
This repository uses a Cursor Cloud Agent to automatically review pull requests when they are marked ready for review.
- When a PR targeting
masteris marked "Ready for review", a GitHub Action triggers - The action spawns a Cursor Cloud Agent via the API
- The agent reviews the PR against the checklist in the PR template
- The agent references the linked issue to understand requirements
- The agent posts a review comment with findings and either approves or requests changes
All PRs should use the template at .github/PULL_REQUEST_TEMPLATE.md, which includes:
- Summary and related issue sections
- Comprehensive review checklist covering architecture, testing, documentation, and code quality
- Reviewer notes section for additional context
- PRs must target the
masterbranch - PRs must link to an issue using "Closes #[issue-number]"
- The
CURSOR_API_KEYsecret must be configured in the repository
When a PR review requests changes, a Cursor Cloud Agent can automatically implement the fixes.
- When a reviewer requests changes, the PR is converted to draft
- The
converted_to_draftevent triggers a GitHub Action - The action spawns a Cursor Cloud Agent via the API
- The agent reads all review comments and implements the requested changes
- The agent commits and pushes fixes to the PR branch
- The agent posts a summary comment and marks the PR ready for review
- Review phase: Agent reviews PR and requests changes (converts to draft)
- Implementation phase: Agent implements requested changes automatically
- Re-review phase: Agent reviews the updated PR
- Cycle continues until PR is approved or requires manual intervention
- PRs must target the
masterbranch - PR must have review comments with requested changes
- The
CURSOR_API_KEYsecret must be configured in the repository
This repository includes configuration for Cursor AI-assisted development in the .cursor/rules/ directory. These rules ensure consistent code quality and workflow adherence.
| Rule File | Purpose |
|---|---|
architecture-rules.mdc |
Layer boundaries and CQRS patterns |
automated-testing-rules.mdc |
Required test coverage and testing guidelines |
code-review-rules.mdc |
Automated PR review process and checklist |
implement-changes-rules.mdc |
Automated implementation of requested PR changes |
github-issue-rules.mdc |
Issue creation interview process |
github-issue-implementation-rules.mdc |
Phase workflow for implementing issues |
cursor-cloud-agent.mdc |
Operational constraints for Cloud Agent |
When using Cursor to contribute, the AI will automatically follow these rules to maintain project standards.