Skip to content

Save and handle conflicts

A save gives the SDK plaintext and the version you edited from. It returns a version number, never a key. Behind the call, the SDK generates fresh keys, writes the stored object and updates the folder index. It retries on its own if the save collides with another write. It asks you one thing: what to do when someone else saved first. It asks before it encrypts anything.

Save the next version

save takes the object’s locator, the new content, and the baseVersion the edit was made from. It also takes an optional subject, your own identifier for the record’s subject, such as a medical record number. The SDK tokenizes it into the subject ref under the tenant’s tokenization key. It never sends the identifier itself. If you leave subject out for a record, the SDK uses the dataset’s configured subject field.

const result = await client.objects.save(
locator,
{ kind: 'record', name: 'Visit note', fields },
{ baseVersion: opened.version, subject: mrn },
);

Create a new object

create takes the destination folder instead of a locator. The Seald Healthcare Cloud assigns a random locator. The first version is always 1. create takes the same optional subject. It takes no baseVersion, because nothing can conflict yet.

const created = await client.objects.create(
folder,
{ kind: 'file', name: 'study-4471.dcm', type: 'application/dicom', bytes: fileStream },
{ subject: mrn },
);

Read the outcome

Once the Seald Healthcare Cloud answers, save returns a Decided<SaveOutcome> and create a Decided<Saved>. When the Seald Healthcare Cloud is unreachable, either returns a Drafted instead. Check for a draft first, because it has no outcome field. The sample handles a save result.

if (!('outcome' in result)) return tellOffline(result.draftId); // a Drafted, kind 'draft'
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); // Saved: locator, version, pending
}

A Saved carries the locator, the new version and pending. pending is true only for an AI agent’s own save. That version is written but not current until its delegator accepts it.

A BaseMoved means the version you edited from is no longer current. The SDK has encrypted nothing yet. Choose one:

  • saveAnyway() saves the next version and records the base it was made from.
  • abandon() saves nothing. You can then open the current version and carry your changes over.

What the SDK does for you

  • Generates fresh keys for every save. It reuses nothing from the version before.
  • Writes the stored object, then updates the folder index with the new version.
  • Retries on its own if the save collides with another write.
  • Stores an edit as an encrypted draft when the Seald Healthcare Cloud is unreachable. Nothing is lost while offline.
  • Tokenizes the subject identifier on the device. The identifier itself never leaves it.

Decisions and errors you may see

Outcome or ErrorCodeWhenWhat to do
denyThe policies refuse the save. reason and text say why.Show text. The SDK discards the edit.
challengeThe policies require a fresh multi-factor sign-in first.Call stepUp(), or use the allowed helper.
base-moved (SaveOutcome)Another version was saved after baseVersion.Ask the person to save anyway or abandon and reopen.
draft (Drafted)The Seald Healthcare Cloud is unreachable.Tell the person the edit is queued. It saves once offline work reconnects.

Next