VendorRiskScoringApp is a sample enterprise application built with .NET 8 and Angular for managing vendors and calculating vendor risk scores.
The project demonstrates layered backend architecture, CQRS-style application flow, Redis caching, PostgreSQL persistence, structured logging with Serilog, Elasticsearch/Kibana integration, Docker Compose setup, and automated tests.
- .NET 8 Web API backend
- Angular frontend
- PostgreSQL database
- Redis caching
- Elasticsearch and Kibana integration
- Serilog structured logging
- Correlation ID middleware
- Docker Compose based local setup
- EF Core migrations and sample data seeding
- Unit and integration test project
- Swagger API documentation
Backend: .NET 8, ASP.NET Core Web API, C#, MediatR, FluentValidation, Entity Framework Core, Serilog
Frontend: Angular, TypeScript, HTML, SCSS
Infrastructure: PostgreSQL, Redis, Elasticsearch, Kibana, Docker, Docker Compose
VendorRiskScoringApp/
├── frontend/
├── src/
│ ├── VendorRisk.Api/
│ ├── VendorRisk.Application/
│ ├── VendorRisk.Domain/
│ └── VendorRisk.Infrastructure/
├── tests/
│ └── VendorRisk.Tests/
├── docker-compose.yml
└── VendorRisk.sln
- .NET 8 SDK
- Docker
- Docker Compose
Clone the repository and navigate to the project folder:
git clone https://github.com/melihcantosun/VendorRiskScoringApp.git
cd VendorRiskScoringAppStart the application and required services:
docker-compose up --buildThe following services will be available:
| Service | URL / Port |
|---|---|
| API | http://localhost:5180 |
| Swagger | http://localhost:5180/swagger |
| PostgreSQL | localhost:5432 |
| Redis | localhost:6379 |
| Elasticsearch | http://localhost:9200 |
| Kibana | http://localhost:5601 |
Default PostgreSQL settings:
Username: postgres
Password: postgres
Database: vendorrisk_db
Make sure PostgreSQL and Redis are running locally, then update the connection strings if needed.
Default development connection strings are located in:
src/VendorRisk.Api/appsettings.Development.json
Example:
"ConnectionStrings": {
"VendorDb": "Host=localhost;Port=5432;Database=vendor_risk;Username=postgres;Password=postgres",
"Redis": "localhost:6379"
}Run the API:
cd src/VendorRisk.Api
dotnet runThe API will be available at:
http://localhost:5180
In the Development environment, the API automatically applies EF Core migrations and seeds sample vendor data during startup.
Manual migration commands:
dotnet ef migrations add <Name> -p src/VendorRisk.Infrastructure -s src/VendorRisk.Api
dotnet ef database update -p src/VendorRisk.Infrastructure -s src/VendorRisk.ApiIf EF CLI is not installed:
dotnet tool install --global dotnet-efThe solution follows a layered structure:
- Domain: Business rules and risk scoring logic
- Application: CQRS-style application flow, validation, caching logic
- Infrastructure: EF Core persistence, Redis, Serilog, external infrastructure concerns
- API: HTTP endpoints, middleware, request handling, Swagger
Main features:
- Vendor creation, update and listing
- Vendor risk assessment
- Rule-based risk scoring engine
- Weighted scoring formula
- Similarity-based risk boost
- Redis-based caching
- Cache invalidation after vendor updates and risk assessment operations
- Structured request and exception logging
- Correlation ID support with
X-Correlation-ID - Sample data seeding in Development environment
The risk engine evaluates vendors across multiple dimensions:
- Financial
- Operational
- Security
- Compliance
The weighted score calculation is based on the following formula:
0.4 * financial + 0.3 * operational + 0.3 * ((security + compliance) / 2)
Similarity rules can increase the final risk score by up to 30%.
The final score is normalized between 0 and 1 and mapped to one of the following risk levels:
- Low
- Medium
- High
- Critical
Redis is used for caching frequently requested data.
| Data | TTL |
|---|---|
| Vendor detail DTO | 5 minutes |
| Vendor risk history | 15 minutes |
Cache entries are invalidated after vendor updates and risk assessment operations.
Serilog is configured for structured logging.
Logs are written to:
- Console
- Elasticsearch
Kibana can be used to inspect and visualize logs.
The API also includes correlation ID middleware. Requests can include the following header:
X-Correlation-ID
This value is carried through the request/response flow and structured logs.
Run all unit and integration tests:
dotnet test| Method | Endpoint | Description |
|---|---|---|
| POST | /api/vendors |
Create vendor |
| GET | /api/vendors |
Get vendor list |
| GET | /api/vendors/{id} |
Get vendor detail |
| PUT | /api/vendors/{id} |
Update vendor |
| POST | /api/vendors/{id}/risk/assess |
Calculate and save vendor risk |
| GET | /api/vendors/{id}/risk |
Get latest vendor risk |
| GET | /api/vendors/{id}/risk-history |
Get vendor risk history |
Create vendor:
POST /api/vendors
Content-Type: application/json{
"name": "TechPlus Solutions",
"financialHealth": 78,
"slaUptime": 93,
"majorIncidentsLast12M": 1,
"securityCerts": ["ISO27001"],
"contractValid": true,
"privacyPolicyValid": false,
"pentestReportValid": true
}Assess vendor risk:
POST /api/vendors/1/risk/assessExample response:
{
"success": true,
"value": {
"vendorId": 1,
"score": 0.78,
"level": "High",
"dimensions": [
{
"dimension": "Financial",
"score": 0.6,
"level": "High",
"reasons": [
"Financial health below 50."
]
}
],
"similarityReasons": [
"missingISO27001 correlates with: weakAccessControl, noEncryptionPolicy, failedAudit"
]
}
}If the persistent PostgreSQL volume contains an old schema, remove the volume and rebuild the containers:
docker-compose down -v
docker-compose up --buildCheck the API logs for the following message:
Sample vendor data seeded.
You can also verify the vendor count in PostgreSQL:
select count(*) from "Vendors";Make sure the Redis container is running:
docker psAlso verify the Redis connection string in the application settings.
Check Elasticsearch health manually:
curl http://localhost:9200/_cluster/healthThis project is designed as a portfolio/sample enterprise application to demonstrate backend architecture, frontend integration, caching, logging, Docker-based local infrastructure, and risk scoring logic.