BR-001: Multi-Tenant Organization Support
Priority: CRITICAL
Owner: Product Owner
Description
The system shall support multiple independent utility companies (organizations) with complete data isolation at blob storage, processing, and user access levels.
Business Value
- Revenue Model: Enables SaaS subscription model across Nordic markets
- Cost Efficiency: Shared infrastructure reduces per-customer cost by 60-70%
- Market Penetration: Faster onboarding enables rapid customer acquisition
- Scalability: Single platform scales to serve 150+ Swedish utilities alone
Nordic Market Context
- Sweden: ~150 electricity suppliers, ~290 district heating companies
- Norway: ~140 electricity suppliers
- Denmark: ~60 electricity suppliers
- Finland: ~80 electricity suppliers
Total Addressable Market: 700+ potential customers
Acceptance Criteria
| # | 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 |
Dependencies
- Azure Blob Storage (container-per-organization strategy)
- PostgreSQL schema with
user_organization_rolestable - Organization context middleware
- Role-based access control (RBAC) implementation
Risks & Mitigation
| 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 |
BR-002: Multi-Vendor XML Format Support
Priority: HIGH
Owner: Product Owner
Description
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.
Business Value
- Market Coverage: Supports 70% of Swedish utilities market
- Zero Custom Development: No per-vendor integration coding required
- Faster Onboarding: 80% reduction in integration time
- Vendor Agnostic: Future-proofs against vendor migrations
Nordic Market Context
Top 3 Billing Systems in Swedish Market:
- Telinet (EDIEL/GASEL format): ~30% market share
- Karlskoga/Xellent (OIOXML format): ~25% market share
- EG Zynergy (proprietary): ~15% market share
Combined Coverage: ~70% of addressable market
Acceptance Criteria
| # | 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 |
Vendor-Specific Requirements
GASEL (Telinet/EDIEL):
- Namespace:
urn:ediel:se:electricity:invoice:1.0 - Date format: ISO 8601 (YYYY-MM-DD)
- Amount format: Decimal with period separator
- Required elements: InvoiceNumber, PartyName, PayableAmount
XELLENT (Karlskoga/OIOXML):
- Namespace:
http://rep.oio.dk/ubl/xml/schemas/0p71/pie/ - Multiple namespace prefixes:
com:,main:,fsv: - Amount format: "1 245,00" (space separator, comma decimal)
- Must normalize to standard decimal
ZYNERGY (EG Software):
- Namespace:
http://eg.dk/Zynergy/1.0/invoice.xsd - Nested structure: Invoice > Customer, InvoiceData, InvoiceAddress
- Multiple company ID references throughout
- InvoiceAmount vs InvoiceBalance distinction
Dependencies
- Schema registry with field mappings per vendor
- XML parsing library (System.Xml.Linq)
- XSD schema files from vendors
- Canonical JSON schema definition
Risks & Mitigation
| 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 |
BR-003: Batch Invoice Processing
Priority: HIGH
Owner: Product Owner
Description
The system shall process batch invoice files containing up to 100,000 invoices with parallel processing, retry logic, and granular status tracking.
Business Value
- High-Volume Support: Typical Swedish utility has 50K-200K customers
- Time Efficiency: 95% reduction in manual processing effort
- Customer Satisfaction: Days → hours delivery time
- Predictable SLAs: Enables committed service levels
Nordic Market Context
Monthly Invoice Patterns:
- Peak concentration: First/last week of month
- Heating season (Oct-Mar): 40% higher volumes
- January peak: Coldest month, highest consumption
- Summer (Jun-Aug): 50-60% of winter volumes
Acceptance Criteria
| # | 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 |
Processing Flow
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
Dependencies
- Azure Storage Queues (message passing)
- Worker auto-scaling (Container Apps + KEDA)
- Blob storage (source files + processed invoices)
- Batch metadata storage (real-time updates)
Risks & Mitigation
| 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 |
BR-004: Template-Based Invoice Rendering
Priority: HIGH
Owner: Product Owner
Description
The system shall generate PDF and HTML invoices using organization-specific Handlebars templates with dynamic data binding and brand customization.
Business Value
- Brand Consistency: Professional appearance across all communications
- Regulatory Compliance: Swedish Energy Markets Inspectorate requirements
- Flexibility: Per-organization customization without code changes
- Future-Proof: Multi-language support foundation (SE, NO, DK, FI)
Swedish Regulatory Requirements
Energimarknadsinspektionen (Swedish Energy Markets Inspectorate) mandates:
- Consumption details (period, kWh)
- Tax breakdown (25% VAT for electricity)
- Grid owner information
- Metering point ID (mätpunkt)
- Price per kWh
- Fixed monthly fee (månadsavgift)
Acceptance Criteria
| # | 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 |
Template Structure
Required Fields (Swedish Regulations):
- Invoice number (Fakturanummer)
- Invoice date (Fakturadatum)
- Due date (Förfallodatum)
- Period (Period)
- Metering point ID (Mätpunkt)
- Grid area (Elområde)
- Grid owner (Nätägare)
- Consumption (Förbrukning)
- Previous/current reading (Mätarställning)
- Unit price (Pris per kWh)
- Monthly fee (Månadsavgift)
- Subtotal (Delsumma)
- VAT 25% (Moms 25%)
- Total amount (Att betala)
- Payment info (Bankgiro, OCR)
Dependencies
- Handlebars.Net template engine
- PDF generation (Playwright + Chromium or IronPDF)
- Blob storage (template files)
- Template metadata storage with versioning
Risks & Mitigation
| 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 |
BR-005: Multi-Channel Delivery with Nordic Integration
Priority: HIGH
Owner: Product Owner
Description
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.
Business Value
- Delivery Success: >98% vs ~92% email-only
- Cost Reduction: Reduced returned mail costs
- Customer Preference: Digital-first with postal backup
- Legal Compliance: Swedish "rätt till pappersfaktura" (right to paper invoice)
- Future-Ready: Digital mailbox mandate preparations
Nordic Market Context
Legal Requirements:
- Sweden: Postal option legally required for all customers
- Kivra Adoption: 4.2M users in Sweden (40% of population)
- E-faktura: Standard for B2B invoicing across Nordics
- Postal Tradition: Especially important for elderly customers
Delivery Statistics (Industry Average):
- Email delivery: 90-95% success
- Email + Postal fallback: 98-99% success
- Pure postal: 97-98% success
Acceptance Criteria
| # | 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 |
Channel Specifications
Email (SendGrid):
- Dedicated Nordic IP for sender reputation
- SPF/DKIM/DMARC configuration
- Swedish-localized email templates
- PDF attachment (compressed if >5MB)
- Retry: 2 attempts (1 min, 5 min delays)
- Failure → Postal fallback
Postal (21G Bulk SFTP):
- Scheduled processing: 12:00 and 20:00 CET
- ZIP archive format: PDFs + XML metadata
- SFTP upload to
/incoming/{org-code}/ - SLA: 24-48 hours from upload to print
- Tracking: Email confirmation from 21G
Phase 2 Channels:
- Kivra digital mailbox (4.2M Swedish users)
- e-Faktura/PEPPOL (B2B standard)
- SMS notifications (Wiraya integration)
Dependencies
- SendGrid account (Nordic IP reputation)
- 21G SFTP server access and credentials
- Azure Key Vault (credential storage)
- Postal queue processing service
- ZIP file generation for 21G format
Risks & Mitigation
| 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) |