Batch UI Locking
Platform architecture and logic for batch UI locking functionality.
Overview
This page documents how the frontend prevents conflicting or invalid edits in GrowthKit configuration and batch screens.
The term "lock" is used in two related but different ways:
- Configuration edit lock (time/IP-based): Temporary save lock during active editing, based on
lockingIpandlockingDatetime. - Business-state lock (confirmed/published): Permanent or workflow-driven UI restrictions after key state changes:
- Program configuration is confirmed (
programConfiguration.json.confirmed) - Batch is published (
batch.publishedAt)
- Program configuration is confirmed (
Where this documentation comes from
Unlike generated process pages under docs/internal/processes/detailed/, this page is manual systems documentation.
The behavior is derived from implementation in:
platform/src/components/growthkit/ConfirmConfigurationButton.tsxplatform/src/hooks/useProgramConfiguration.tsxplatform/src/hooks/growthkit/useConfigurationLocking.tsxplatform/src/components/growthkit/SaveConfigurationButton.tsxplatform/src/components/growthkit/ConfigurationLockingInfo.tsxplatform/pages/growthkit/configurations/[configurationId]/batches/[batchId].tsx
Locking Mechanism
1) Configuration edit lock (temporary)
The temporary lock is evaluated in useConfigurationLocking:
- Lock metadata is stored on the configuration entity:
lockingIplockingDatetime
- A configuration is considered locked when:
programConfiguration.lockingIp !== currentUserIp- and
lockingDatetimeis still withinNEXT_PUBLIC_CONFIGURATION_LOCK_DURATION_IN_MIN
On update/save, updateProgramConfiguration() calls updateLockingData() first, which writes current editor IP + current timestamp before persisting.
UI effects of temporary configuration lock
- Save button (
SaveConfigurationButton) is disabled when:configurationIsLocked === true, or- another operation is in progress.
ConfigurationLockingInforenders warning text with lock expiry time and countdown when the lock is active.- If an update is attempted while locked, a lock notification is shown and save exits early.
2) Confirmation-based lock (program configuration)
When Team Sales confirms a program configuration:
programConfiguration.json.confirmedis set totrueconfirmationDatetimeis set- configuration is persisted to backend
After confirmation, many configuration inputs across GrowthKit steps are rendered read-only/disabled via checks against programConfiguration.json.confirmed.
Typical patterns:
disabled={programConfiguration.json.confirmed}- editable controls hidden when confirmed
- read-only text/cards shown instead of editors
This is the primary frontend lock that freezes program-level configuration content before downstream batch execution.
3) Published-batch lock (batch editor)
In the batch management page, published state (batch.publishedAt) locks key batch controls:
- Disabled when published:
- Participants per group (
groupSize) input - SSO toggle
- Batch start date picker
- Participants per group (
- Publish/unpublish action visibility toggles:
Publish batchshown only when not publishedUnpublish batchshown when published
This prevents accidental structural changes to a live batch while still allowing explicit unpublish flow.
4) Cross-lock dependency: configuration confirmation gates publishing
Batch publishing is blocked until program configuration is confirmed:
- Publish button disabled when
!programConfiguration.json.confirmed - Tooltip explains why publish is unavailable
This enforces sequence:
- Finalize + confirm program configuration
- Then allow batch publish
User Experience
Users experience locking as deterministic UI state changes rather than backend errors:
- During active concurrent editing: save is disabled and lock info is shown.
- After configuration confirmation: fields become read-only and confirm action turns into a confirmed status indicator (check icon + confirmation timestamp tooltip).
- After batch publish: mutable batch controls are disabled and publish becomes unpublish action.
This makes the state model visible in the interface and reduces accidental edits in critical phases.