Neither Remnawave nor Marzban has this natively (community tools only,
per docs.rw's own comparison table) — one-click download of a tar.gz
with a consistent SQLite snapshot (via sqlite3's backup API, safe even
under WAL) plus .env, and upload-to-restore from the same file.
Restore validates the archive is real (gzip + tar structure), that
mbs.db is an actual sqlite database with the expected tables (not
just any file named mbs.db), and rejects oversized uploads — before
touching anything live. Takes a timestamped safety copy of the
current db/.env before overwriting, clears stale -wal/-shm siblings
so the restored file doesn't get replayed against the wrong WAL, and
restarts mbs-bot automatically when .env was part of the restore
(api.py isn't restarted from within its own request handler for the
obvious reason).
Verified with a full round-trip test: backup -> mutate state -> restore
-> confirm the mutation is reverted, plus three negative cases (garbage
data, oversized upload, a fake non-sqlite mbs.db) all correctly
rejected with no side effects.
Needs python-multipart for FastAPI's UploadFile — added to
requirements.txt, picked up by the next 'mbs update'.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>