diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f890679 --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Database (local dev) +POSTGRES_USER= +POSTGRES_PASSWORD= + +# Internal service token (optional, used for internal APIs between services) +INTERNAL_SERVICE_TOKEN= + +# SMTP (optional) +SMTP_USERNAME= +SMTP_PASSWORD= + diff --git a/README.md b/README.md new file mode 100644 index 0000000..3ed91fe --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# accounts.svc.plus + +Cloud Neutral Toolkit 的账号与身份服务 (Account Service). + +> A production-oriented account service for sign-in, sessions, MFA, and agent coordination. + +## 部署要求 (Deployment Requirements) + +| 维度 | 要求 / 规格 | 说明 | +|---|---|---| +| 网络 | 可访问的 API 域名 (可选) | 生产建议配置 `server.publicUrl` | +| 端口 | `:8080` | API 服务默认监听端口 | +| 数据库 | PostgreSQL | 存储账号/会话/状态等核心数据 | +| 缓存 (可选) | Redis | `session.cache=redis` 时需要 | +| 最低 | 1 CPU / 1GB RAM | 开发/小规模 | +| 推荐 | 2 CPU / 2GB RAM | 生产建议 | + +## 快速开始 (Quickstart) + +### 一键初始化 (Setup Script) + +```bash +curl -fsSL "https://raw.githubusercontent.com/cloud-neutral-toolkit/accounts.svc.plus/main/scripts/setup.sh?$(date +%s)" \ + | bash -s -- accounts.svc.plus +``` + +### 本地运行 (Local Dev) + +```bash +cp .env.example .env +make dev +``` + +## 核心特性 & 技术栈 (Features & Tech Stack) + +核心特性: +- 账号体系:注册/登录/会话/角色与权限 +- 安全能力:邮件验证、TOTP MFA(可选) +- Agent 协同:与节点/控制面协作的同步与状态上报 +- 多部署形态:本地/VM、Docker、Cloud Run(含 stunnel sidecar 示例) + +技术栈: +- Go + Gin +- PostgreSQL (primary store) +- Redis (optional session cache) +- stunnel (optional secure DB connectivity; Cloud Run example included) + +## 说明文档 (Docs) + +- 文档入口:`docs/README.md` +- 快速开始:`docs/getting-started/quickstart.md` +- 配置说明:`docs/usage/config.md` +- 部署方式:`docs/usage/deployment.md` +- API 参考:`docs/api/overview.md` +- 运维:`docs/operations/monitoring.md`, `docs/operations/troubleshooting.md` +- Runbooks:`docs/Runbook/README.md` + diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000..1bc5f33 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'EOF' +Usage: + setup.sh [--repo ] [--ref ] [--dir ] + +Examples: + # Remote install: + # curl -fsSL "https://raw.githubusercontent.com/cloud-neutral-toolkit//main/scripts/setup.sh?$(date +%s)" | bash -s -- + # + # Local: + # bash scripts/setup.sh + +Notes: + - Safe: no secrets written; no destructive actions. + - If .env does not exist, it copies .env.example -> .env (placeholder only). +EOF +} + +log() { printf '[setup] %s\n' "$*"; } + +need_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + log "missing required command: $1" + exit 1 + fi +} + +if [[ "${1:-}" == "" || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage + exit 0 +fi + +NAME="$1" +shift + +REPO_URL="" +REF="main" +DIR="$NAME" + +while [[ $# -gt 0 ]]; do + case "$1" in + --repo) REPO_URL="${2:-}"; shift 2 ;; + --ref) REF="${2:-}"; shift 2 ;; + --dir) DIR="${2:-}"; shift 2 ;; + *) log "unknown arg: $1"; usage; exit 2 ;; + esac +done + +if [[ -z "${REPO_URL}" ]]; then + REPO_URL="https://github.com/cloud-neutral-toolkit/${NAME}.git" +fi + +need_cmd git +need_cmd curl + +if [[ -e "${DIR}" && ! -d "${DIR}" ]]; then + log "path exists and is not a directory: ${DIR}" + exit 2 +fi + +if [[ ! -d "${DIR}" ]]; then + log "cloning ${REPO_URL} (ref=${REF}) -> ${DIR}" + git clone --depth 1 --branch "${REF}" "${REPO_URL}" "${DIR}" +else + if [[ ! -d "${DIR}/.git" ]]; then + log "directory exists but is not a git repo: ${DIR}" + exit 2 + fi + log "repo directory already exists: ${DIR}" +fi + +cd "${DIR}" + +did_any=false + +if [[ -f "package.json" ]]; then + need_cmd node + if command -v corepack >/dev/null 2>&1; then + corepack enable >/dev/null 2>&1 || true + fi + if command -v yarn >/dev/null 2>&1; then + log "installing JS dependencies (yarn install)" + yarn install + did_any=true + else + log "yarn not found; install yarn (or enable corepack) then re-run" + exit 1 + fi +fi + +if [[ -f "go.mod" ]]; then + need_cmd go + log "downloading Go dependencies (go mod download)" + go mod download + did_any=true +fi + +if [[ "${did_any}" == "false" ]]; then + log "no supported project type detected (package.json/go.mod)." + log "setup script completed without installing deps." +fi + +if [[ ! -f ".env" && -f ".env.example" ]]; then + log "creating .env from .env.example (placeholder only)" + cp .env.example .env +fi + +if [[ -f "scripts/post-setup.sh" ]]; then + log "running scripts/post-setup.sh" + bash scripts/post-setup.sh +fi + +log "setup complete" +log "next steps:" +if [[ -f "go.mod" ]]; then + log " cp .env.example .env" + log " make dev" +fi +