fix(backup): ссылка на архив переживает F5 и повторное скачивание
HEAD-проба в downloadBackup() сжигала одноразовый тикет: Express 4 прогоняет HEAD через GET-хендлер /api/backup/:token, который удалял тикет и файл до отдачи архива, поэтому настоящий GET всегда получал 404 «Ссылка на бэкап устарела». - server.js: GET /api/backup/:token больше не удаляет тикет и файл — ссылка живёт BACKUP_TTL_MS (30 мин), Range-докачка работает - вынес dropBackupTicket(), fs.rmSync обёрнут в try/catch - BACKUP_TICKETS_MAX = 3: лишние тикеты вычищаются по возрасту - sweepBackupStorage() режет с запасом 5 минут сверх TTL - settings.js: убрана HEAD-проба, в #backupStatus рендерится реальная кликабельная ссылка вместо невидимого синтетического <a> - AGENTS.md: раздел 8 — новое поведение + предупреждение про HEAD
This commit is contained in:
@@ -155,7 +155,8 @@ This document defines how AI agents should work with the WhatIDo codebase. Follo
|
||||
- Cert: app generates self-signed cert at build (`certs/cert.pem`), mounted into tailscale container
|
||||
|
||||
### 8. Backup / Restore
|
||||
- **Admin UI**: `POST /api/backup` → тикет + `GET /api/backup/:token` (разовая ссылка, 30 мин), `POST /api/restore` (upload `.tar.gz`)
|
||||
- **Admin UI**: `POST /api/backup` → тикет + `GET /api/backup/:token` (ссылка живёт `BACKUP_TTL_MS`, 30 мин, **скачивание можно повторять** — в том числе после обрыва связи и F5; не «сжигать» тикет `HEAD`-пробой, Express 4 отдаёт HEAD через GET-хендлер), `POST /api/restore` (upload `.tar.gz`)
|
||||
- **Хранение тикетов**: in-memory `Map` (`server.js`), поэтому после рестарта приложения ссылка даёт 404 — это ожидаемо. Одновременно живых тикетов не больше `BACKUP_TICKETS_MAX`, лишние и истёкшие вычищаются `pruneBackupTickets()`; файлы доживают `sweepBackupStorage()` с запасом в 5 минут сверх TTL
|
||||
- **Scripts**: `scripts/backup.sh`, `scripts/restore.sh` (host-level)
|
||||
- Формат архива: `tar.gz` с `data.json` + `uploads/`. Версия формата — `BACKUP_FORMAT_VERSION` в `backup-restore.js` (сейчас `2`), принимаются версии `1..2`; версия пишется в `data.json.version` и возвращается в ответе `POST /api/backup` и `POST /api/restore`
|
||||
- `data.json` содержит `version`, `created_at`, `app` (версия/коммит), `counts` (строки по таблицам + `files`) и сами данные. Таблицы перечислены в `BACKUP_TABLES` — **при добавлении таблицы править её и в `buildBackupArchive`, и здесь**
|
||||
|
||||
Reference in New Issue
Block a user