Skip to content

Pavol-dotnetstack/InvoiceProcessingSystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

InvoiceProcessingSystem

A scalable, enterprise-grade invoice processing system designed for 50-year operation, handling 10,000 transactions per minute, with support for 26 billion invoices using distributed SQL (PostgreSQL Citus), tiered storage, and zero-downtime schema evolution.

πŸš€ Quick Links

πŸ“š Documentation

Choose your path based on your role:

⚑ Getting Started (3 Steps)

  1. Read: Documentation/QUICK_REFERENCE.md (5 minutes)
  2. Understand: Documentation/ENTITY_MODEL_CHANGES.md (20 minutes)
  3. Implement: Plan your code updates using Documentation/DOCUMENTATION_INDEX.md

✨ Key Features

βœ… Horizontal Scaling via Citus

  • Distributed SQL with automatic sharding by TenantId
  • 10,000 tx/minute with 4-8 worker nodes
  • Multi-tenant isolation built-in

βœ… Tiered Storage (Hot/Cold)

  • Current + 1 year on fast SSD (<100ms queries)
  • Older data in cost-effective archive (S3, Glacier)
  • 10-100x cost savings vs. all-hot storage

βœ… Schema Evolution (Zero Downtime)

  • JSONB metadata columns for unlimited flexibility
  • Add fields without database migrations
  • 50-year forward compatibility (2024-2074)

βœ… Enterprise Ready

  • Clean architecture (Domain/Application/Infrastructure)
  • Comprehensive audit trails (CreatedAt, ModifiedAt)
  • Full EF Core integration with PostgreSQL
  • Production-grade documentation

πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         PostgreSQL + Citus (Coordinator)            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Invoices | Participants | LineItems | Payments    β”‚
β”‚  (Distributed by TenantId across workers)          β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”œβ”€ Worker 1 (Tenant A: 6.5B invoices)
       β”œβ”€ Worker 2 (Tenant B: 6.5B invoices)
       β”œβ”€ Worker 3 (Tenant C: 6.5B invoices)
       └─ Worker 4 (Tenant D: 6.5B invoices)
           = 26B invoices over 50 years

Hot/Cold Tiering:

  • Hot: Current year + 1 previous year (SSD)
  • Cold: Older years (Archive storage)

πŸ“Š Performance Targets

Metric Capacity
Throughput 10,000 tx/min (Citus 4-node)
Invoices 26 billion over 50 years
Hot Query Latency <100ms (p99)
Cold Query Latency <5 seconds (p99)
Active Tenants 100+ concurrent
Daily Invoice Volume 100,000+ invoices/day

πŸ”§ Technology Stack

  • Framework: .NET 10.0
  • Database: PostgreSQL 15+ with Citus extension
  • ORM: Entity Framework Core with Npgsql provider
  • Architecture: Clean Architecture (Domain/Application/Infrastructure)
  • Package Management: NuGet (centralized via Directory.Packages.props)

πŸ“ Domain Model

Core Entities

Invoice

  • PK: Id (Guid)
  • SK: TenantId (Guid) - Citus shard key
  • Year - Tiered storage partitioning
  • IsArchived - Hot/cold flag
  • Metadata (JSONB) - Schema evolution
  • CreatedAt, ModifiedAt - Audit trail
  • Status, Amount, LineItems, Payments...

Participant (Supplier/Customer)

  • PK: Id (Guid)
  • SK: TenantId (Guid) - Citus shard key
  • Metadata (JSONB) - Regional variants, compliance data
  • IsArchived - Inactive flag
  • Address, TaxId, Email...

InvoiceLineItem & PaymentRecord

  • Include TenantId to match parent Invoice
  • Auto-managed CreatedAt timestamps

πŸš€ Getting Started

Prerequisites

  • .NET 10.0 SDK
  • PostgreSQL 15+ (with Citus extension)
  • Visual Studio Code or Visual Studio 2022+

