Merge branch 'fix/backup-rotation-and-deletion' into release/v1.39.3

# Conflicts:
#	docs/api/openapi.yaml
#	src/lib/jobs/apple-health-import-worker.ts
This commit is contained in:
Marc-André Bombeck committed 2026-09-26 21:48:20 +02:00
commit 4409529c89
74 files changed
+4022 -307

No files matched your search

+51 -38
View File
@@ -13353,6 +13353,14 @@ paths:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"401": *a1
"409":
description: An import for this account is already queued or running, and these bytes are not the ones it carries (the
same bytes resolve to that job as a 202). `meta.errorCode` is `import.apple_health.busy` and `meta.jobId`
names the running job; poll it, then upload again. The upload was discarded.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"413":
description: The declared `Content-Length` exceeds 1.5 GB. A body that exceeds the cap without declaring it is refused
by the streaming sink instead, which surfaces as the 422 below.
@@ -13374,8 +13382,8 @@ paths:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"503":
description: No background worker is bound to this process, so the job cannot be queued. The upload was staged and is
discarded; retry once a worker is running.
description: No background worker is bound to this process, or the queue did not accept the job, so nothing will run it.
The staged upload is discarded (and a created job is marked failed); retry once a worker is running.
content:
application/json:
schema:
@@ -31389,31 +31397,31 @@ components:
anamnesis.fact.invalidValue; auth — auth.admin.required, auth.already_authenticated,
auth.mfa.code_invalid, auth.missing, auth.refresh.invalid, auth.refresh.reuse, auth.refresh.revoked,
auth.reproof.failed, auth.reproof.required, auth.reproof.too_weak, auth.scope.insufficient,
auth.stepup.required, auth.token.expired, auth.token.invalid; backup — backup.payload.undecryptable,
backup.restore.active, backup.section.missing, backup.upload.too_large; body-site — body-site.invalid;
coach — coach.budget.exceeded, coach.conversation.invalidTitle, coach.conversation.notFound,
coach.fenced.attachmentConflict, coach.fenced.attachmentLimit, coach.fenced.attachmentNotFound,
coach.fenced.attachmentNotIndexed, coach.fenced.attachmentRequired, coach.fenced.attachmentUnavailable,
coach.fenced.invalid, coach.request.invalid; coach-prefs — coach-prefs.body.invalid_json,
coach-prefs.body.invalid_shape; consent — consent.ai.required; cycle — cycle.bulk.invalid,
cycle.bulk.too_large, cycle.calendar.invalid, cycle.calendar.range, cycle.cycles.invalid,
cycle.day-log.conflict, cycle.day-log.invalid, cycle.disabled, cycle.period.invalid,
cycle.symptom.custom.invalid, cycle.symptom.custom.limit; cycle-prefs — cycle-prefs.body.invalid_json,
cycle-prefs.invalid; disable-coach — disable-coach.body.invalid_json; documents —
documents.chat.conversationNotFound, documents.chat.invalid, documents.inbound.alreadyConfirmed,
documents.inbound.alreadyPartlyConfirmed, documents.inbound.budgetExceeded,
documents.inbound.decryptFailed, documents.inbound.encounterNotFound, documents.inbound.episodeNotFound,
documents.inbound.extractFailed, documents.inbound.factNotFound, documents.inbound.factNotPending,
documents.inbound.factTypeMismatch, documents.inbound.fileTooLarge, documents.inbound.fileType,
documents.inbound.invalidMetadata, documents.inbound.invalidQuery, documents.inbound.invalidUpdate,
documents.inbound.localOcrDisabled, documents.inbound.notFound, documents.inbound.notIndexed,
documents.inbound.pdfNeedsAnthropic, documents.inbound.providerUnsupported,
documents.inbound.quotaExceeded, documents.inbound.rateLimited, documents.inbound.restoreDuplicate,
documents.inbound.restoreGone, documents.inbound.sourceAliasLimit, documents.inbound.uploadBusy,
documents.inbound.uploadTimeout, documents.inbound.vaccinationNotFound, documents.sources.authRefused,
documents.sources.badResponse, documents.sources.browserOnly, documents.sources.invalidAddress,
documents.sources.linkTargetNotFound, documents.sources.notConnected, documents.sources.notFound,
documents.sources.organizationRequired, documents.sources.originNotAllowed,
auth.stepup.required, auth.token.expired, auth.token.invalid; backup — backup.foreign_reference,
backup.key.missing, backup.payload.undecryptable, backup.restore.active, backup.section.missing,
backup.upload.too_large; body-site — body-site.invalid; coach — coach.budget.exceeded,
coach.conversation.invalidTitle, coach.conversation.notFound, coach.fenced.attachmentConflict,
coach.fenced.attachmentLimit, coach.fenced.attachmentNotFound, coach.fenced.attachmentNotIndexed,
coach.fenced.attachmentRequired, coach.fenced.attachmentUnavailable, coach.fenced.invalid,
coach.request.invalid; coach-prefs — coach-prefs.body.invalid_json, coach-prefs.body.invalid_shape;
consent — consent.ai.required; cycle — cycle.bulk.invalid, cycle.bulk.too_large, cycle.calendar.invalid,
cycle.calendar.range, cycle.cycles.invalid, cycle.day-log.conflict, cycle.day-log.invalid,
cycle.disabled, cycle.period.invalid, cycle.symptom.custom.invalid, cycle.symptom.custom.limit;
cycle-prefs — cycle-prefs.body.invalid_json, cycle-prefs.invalid; disable-coach —
disable-coach.body.invalid_json; documents — documents.chat.conversationNotFound,
documents.chat.invalid, documents.inbound.alreadyConfirmed, documents.inbound.alreadyPartlyConfirmed,
documents.inbound.budgetExceeded, documents.inbound.decryptFailed, documents.inbound.encounterNotFound,
documents.inbound.episodeNotFound, documents.inbound.extractFailed, documents.inbound.factNotFound,
documents.inbound.factNotPending, documents.inbound.factTypeMismatch, documents.inbound.fileTooLarge,
documents.inbound.fileType, documents.inbound.invalidMetadata, documents.inbound.invalidQuery,
documents.inbound.invalidUpdate, documents.inbound.localOcrDisabled, documents.inbound.notFound,
documents.inbound.notIndexed, documents.inbound.pdfNeedsAnthropic,
documents.inbound.providerUnsupported, documents.inbound.quotaExceeded, documents.inbound.rateLimited,
documents.inbound.restoreDuplicate, documents.inbound.restoreGone, documents.inbound.sourceAliasLimit,
documents.inbound.uploadBusy, documents.inbound.uploadTimeout, documents.inbound.vaccinationNotFound,
documents.sources.authRefused, documents.sources.badResponse, documents.sources.browserOnly,
documents.sources.invalidAddress, documents.sources.linkTargetNotFound, documents.sources.notConnected,
documents.sources.notFound, documents.sources.organizationRequired, documents.sources.originNotAllowed,
documents.sources.permissionMissing, documents.sources.rateLimited, documents.sources.redirected,
documents.sources.tokenRequired, documents.sources.unavailable, documents.sources.unreachable,
documents.sources.versionTooOld; encounter — encounter.invalid, encounter.link.invalid,
@@ -31423,13 +31431,13 @@ components:
feedback — feedback.body.invalid; health_score_config — health_score_config.invalid,
health_score_config.too_narrow; illness — illness.day-log.invalid, illness.disabled,
illness.episode.chronic-no-resolve, illness.episode.invalid, illness.episode.invalid-window,
illness.episode.parent-not-found, illness.insights.invalid; import — import.write_failed; ingest —
ingest.rate_limited; insights — insights.generate.budgetExceeded, insights.generate.outboundScreened,
insights.generate.profileScopeChanged, insights.generate.scopeChanged; labs —
labs.biomarker.create.invalid, labs.biomarker.duplicate, labs.biomarker.notFound,
labs.biomarker.update.invalid, labs.biomarker.update.referenceRangeInvalid, labs.create.invalid,
labs.ocr.budgetExceeded, labs.ocr.extractFailed, labs.ocr.fileTooLarge, labs.ocr.fileType,
labs.ocr.localOcrDisabled, labs.ocr.pdfNeedsAnthropic, labs.ocr.providerUnsupported,
illness.episode.parent-not-found, illness.insights.invalid; import — import.apple_health.busy,
import.write_failed; ingest — ingest.rate_limited; insights — insights.generate.budgetExceeded,
insights.generate.outboundScreened, insights.generate.profileScopeChanged,
insights.generate.scopeChanged; labs — labs.biomarker.create.invalid, labs.biomarker.duplicate,
labs.biomarker.notFound, labs.biomarker.update.invalid, labs.biomarker.update.referenceRangeInvalid,
labs.create.invalid, labs.ocr.budgetExceeded, labs.ocr.extractFailed, labs.ocr.fileTooLarge,
labs.ocr.fileType, labs.ocr.localOcrDisabled, labs.ocr.pdfNeedsAnthropic, labs.ocr.providerUnsupported,
labs.ocr.rateLimited, labs.restore.invalid, labs.result.notFound, labs.update.invalid,
labs.update.linkedFieldsImmutable, labs.update.numericExpected, labs.update.qualitativeExpected,
labs.update.referenceRangeInvalid, labs.update.sourceReferenceRangeInvalid; managed_profile —
@@ -73040,21 +73048,26 @@ components:
type: string
description: "Stable reason: `backup_not_found`, `backup_changed`, `backup.payload.undecryptable`, `schema_invalid`,
`incompatible_schema_version`, `owner_mismatch`, `owner_not_found`, `backup.section.missing`,
`document_ciphertext_missing`, `time_budget`, `transaction_failed`, `interrupted`, `not_started`,
`enqueue_failed`, `failed_after_commit`, `unexpected`. Every code but `failed_after_commit` means the
account was not changed."
`document_ciphertext_missing`, `backup.key.missing`, `backup.foreign_reference`, `time_budget`,
`transaction_failed`, `interrupted`, `not_started`, `enqueue_failed`, `failed_after_commit`, `unexpected`.
Every code but `failed_after_commit` means the account was not changed."
message:
type: string
sections:
type: array
items:
type: string
keyIds:
type: array
items:
type: string
required:
- code
- message
additionalProperties: false
description: Why the restore did not happen, in a sentence an operator can act on. `sections` names the missing sections
for `backup.section.missing`.
for `backup.section.missing`; `keyIds` names the encryption key ids the file needs and this server cannot open
it with, for `backup.key.missing`.
AdminBackupRestoreJobResponse:
type: object
properties: