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 closedTenantCostCenterTemplateApplyService 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.