Priority: CRITICAL
Owner: Product Owner
The system shall support multiple independent utility companies (organizations) with complete data isolation at blob storage, processing, and user access levels.
Total Addressable Market: 700+ potential customers
| # | Criterion | Measurement Method | Target |
|---|---|---|---|
| 1 | Concurrent organizations supported | Load test with 50 orgs | All batches process successfully |
| 2 | Data isolation enforcement | Cross-org access attempts | 100% blocked (403 Forbidden) |
| 3 | Organization-specific blob containers | Verify storage paths | Pattern: {org-id}-{type}-{year}/ |
| 4 | User organization boundary enforcement | API calls with wrong org context | All rejected |
| 5 | Independent branding per organization | Upload logo, verify rendering | Branding applied correctly |
| 6 | Configurable delivery channels | Set priority [email, postal] | Order respected |
user_organization_roles table| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Data leakage between orgs | LOW | CRITICAL | Middleware enforcement, automated testing, penetration testing |
| Performance degradation (50+ tenants) | MEDIUM | HIGH | Blob auto-scaling, connection pooling, indexed queries |
| Swedish data residency requirements | LOW | HIGH | West Europe primary, no cross-border transfer |
Priority: HIGH
Owner: Product Owner
The system shall process invoice batch files from multiple vendor billing systems (GASEL/Telinet, XELLENT/Karlskoga, ZYNERGY/EG Software) with automatic format detection and transformation to canonical JSON.
Top 3 Billing Systems in Swedish Market:
Combined Coverage: ~70% of addressable market
| # | Criterion | Measurement Method | Target |
|---|---|---|---|
| 1 | GASEL format detection | 50 sample files | 100% accuracy |
| 2 | XELLENT format detection | 50 sample files | 100% accuracy |
| 3 | ZYNERGY format detection | 50 sample files | 100% accuracy |
| 4 | Canonical JSON transformation | Schema validation | All fields present |
| 5 | XSD schema validation | Vendor-specific XSD | Pass validation |
| 6 | Unsupported format handling | Unknown XML upload | 415 error with vendor list |
| 7 | Detection performance | 100MB file | < 1 second |
GASEL (Telinet/EDIEL):
urn:ediel:se:electricity:invoice:1.0XELLENT (Karlskoga/OIOXML):
http://rep.oio.dk/ubl/xml/schemas/0p71/pie/com:, main:, fsv:ZYNERGY (EG Software):
http://eg.dk/Zynergy/1.0/invoice.xsd| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Vendor schema changes without notice | MEDIUM | HIGH | Version all schemas, support multiple versions, 3-month deprecation notice |
| EDIEL standard evolution | MEDIUM | MEDIUM | Monitor Ediel.org, participate in Nordic working groups, backward compatibility |
| Complex namespace handling (OIOXML) | LOW | MEDIUM | XmlNamespaceManager, extensive unit testing per vendor |
| Incomplete field mappings | MEDIUM | MEDIUM | Comprehensive validation, custom fields dictionary, lenient parsing mode |
Priority: HIGH
Owner: Product Owner
The system shall process batch invoice files containing up to 100,000 invoices with parallel processing, retry logic, and granular status tracking.
Monthly Invoice Patterns:
| # | Criterion | Measurement Method | Target |
|---|---|---|---|
| 1 | Single batch capacity | Upload 100K invoices | All processed |
| 2 | Asynchronous processing | API response time | < 500ms (202 Accepted) |
| 3 | Real-time progress tracking | Poll during processing | Updates every 30 seconds |
| 4 | Failed item isolation | 10 errors in 1000-item batch | 990 succeed independently |
| 5 | Retry mechanism | Force temporary failure | 3 retries then poison queue |
| 6 | Processing time SLA | 100K invoice batch | ≤ 120 minutes |
| 7 | Format support (Phase 1) | Upload XML, JSON, CSV | XML fully supported |
1. API receives batch upload → 201 Created (batch stored)
2. POST /start → 202 Accepted (queued for processing)
3. ParserService picks from batch-upload-queue
4. Parse XML → Individual JSON files (canonical format)
5. Group into 32-item batches → Enqueue to batch-items-queue
6. DocumentGenerator renders 32 items in parallel
7. Generate HTML → PDF → Store in blob
8. Route to delivery queue (email or postal)
9. Update batch statistics in real-time
10. Complete when all items processed
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Processing timeout during heating season | MEDIUM | HIGH | Pre-warm workers 1st/last week, priority queue, off-peak scheduling |
| Memory constraints (large XML >50MB) | MEDIUM | MEDIUM | Stream-based parsing, chunk processing, 100MB hard limit |
| Disk space exhaustion | LOW | MEDIUM | Ephemeral storage cleanup, blob-only persistence |
| Queue 64KB message limit | MEDIUM | MEDIUM | Store data in blob, queue references only |
Priority: HIGH
Owner: Product Owner
The system shall generate PDF and HTML invoices using organization-specific Handlebars templates with dynamic data binding and brand customization.
Energimarknadsinspektionen (Swedish Energy Markets Inspectorate) mandates:
| # | Criterion | Measurement Method | Target |
|---|---|---|---|
| 1 | Custom template upload | Upload via API/blob | Stored successfully |
| 2 | Dynamic data binding | Test with invoice data | All fields populated |
| 3 | PDF generation | HTML → PDF | A4 format, readable |
| 4 | Template versioning | Create v2.0.0 | Old batches use v1.0.0 |
| 5 | In-flight batch isolation | Update template during processing | In-flight uses old version |
| 6 | Template validation | Missing variable upload | Validation error returned |
| 7 | Organization branding | Logo, colors, fonts | Visible in rendered PDF |
| 8 | Swedish regulatory fields | Verify required elements | All present |
Required Fields (Swedish Regulations):
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Template rendering bottleneck | HIGH | HIGH | Compiled template caching (24h), parallel rendering (32 items), POC: 10K in <5 min |
| PDF generation quality (Swedish chars) | MEDIUM | MEDIUM | UTF-8 encoding, font embedding (åäö), visual regression testing |
| Swedish regulatory compliance | LOW | CRITICAL | Legal review, required fields checklist, annual update review |
| Template injection attacks | LOW | CRITICAL | Sandboxed execution, no eval/exec helpers, sanitization, security review |
Priority: HIGH
Owner: Product Owner
The system shall deliver invoices through multiple channels (email, postal, future: Kivra, e-Faktura) with configurable priority, automatic fallback, and integration with Nordic delivery partners.
Legal Requirements:
Delivery Statistics (Industry Average):
| # | Criterion | Measurement Method | Target |
|---|---|---|---|
| 1 | Email delivery (SendGrid) | 1000 test invoices | >95% delivered |
| 2 | Postal delivery (21G SFTP) | Create ZIP, upload | File accepted by 21G |
| 3 | Channel priority configuration | Set [email, postal] | Email attempted first |
| 4 | Automatic fallback | Force email failure | Postal triggered auto |
| 5 | Delivery status tracking | Check invoice metadata | Status + timestamps recorded |
| 6 | Retry logic (transient failures) | Simulate SendGrid 429 | Retries with backoff |
| 7 | Delivery confirmation logging | Verify audit log | All deliveries logged |
| 8 | 21G bulk processing schedule | Verify postal queue | 12:00 and 20:00 CET |
Email (SendGrid):
Postal (21G Bulk SFTP):
/incoming/{org-code}/Phase 2 Channels:
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| SendGrid Nordic deliverability issues | MEDIUM | HIGH | Dedicated IP, SPF/DKIM/DMARC, sender reputation monitoring, backup: Azure Communication Services |
| 21G SFTP connectivity issues | LOW | HIGH | Retry logic, dual credentials, alert on failure, 21G SLA monitoring, manual upload procedure |
| Postal delivery delays (Swedish postal) | MEDIUM | MEDIUM | Set expectations (5-7 days), track confirmations, escalation for >10 days |
| Email spam filtering (Swedish ISPs) | MEDIUM | MEDIUM | IP warmup, monitor bounce rates, ISP whitelist requests (Telia, Tele2, Telenor) |
Priority: HIGH
Owner: Technical Architect
| Metric | Target | Measurement | Test Scenario |
|---|---|---|---|
| Monthly throughput | 10M invoices | Application Insights | Production monitoring |
| 100K batch processing | < 2 hours | Timestamp diff | Load test TC-200 |
| API response (p50) | < 200ms | Application Insights | Load test TC-201 |
| API response (p95) | < 500ms | Application Insights | Load test TC-202 |
| API response (p99) | < 1000ms | Application Insights | Load test TC-203 |
| PDF generation (p95) | < 5 seconds/invoice | Custom metric | Render test TC-204 |
| Handlebars render (p95) | < 2 seconds/invoice | Custom metric | Render test TC-205 |
| Queue processing lag | < 5 minutes | Queue depth / throughput | Queue monitoring |
| Database query (p95) | < 100ms | PostgreSQL slow query log | Query analysis |
| ParserService (10K batch) | < 2 minutes | Parse duration | Parser test TC-206 |
Scenario 1: Steady State (Normal Month)
Scenario 2: Peak Load (Heating Season)
Scenario 3: Spike Test
| # | Criterion | Validation | Target |
|---|---|---|---|
| 1 | 100K batch completion | End-to-end test | ≤ 2 hours |
| 2 | API latency under load | 1000 RPS test | p95 ≤ 500ms |
| 3 | 10M monthly capacity | Production monitoring | ≥ 10M in peak month |
| 4 | 50-org performance | 50 concurrent uploads | All SLAs met |
| 5 | Worker auto-scaling | Monitor queue during peaks | Lag ≤ 5 min |
| 6 | PDF generation performance | 1000 PDFs | p95 ≤ 5 seconds |
Priority: HIGH
Owner: Technical Architect
| Component | Min | Max | Trigger | Threshold | Scale Up | Scale Down |
|---|---|---|---|---|---|---|
| CoreApiService | 5 | 20 | CPU OR Request Rate | 70% OR 1000 RPS | 2 min | 10 min |
| ParserService | 2 | 10 | Queue Length | >0 | 1 min | 5 min |
| DocumentGenerator | 2 | 100 | Queue Length | >32 | 1 min | 5 min |
| EmailService | 5 | 50 | Queue Length | >50 | 1 min | 5 min |
| PostalService | 1 | 3 | Scheduled | 12:00, 20:00 CET | N/A | After completion |
Normal Load (non-heating, mid-month):
Peak Load (heating season, first/last week):
Monthly Schedule:
- Day 1-7: Pre-warm to 50 instances at 00:00
- Day 8-23: Scale based on queue (2-20 instances)
- Day 24-31: Pre-warm to 50 instances at 00:00
Heating Season (Oct-Mar): Double levels
- Day 1-7: Pre-warm to 80 instances
- Day 24-31: Pre-warm to 80 instances
Priority: HIGH
Owner: Technical Architect
| Metric | Target | Allowed Downtime | Measurement |
|---|---|---|---|
| System Uptime | 99.9% | 43 min/month | Azure Monitor |
| Batch Success Rate | >99.5% | 50 failures per 10K | Processing logs |
| Delivery Success Rate | >98% | 200 failures per 10K | Delivery tracking |
| API Availability | 99.9% | 43 min/month | Health checks |
| MTTR | <30 minutes | N/A | Incident timestamps |
| MTBF | >720 hours | N/A | Incident tracking |
Primary Region: West Europe (Sweden, Denmark)
Secondary Region: North Europe (Norway, Finland)
Traffic Routing:
Priority: CRITICAL
Owner: Technical Architect
OAuth 2.0:
Roles:
In Transit:
At Rest:
Priority: HIGH
Owner: Legal/Compliance
| Data Type | Retention | Storage Tier Transitions |
|---|---|---|
| Invoices (PDF/HTML/JSON) | 7 years | Day 0-365: Hot Day 366-2555: Cool Day 2556+: Archive |
| Batch Source (XML) | 90 days | Day 0-30: Hot Day 31-90: Cool Day 91+: Delete |
| Audit Logs | 7 years | Year 0-1: PostgreSQL Year 1-7: Blob (compressed) |
| Application Logs | 90 days | Application Insights |
| Stakeholder Role | Name | Signature | Date | Status |
|---|---|---|---|---|
| Product Owner | ☐ PENDING | |||
| Technical Architect | ☐ PENDING |
Any changes to approved CRITICAL or HIGH priority requirements must follow the change control process:
| Version | Date | Author | Changes | Release Target |
|---|---|---|---|---|
| 1.0 | 2025-11-20 | Product Owner | Initial draft | egflow-1.0.0 |
| 1.1 | 2025-11-21 | Product Owner | Added FR-003 details, updated acceptance criteria | egflow-1.0.0 |
| 1.2 | 2025-11-27 | Product Owner | Updated versioning strategy to match Gasell model | egflow-1.0.0 "Corny Flamingo" |
End of Business Requirements Document