diff --git a/README.md b/README.md index 75ad08f..d6fd87e 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ### 后端 - Python 3.10+ + Flask - Gunicorn(生产运行) -- 可插拔数据层:SQLite(本地开发)/ MariaDB(生产,运行于 NAS,经 PyMySQL) +- 可插拔数据层:SQLite(本地开发)/ MariaDB(生产,Oracle 云服务器本地 MariaDB 10.3,经 PyMySQL) - JWT 鉴权 + scrypt 密码哈希 - garminconnect(可选,Garmin API 集成) @@ -92,15 +92,16 @@ CORS_ORIGIN=http://localhost:3000,http://localhost:5173 数据层通过 `DB_TYPE` 环境变量切换后端,**业务代码无需改动**: - **SQLite(默认,本地开发)**:零配置,由 `DATABASE_PATH` 指定文件位置。 -- **MariaDB(生产,运行在 NAS 上)**:经 `mysql2` 连接,优先走 socket(`MARIADB_SOCKET`),也可用 `MARIADB_HOST` + `MARIADB_PORT`。 +- **MariaDB(生产)**:运行于 Oracle 云服务器(129.146.26.249)本地的 MariaDB 10.3,专用账号 `garmin` 经 `127.0.0.1:3306` 连接(PyMySQL)。 -生产使用 NAS 上的独立库 `garmin_health_lab`(与 `sentinel_home_ai` 隔离)。完整配置见 `backend/.env.example`: +生产使用独立库 `garmin_health_lab`(与 `sentinel_home_ai` 隔离)。完整配置见 `backend/.env.example`: ```env DB_TYPE=mariadb -MARIADB_SOCKET=/run/mysqld/mysqld10.sock -MARIADB_USER=root -MARIADB_PASSWORD=your_nas_mariadb_root_password +MARIADB_HOST=127.0.0.1 +MARIADB_PORT=3306 +MARIADB_USER=garmin +MARIADB_PASSWORD=your_production_mariadb_password MARIADB_DATABASE=garmin_health_lab ``` diff --git a/backend/.env.example b/backend/.env.example index 2b67bef..dab166e 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -8,12 +8,13 @@ DB_TYPE=sqlite # SQLite file (used when DB_TYPE=sqlite) DATABASE_PATH=./data/health.db -# MariaDB (used when DB_TYPE=mariadb) — runs on the NAS -# MARIADB_SOCKET=/run/mysqld/mysqld10.sock +# MariaDB (used when DB_TYPE=mariadb) — production DB on the Oracle server +# (129.146.26.249, local MariaDB 10.3). Dedicated account over TCP 127.0.0.1; +# MARIADB_SOCKET is only needed if TCP auth is disabled for the app user. # MARIADB_HOST=127.0.0.1 # MARIADB_PORT=3306 -# MARIADB_USER=root -# MARIADB_PASSWORD=your_nas_mariadb_root_password +# MARIADB_USER=garmin +# MARIADB_PASSWORD=your_production_mariadb_password # MARIADB_DATABASE=garmin_health_lab # --- Auth --- @@ -36,7 +37,7 @@ CORS_ORIGIN=http://localhost:3000,http://localhost:5173 # absorbs single-vendor quota limits. Reached directly, bypassing any local # HTTP proxy. NOTE: its NVIDIA upstream is a large reasoning model — replies # can take 2-3 minutes, so set AI_TIMEOUT_SECONDS accordingly. -AI_GATEWAY_BASE_URL=http://129.146.203.203:5100/v1 +AI_GATEWAY_BASE_URL=http://129.146.26.249:5100/v1 AI_GATEWAY_TOKEN= AI_GATEWAY_MODEL=ai-gateway-auto diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 912996a..ec31da6 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -159,17 +159,9 @@ AnalysisService.generateRecommendations() ## 部署架构 -``` -┌─────────────────────────────────┐ -│ Development 本地开发 │ -│ └─ npm run dev (同时运行前后端) │ -└─────────────────────────────────┘ - -┌─────────────────────────────────┐ -│ Production 生产环境 │ -│ ├─ Docker 容器化 │ -│ ├─ Nginx 反向代理 │ -│ ├─ Node.js 后端服务 │ -│ └─ SQLite 数据持久化 │ -└─────────────────────────────────┘ -``` +- **Development 本地开发**:`npm run dev` 同时启动前后端 —— Vite/React (3000/5173) + Flask (5000, SQLite)。 +- **Production 生产环境**(Oracle 云服务器 129.146.26.249): + - Flask + gunicorn 直绑 `0.0.0.0:8123`(systemd `garmin-health-lab.service`,开机自启) + - React SPA 静态包由后端 `STATIC_DIR` 提供 + - MariaDB 10.3(`127.0.0.1:3306`,专用账号 `garmin`,库 `garmin_health_lab`) + - AI 网关 `129.146.26.249:5100/v1` diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index 4091b1b..d9e84f5 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -4,7 +4,7 @@ 状态:`✅ 已完成` · `🚧 进行中` · `📋 待做` · `⏸ 已搁置` -最后更新:2026-08-24 +最后更新:2026-08-25 --- @@ -13,8 +13,8 @@ | # | 需求 | 理解 | 状态 | |---|---|---|---| | 1.1 | 新建项目分析佳明海外账号健康数据 | Gitea 自建仓库,Web 应用 | ✅ | -| 1.2 | 部署到 NAS (192.168.50.64),用 MariaDB | Flask + gunicorn + MariaDB(socket),SQLite 供开发 | ✅ | -| 1.3 | 公网可访问 | frp 隧道 NAS:8123 → Oracle:8123 | ✅ | +| 1.2 | 部署到 Oracle 云服务器 (129.146.26.249),用 MariaDB | Flask + gunicorn + MariaDB(127.0.0.1:3306),SQLite 供开发 | ✅ | +| 1.3 | 公网可访问 | gunicorn 直绑 Oracle:8123(frp 隧道已移除) | ✅ | | 1.4 | 单元测试 / 界面自测 / 性能测试 | 446 项 pytest;界面用浏览器实测;接口逐个计时 | ✅ | | 1.5 | 一任务一 commit,完成即推送 | 已成为固定流程 | ✅ |