Production Readiness Checklist
A focused verification and hardening pass run after this guide's initial publication (2026-07-18), covering the full Business Onboarding → Settings Patch → Entitlement → Tenant Starter Kit → Product Catalog chain. Scope was deliberately narrow: close the remaining pre-production gaps by verifying real behavior — through existing/new tests and direct dev-database inspection — never by adding features, changing onboarding business decisions, or touching production tenants.
What this pass covered
| # | Area | Result |
|---|---|---|
| 1 | Swagger/API visibility for all 7 SaaS admin controllers | Confirmed — correct GroupName, correct routes, no accidental [AllowAnonymous] beyond the one documented exception (BusinessActivitiesController.GetActiveListAsync) |
| 2 | Permissions (TenancyPermissions) and MenuClaims.json coverage | Confirmed — all 7 permission group keys present; MenuClaimsPermissionSyncTests (3/3) pass |
| 3 | TenantAccessGuardBehavior coverage | Confirmed — 8 existing tests cover root/non-root, own/other-tenant, missing-claim, never-calls-next-when-forbidden |
| 4 | Entitlement default-behavior asymmetry | Confirmed via 2 new tests — accounting chain defaults to Blocked (hard true Include* flags), product chain defaults to soft Skipped (nullable Include* flags). Deliberate Phase 6C design, already documented — not changed |
| 5 | Default plan / needsCostCenters behavior | Confirmed sufficient via existing TenantStarterKitServiceTests cases |
| 6 | Live HTTP Apply feasibility | Not exercised — the internal apply bridge is Enabled: false in the committed Host appsettings.json, with BackEndBaseUrl pointing at a real production hostname and no dev override. Per explicit instruction, this was left untouched and reported honestly rather than enabled for this pass — see below |
| 7 | Internal apply bridge disabled-guard safety | Confirmed via 7 new tests (one per bridge) + 3 new config-binding assertions — every bridge returns a clear Succeeded=false failure without ever attempting an outbound HTTP call when disabled |
| 8 | Orchestration-service test coverage | Gap closed — TenantCostCenterTemplateApplyService and TenantInventoryAccountCategoryTemplateApplyService previously had zero test coverage of their own (only seeder/validation/controller-authorization layers were tested). 19 new tests added across both files |
| 9 | Idempotency / safe re-run (BackEnd apply services) | Confirmed — all 7 BackEnd internal apply services already have a ReApplyingTheSameSnapshotIsIdempotent-style test; re-applying skips existing rows by Code/Name and only fills blank fields when Force=true |
| 10 | Ambiguous multi-row target behavior | Confirmed — only Inventory Account Category Templates has a true multi-target-mode concept (CreateDefault/UpdateSingleExisting/UpdateExplicitTarget/AmbiguousTarget), already tested. The other 6 flows only have an ambiguous-duplicate-code/name block, also already tested |
| 11 | BackEnd internal endpoint security | Confirmed — all 7 internal endpoints require a custom X-Shumoul-Internal-Key header compared via string.Equals(..., Ordinal); on a missing/invalid key only a warning log is written, and the raw key value is never interpolated into any log, exception, or response body |
| 12 | Full test suite baseline | MultiTenancyApi: 1058/1064 passed; BackEnd: 722/757 passed — see below |
| 13 | Manual dev-database verification | Confirmed read-only — see below |
Internal apply bridge — a confirmed, deliberate safeguard
AccountingChartTemplateApplyBridgeSettings (shared by all 7 bridges) ships with Enabled: false in the
committed Shumoul.Framework.MultiTenancy.Host/appsettings.json, and BackEndBaseUrl set to a real
production hostname with no appsettings.Development.json override. This means the bridge is safe by
default in every environment today: enabling it without also correcting the URL would point a dev/test
call at production.
This pass treated that as a correctly-conservative, pre-existing safeguard — not a bug to fix — and did not touch the appsettings file, enable the bridge, or attempt a live HTTP Apply round-trip against any tenant. Readiness was instead verified as thoroughly as possible without it: by code inspection, the full existing test suites, 19 new targeted tests, and read-only dev-database queries. This mirrors the same honest-limitation approach Phase 5F already used (see Known Limitations).
Full test suite baseline
Both baselines below were confirmed to be pre-existing and unrelated to this pass — neither repo had
any source change touching the failing areas (verified via git status/git diff before attributing a
failure as "pre-existing").
| Repository | Passed | Failed | Failure areas |
|---|---|---|---|
Shumoul.Saas.MultiTenancyApi (Shumoul.Framework.MultiTenancy.Test) | 1058 / 1064 | 6 | Core tenant-resolution library: MultiTenantMiddlewareShould (2), TenantResolverShould (2), RouteStrategyShould (1), EntityTypeBuilderExtensionsShould (1) — unrelated to onboarding/starter-kit/product-catalog |
Shumoul.Saas.Api (Shumoul.Application.Tests) | 722 / 757 | 35 | OAuth/MCP integration (OAuthServiceTests, RegisterClientTests) and DateOnlyJsonConverterTests — unrelated to onboarding/starter-kit/product-catalog; matches the same 722/35 baseline already recorded in Phase 6C's release record |
Manual dev-database verification (read-only)
Run against the real dev database (SHUMOUL-DEV-MNG), read-only, no live Apply performed:
- Migrations:
dbo.__EFMigrationsHistoryconfirmsAdd_TenantStarterKitApplyLog_ProductCatalogColumns(Phase 6C's migration) is the latest applied migration. - Seed data present:
BusinessActivities(5),CostCenterTemplates(5) /…Items(45),InventoryAccountCategoryTemplates(10) /…Accounts(130),ProductCatalogTemplates(5) /…Items(10),ProductCatalogPrerequisiteTemplates(5). - All template-apply log tables are empty (
TenantStarterKitApplyLogs,TenantCostCenterTemplateApplyLogs,TenantInventoryAccountCategoryTemplateApplyLogs,TenantAccountingChartTemplateApplyLogs,TenantProductCatalogItemTemplateApplyLogs,TenantProductCatalogPrerequisiteTemplateApplyLogs) — consistent with no live Apply having been run, by this pass or otherwise, against the dev database's real tenants. - Tenant 555001 (the designated safe E2E test tenant — see Known Limitations) is confirmed active and verified.
Features.AccountManagementandFeatures.ProductsManagementare both confirmed seeded and active inSaas.SubscriptionFeatures.
No connection strings, passwords, or other secrets were printed at any point during this verification —
queries were built by parsing the connection string's components in-memory and passing them directly to
sqlcmd, never echoing them to output.
New test coverage added by this pass
| File | New tests | What it closes |
|---|---|---|
Shumoul.Framework.MultiTenancy.Test/StarterKits/TenantStarterKitProductCatalogStepsShould.cs | +2 | Accounting-Blocked-vs-product-Skipped entitlement asymmetry; confirms zero underlying Preview/Apply service calls when both chains are unentitled |
Shumoul.Framework.MultiTenancy.Test/Security/AllApplyBridgesShould.cs | +7 (new file) | Every one of the 7 internal apply bridges returns a safe, non-throwing failure when disabled, without ever sending a real HTTP request |
Shumoul.Framework.MultiTenancy.Test/AccountingChartTemplates/AccountingChartTemplateApplyBridgeSettingsConfigurationShould.cs | +3 assertions (2 existing tests extended) | The 3 product-catalog bridge path defaults were never previously asserted, despite the test's whole purpose being to guard this settings class against a silent config-binding regression |
Shumoul.Framework.MultiTenancy.Test/CostCenterTemplates/TenantCostCenterTemplateApplyServiceShould.cs | +8 (new file) | TenantCostCenterTemplateApplyService had zero orchestration-level test coverage; now covers template-not-found/inactive/no-items, tenant-not-found/inactive, missing entitlement, Preview-never-writes-log, Apply-writes-exactly-one-log-row (success and failure), and the needsCostCenters onboarding-warning behavior |
Shumoul.Framework.MultiTenancy.Test/InventoryAccountCategoryTemplates/TenantInventoryAccountCategoryTemplateApplyServiceShould.cs | +11 (new file) | TenantInventoryAccountCategoryTemplateApplyService had zero orchestration-level test coverage; now covers the same validation set plus TargetInventoryAccountCategoryId forwarding and the AmbiguousTarget pass-through case |
Total: 31 new tests, all passing on first run.
Package release discipline for this pass
Every change in this pass was to Shumoul.Framework.MultiTenancy.Test (a test project, never packaged or
shipped) plus this documentation chapter — Shumoul.Framework.MultiTenancy.Api's own shipped source was
not modified. Per the release discipline rule,
a package version bump was correctly not triggered; the package remains at 1.0.114.
