Edit a record and save a new version
Save an edited record as its next version. The earlier versions stay readable.
Who can do this: a member of the record’s key domain whose role includes Save.
The samples use the allowed helper from Access decisions.
1. Open the record
Keep version. It is the base of your edit.
const opened = await allowed(await client.objects.open({ locator }));if (opened?.kind !== 'record') return;const fields = edit(opened.fields); // your editorguard case .record(let opened)? = try await allowed(client.objects.open(ObjectRef(locator: locator))) else { return }let fields = edit(opened.fields) // your editorval opened = (allowed(client.objects.open(ObjectRef(locator))) as? Opened.Record)?.record ?: returnval fields = edit(opened.fields) // your editor2. Save with the base version
const result = await client.objects.save( locator, { kind: 'record', name: 'Visit note', fields }, { baseVersion: opened.version },);let result = try await client.objects.save( locator, content: .record(RecordContent(name: "Visit note", fields: fields)), baseVersion: opened.version,)val result = client.objects.save( locator, content = RecordContent(name = "Visit note", fields = fields), baseVersion = opened.version,)3. Handle the outcome, then close
The result is one of three:
| Result | Meaning | What to do |
|---|---|---|
saved | The new version exists. | Show its version. |
base-moved | Someone saved after your base version. | Ask the person, then call saveAnyway() or abandon(). |
| a draft | The device is offline. | Tell the person. The SDK sends it later. |
if (!('outcome' in result)) return tellOffline(result.draftId);const answer = await allowed(result);if (answer?.kind === 'base-moved') { if (await askPerson(`Version ${answer.currentVersion} was saved meanwhile. Save anyway?`)) render(await answer.saveAnyway()); else answer.abandon();} else if (answer) render(answer);opened.close(); // discards the plaintext and its keysswitch result {case .draft(let drafted): tellOffline(drafted.draftId)case .decided(let decided): switch try await allowed(decided) { case .saved(let saved)?: render(saved) case .baseMoved(let moved)?: if await askPerson("Version \(moved.currentVersion) was saved meanwhile. Save anyway?") { render(try await moved.saveAnyway()) } else { moved.abandon() } case nil: break }}opened.close() // discards the plaintext and its keyswhen (result) { is SaveResult.Draft -> tellOffline(result.drafted.draftId) is SaveResult.Decided -> when (val outcome = allowed(result.decided)) { is SaveOutcome.Saved -> render(outcome.saved) is SaveOutcome.BaseMoved -> if (askPerson("Version ${outcome.baseMoved.currentVersion} was saved meanwhile. Save anyway?")) render(outcome.baseMoved.saveAnyway()) else outcome.baseMoved.abandon() null -> {} }}opened.close() // discards the plaintext and its keysNext
- Save and handle conflicts for
subject, drafts and pending versions.