Skip to main content
Version: Latest

17. Known Limitations

17.1 No partial/override apply

apply requires acceptAll: true; the overrides field exists in the request contract but is accepted and ignored, not processed. An admin cannot currently accept most of a recommendation while rejecting or editing individual values before applying — it's all-or-nothing.

17.2 Recommendation regeneration overwrites history

Calling POST recommendation again — even after a session is already Applied — regenerates and overwrites RecommendedProfileCode/GeneratedSettingsPatchJson/etc. on the same session row. There is no history of multiple recommendations generated over time, only the most recent one.

17.3 Registration/verification flow is now exercised for real; OTP/notification delivery is not

Earlier phases of this feature's testing used a tenant seeded directly into the database rather than a real Register → Verify → Login flow. The New Subscriber E2E run (docs/testing/ NEW_SUBSCRIBER_E2E_TEST_REPORT.md, Shumoul.BackEnd/Shumoul repo) has since exercised the real POST api/Tenant/Registration/Register and tenant-verification endpoints end-to-end, confirming the exact transition from "tenant just registered" through "tenant verified/activated" to "first login shows onboarding" against the real registration pipeline — not simulated.

What remains genuinely non-functional: no real email/SMS/WhatsApp provider call succeeds or was relied upon in that test run. Registration/verification used to fail outright (500 errors, transaction rollback) whenever a notification-dispatch handler threw, because those handlers ran before the transaction committed — this was fixed by wrapping the dispatch calls in try/catch so a failed notification is logged and swallowed instead of blocking tenant creation (see the E2E report's Bug #1/#2). The underlying delivery mechanism itself (actually sending the OTP email/SMS/WhatsApp message) is still not implemented in this environment — registration and verification succeed despite delivery failing, not because delivery works.

17.4 Platform-admin permissions are deny-by-default only for a standalone host

OnboardingCurrentUserPermissionsService is a narrow, claims-based ICurrentUserPermissionsService that only knows how to evaluate Permissions.Onboarding.*; every other permission it sees is denied. This is no longer the whole story when the package is consumed by Shumoul.Api (the normal deployment): a fix registers it with services.TryAddScoped<ICurrentUserPermissionsService, OnboardingCurrentUserPermissionsService>() instead of AddScoped, so when Shumoul.Api's own AddIdentity() has already registered the real, DB-backed CurrentUserPermissionsService (which queries ApplicationDbContext's Roles/RoleClaims) before AddMultiTenancy() runs, that real implementation wins and correctly evaluates every TenancyPermissions/TenantPermissions check — SubscriptionPlans, Tenants, Currencies, SharedDbConnectionStrings, PaymentMethods, etc. — against the actual database, not a stub.

The deny-by-default OnboardingCurrentUserPermissionsService stub only takes effect as a genuine fallback: a standalone host (e.g. Shumoul.Framework.MultiTenancy.Host) that never calls AddIdentity() itself has no other registration to compete with, so it still gets this narrow, Onboarding-only, safe-by-default implementation. In that configuration, every non-Onboarding permission is still denied to everyone, exactly as this section previously described — that part of the analysis remains correct for a standalone host, just not for the Shumoul.Api-hosted configuration this platform actually runs.

17.5 Only the Admin role name is real today

The tenant-admin detection accepts Owner, TenantOwner, Admin, TenantAdmin, Administrator, and SuperAdmin role-claim values, but only Admin is ever actually assigned by the current tenant-provisioning seeder. The others are forward-compatible placeholders, not currently reachable through any real flow.

17.6 Cross-tenant safety proof is partly source-level

The deepest cross-tenant guard (OnboardingService's session.TenantId != CurrentTenantId check) has been verified by direct source review and by live tests where an earlier gate (tenant subscription status) intercepted the cross-tenant attempt first. A live test that reaches that exact code path — two real, fully-provisioned tenants, one admin token from each — has not been executed, since only one dev tenant fixture existed at the time of testing.

17.7 Some TaxController/TaxGroupController actions remain anonymous by design

A handful of read-only dropdown/lookup actions in those two controllers (unrelated to onboarding) are intentionally left public — see Chapter 15 — because they carry no permission attribute of their own and appear to serve pre-registration lookup use cases. This wasn't re-examined as part of this feature's own scope beyond documenting the decision.

17.8 No Angular implementation yet

This entire feature is backend-complete and documented, but the Angular client does not yet exist. See Chapter 13 for the integration guide and a ready-to-use prompt to start that work.

17.9 Settings-engine gaps carried from Phase 8

See Chapter 20, §20.8 — Known Remaining Gaps / Not Blockers for the AppSettingService per-property round-trip performance note, the still-unwired SalesInvoiceTemplateSettings/PrinterSettings groups, and the pre-existing SetLoyaltyAsync parameter-type bug found while adding Phase 8's three new groups. None of these block first-login onboarding.

17.10 Dev/staging subscription data drift — see the remediation tool

A dev/staging tenant's TenantSubscription can point at a SubscriptionPlanPackage row that has since been removed or reorganized, which blocks meaningful entitlement testing for that tenant. A root-admin-only Preview/Apply tool now exists to diagnose and safely repair this — see Subscription Packages & Entitlements, Chapter 16. It is disabled (Apply) by default in every environment and never guesses a target package.

17.11 AppSettings caching is now tenant-isolated

Every AppSettings cache key used by onboarding's settings-patch apply (GetAppSetting<T>/SetAppSetting<T> via IAppSettingService) now embeds the resolved tenant identity — see Subscription Packages & Entitlements, Chapter 17. Previously, two tenants served by the same host process (isolated-DB or shared-DB) could read or invalidate each other's cached settings; InternalOnboardingSettingsPatchService.ApplyGroupAsync<T>'s GetAppSetting<T>(refreshCache: true) call is now also actually honored (it was previously silently ignored).