Skip to content

SaaS platform foundations for generated products

Evidence (dated)

This page records observations at a stated revision and date. Re-verify before relying on it; it is not a permanent contract.

Filled 2026-10-09

This page (platform-foundations/saas-platform-foundations.md) was empty. It records what a generated product inherits and what is verified about the generation interface; Factory tenancy is specified separately in tenancy and scope.

Inherited decisions

  • Canonical ADR-0100 (accepted 2026-05-01): tenant tokens per layer (tid, X-Tenant-Id untrusted until validated, tenant-id metadata), resolution order, installation modes SharedDb, DatabasePerTenant, ResidencySilo, DedicatedSingleTenant, fail-closed on conflicting evidence, no key-only loads in shared DB.
  • Canonical ADR-0101 (accepted 2026-06-30): Authorization Server as sole issuer; Identity Service for accounts, credentials, MFA, memberships; gateway validates; backends enforce; Shell owns frontend auth.
  • A product tenant is not a Factory tenant (ADR-0015).

The SaaS templates (verified 2026-10-08)

Repository Aggregate root Descriptor and schemas build/regenerate.ps1 behaviour
ConnectSoft.Saas.TenantsTemplate (ed6fad0, 2026-09-16) Tenant ConnectSoft.Saas.Tenants.json, .schema.json, .entitymodel.schema.json, Microservice.schema.json Without endpoint: parses JSON, returns. With endpoint: prints "Invoking microservice-generator-agent …" and exits 0; no call
ConnectSoft.Saas.ProductsCatalogTemplate (89e5255) Product same shape same as Tenants
ConnectSoft.Saas.EntitlementsTemplate (ad6871f) Entitlement same shape Ignores the endpoint variable; -ValidateOnly parses and returns; otherwise throws "Upstream blocker: the Software Factory generator transport is not implemented"
ConnectSoft.Saas.BillingTemplate (36c193f) Subscription same shape Throws in both branches ("Regeneration blocked …")
ConnectSoft.Saas.MeteringTemplate (a0561ef) UsageMeter same shape same as Tenants; the template also has real transactional usage/quota logic

All five were last committed on 2026-09-16, two months after this site's last commit. None emits the JSON run record (repo, descriptor, aggregateRoot, factory, status, durationMs) described by the canonical starters/saas-factory-generation.md page; parse-only is not schema validation.

The generation interface — provisional

The SaaS descriptor → microservice-generator-agent interface is documented in the Factory's generator specification and the canonical starter page. On 2026-10-14 the product owner decided (ADR-0025) that the descriptor is an import format: BlueprintService maps it into Service and Module blueprints and generation runs only through the recipe path; the Factory exposes no generator endpoint, and the five regenerate scripts are outside the Factory until they submit runs. Documented generated/preserved ownership: generated = EntityModel, PersistenceModel.NHibernate, DatabaseModel.Migrations, ServiceModel (+RestApi, +Grpc), MessagingModel; preserved = DomainModel.Impl, FlowModel(.MassTransit), ActorModel.Orleans, Application(Model), InfrastructureModel, DiagramAsCodeModel, docs, Deployment, observability, pipelines, build scripts. The profile uses NHibernate, dialect-aware migrations and code-first gRPC; MassTransit-only instructions must be reconciled with ADR-0012.

Libraries

ConnectSoft.Extensions.Saas.Abstractions, .AspNetCore, .AspNetCore.Grpc, .AspNetCore.SignalR, .NHibernate, .Orleans, .Options, .Messaging.MassTransit, .Messaging.NServiceBus, .Metering, .Billing, .Testing; SaaS admin MFEs for each template; Blazor.Saas.ShellTemplate.

Reference consumer

DerechHaLev / Bereshit 2.0 runs Gateway, AuthServer, Identity and six domain services from the template estate with per-service Orleans silos and a custom BFF. It was hand-built from the templates, not generated.