Skip to main content
Version: Latest

11. Technical Debt

Every item below is a confirmed, evidenced finding from the Phase 0 discovery. None were in scope for the Phase 0.2 critical-fix pass (which addressed only the Critical/High security items in Chapter 7) — they remain open.

1. The Tenancy Fork Is Duplication, Not an Adapter — And It Has Already Drifted

Shumoul.Framework.EInvoicing.Tenancy mirrors the entire core SDK's namespace/class structure rather than sharing a common core with a tenancy-specific persistence adapter. Confirmed, concrete divergences:

  • DTOs/Invoice/Money.cs's MoneyValidator — core and Tenancy versions have different branching logic; Tenancy carries an extra _logger field core doesn't have.
  • OTP logging — core logged the raw OTP in plaintext before Phase 0.2; the Tenancy copy already logged an inert placeholder instead — a security-relevant behavioral difference that predates Phase 0.2's fix.
  • CSR field OID — core uses a custom OID for LocationAddress; Tenancy uses the standard X509Name.L OID.
  • Logging verbosity — several _logger.Information(...) trace calls present in core are absent from the Tenancy copies.
  • Build configuration asymmetryDirectory.Build.props exists for core, has no equivalent for Tenancy.

Any future bug fix or ZATCA rule-change update applied to one fork requires a second, manual, easy-to-forget pass over the other — discipline has already lapsed at least four times.

2. Dead Code — Example Providers (5 Classes, Confirmed Never Registered)

Examples/ (AdditionalInfoSettingsExample, AddressDetailsSettingsExample, VatRegistrationSettingsExample, UblInvoiceDtoExample, CsrParametersExample) correctly implement IExampleProvider<T>, but both live Startup.cs call sites (.Api and .TenancyApi) scan the wrong assembly (Shumoul.Framework.Infrastructure, which has zero IExampleProvider<T> implementations) instead of the EInvoicing assembly where these classes actually live. Result: all 5 classes compile but are never registered in DI and never produce a Swagger example.

Examples/Security/CsrParametersExample.cs also declares the wrong namespace (copy-pasted from the Invoice examples folder) and has an unused extra method, GetExample2(), not part of IExampleProvider<T>.

3. Dead Code — The Core SDK's Own DI Bootstrap Is Commented Out

Shumoul.Framework.EInvoicing/Startup.cs's AddEInvoicingSDK-equivalent method is entirely commented out — the actively-used registration lives in Shumoul.Framework.EInvoicing.Api/Startup.cs instead. Same pattern in the Tenancy fork's AddEInvoicingTenancySDK.

4. Filename/Class-Name Mismatch

Onboarding/ComplianceChecks/StandardTaxInvoiceCompliance.cs actually declares a class named StandardInvoiceCompliance. The class is live code, referenced elsewhere — not dead, but a readability/ maintenance hazard.

5. Route Spelling — ConfigrationMode

EInvoicingSettingsController's route for the production/compliance mode toggle is literally api/EInvoicing/Settings/ConfigrationMode (missing the "u" in "Configuration") — a live, shipped route, not a documentation typo. Any future rename would be a breaking API change.

6. Zero Test Coverage for the Security-Critical Core

217+ test cases exist, the large majority under ValidationRules/ (FluentValidation DTO rules), plus two Phase 0.2 regression tests (RestClient auth attachment, file-download path traversal). No test file references Signer, X509, QrCode, Certificate, Hash, Compliance, or Onboarding beyond those two additions — the signing, certificate/CSR/CSID management, hashing, and QR-generation code has no automated regression protection for its own logic. The Tenancy fork has zero test coverage of any kind.

7. Undeclared Direct Dependency — BouncyCastle

Org.BouncyCastle.* types are used directly in security-critical code (CSR generation, key handling), and BouncyCastle.Cryptography 2.6.2 is confirmed present in the resolved build graph — but no <PackageReference Include="BouncyCastle..."> exists in Shumoul.Framework.EInvoicing.csproj. It resolves only as a transitive dependency.

8. Stray Committed Backup File

UnitTests/Shumoul.Framework.EInvoicing.Test/Shumoul.Framework.EInvoicing.Test.csproj.Backup.tmp is committed to git — a .tmp backup file that should never have been tracked.

9. Legacy Naming Remnants

Old .nupkg/.nuspec artifacts carry PackageId Bayan.Framework.EInvoicing* (the platform's pre-rename name) alongside the current Shumoul.Framework.EInvoicing* identifiers — harmless build history.

10. Zero ADR or Boundary Documentation

Unlike WhatsApp Integration (formal ADR-001 recording its module-shape decision), E-Invoicing has no architecture decision record anywhere explaining why it is packaged the way it is, why the Tenancy variant is a full fork rather than an adapter, or what the intended long-term shape is.

11. ApplicationDbContext — Incidental, Unrelated Finding

While tracing AppSetting's multi-tenancy configuration, ApplicationDbContext.cs:392 was observed to register DbSet<ZatcaTaxCategory> ZatcaTaxCategorys — which appears to be a duplicate/typo of the ZatcaTaxCategories DbSet already registered nearby. Unrelated to E-Invoicing's own architecture (a ZATCA reference-data lookup table registration in the ERP's own domain layer); noted for completeness only, not investigated further.