feat(server): 试运行部署与运营基线(E13/E14/E17/E19/E20/E21)

- 增加 deploy/trialrun:Docker Compose + env 模板 + runbook + 发布/回滚 checklist

- 新增 DB/文件存储备份恢复脚本(backup/restore)

- 新增 system.users 运营接口:创建/启用禁用/重置密码/分配角色 + 审计

- 新增 seed:trialrun 引导管理员账号(一次性口令)

- 补齐 SIGTERM/SIGINT 优雅停机(关闭 job/HTTP/DB)
这个提交包含在:
2026-02-09 01:12:49 +08:00
父节点 89c0ed2ec1
当前提交 4223d81eb4
共修改 19 个文件,包含 1385 行新增和 1 行删除
可执行文件
+45
查看文件
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKUP_DIR="${BACKUP_DIR:-$ROOT_DIR/deploy/trialrun/backups}"
mkdir -p "$BACKUP_DIR"
TS="$(date +%Y%m%d_%H%M%S)"
OUT_FILE="${OUT_FILE:-$BACKUP_DIR/hyb-oa-db-${TS}.dump}"
if [[ -z "${DATABASE_URL:-}" ]]; then
echo "[ERR] DATABASE_URL is required" >&2
exit 1
fi
echo "[INFO] DB backup start: $OUT_FILE"
if command -v pg_dump >/dev/null 2>&1; then
pg_dump "$DATABASE_URL" --format=c --no-owner --no-acl --file "$OUT_FILE"
echo "[OK] DB backup done (pg_dump): $OUT_FILE"
exit 0
fi
if ! command -v docker >/dev/null 2>&1; then
echo "[ERR] pg_dump not found and docker not available" >&2
exit 1
fi
DB_CONTAINER="${DB_CONTAINER:-hyb-oa-trialrun-db}"
POSTGRES_DB="${POSTGRES_DB:-}"
POSTGRES_USER="${POSTGRES_USER:-}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-}"
if [[ -z "$POSTGRES_DB" || -z "$POSTGRES_USER" || -z "$POSTGRES_PASSWORD" ]]; then
echo "[ERR] Using docker fallback requires POSTGRES_DB/POSTGRES_USER/POSTGRES_PASSWORD" >&2
exit 1
fi
docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$DB_CONTAINER" \
pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --format=c --no-owner --no-acl \
>"$OUT_FILE"
echo "[OK] DB backup done (docker exec): $OUT_FILE"
+30
查看文件
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKUP_DIR="${BACKUP_DIR:-$ROOT_DIR/deploy/trialrun/backups}"
mkdir -p "$BACKUP_DIR"
TS="$(date +%Y%m%d_%H%M%S)"
OUT_FILE="${OUT_FILE:-$BACKUP_DIR/hyb-oa-storage-${TS}.tar.gz}"
STORAGE_DIR_HOST="${STORAGE_DIR_HOST:-}"
if [[ -z "$STORAGE_DIR_HOST" ]]; then
if [[ -n "${STORAGE_DIR:-}" && -d "${STORAGE_DIR:-}" ]]; then
STORAGE_DIR_HOST="$STORAGE_DIR"
elif [[ -d "$ROOT_DIR/deploy/trialrun/data/storage" ]]; then
STORAGE_DIR_HOST="$ROOT_DIR/deploy/trialrun/data/storage"
else
echo "[ERR] storage dir not found; set STORAGE_DIR_HOST" >&2
exit 1
fi
fi
echo "[INFO] Storage backup start: $OUT_FILE"
echo "[INFO] Storage dir: $STORAGE_DIR_HOST"
tar -czf "$OUT_FILE" -C "$STORAGE_DIR_HOST" .
echo "[OK] Storage backup done: $OUT_FILE"
+1
查看文件
@@ -18,6 +18,7 @@ echo "=== [2/3] Server Static Checks ==="
node --check src/routes/delegations.js
node --check src/routes/invoicePool.js
node --check src/routes/audit.js
node --check src/routes/users.js
node --check src/jobs/delegationRevokeJob.js
node --check src/jobs/ocrJob.js
node --check src/services/ocr/index.js
可执行文件
+49
查看文件
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKUP_FILE="${1:-${BACKUP_FILE:-}}"
if [[ -z "${BACKUP_FILE:-}" ]]; then
echo "Usage: $0 <backup-file.dump>" >&2
exit 1
fi
if [[ ! -f "$BACKUP_FILE" ]]; then
echo "[ERR] backup file not found: $BACKUP_FILE" >&2
exit 1
fi
if [[ -z "${DATABASE_URL:-}" ]]; then
echo "[ERR] DATABASE_URL is required" >&2
exit 1
fi
echo "[INFO] DB restore start: $BACKUP_FILE"
if command -v pg_restore >/dev/null 2>&1; then
pg_restore --clean --if-exists --no-owner --no-acl -d "$DATABASE_URL" "$BACKUP_FILE"
echo "[OK] DB restore done (pg_restore): $BACKUP_FILE"
exit 0
fi
if ! command -v docker >/dev/null 2>&1; then
echo "[ERR] pg_restore not found and docker not available" >&2
exit 1
fi
DB_CONTAINER="${DB_CONTAINER:-hyb-oa-trialrun-db}"
POSTGRES_DB="${POSTGRES_DB:-}"
POSTGRES_USER="${POSTGRES_USER:-}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-}"
if [[ -z "$POSTGRES_DB" || -z "$POSTGRES_USER" || -z "$POSTGRES_PASSWORD" ]]; then
echo "[ERR] Using docker fallback requires POSTGRES_DB/POSTGRES_USER/POSTGRES_PASSWORD" >&2
exit 1
fi
cat "$BACKUP_FILE" | docker exec -i -e PGPASSWORD="$POSTGRES_PASSWORD" "$DB_CONTAINER" \
pg_restore --clean --if-exists --no-owner --no-acl -U "$POSTGRES_USER" -d "$POSTGRES_DB"
echo "[OK] DB restore done (docker exec): $BACKUP_FILE"
+34
查看文件
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKUP_FILE="${1:-${BACKUP_FILE:-}}"
if [[ -z "${BACKUP_FILE:-}" ]]; then
echo "Usage: $0 <backup-file.tar.gz>" >&2
exit 1
fi
if [[ ! -f "$BACKUP_FILE" ]]; then
echo "[ERR] backup file not found: $BACKUP_FILE" >&2
exit 1
fi
STORAGE_DIR_HOST="${2:-${STORAGE_DIR_HOST:-}}"
if [[ -z "$STORAGE_DIR_HOST" ]]; then
if [[ -n "${STORAGE_DIR:-}" && -d "${STORAGE_DIR:-}" ]]; then
STORAGE_DIR_HOST="$STORAGE_DIR"
else
STORAGE_DIR_HOST="$ROOT_DIR/deploy/trialrun/data/storage"
fi
fi
mkdir -p "$STORAGE_DIR_HOST"
echo "[INFO] Storage restore start: $BACKUP_FILE"
echo "[INFO] Storage dir: $STORAGE_DIR_HOST"
tar -xzf "$BACKUP_FILE" -C "$STORAGE_DIR_HOST"
echo "[OK] Storage restore done: $BACKUP_FILE"