feat: prepare six-lesson trial backend with reliable rewards and operations
Backend CI / type-check, build, tests (push) Successful in 1m0s
Backend CI / type-check, build, tests (push) Successful in 1m0s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Cutover npm scripts (removed)
|
||||
|
||||
Historical migration scripts lived at `scripts/cutover/` (workspace parent of `backend-nest`). That folder was not recovered after the 2026-08 incident.
|
||||
|
||||
The following **npm scripts were removed** from `package.json` because they pointed at missing files:
|
||||
|
||||
- `test:cutover:g1a`
|
||||
- `test:cutover:g1b`
|
||||
- `test:cutover:g1b2b`
|
||||
- `test:cutover:g1b:dry-run`
|
||||
|
||||
**Use instead:**
|
||||
|
||||
- `npm run test:progression` — Gold Land progression, grader, `reward_ledger`
|
||||
- `npm run test:integration` — auth, economy, API contracts (temporary SQLite only)
|
||||
|
||||
To recover old cutover tooling, restore from Git history or the backend remote archive; do not re-add broken script paths without the files.
|
||||
@@ -0,0 +1,73 @@
|
||||
# Restore SQLite onto the live database path
|
||||
|
||||
The restore script **refuses to write directly** to the path in `DB_PATH` while that variable still points at the live file. That avoids accidental overwrite with the service running.
|
||||
|
||||
`RESTORE_ACK_STOPPED=YES` is an **operator acknowledgment** only — the script does **not** detect whether the backend process is stopped. You must stop the service yourself before swapping files.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Backend **stopped** (no open handles on `app.db`, `-wal`, `-shm`).
|
||||
- A validated backup from `npm run backup:sqlite` (WAL-safe, schema-checked).
|
||||
- Shell access to the data directory (host path or mounted volume).
|
||||
|
||||
## Recommended procedure (same logical database)
|
||||
|
||||
Replace `/app/data/app.db` with your paths.
|
||||
|
||||
1. **Stop backend**
|
||||
|
||||
```powershell
|
||||
docker compose stop backend
|
||||
# or: stop the Node process / systemd unit
|
||||
```
|
||||
|
||||
2. **Optional safety backup of current file**
|
||||
|
||||
```powershell
|
||||
$env:DB_PATH = "/app/data/app.db"
|
||||
$env:BACKUP_DIR = "./backups"
|
||||
npm run backup:sqlite
|
||||
```
|
||||
|
||||
3. **Restore to a sibling file** (not the live `DB_PATH` target)
|
||||
|
||||
```powershell
|
||||
npm run restore:sqlite -- ./backups/app-2026-01-01T12-00-00.db /app/data/app-restored.db
|
||||
```
|
||||
|
||||
Use `RESTORE_ACK_STOPPED=YES` if `/app/data/app-restored.db` already exists from a prior attempt.
|
||||
|
||||
4. **Verify** (optional second check)
|
||||
|
||||
```powershell
|
||||
node -e "import('./scripts/sqlite-app-schema.mjs').then(m=>console.log(m.validateAppSqliteFile('/app/data/app-restored.db')))"
|
||||
```
|
||||
|
||||
5. **Swap files** (preserve previous DB on disk)
|
||||
|
||||
```powershell
|
||||
mv /app/data/app.db /app/data/app.db.pre-restore-<timestamp>
|
||||
rm -f /app/data/app.db-wal /app/data/app.db-shm
|
||||
mv /app/data/app-restored.db /app/data/app.db
|
||||
```
|
||||
|
||||
6. **Start backend** and check readiness
|
||||
|
||||
```powershell
|
||||
docker compose start backend
|
||||
curl http://127.0.0.1:<frontend-port>/health/ready
|
||||
```
|
||||
|
||||
## What the script enforces
|
||||
|
||||
| Rule | Meaning |
|
||||
|------|---------|
|
||||
| No restore when `target === DB_PATH` | Use a sibling path, then rename after stop |
|
||||
| `RESTORE_ACK_STOPPED=YES` if target exists | Confirms you intend to overwrite an existing file |
|
||||
| Schema + `integrity_check` | Backup must match app migrations |
|
||||
| Failed validation | Staging removed; live file unchanged |
|
||||
| Existing target | Moved to `*.pre-restore-<timestamp>.bak` before replace |
|
||||
|
||||
## Development
|
||||
|
||||
Restoring to a **new temp path** does not require stopping production. See `npm run restore:sqlite -- backup.db ./tmp/restored.db`.
|
||||
Reference in New Issue
Block a user