Skip to content

Latest commit

 

History

History
259 lines (227 loc) · 10.8 KB

File metadata and controls

259 lines (227 loc) · 10.8 KB

Project Architecture

Overview

┌─────────────────────────────────────────────────────────────────┐
│                     Azure Blob Storage                          │
│                    (Invoice Upload)                             │
└───────────────────────┬─────────────────────────────────────────┘
                        │ Blob Trigger
                        ▼
┌─────────────────────────────────────────────────────────────────┐
│              InvoiceUploadFunction                              │
│              (Azure Function - Blob Trigger)                    │
└───────────────────────┬─────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────────┐
│           IInvoiceProcessingService                             │
│           (Business Logic Orchestration)                        │
└─────┬─────────────────┬──────────────────┬──────────────────────┘
      │                 │                  │
      ▼                 ▼                  ▼
┌──────────┐  ┌─────────────────┐  ┌─────────────────┐
│Document  │  │  Validation     │  │   Repository    │
│Intel.    │  │  Service        │  │   (CosmosDB)    │
│Service   │  │                 │  │                 │
└──────────┘  └─────────────────┘  └─────────────────┘
      │                                     │
      ▼                                     ▼
┌──────────────┐                  ┌──────────────────┐
│Azure AI      │                  │  CosmosDB        │
│Document      │                  │  - Invoice Data  │
│Intelligence  │                  │  - Status        │
└──────────────┘                  │  - History       │
                                  └──────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│         EmailReminderFunction (Timer Trigger)                   │
│         - Daily at 9 AM                                         │
│         - Every 5 minutes (for retries)                         │
└───────────────────────┬─────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────────┐
│           IInvoiceProcessingService                             │
│           ProcessScheduledRemindersAsync()                      │
└─────┬──────────────────────────────────────────────────────┬────┘
      │                                                       │
      ▼                                                       ▼
┌──────────────┐                                    ┌─────────────┐
│ Repository   │                                    │   Email     │
│ (Query)      │                                    │   Service   │
└──────────────┘                                    │ (SendGrid)  │
                                                    └─────────────┘

Layer Architecture

Core Layer (Domain)

InvoiceReminderSystem.Core/
├── Models/
│   ├── Invoice.cs (Aggregate Root)
│   ├── BlobMetadata.cs
│   ├── ExtractedData.cs
│   ├── ProcessingStatus.cs
│   ├── EmailNotification.cs
│   └── ...
├── Interfaces/
│   ├── IInvoiceRepository.cs
│   ├── IDocumentIntelligenceService.cs
│   ├── IEmailService.cs
│   ├── IInvoiceValidationService.cs
│   └── IInvoiceProcessingService.cs
├── Enums/
│   ├── InvoiceStatus.cs
│   ├── EmailSendStatus.cs
│   └── AttemptResult.cs
└── Exceptions/
    ├── ValidationException.cs
    └── DocumentExtractionException.cs

Infrastructure Layer

InvoiceReminderSystem.Infrastructure/
├── Repositories/
│   └── InvoiceRepository.cs
├── Services/
│   ├── DocumentIntelligenceService.cs
│   ├── SendGridEmailService.cs
│   ├── InvoiceValidationService.cs
│   └── InvoiceProcessingService.cs
└── [Settings Classes]

Function App Layer

InvoiceReminderSystem.FunctionApp/
├── Functions/
│   ├── InvoiceUploadFunction.cs
│   └── EmailReminderFunction.cs
├── Extensions/
│   └── ServiceCollectionExtensions.cs
├── Program.cs
├── host.json
└── local.settings.json

Data Flow

1. Invoice Upload Flow

User uploads PDF
    ↓
Blob Storage receives file
    ↓
Blob Trigger fires
    ↓
InvoiceUploadFunction executes
    ↓
InvoiceProcessingService.ProcessNewInvoiceAsync()
    ↓
┌─────────────────────────────────────┐
│ 1. Extract data (Document Intel)   │
│ 2. Validate data                    │
│ 3. Calculate reminder date          │
│ 4. Save to CosmosDB                 │
└─────────────────────────────────────┘

2. Email Reminder Flow

Timer Trigger fires (9 AM daily)
    ↓
EmailReminderFunction executes
    ↓
InvoiceProcessingService.ProcessScheduledRemindersAsync()
    ↓
Query CosmosDB for due invoices
    ↓
For each invoice:
    ├─ Update status to "Sending"
    ├─ Send email via SendGrid
    ├─ Log attempt in history
    └─ Update final status (Sent/Failed)

SOLID Principles Applied

Single Responsibility Principle (SRP)

  • InvoiceRepository: Only handles data access
  • DocumentIntelligenceService: Only extracts data from documents
  • SendGridEmailService: Only sends emails
  • InvoiceValidationService: Only validates data
  • InvoiceProcessingService: Orchestrates the workflow

Open/Closed Principle (OCP)

  • All services implement interfaces
  • New implementations can be added without modifying existing code
  • Example: Could add AzureCommunicationEmailService implementing IEmailService

Liskov Substitution Principle (LSP)

  • Any IEmailService implementation can replace SendGridEmailService
  • Any IInvoiceRepository implementation can replace InvoiceRepository

Interface Segregation Principle (ISP)

  • Small, focused interfaces (e.g., IEmailService only has one method)
  • Functions depend only on interfaces they need

Dependency Inversion Principle (DIP)

  • High-level modules (Functions) depend on abstractions (Interfaces)
  • Low-level modules (Services) implement abstractions
  • All dependencies injected via constructor

Error Handling Strategy

┌─────────────────────────────────────┐
│   Validation Errors                 │
│   (Low confidence, missing data)    │
└───────────────┬─────────────────────┘
                │
                ▼
        Mark as "ValidationFailed"
        Store errors in CosmosDB
        Alert via Application Insights

┌─────────────────────────────────────┐
│   Transient Email Errors            │
│   (Rate limits, network issues)     │
└───────────────┬─────────────────────┘
                │
                ▼
        Retry with exponential backoff
        Attempt 1: +1 min
        Attempt 2: +5 min
        Attempt 3: +15 min

┌─────────────────────────────────────┐
│   Permanent Email Errors            │
│   (Invalid email, blocked)          │
└───────────────┬─────────────────────┘
                │
                ▼
        Mark as "SendFailed"
        No retry
        Alert for manual review

Monitoring Points

  1. Application Insights

    • Function execution times
    • Success/failure rates
    • Exception tracking
  2. CosmosDB Metrics

    • Request units consumed
    • Query performance
    • Storage size
  3. Custom Logging

    • Invoice processing status changes
    • Validation failures with details
    • Email sending attempts and results

Security Considerations

  1. Secrets Management

    • API keys stored in Azure Key Vault (production)
    • local.settings.json for development (not committed)
  2. Data Protection

    • CosmosDB uses encryption at rest
    • Blob storage uses HTTPS
    • SendGrid API uses TLS
  3. Access Control

    • Managed Identity for Azure resources
    • RBAC for CosmosDB and Storage
    • Least privilege principle

Scalability

  1. Horizontal Scaling

    • Azure Functions scale automatically
    • CosmosDB can be scaled via RU/s
    • Blob storage has unlimited capacity
  2. Partition Strategy

    • CosmosDB partitioned by invoiceMonth
    • Distributes load evenly across months
  3. Performance Optimization

    • Indexed queries on status and date fields
    • Batch processing for reminders
    • Async/await throughout