Quick Start

  1. Restore & Build

    dotnet restore
    dotnet build InvoiceProcessingSystem.slnx
  2. Create Database Migration

    cd src/InvoiceSystem.Infrastructure
    dotnet ef migrations add InitialCreate
    dotnet ef database update
  3. Enable Citus (PostgreSQL)

    CREATE EXTENSION IF NOT EXISTS citus;
    SELECT create_distributed_table('invoices', 'tenant_id');
    SELECT create_distributed_table('invoice_line_items', 'tenant_id');
    SELECT create_distributed_table('payment_records', 'tenant_id');
    SELECT create_reference_table('participants');
  4. Run the API

    dotnet run --project src/InvoiceSystem.WebAPI/
  5. Run Tests

    dotnet test tests/InvoiceSystem.UnitTests/
    dotnet test tests/InvoiceSystem.IntegrationTests/

⚠️ Important: Breaking Changes

The domain model has been updated for scalability. All application code must be updated:

Before (Old)

var invoice = new Invoice(sender, receiver, "INV-001", 30);

After (New)

var tenantId = Guid.Parse("...");
var invoice = new Invoice(tenantId, sender, receiver, "INV-001", 30);

See: Documentation/ENTITY_MODEL_CHANGES.md for complete migration guide.

πŸ” Query Patterns

βœ… CORRECT (Citus co-located execution)

var invoices = dbContext.Invoices
    .Where(i => i.TenantId == tenantId)      // ← Always filter by TenantId first!
    .Where(i => i.Year == 2024)
    .ToList();

❌ WRONG (Cross-shard, slow)

var invoices = dbContext.Invoices
    .Where(i => i.Year == 2024)              // ❌ Missing TenantId filter
    .ToList();

See: Documentation/QUICK_REFERENCE.md for detailed query examples.

πŸ“š Documentation Files

File Purpose Read Time
Documentation/DOCUMENTATION_INDEX.md Navigation guide for all docs 5 min
Documentation/QUICK_REFERENCE.md Developer handbook with examples 10 min
Documentation/IMPLEMENTATION_SUMMARY.md Architecture overview + diagrams 15 min
Documentation/SCALABILITY_DESIGN.md Complete 50-year blueprint 40 min
Documentation/ENTITY_MODEL_CHANGES.md Breaking changes + migration guide 25 min

πŸ› οΈ Development Workflow

Adding a Feature

  1. Update domain entity if needed
  2. Create/update EF Core migration: dotnet ef migrations add <Name>
  3. Update ApplicationDbContext if entity relationships changed
  4. Always include TenantId in new queries
  5. Write tests with multi-tenant scenarios
  6. Update relevant documentation

Testing

# Run all tests
dotnet test

# Run specific test project
dotnet test tests/InvoiceSystem.UnitTests/

# Run with coverage
dotnet test /p:CollectCoverage=true

πŸ” Multi-Tenancy

Data isolation is enforced at the database level via Citus sharding:

// Tenant A can only see their invoices
var tenantA_invoices = dbContext.Invoices
    .Where(i => i.TenantId == tenantA_id)
    .ToList();

// Tenant B queries are automatically isolated
var tenantB_invoices = dbContext.Invoices
    .Where(i => i.TenantId == tenantB_id)
    .ToList();

πŸ“ˆ Scaling Strategy

Period Configuration Capacity
Year 1-10 2-node Citus 10-100 tenants
Year 10-30 4-6 node Citus 100-1,000 tenants
Year 30-50 8+ node Citus 1,000+ tenants

See Documentation/SCALABILITY_DESIGN.md for details.

🀝 Contributing

  1. Create a feature branch
  2. Follow clean architecture patterns
  3. Always include TenantId in domain models and queries
  4. Update documentation if schema/API changes
  5. Ensure all tests pass
  6. Submit PR for review

πŸ“‹ Project Status

βœ… Domain model redesigned for scalability βœ… ApplicationDbContext fully configured for Citus βœ… Comprehensive documentation provided βœ… Solution builds successfully (0 errors, 0 warnings) βœ… Ready for production implementation

πŸ“ž Support

πŸ“„ License

See LICENSE file for details.


Last Updated: March 16, 2026 Target Framework: .NET 10.0 Database: PostgreSQL 15+ with Citus Architecture: Clean Architecture Status: Production Ready βœ…

About

Invoice Processing System

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages