Skip to main content

DeletedRecordResult

One cycle's worth of deletions, plus the cursor state the caller needs to run the next cycle. A transport envelope rather than a stored entity, so it carries no id and no audit fields.

type DeletedRecordResult {
currentCursor: String!
fullReloadRequired: Boolean!
records: [DeletedRecord!]!
truncated: Boolean!
}

Fields

DeletedRecordResult.currentCursor ● String! non-null scalar

The cursor to store and pass as sinceCursor on the next call. Store it on every call that returned, fullReloadRequired: true included — that response still carries the watermark the next cycle has to resume from, and discarding it leaves the caller with no cursor again on the next call, which asks for another full reload. Only a call that failed outright leaves the stored cursor untouched, because a cursor advanced past a cycle whose records never arrived skips that window permanently.

DeletedRecordResult.fullReloadRequired ● Boolean! non-null scalar

A general "give up and reload" escape hatch: an unparseable cursor, a cursor older than the retention floor (30 days — matching the retention contract with the upstream prune job), or a tenant mid-migration. The caller must force a full reload and ignore records, while storing currentCursor as it would on any other call.

DeletedRecordResult.records ● [DeletedRecord!]! non-null object

The deletions found in this cycle. Not offset-paginated: an offset over a set that is still being deleted from is unstable, so truncation is resumed through currentCursor instead, and the call's limit bounds this list per entity type.

DeletedRecordResult.truncated ● Boolean! non-null scalar

True when at least one entity type's scan hit the limit and was truncated. The consumer should re-poll immediately rather than waiting for its next scheduled tick, so the resume window stays short and the watermark does not freeze for longer than necessary.

Returned By

deletedRecords query