A vertical-slice architecture Blazor Server application for managing banking agency operations in Uganda.
- Framework: ASP.NET Core Blazor Server (.NET 10)
- Database: PostgreSQL
- Authentication: ASP.NET Identity
- UI: MudBlazor
- Real-time: SignalR
- Architecture: Vertical Slice Architecture
- .NET 10.0 SDK
- Docker & Docker Compose (for PostgreSQL)
- Visual Studio Code (Recommended)
-
Configure environment variables:
cp .env.example .env # Edit .env and set POSTGRES_PASSWORD -
Start PostgreSQL Container:
docker-compose up -d
-
Verify PostgreSQL Connection:
docker-compose exec postgres psql -U $POSTGRES_USER -d agenti_dev -c "SELECT 1"
-
Apply Database Migrations:
cd EastSeat.Agenti.Web dotnet ef database update -
Run the Application:
dotnet run
The application will be available at:
https://localhost:7001
Database credentials are stored in a .env file (not committed to version control).
- Copy the example file:
cp .env.example .env - Edit
.envand set your password - The connection string format is:
Server=localhost;Port=5432;Database=agenti_dev;User Id=<user>;Password=<password>;
The project uses GitHub Actions for continuous integration and deployment to Azure.
| Stage | Trigger | Description |
|---|---|---|
| Build | All branches | Restores, builds, and publishes the application |
| Unit Tests | All branches | Runs unit tests with code coverage |
| Integration Tests | All branches | Runs integration tests against PostgreSQL |
| E2E Tests | All branches | Runs end-to-end tests |
| Deploy | main branch only |
Deploys to Azure App Service |
| Resource | SKU | Est. Cost |
|---|---|---|
| App Service Plan | Basic B1 | ~$13/month |
| Container Instance (PostgreSQL) | 1 vCPU, 1.5GB | ~$10/month |
-
Run the infrastructure setup script:
cd scripts/azure .\setup-infrastructure.ps1 -PostgresPassword "YourSecurePassword123!"
-
Configure GitHub secrets - see setup-secrets.md
| Secret | Description |
|---|---|
AZURE_CREDENTIALS |
Azure service principal JSON for deployment |
Features/ # Vertical slices (feature modules)
├── Authentication/ # Auth & Identity management
├── WalletCatalog/ # Wallet type management
├── DailyCashSession/ # Daily session opening/closing
├── CashCounts/ # Cash count recording
├── Transactions/ # Movement between wallets
├── DiscrepancyWorkflow/ # Discrepancy explanation & approval
├── Notifications/ # SignalR notifications
└── Reporting/ # Reports & analytics
Shared/ # Cross-cutting concerns
├── Domain/ # Domain entities & enums
├── Infrastructure/ # DbContext, migrations
├── Exceptions/ # Custom exceptions
├── Middleware/ # Middleware components
├── Security/ # Auth/authorization
└── SignalR/ # Real-time hubs
Components/ # Global Blazor components
Pages/ # Global pages
Layouts/ # Global layouts
Data/ # Database context & migrations
- ✅ Daily Opening Cash Count
- ✅ Daily Closing Cash Count
- ✅ Wallet Management (predefined + custom types)
- ✅ Transaction Recording
- ✅ Discrepancy Detection & Explanation
- ✅ Supervisor Approval Workflow
- ✅ ASP.NET Identity Authentication
- ✅ Basic Reporting
- ✅ Real-time Notifications (SignalR)
- Opening Count Validation: Today's opening total = Previous day's closing total
- Closing Count Validation: Closing total = Opening total (float conservation)
- Discrepancy Workflow: Mismatches require teller explanation + supervisor approval
- Transaction Integrity: Movements between wallets don't change total float
- Each slice is independent with its own Models, Services, Components, and Validators
- Shared domain entities live in
Shared/Domain/Entities/ - Database configuration is in
Data/ApplicationDbContext.cs - Cross-slice communication via querier interfaces
- Phase 2: Multi-branch support, advanced analytics
- Phase 3: Mobile app, offline support (PWA)
- Phase 4: API layer, third-party integrations