Skip to content

Repository files navigation

VendorRiskScoringApp

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.

Highlights

  • .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

Tech Stack

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

Project Structure

VendorRiskScoringApp/
├── frontend/
├── src/
│   ├── VendorRisk.Api/
│   ├── VendorRisk.Application/
│   ├── VendorRisk.Domain/
│   └── VendorRisk.Infrastructure/
├── tests/
│   └── VendorRisk.Tests/
├── docker-compose.yml
└── VendorRisk.sln

Requirements

  • .NET 8 SDK
  • Docker
  • Docker Compose

Quick Start with Docker Compose

Clone the repository and navigate to the project folder:

git clone https://github.com/melihcantosun/VendorRiskScoringApp.git
cd VendorRiskScoringApp

Start the application and required services:

docker-compose up --build

The 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

Local Development without Docker

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 run

The API will be available at:

http://localhost:5180

Database and Migrations

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.Api

If EF CLI is not installed:

dotnet tool install --global dotnet-ef

Architecture and Features

The 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

Risk Scoring Logic

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

Caching

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.

Logging

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.

Running Tests

Run all unit and integration tests:

dotnet test

API Endpoints

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

Example Request

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/assess

Example 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"
    ]
  }
}

Troubleshooting

Migration error: relation already exists

If the persistent PostgreSQL volume contains an old schema, remove the volume and rebuild the containers:

docker-compose down -v
docker-compose up --build

Seed data is not created

Check the API logs for the following message:

Sample vendor data seeded.

You can also verify the vendor count in PostgreSQL:

select count(*) from "Vendors";

Redis connection error

Make sure the Redis container is running:

docker ps

Also verify the Redis connection string in the application settings.

Elasticsearch health check

Check Elasticsearch health manually:

curl http://localhost:9200/_cluster/health

Notes

This 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.

About

.NET 8 and Angular vendor risk scoring application with Redis caching, PostgreSQL, Docker, Serilog and Elasticsearch/Kibana.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages