SilverSight/scripts/fix_appflowy.py
allaun 85141a4b94 feat(nuvmap,braid): NUVMAP port + Rossby/Kelvin braid correspondence
- Port NUVMAP projection engine from Research Stack to SilverSight
  with Q16_16 fixed-point (zero Float) and CBOR serialization
- Add Rotational Wave — Braid Correspondence formalization at boundary
  (ChiralLabel, RossbyDrift, rossby_convergence_bound stubbed,
   kelvin_wave_eigensolid proven)
- Add auto-pipeline CI workflow, webhook receiver, Forgejo MCP server
- Add SOPS/Age encryption config
- Add stack compose for portable deployment
- Add rotational wave design doc
2026-06-30 16:38:11 -05:00

92 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""Last-resort AppFloyo fix — runs all commands directly via SSH."""
import subprocess, time
HOST = "allaun@100.92.88.64"
def sh(cmd, timeout=60):
r = subprocess.run(["ssh", "-o", "ConnectTimeout=10", HOST, cmd],
capture_output=True, text=True, timeout=timeout)
if r.stdout.strip():
print(r.stdout.strip()[:200])
if r.returncode != 0:
err = r.stderr.strip()[:100]
if err:
print(f" (stderr: {err})")
def run(cmd, timeout=60):
return subprocess.run(["ssh", "-o", "ConnectTimeout=10", HOST, cmd],
capture_output=True, text=True, timeout=timeout).returncode
print("1. Postgres")
run("podman restart arxiv-pg 2>/dev/null", timeout=15)
time.sleep(10)
run("pg_isready -h localhost", timeout=10)
print("2. AppFloyo DB + Redis")
sh("podman exec arxiv-pg psql -U postgres -c 'CREATE DATABASE appflowy' 2>/dev/null || true", timeout=15)
sh("podman exec arxiv-pg psql -U postgres -d appflowy -c 'CREATE SCHEMA IF NOT EXISTS auth' 2>/dev/null", timeout=10)
run("podman run -d --name redis --network host docker.io/library/redis:7-alpine 2>/dev/null", timeout=20)
print("3. GoTrue init migration")
init_sql = subprocess.run(
["podman", "run", "--rm", "docker.io/appflowyinc/gotrue:0.15.1", "cat", "/migrations/00_init_auth_schema.up.sql"],
capture_output=True, text=True, timeout=15
).stdout.replace("{{ index .Options \"Namespace\" }}", "auth")
proc = subprocess.Popen(
["ssh", HOST, "podman exec -i arxiv-pg psql -U postgres -d appflowy -v ON_ERROR_STOP=1"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = proc.communicate(input=init_sql.encode(), timeout=60)
print(f" Init: {stdout.decode()[:100] if stdout else 'ok'}")
print("4. Mark all GoTrue migrations done")
migs = subprocess.run(
["podman", "run", "--rm", "docker.io/appflowyinc/gotrue:0.15.1", "ls", "/migrations/"],
capture_output=True, text=True, timeout=15
)
versions = sorted(set(f.split("_")[0] for f in migs.stdout.strip().split("\n") if f.endswith(".up.sql")))
for v in versions:
run(f"podman exec arxiv-pg psql -U postgres -d appflowy -c \"INSERT INTO auth.schema_migrations (version) VALUES ('{v}') ON CONFLICT DO NOTHING\"", timeout=10)
ct = run("podman exec arxiv-pg psql -U postgres -d appflowy -t -A -c 'SELECT COUNT(*) FROM auth.schema_migrations'", timeout=10)
print(f" {len(versions)} versions, tracked")
print("5. Pre-create one_time_tokens")
subprocess.Popen(
["ssh", HOST, "podman exec -i arxiv-pg psql -U postgres -d appflowy"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
).communicate(
input=b"CREATE TABLE IF NOT EXISTS auth.one_time_tokens (id uuid PRIMARY KEY, user_id uuid, token_type text NOT NULL, token_hash text NOT NULL, expires_at timestamptz NOT NULL, created_at timestamptz NOT NULL DEFAULT now());",
timeout=30
)
print("6. Start GoTrue")
run("podman rm -f appflowy_gotrue_1 2>/dev/null", timeout=10)
sh(
'podman run -d --name appflowy_gotrue_1 --network host '
'-e GOTRUE_ADMIN_EMAIL=admin@researchstack.info '
'-e GOTRUE_ADMIN_PASSWORD=admin123 '
'-e GOTRUE_DISABLE_SIGNUP=false '
'-e GOTRUE_SITE_URL=https://researchstack.info/appflowy '
'-e GOTRUE_URI_ALLOW_LIST=** '
'-e GOTRUE_JWT_SECRET=jwt_ '
'-e GOTRUE_JWT_EXP=3600 '
'-e GOTRUE_DB_DRIVER=postgres '
'-e API_EXTERNAL_URL=https://researchstack.info/appflowy/gotrue '
"-e DATABASE_URL='postgres://postgres:postgres@localhost:5432/appflowy' "
'-e PORT=9999 '
'-e GOTRUE_MAILER_AUTOCONFIRM=true '
'-e GOTRUE_LOG_LEVEL=info '
'-e REDIS_ENABLED=true '
'-e REDIS_URL=redis://localhost:6379 '
'docker.io/appflowyinc/gotrue:0.15.1', timeout=20
)
time.sleep(10)
hc = subprocess.run(["ssh", "-o", "ConnectTimeout=5", HOST,
"curl -s -o /dev/null -w '%{http_code}' http://localhost:9999/health"],
capture_output=True, text=True, timeout=10)
print(f" GoTrue: {hc.stdout.strip()}")