AI Implementation feature(919): Admin Area System: Database Backup/Restore and Danger Zone 1.02 (#64)
This commit was merged in pull request #64.
This commit is contained in:
@@ -4,7 +4,7 @@ title: Admin System Endpoints
|
||||
description: Admin-only destructive System operations: backup download, restore validate/commit, re-authenticated confirmation tokens, reset-scores, and wipe-challenges.
|
||||
resource: backend/src/modules/admin/system/admin-system.controller.ts
|
||||
tags: [api, admin, system, backup, restore, danger-zone, confirmation-tokens]
|
||||
timestamp: 2026-07-23T13:27:25Z
|
||||
timestamp: 2026-07-23T15:46:55Z
|
||||
---
|
||||
|
||||
# Overview
|
||||
@@ -127,9 +127,15 @@ Flow:
|
||||
by cloning the live DB, then clearing every application table and
|
||||
inserting the archived rows in FK-safe order. Uploads are copied
|
||||
aside as `<UPLOAD_DIR>.restore-stage-<stamp>` and the live
|
||||
database + uploads are swapped atomically via
|
||||
`FilesystemTransactionService.stageSwap()` (with a `restore-backup`
|
||||
rollback handle).
|
||||
database + uploads are swapped as one recoverable generation via
|
||||
`FilesystemTransactionService.stageSwap(..., { stagingDir })` (with a
|
||||
`restore-backup` rollback handle). Before moving either live path, the
|
||||
service writes `<SYSTEM_OP_STAGING_DIR>/<transactionId>/manifest.json`.
|
||||
The manifest advances through `prepared`, `live-snapshotted`,
|
||||
`replacements-installed`, and `verified`; commit removes rollback and
|
||||
manifest artifacts. SQLite `-wal` and `-shm` sidecars travel with the
|
||||
database rollback generation and stale sidecars are removed from the
|
||||
replacement.
|
||||
|
||||
The offline clone rebuild begins by capturing the exact SQL of the
|
||||
deployment-wide `trg_user_last_admin_update` and
|
||||
@@ -161,6 +167,25 @@ Flow:
|
||||
revoked via `AuthService.revokeAllRefreshSessions()` so the SPA is
|
||||
forced back to `/login`.
|
||||
|
||||
### Startup recovery contract
|
||||
|
||||
Before TypeORM opens SQLite, `DatabaseInitService.init()` calls
|
||||
`FilesystemTransactionService.recoverTransactions()` using
|
||||
`SYSTEM_OP_STAGING_DIR` (default `<DATA_DIR>/.system-staging`):
|
||||
|
||||
| Manifest phase | Required complete generation | Startup action |
|
||||
|---|---|---|
|
||||
| `prepared` | Existing live paths | Keep the old generation and remove the transaction manifest. |
|
||||
| `live-snapshotted` | Every rollback path exists and corresponding live path is absent | Restore all rollback paths, including tracked SQLite sidecars. |
|
||||
| `replacements-installed` or `verified` | Every replacement live path and rollback path exists | Keep the complete new generation and remove rollback/staged artifacts. |
|
||||
| Any ambiguous or mixed state | Neither generation is complete | Throw `SYSTEM_RESTORE_FAILED`, preserve the manifest and artifacts, and abort startup. |
|
||||
| `committed` or `rolled-back` | Terminal | Remove the transaction directory. |
|
||||
|
||||
After manifest recovery, startup best-effort removes stale unowned
|
||||
`.rollback-*`, `.restore-stage-*`, and `.wipe-stage-*` artifacts near the
|
||||
configured database/uploads paths. Fresh artifacts and paths referenced by a
|
||||
manifest are retained.
|
||||
|
||||
Returns `{ ok: true, operation: 'restore-backup' }`.
|
||||
|
||||
## POST /confirmations
|
||||
@@ -301,7 +326,9 @@ curl -sS ... -d '{"operation":"reset-scores","token":"<raw>"}'
|
||||
| Restore | `backend/src/modules/admin/system/restore.service.ts` |
|
||||
| Confirmation tokens | `backend/src/modules/admin/system/confirmation-token.service.ts` |
|
||||
| Danger zone | `backend/src/modules/admin/system/danger-zone.service.ts` |
|
||||
| Filesystem swap | `backend/src/modules/admin/system/filesystem-transaction.service.ts` |
|
||||
| Filesystem swap + recovery | `backend/src/modules/admin/system/filesystem-transaction.service.ts` |
|
||||
| Shared filesystem module | `backend/src/modules/admin/system/filesystem-transaction.module.ts` |
|
||||
| Startup recovery wiring | `backend/src/database/database-init.service.ts`, `backend/src/database/database.module.ts` |
|
||||
| Staging dir helper | `backend/src/common/utils/upload.ts` (`resolveSystemStagingDir`) |
|
||||
| Password re-auth / revoke | `backend/src/modules/auth/auth.service.ts` (`reauthenticateAdmin`, `revokeAllRefreshSessions`) |
|
||||
| Error codes | `backend/src/common/errors/error-codes.ts` |
|
||||
@@ -313,4 +340,4 @@ curl -sS ... -d '{"operation":"reset-scores","token":"<raw>"}'
|
||||
| Front-end route | `frontend/src/app/app.routes.ts` (admin child `system`) |
|
||||
| Cross-store invalidation | `frontend/src/app/core/services/system-data-change.service.ts` |
|
||||
| Forced logout helper | `frontend/src/app/core/services/auth.service.ts` (`forceServerInvalidation`) |
|
||||
| Tests | `tests/backend/admin-system-authorization.spec.ts`, `admin-system-backup.spec.ts`, `admin-system-confirmation-token.spec.ts`, `admin-system-danger.spec.ts`, `admin-system-restore-validation.spec.ts`, `admin-system-restore-commit.spec.ts`; `tests/frontend/admin-system.pure.spec.ts` |
|
||||
| Tests | `tests/backend/admin-system-authorization.spec.ts`, `admin-system-backup.spec.ts`, `admin-system-confirmation-token.spec.ts`, `admin-system-danger.spec.ts`, `admin-system-restore-validation.spec.ts`, `admin-system-restore-commit.spec.ts`, `database-init-recovery.spec.ts`, `filesystem-transaction.spec.ts`; `tests/frontend/admin-system.pure.spec.ts` |
|
||||
|
||||
Reference in New Issue
Block a user