chore: initial commit

- Track MiroSociety source: backend (FastAPI), frontend (Vue3/Vite), docs, configs.
- Add start.sh / deploy.sh for local dev (uv venv + npm + dev servers on 31400/31401).
- Fix pyproject.toml: missing httpx dependency.
- Tighten .gitignore: .env, .venv, node_modules, data/, *.log, uv.lock, frontend/dist, etcd.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-09-17 13:48:30 +08:00
co-authored by Claude
commit 36b0f2b660
100 changed files with 26255 additions and 0 deletions
Executable
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env bash
# MiroSociety 启动脚本 (开发模式)
# 前置: 请先执行 ./deploy.sh 安装依赖
# 前端: http://localhost:31400 后端: http://localhost:31401
set -euo pipefail
FRONTEND_PORT=31400
BACKEND_PORT=31401
# 解析到脚本所在目录,并使用绝对路径避免子 shell cd 后路径重复
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/backend/.venv"
BACKEND_DIR="$SCRIPT_DIR/backend"
FRONTEND_DIR="$SCRIPT_DIR/frontend"
# 切到脚本所在目录,确保相对路径正确
cd "$(dirname "$0")"
# --- 颜色 ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[start.sh]${NC} $*"; }
warn() { echo -e "${YELLOW}[start.sh]${NC} $*"; }
err() { echo -e "${RED}[start.sh]${NC} $*" >&2; }
# --- 检查命令依赖 ---
for cmd in lsof npm node curl; do
if ! command -v "$cmd" >/dev/null 2>&1; then
err "缺少依赖命令: $cmd"
exit 1
fi
done
# --- 检查依赖是否已部署 ---
if [[ ! -x "$VENV_DIR/bin/python3" ]]; then
err "未检测到 $VENV_DIR/bin/python3,请先执行 ./deploy.sh"
exit 1
fi
if ! "$VENV_DIR/bin/python3" -c "import uvicorn" 2>/dev/null; then
err "venv 缺少 uvicorn,请先执行 ./deploy.sh"
exit 1
fi
if [[ ! -d frontend/node_modules ]]; then
err "未检测到 frontend/node_modules,请先执行 ./deploy.sh"
exit 1
fi
# --- 释放端口: kill 占用进程 ---
free_port() {
local port="$1"
local pids
pids=$(lsof -ti tcp:"$port" 2>/dev/null || true)
if [[ -n "$pids" ]]; then
warn "端口 $port 被占用 (pid: $pids),正在终止..."
# shellcheck disable=SC2086
kill -9 $pids 2>/dev/null || true
sleep 1
fi
}
free_port "$FRONTEND_PORT"
free_port "$BACKEND_PORT"
# --- 清理函数: 退出时杀掉所有子进程 ---
cleanup() {
log "正在关闭子进程..."
if [[ -n "${BACKEND_PID:-}" ]]; then kill -9 "$BACKEND_PID" 2>/dev/null || true; fi
if [[ -n "${FRONTEND_PID:-}" ]]; then kill -9 "$FRONTEND_PID" 2>/dev/null || true; fi
exit 0
}
trap cleanup INT TERM EXIT
# --- 启动后端 (后台, 使用 venv 内的 uvicorn) ---
log "启动后端 FastAPI @ :$BACKEND_PORT"
(
cd "$BACKEND_DIR"
HOST=0.0.0.0 PORT="$BACKEND_PORT" \
exec "$VENV_DIR/bin/python3" -m uvicorn app.main:app --host 0.0.0.0 --port "$BACKEND_PORT"
) >"$SCRIPT_DIR/backend.log" 2>&1 &
BACKEND_PID=$!
# --- 启动前端 (后台, 端口固定为 31400) ---
log "启动前端 Vite @ :$FRONTEND_PORT"
(
cd "$FRONTEND_DIR"
npx vite --port "$FRONTEND_PORT" --strictPort
) >"$SCRIPT_DIR/frontend.log" 2>&1 &
FRONTEND_PID=$!
log "后端 pid=$BACKEND_PID 前端 pid=$FRONTEND_PID"
log "等待服务就绪..."
# --- 健康检查 ---
wait_for() {
local url="$1" name="$2"
for _ in $(seq 1 30); do
if curl -sf "$url" >/dev/null 2>&1; then
log "$name 已启动 ✓ ($url)"
return 0
fi
sleep 1
done
err "$name 启动超时,请查看 ${name%% *}.log"
return 1
}
wait_for "http://localhost:$BACKEND_PORT/health" "后端"
wait_for "http://localhost:$FRONTEND_PORT" "前端"
echo
log "全部就绪!"
echo -e " ${GREEN}前端:${NC} http://localhost:$FRONTEND_PORT"
echo -e " ${GREEN}后端:${NC} http://localhost:$BACKEND_PORT (健康检查: /health)"
echo -e " ${GREEN}日志:${NC} backend.log / frontend.log"
echo
warn "按 Ctrl+C 终止所有服务"
# --- 保持前台,跟随日志 ---
tail -F "$SCRIPT_DIR/backend.log" "$SCRIPT_DIR/frontend.log"