Module: Namespaces::Stateful::StatePreservation

Defined in:
app/models/concerns/namespaces/stateful/state_preservation.rb

Overview

State Preservation allows the state machine to “remember” the state a namespace was in before a transition, so it can be restored later when a corresponding reverse transition occurs.

Example flow:

1. Namespace is in :archived state
2. User triggers :schedule_deletion -> state becomes :deletion_scheduled
   - The previous state (:archived) is saved to state_metadata
3. User triggers :cancel_deletion -> state is restored to :archived
   - The preserved state is read and used to determine the target state
   - The preserved state is then cleared from state_metadata

Without preservation, cancel_deletion would always return to :ancestor_inherited, losing the fact that the namespace was archived before deletion was scheduled.

## How STATE_MEMORY_CONFIG works

The config maps preserve events to their corresponding restore events:

STATE_MEMORY_CONFIG = {
  schedule_deletion: :cancel_deletion   # key = preserve, value = restore
}

Preserved states are stored in state_metadata under the preserve event’s name:

 = {
  'preserved_states' => {
    'schedule_deletion' => 'archived'
  }
}

When a restore event occurs (e.g., :cancel_deletion), we perform a reverse lookup using Hash#key to find the corresponding preserve event, then use that key to retrieve and clear the preserved state.

Constant Summary collapse

STATE_MEMORY_CONFIG =

Maps events that should preserve state to their corresponding restore events. Key: event that triggers state preservation (saves the “from” state) Value: event that triggers state restoration (restores to the saved state)

Examples:

With schedule_deletion => cancel_deletion

# When :schedule_deletion fires, the current state is saved
# When :cancel_deletion fires, the saved state is restored and cleared

With start_deletion => reschedule_deletion

# When :start_deletion fires on a child namespace (not explicitly scheduled),
# the current state is saved so it can be restored if deletion fails
# When :reschedule_deletion fires, the saved state is restored and cleared
{
  schedule_deletion: :cancel_deletion,
  start_deletion: :reschedule_deletion
}.freeze