feat: 实现密码重置功能与用户搜索API,优化注册登录流程
- 新增忘记密码页面与重置密码确认流程(前端+后端) - 修复注册验证码页登录跳转路由 - 新增用户搜索API(按邮箱查询) - 简化infra脚本,统一为app.sh - 补充密码重置与用户API测试覆盖 - 更新runtime文档与AGENTS配置
This commit is contained in:
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
SESSION_NAME="${SESSION_NAME:-social-dev}"
|
||||
COMPOSE_FILE="$ROOT_DIR/infra/docker/docker-compose.yml"
|
||||
ENV_FILE="$ROOT_DIR/.env"
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 {start|stop}"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " start Start web + worker processes in tmux"
|
||||
echo " stop Stop and clean up tmux session"
|
||||
exit 1
|
||||
}
|
||||
|
||||
start() {
|
||||
echo "=== App Up ==="
|
||||
echo "This script starts web + worker processes in tmux."
|
||||
echo "NOTE: Bootstrap (migrate + init-data) must be run separately."
|
||||
echo ""
|
||||
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
echo "Error: tmux is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "Error: env file not found at $ENV_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||
echo "Error: compose file not found at $COMPOSE_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
. "$ENV_FILE"
|
||||
set +a
|
||||
|
||||
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
||||
echo "Error: tmux session '$SESSION_NAME' already exists." >&2
|
||||
echo "Hint: tmux kill-session -t $SESSION_NAME" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting web + worker processes in tmux session '$SESSION_NAME'..."
|
||||
|
||||
WEB_CMD="cd '$ROOT_DIR' && PYTHONPATH=backend/src SOCIAL_RUNTIME__SERVICE_NAME=web uv run gunicorn app:app --bind \
|
||||
${SOCIAL_WEB__HOST:-0.0.0.0}:${SOCIAL_WEB__PORT:-8000} --workers \
|
||||
${SOCIAL_WEB__GUNICORN__WORKERS:-2} --worker-class \
|
||||
${SOCIAL_WEB__GUNICORN__WORKER_CLASS:-uvicorn.workers.UvicornWorker} --timeout \
|
||||
${SOCIAL_WEB__GUNICORN__TIMEOUT:-60} \
|
||||
--log-level ${SOCIAL_RUNTIME__LOG_LEVEL:-info}"
|
||||
|
||||
WORKER_CRITICAL_CMD="cd '$ROOT_DIR' && PYTHONPATH=backend/src SOCIAL_RUNTIME__SERVICE_NAME=worker-critical uv run celery -A core.celery.app worker --loglevel=info --queues=critical --concurrency=${SOCIAL_WORKER__GROUPS__CRITICAL__CONCURRENCY:-2}"
|
||||
WORKER_DEFAULT_CMD="cd '$ROOT_DIR' && PYTHONPATH=backend/src SOCIAL_RUNTIME__SERVICE_NAME=worker-default uv run celery -A core.celery.app worker --loglevel=info --queues=default --concurrency=${SOCIAL_WORKER__GROUPS__DEFAULT__CONCURRENCY:-2}"
|
||||
WORKER_BULK_CMD="cd '$ROOT_DIR' && PYTHONPATH=backend/src SOCIAL_RUNTIME__SERVICE_NAME=worker-bulk uv run celery -A core.celery.app worker --loglevel=info --queues=bulk --concurrency=${SOCIAL_WORKER__GROUPS__BULK__CONCURRENCY:-1}"
|
||||
|
||||
tmux new-session -d -s "$SESSION_NAME" -n web "bash -lc \"$WEB_CMD; echo '[web] exited'; exec bash\""
|
||||
tmux new-window -t "$SESSION_NAME" -n worker-critical "bash -lc \"$WORKER_CRITICAL_CMD; echo '[worker-critical] exited'; exec bash\""
|
||||
tmux new-window -t "$SESSION_NAME" -n worker-default "bash -lc \"$WORKER_DEFAULT_CMD; echo '[worker-default] exited'; exec bash\""
|
||||
tmux new-window -t "$SESSION_NAME" -n worker-bulk "bash -lc \"$WORKER_BULK_CMD; echo '[worker-bulk] exited'; exec bash\""
|
||||
|
||||
echo ""
|
||||
echo "=== App Started ==="
|
||||
echo "Log files will be created in logs/ directory:"
|
||||
echo " - web.log, web.error.log"
|
||||
echo " - worker-critical.log, worker-critical.error.log"
|
||||
echo " - worker-default.log, worker-default.error.log"
|
||||
echo " - worker-bulk.log, worker-bulk.error.log"
|
||||
echo ""
|
||||
echo "tmux attach -t $SESSION_NAME"
|
||||
echo "tmux list-windows -t $SESSION_NAME"
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo "=== App Down ==="
|
||||
|
||||
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
||||
echo "Stopping tmux session '$SESSION_NAME'..."
|
||||
tmux kill-session -t "$SESSION_NAME"
|
||||
else
|
||||
echo "No tmux session '$SESSION_NAME' found."
|
||||
fi
|
||||
|
||||
echo "Checking for orphaned processes..."
|
||||
if pgrep -f "gunicorn.*app:app" > /dev/null 2>&1; then
|
||||
echo "Killing orphaned gunicorn processes..."
|
||||
pkill -f "gunicorn.*app:app"
|
||||
fi
|
||||
if pgrep -f "celery.*worker" > /dev/null 2>&1; then
|
||||
echo "Killing orphaned celery processes..."
|
||||
pkill -f "celery.*worker"
|
||||
fi
|
||||
|
||||
echo "Session stopped and cleaned up."
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
start) start ;;
|
||||
stop) stop ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user