diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 29cc4ea93..a4b9df983 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -25189,10 +25189,10 @@ paths: $ref: "#/components/schemas/ErrorEnvelope" "409": description: "The chosen target cannot take the copy, and nothing was stored: a managed profile - (`backup.target.managed_profile`), an account pending deletion (`backup.target.pending_deletion`), an - account that already holds records (`backup.target.holds_records`, `meta.models` naming them), a username - already taken (`backup.target.username_taken`), or a file whose own account is still here - (`backup.owner.exists`)." + (`backup.target.managed_profile`), an account pending deletion (`backup.target.pending_deletion`), an admin + account (`backup.target.admin_account`), an account that already holds records + (`backup.target.holds_records`, `meta.models` naming them), a username already taken + (`backup.target.username_taken`), or a file whose own account is still here (`backup.owner.exists`)." content: application/json: schema: @@ -38717,21 +38717,21 @@ components: auth.session.unavailable, auth.stepup.required, auth.token.expired, auth.token.invalid; backup — backup.foreign_reference, backup.key.missing, backup.owner.exists, backup.owner.missing, backup.payload.undecryptable, backup.restore.active, backup.section.missing, - backup.target.holds_records, backup.target.managed_profile, backup.target.not_found, - backup.target.pending_deletion, backup.target.unconfirmed, backup.target.username_taken, - backup.upload.too_large; biomarkers — biomarkers.unit.locked; 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.confirmRequired, 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; - data_wipe — data_wipe.copy_failed; dawarich — dawarich.credentials_rejected, - dawarich.home_place_unknown, dawarich.invalid, dawarich.not_connected, dawarich.rate_limited, - dawarich.unreachable; day — day.invalid; demo — demo.readOnly; documents — + backup.target.admin_account, backup.target.holds_records, backup.target.managed_profile, + backup.target.not_found, backup.target.pending_deletion, backup.target.unconfirmed, + backup.target.username_taken, backup.upload.too_large; biomarkers — biomarkers.unit.locked; 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.confirmRequired, + 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; data_wipe — data_wipe.copy_failed; dawarich — + dawarich.credentials_rejected, dawarich.home_place_unknown, dawarich.invalid, dawarich.not_connected, + dawarich.rate_limited, dawarich.unreachable; day — day.invalid; demo — demo.readOnly; 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, diff --git a/docs/ops/backup-restore.md b/docs/ops/backup-restore.md index 6f3e1baaa..94bd55a96 100644 --- a/docs/ops/backup-restore.md +++ b/docs/ops/backup-restore.md @@ -112,14 +112,21 @@ exists, and the console then asks where the records should go: count (the setup answers and the cycle settings): the restore replaces both with the copy's. A reading or medication entered on setup's last screen is a record, and the account is refused until it is deleted, because the restore - would delete it too. Managed profiles and accounts pending deletion are not - offered. + would delete it too. Managed profiles, accounts pending deletion and admin + accounts are not offered: an admin account is the operator's, its settings + are read under the operator's wider AI endpoint policy, and its role reaches + every account, so another person's record does not go into it. The file is then uploaded a second time, and its owner is changed to the chosen account as it is read. Nothing else in the file changes. The stored copy is -then that account's copy in every respect: its preview, its download and its -restore are the ordinary ones, and **Restore** on its row brings everything -back under the chosen account. The erased account's id is not stored, not in +then that account's copy in every respect but one: its preview, its download +and its restore are the ordinary ones, and **Restore** on its row brings +everything back under the chosen account. The one difference is that it is +stored as `RETARGETED_UPLOAD_