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_id column to the variability settings table so per-party flags do not require embedding UUIDs in key names.
  • Introduce onboarding.system, onboarding.tenant, onboarding.party flags (the latter scoped via the new party_id column, 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_backoff in 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_tbl has a non-nullable party_id column. System-party UUID is used for system/tenant-scoped settings.
  • onboarding.system, onboarding.tenant, onboarding.party exist in system_setting_definitions with clear descriptions.
  • System provisioner wizard writes onboarding.system = true on completion.
  • Tenant provisioner wizard writes onboarding.tenant = true on completion (replaces system.bootstrap_mode clear; both coexist during transition).
  • Party provisioner wizard writes onboarding.party = true on completion.
  • Login response party_setup_required is derived from the onboarding.party flag (direct DB read, no cache dependency) rather than party.status.
  • If the party wizard ran but the party is still Inactive, login returns party_setup_required = false and a new party_setup_warning field so the client can show a message box instead of re-launching the wizard.
  • NOTIFY listener max_backoff reduced 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_id column 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.party is checked via a fresh DB read at login time (same pattern as auth_is_tenant_bootstrap_mode) so it is immune to the party cache.
  • system.bootstrap_mode is kept for now and cleared alongside the new onboarding.tenant flag; 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).

Emacs 29.1 (Org mode 9.6.6)