Skip to main content
Version: Latest

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​

#AreaResult
1Swagger/API visibility for all 7 SaaS admin controllersConfirmed — correct GroupName, correct routes, no accidental [AllowAnonymous] beyond the one documented exception (BusinessActivitiesController.GetActiveListAsync)
2Permissions (TenancyPermissions) and MenuClaims.json coverageConfirmed — all 7 permission group keys present; MenuClaimsPermissionSyncTests (3/3) pass
3TenantAccessGuardBehavior coverageConfirmed — 8 existing tests cover root/non-root, own/other-tenant, missing-claim, never-calls-next-when-forbidden
4Entitlement default-behavior asymmetryConfirmed 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
5Default plan / needsCostCenters behaviorConfirmed sufficient via existing TenantStarterKitServiceTests cases
6Live HTTP Apply feasibilityNot 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
7Internal apply bridge disabled-guard safetyConfirmed 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
8Orchestration-service test coverageGap 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
9Idempotency / 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
10Ambiguous multi-row target behaviorConfirmed — 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
11BackEnd internal endpoint securityConfirmed — 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
12Full test suite baselineMultiTenancyApi: 1058/1064 passed; BackEnd: 722/757 passed — see below
13Manual dev-database verificationConfirmed 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").

RepositoryPassedFailedFailure areas
Shumoul.Saas.MultiTenancyApi (Shumoul.Framework.MultiTenancy.Test)1058 / 10646Core 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 / 75735OAuth/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.__EFMigrationsHistory confirms Add_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.AccountManagement and Features.ProductsManagement are both confirmed seeded and active in Saas.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​

FileNew testsWhat it closes
Shumoul.Framework.MultiTenancy.Test/StarterKits/TenantStarterKitProductCatalogStepsShould.cs+2Accounting-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.