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'sMoneyValidator— core and Tenancy versions have different branching logic; Tenancy carries an extra_loggerfield 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 standardX509Name.LOID. - Logging verbosity — several
_logger.Information(...)trace calls present in core are absent from the Tenancy copies. - Build configuration asymmetry —
Directory.Build.propsexists 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.
