scripts/

Operational scripts. All of them cd to the project root themselves, so they can be invoked from anywhere: ./scripts/run.sh, scripts/run.sh, whatever.

Daily loop

Script What it does When to run
run.sh Kills whatever holds port 8000, sources .env, starts web.py. Every local start. It's the only correct way to launch — running python web.py bare skips the .env load.
test.sh Full suite, one topic per line with a progress bar. Passing args (scripts/test.sh tests/test_auth.py -k login) forwards straight to pytest instead. Before deploying, after touching anything with a test.
commit.sh git add -A + commit stamped Deploy <date> <time>, then offers to push to the vps remote. Skips the prompt when there's no TTY. Checkpoint commits. Not for real feature commits — the message is a timestamp.
loc.sh Line counts per file type. Curiosity.

Production

The VPS is root@31.70.81.85, app at /var/www/vhosts/beyondmarkets.ai/app.

Script What it does When to run
deploy.sh Offers to run tests, previews deletions, rsyncs the tree, ships .env, updates the systemd unit, pip-installs, ensures Playwright chromium, restarts beyondmarkets. Every prod release.
pull_prod.sh The reverse for git-tracked files prod regenerates: static/symbols/*.json (only when prod's copy is newer) and new static/logos/*.png. Prompts, then leaves the changes uncommitted for review. When prod has refreshed symbol lists or cached new logos and you want them in git.
backup_prod.sh Pulls the irreplaceable prod-only data to backups/<timestamp>/: WAL-safe snapshots of tenants.db / trades.db / symbol_cache.db, the reports tree, logs, and prod .env. Skips the rebuildable tool cache. On demand, and before any risky prod change. Nothing schedules this.
restore_prod.sh Restores a backup_prod.sh backup. Offers /tmp staging before live, verifies file-by-file afterwards, never restores webserver logs. Recovery only. See documentation/backup-plan.md.

deploy.sh syncs with --delete, so the server tree is an exact mirror of this checkout. Anything that lives only on the server must be in its EXCLUDES list or a deploy will wipe it — that list is why .data/, snapshots/ and static/symbols/ survive. It prints a dry-run of every deletion and requires an explicit yes before touching prod.

Two knobs, both for staging a deploy without touching the live app: DEPLOY_TARGET=/tmp/somewhere syncs elsewhere, DEPLOY_CODE_ONLY=1 skips .env, systemd, installs and the restart.

One-offs

Not part of any routine — run by hand, with an argument, when the specific thing is needed.