架构治理: - Feature Flag 落地: Cargo.toml [features] default=["diary"] + main.rs cfg 条件编译 - 环境配置统一: AppConfig 类 + --dart-define 注入 + SSE 端口 8080→3000 修复 搜索替代方案 (无 FTS): - SearchBloc + 标签/心情筛选接入后端 API - JournalRepository 扩展 mood/tag 筛选参数 - 搜索页 UI 接入实际数据(替换占位文本) 家长中心最小集 (PIPL 合规): - 后端: parent_service (绑定/查看/导出/删除/解绑) + parent_handler (6 个 API 端点) - 前端: ParentBloc + ParentPage 功能完整实现 - 绑定孩子、只读查看日记、导出数据、删除数据、解绑 Docker 部署: - verify.sh 健康检查脚本 (Axum/PG/Redis/OpenAPI 四项检查) 测试修复: - home_bloc_test / calendar_bloc_test 适配 JournalRepository 新参数 验证: flutter test 84/84 pass, cargo test 76/76 pass, cargo check pass
124 lines
3.1 KiB
Bash
Executable File
124 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# verify.sh — 暖记部署健康检查脚本
|
|
#
|
|
# 用法: ./verify.sh [--host HOST] [--timeout SECONDS]
|
|
# 默认: host=localhost, timeout=60
|
|
|
|
set -euo pipefail
|
|
|
|
# 配置
|
|
HOST="${VERIFY_HOST:-localhost}"
|
|
TIMEOUT="${VERIFY_TIMEOUT:-60}"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
# 颜色输出
|
|
green() { echo -e "\033[32m✓ $1\033[0m"; }
|
|
red() { echo -e "\033[31m✗ $1\033[0m"; }
|
|
info() { echo -e "\033[36m→ $1\033[0m"; }
|
|
|
|
# 解析参数
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--host) HOST="$2"; shift 2 ;;
|
|
--timeout) TIMEOUT="$2"; shift 2 ;;
|
|
*) echo "未知参数: $1"; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
info "暖记部署健康检查 (host=$HOST, timeout=${TIMEOUT}s)"
|
|
echo "---"
|
|
|
|
# 等待服务启动
|
|
info "等待服务启动..."
|
|
elapsed=0
|
|
until [ $elapsed -ge $TIMEOUT ]; do
|
|
if curl -sf "http://$HOST:3000/api/v1/health" > /dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
elapsed=$((elapsed + 2))
|
|
done
|
|
|
|
if [ $elapsed -ge $TIMEOUT ]; then
|
|
red "服务在 ${TIMEOUT}s 内未启动"
|
|
exit 1
|
|
fi
|
|
|
|
# 1. 检查 Axum 后端健康
|
|
echo ""
|
|
info "检查后端服务..."
|
|
health_response=$(curl -sf "http://$HOST:3000/api/v1/health" 2>/dev/null || echo "FAILED")
|
|
if [[ "$health_response" != "FAILED" ]]; then
|
|
green "后端 Axum (port 3000): 正常"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "后端 Axum (port 3000): 不可达"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
|
|
# 2. 检查 PostgreSQL
|
|
info "检查 PostgreSQL..."
|
|
if command -v psql &> /dev/null; then
|
|
if PGPASSWORD=123123 psql -h "$HOST" -p 5432 -U postgres -d nuanji -c "SELECT 1" > /dev/null 2>&1; then
|
|
green "PostgreSQL (port 5432): 正常"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "PostgreSQL (port 5432): 连接失败"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
else
|
|
# 使用 docker exec 检查
|
|
if docker exec $(docker ps -q -f name=postgres) pg_isready -U postgres > /dev/null 2>&1; then
|
|
green "PostgreSQL: 正常 (docker exec)"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "PostgreSQL: 未就绪"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
fi
|
|
|
|
# 3. 检查 Redis
|
|
info "检查 Redis..."
|
|
if command -v redis-cli &> /dev/null; then
|
|
if redis-cli -h "$HOST" -p 6379 ping > /dev/null 2>&1; then
|
|
green "Redis (port 6379): 正常"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "Redis (port 6379): 连接失败"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
else
|
|
if docker exec $(docker ps -q -f name=redis) redis-cli ping > /dev/null 2>&1; then
|
|
green "Redis: 正常 (docker exec)"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "Redis: 未就绪"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
fi
|
|
|
|
# 4. 检查 API 文档
|
|
info "检查 OpenAPI 文档..."
|
|
swagger_status=$(curl -sf -o /dev/null -w "%{http_code}" "http://$HOST:3000/api-docs/openapi.json" 2>/dev/null || echo "000")
|
|
if [[ "$swagger_status" == "200" ]]; then
|
|
green "OpenAPI 文档: 可访问"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
red "OpenAPI 文档: 不可达 (status=$swagger_status)"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
|
|
# 汇总
|
|
echo ""
|
|
echo "========================================"
|
|
if [ $FAIL -eq 0 ]; then
|
|
green "全部检查通过 ($PASS/$PASS)"
|
|
echo "========================================"
|
|
exit 0
|
|
else
|
|
red "部分检查失败 (通过: $PASS, 失败: $FAIL)"
|
|
echo "========================================"
|
|
exit 1
|
|
fi
|