Skip to main content
Restricted Access: This documentation is only accessible to @tenzo.ai and @salv.ai email addresses.

Goal

The Configure tab used to share fetch, save, and dirty state through hook-call order and four parallel baselines (originalScriptValues, JSON lastSaved*Refs, orgBackgroundInfoBaselineRef). Those clusters now share one last-confirmed snapshot.

Three layers

Unsaved state is not in either store. It lives in useScriptFormState as two flags plus their synchronous nav refs, and dirty is a function of the draft: useScriptDirtyCheck is keyed on form values and reads the snapshot at comparison time. Anything that moves lastSaved away from the draft therefore has to write the form in the same turn or set the flag itself, because no comparison is scheduled on a commit’s behalf. orgBackgroundInfoBaselineRef is still the PATCH gate: a failed org GET leaves it unchanged (or null if it never loaded) so the editor will not write empty defaults over org-wide settings. Hydrate on failure copies that leftover baseline into lastSaved.orgBackground instead of an empty sentinel. Discard restores org text from the baseline ref, not from a failed-GET snapshot.

Actions

  • hydrate(campaignId, snapshot) — fetch writes this once after mapScriptRead and settleFetchedScript (virtual-calendar follow-up users, session auto-match, new-script default outro). Then one setValues.
  • commit(campaignId, patch) — save (and question-bank persist, org PATCH, version-restore clocks) merge into lastSaved. No-op if campaignId does not match or lastSaved is null. Clock fields (currentScriptVersionId, cosmosUpdatedAt) only advance when the patch value is non-null.
  • clear(campaignId) — campaign switch. Same turn as form reset so a late commit of the previous job cannot land.
lastSaved == null means “not hydrated yet.” Dirty skips; the post-generation one-shot waits.

Late settle

Calendar provider, SWR outro text, and session auto-match can arrive after hydrate. A small effect patches only fields the draft still matches on lastSaved (so a dirty call intro cannot block a virtual-calendar user clear), then commits those same field patches. User edits to a settled field are left alone. Post-generation one-shot save waits until calendar integration has resolved so it cannot persist pre-settle values.

What this page does not cover

  • Phase 2 — collapse fetch/save/version into useJobDocumentController.
  • Phase 3 — provider composition. JobDocumentProviders nests four providers; its doc comment describes the grouping.
  • Phase 4 — org-template bootstrap aggregator. See Job editor bootstrap.