Story: Symmetric onboarding flags for provisioner wizards
Table of Contents
This page documents a story in Sprint 19. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
Goal
Three provisioner wizards exist (system, tenant, party) but only the tenant
wizard uses a variability flag (system.bootstrap_mode) to record completion.
The party wizard relies solely on party.status = Inactive= checked via a
server-side cache that can be stale for ~30s after a heavy party import. This
causes the party wizard to refire after logout/login even though it completed
successfully.
Deliver a symmetric, cache-immune onboarding flag for all three wizards:
- Add a
party_idcolumn to the variability settings table so per-party flags do not require embedding UUIDs in key names. - Introduce
onboarding.system,onboarding.tenant,onboarding.partyflags (the latter scoped via the newparty_idcolumn, using the system party for system/tenant-level entries). - Wire all three wizards to write their flag on completion and check it at login, bypassing the party status cache entirely.
- Also reduce
max_backoffin the NOTIFY listener from 30s to 5s and document the thread-starvation risk under heavy import load.
Status
| Field | Value |
|---|---|
| State | BACKLOG |
| Parent sprint | Sprint 19 |
| Now | Investigation complete; ready to implement. |
| Waiting on | PR for unify-entity-timestamps to merge. |
| Next | Task 1: schema + C++ layer for party_id in variability. |
| Last touched | 2026-06-03 |
Acceptance
ores_variability_system_settings_tblhas a non-nullableparty_idcolumn. System-party UUID is used for system/tenant-scoped settings.onboarding.system,onboarding.tenant,onboarding.partyexist insystem_setting_definitionswith clear descriptions.- System provisioner wizard writes
onboarding.system = trueon completion. - Tenant provisioner wizard writes
onboarding.tenant = trueon completion (replacessystem.bootstrap_modeclear; both coexist during transition). - Party provisioner wizard writes
onboarding.party = trueon completion. - Login response
party_setup_requiredis derived from theonboarding.partyflag (direct DB read, no cache dependency) rather thanparty.status. - If the party wizard ran but the party is still Inactive, login returns
party_setup_required = falseand a newparty_setup_warningfield so the client can show a message box instead of re-launching the wizard. - NOTIFY listener
max_backoffreduced from 30s to 5s. - Full build green.
Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Add party_id column to variability settings | BACKLOG | Schema, entity, mapper, repository, service. | ||
| Introduce onboarding.* flag definitions | BACKLOG | system_setting_definitions + service accessors. | ||
| Wire wizards + fix login party_setup_required | BACKLOG | All three wizards write flag; auth bypasses party cache. | ||
| Reduce NOTIFY listener max_backoff to 5s | BACKLOG | Mitigation for heavy-import notification lag. |
Decisions
- The
party_idcolumn is non-nullable: system/tenant flags use the system party UUID (available on every tenant). This avoids a nullable FK and keeps index cardinality well-defined. onboarding.partyis checked via a fresh DB read at login time (same pattern asauth_is_tenant_bootstrap_mode) so it is immune to the party cache.system.bootstrap_modeis kept for now and cleared alongside the newonboarding.tenantflag; removal is a follow-on clean-up task.
Out of scope
- Removing
system.bootstrap_mode(follow-on). - Migrating the system provisioner wizard to use
onboarding.system(it currently clears bootstrap mode implicitly; defer to a follow-on). - Fixing the root cause of NOTIFY thread starvation under import load (tracked separately; the max_backoff reduction is a mitigation).