docs: 同步 Docker 编排说明并补充重构计划与 UI 参考

- README 与 docker/README 更新双 compose 文件说明:docker-compose.yml 仅主应用、docker-compose.full.yml 完整栈
- 新增 docs/superpowers/plans 800 行重构实施计划,规划前后端代码体量护栏与按职责拆分路径
- 新增 docs/ui-mockups 附件关联企业版 UI 参考稿
This commit is contained in:
caoxiaozhu
2026-06-22 12:02:08 +08:00
parent 607e127f59
commit e42dedaba1
4 changed files with 335 additions and 111 deletions

View File

@@ -1,45 +1,50 @@
# X-Financial # X-Financial
项目结构已按前后端拆开: 项目结构已按前后端拆开:
- `web/`:前端工程(当前 Vue + Vite 项目) - `web/`:前端工程(当前 Vue + Vite 项目)
- `server/`:后端工程目录 - `server/`:后端工程目录
- `docs/`:方案和阶段文档 - `docs/`:方案和阶段文档
- `UI/`:界面参考稿 - `UI/`:界面参考稿
- `document/`:业务文档 - `document/`:业务文档
根目录统一环境变量: 根目录统一环境变量:
- `.env` - `.env`
- `.env.example` - `.env.example`
这里集中维护: 这里集中维护:
- 前端启动端口 - 前端启动端口
- 后端启动端口 - 后端启动端口
- PostgreSQL 连接参数 - PostgreSQL 连接参数
- `DATABASE_URL` - `DATABASE_URL`
- `REDIS_URL` - `REDIS_URL`
从根目录统一启动: 从根目录统一启动:
```bash ```bash
./start.sh ./start.sh
``` ```
可选模式: 可选模式:
```bash ```bash
./start.sh web ./start.sh web
./start.sh server ./start.sh server
./start.sh all ./start.sh all
``` ```
根目录 `start.sh` 是统一编排入口;前端和后端的子启动脚本分别是 `web/web_start.sh``server/server_start.sh` 根目录 `start.sh` 是统一编排入口;前端和后端的子启动脚本分别是 `web/web_start.sh``server/server_start.sh`
手动进入前端目录 Docker Compose 运行方式见 `docker/README.md`
```bash - `docker-compose.yml`只启动主应用容器适合复用已有数据库、ONLYOFFICE 等外部依赖。
cd web - `docker-compose.full.yml`启动主应用、PostgreSQL、Qdrant、ONLYOFFICE 的完整本地开发栈。
npm run dev
``` 手动进入前端目录:
```bash
cd web
npm run dev
```

View File

@@ -1,67 +1,127 @@
# Docker Compose # Docker Compose
This project currently uses the Vite `__setup/*` middleware during the initial setup flow. X-Financial 现在按运行依赖分成两层 Docker Compose
Because of that, the Docker deployment keeps the web frontend and FastAPI startup chain in
the same main container and runs the existing root `start.sh`. - `docker-compose.yml`:只启动主应用容器,适合已经有远端 PostgreSQL、ONLYOFFICE 或 Qdrant 的环境。
- `docker-compose.full.yml`:启动完整本地开发栈,适合没有外部依赖、希望本机一次性跑齐所有服务的环境。
## Start
主应用容器仍然同时启动 Web 前端和 FastAPI 后端,并复用根目录 `start.sh`
```bash 项目根目录会挂载到容器内 `/app`
cp .env.example .env
docker compose up -d ## 轻量启动:只跑主应用
```
适合你已经有数据库和 ONLYOFFICE 的情况。
Open:
```bash
```text cp .env.example .env
docker compose up -d
```
默认只会启动:
```text
main
```
打开:
```text
http://<your-linux-host>:5273 http://<your-linux-host>:5273
``` ```
## Container Layout 这条路径不会主动拉起本地 PostgreSQL、Qdrant 或 ONLYOFFICE。
数据库、ONLYOFFICE 和 Qdrant 地址都从 `.env` 或外部环境变量读取。
- `main`: web + FastAPI main container
- `onlyoffice`: ONLYOFFICE Document Server 常见外部依赖变量:
- `postgres`: PostgreSQL database container
```text
The project root is mounted directly into the main container: DATABASE_URL
POSTGRES_HOST
```text POSTGRES_PORT
.:/app ONLYOFFICE_ENABLED
``` ONLYOFFICE_PUBLIC_URL
ONLYOFFICE_BACKEND_URL
That means the container reads your existing `.env`, source code, `server/.secrets`, logs, QDRANT_URL
and generated dependency directories directly from the mapped project folder. ```
This is a `compose`-only setup. There is no custom `Dockerfile`. ## 完整启动:本地全栈
The tradeoff is that the `main` container installs the Python runtime packages it needs
when it starts. 适合没有远端数据库和 ONLYOFFICE 的情况。
## Persistence ```bash
docker compose -f docker-compose.full.yml up -d
The PostgreSQL data directory is stored in the named volume `postgres_data`. ```
## Notes 会启动:
- Most configuration should be maintained in the project root `.env`. ```text
- The first `docker compose up -d` does not require an existing `.env`; the compose file main
uses built-in defaults for the PostgreSQL container and the main container database URL. postgres
- Docker Compose only overrides a few values that must differ inside containers: qdrant
- `WEB_HOST=0.0.0.0` onlyoffice
- `SERVER_HOST=0.0.0.0` ```
- `POSTGRES_HOST=postgres`
- `POSTGRES_PORT=5432` 本地服务端口:
- `DATABASE_URL=...@postgres:...`
- PostgreSQL is also published to the host by default as `127.0.0.1:55432`. ```text
- ONLYOFFICE is published to the host by default as `127.0.0.1:8082`. Web: 5273
- First boot with `SETUP_COMPLETED=false` starts the setup UI only. FastAPI: 8000
- After you complete setup in the browser, the Vite setup bridge will start FastAPI in the PostgreSQL: 55432 -> 5432
same container using the saved runtime configuration. Qdrant: 6333 / 6334
- On later restarts, `start.sh` will detect the saved setup state and start both web and ONLYOFFICE: 8082
server automatically. SSH: 2223
- If you access the system from another machine, make sure `CORS_ORIGINS` in `.env` includes ```
the frontend address you actually use.
- For Navicat or any host-side client, use `127.0.0.1:55432`. 完整栈会把主容器内的数据库地址指向 `postgres:5432`
- If you need to access ONLYOFFICE from another machine, override `ONLYOFFICE_PUBLIC_URL` 并把 Qdrant 地址指向 `http://qdrant:6333`
so the browser can reach the document server address you actually expose.
- For the setup page, using `127.0.0.1` is acceptable in this Docker layout; the internal ONLYOFFICE 默认使用本机可访问地址:
test bridge will resolve that back to the Docker PostgreSQL service.
```text
http://127.0.0.1:8082
```
如果浏览器从另一台机器访问,需要覆盖:
```bash
LOCAL_ONLYOFFICE_PUBLIC_URL=http://<host>:8082 \
docker compose -f docker-compose.full.yml up -d
```
如果 ONLYOFFICE 回调后端也需要外部地址,可以同时覆盖:
```bash
LOCAL_ONLYOFFICE_BACKEND_URL=http://<host>:8000 \
docker compose -f docker-compose.full.yml up -d
```
## 可选:只额外启动本地 PostgreSQL
如果只想在轻量主容器旁边补一个本地 PostgreSQL可以使用覆盖文件
```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up -d
```
这会启动:
```text
main
postgres
```
## 停止与清理
停止当前默认轻量栈:
```bash
docker compose down
```
停止完整本地栈:
```bash
docker compose -f docker-compose.full.yml down
```
如需删除本地数据卷,先确认不再需要其中数据,再手动执行带 `-v` 的清理命令。

View File

@@ -0,0 +1,159 @@
# Refactor Under 800 Lines Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Keep every Python class and every frontend core component/module under 800 lines, while deleting proven dead code and reducing avoidable runtime overhead.
**Architecture:** Add automated code-size guardrails first, then split oversized units by existing responsibility boundaries. Preserve public APIs wherever possible, move private helpers into focused modules, and delete code only after usage checks or tests prove it is not needed.
**Tech Stack:** Vue single-file components, Vite/Node test runner, Python/FastAPI service layer, pytest inside Docker container `x-financial-main`.
---
### Task 1: Guardrails
**Files:**
- Create: `web/tests/code-size-limits.test.mjs`
- Create: `server/tests/test_code_size_limits.py`
- [x] **Step 1: Add frontend source-unit limit test**
```bash
node --test web/tests/code-size-limits.test.mjs
```
Expected current result: FAIL, listing oversized files in `web/src/components`, `web/src/composables`, `web/src/utils`, and `web/src/views`.
- [x] **Step 2: Add backend class limit test**
```bash
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_code_size_limits.py
```
Expected current result: FAIL, listing Python classes over 800 lines.
### Task 2: Backend Python Class Split
**Files:**
- Modify: `server/src/app/services/user_agent_application.py`
- Modify: `server/src/app/services/risk_rule_template_executor.py`
- Modify: `server/src/app/services/steward_planner.py`
- Modify: `server/src/app/services/receipt_folder.py`
- Modify: `server/src/app/services/expense_claim_draft_flow.py`
- Modify: `server/src/app/services/expense_claims.py`
- Modify: `server/src/app/services/orchestrator_execution.py`
- Modify: `server/src/app/services/finance_dashboard.py`
- Modify: `server/src/app/services/agent_assets.py`
- Create focused helper or mixin files under `server/src/app/services/`
- [ ] **Step 1: Split low-risk helper groups first**
Move private formatting, parsing, label, and serialization methods into helper mixins or helper modules. Keep original public classes and method names stable.
- [ ] **Step 2: Split domain-heavy groups**
Move larger responsibility groups into named mixins:
```text
UserAgentApplicationMixin
├── application fact resolution
├── application persistence
└── application duplicate/detail helpers
RiskRuleTemplateExecutor
├── condition evaluators
├── value resolvers
└── date/window parsing
ReceiptFolderService
├── storage/meta helpers
├── editable field resolution
└── train ticket extraction
```
- [ ] **Step 3: Verify backend class limit**
```bash
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_code_size_limits.py
```
Expected final result: PASS.
- [ ] **Step 4: Run targeted backend regression tests**
```bash
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_user_agent_service.py server/tests/test_expense_claim_service.py server/tests/test_steward_planner.py server/tests/test_risk_rule_generation.py server/tests/test_agent_asset_service.py server/tests/test_reimbursement_endpoints.py
```
Expected final result: PASS or a documented pre-existing failure with evidence.
### Task 3: Frontend Source Unit Split
**Files:**
- Modify: `web/src/components/business/PersonalWorkbenchAiMode.vue`
- Modify: `web/src/views/scripts/TravelReimbursementCreateView.js`
- Modify: `web/src/views/scripts/TravelRequestDetailView.js`
- Modify: `web/src/views/scripts/useTravelReimbursementSubmitComposer.js`
- Modify remaining files reported by `web/tests/code-size-limits.test.mjs`
- Create focused modules beside the existing owners under `web/src/views/scripts/`, `web/src/components/`, `web/src/composables/`, and `web/src/utils/`
- [ ] **Step 1: Split pure helpers before stateful runtime code**
Extract pure formatting, payload normalization, label mapping, row building, and text rendering helpers. This reduces file size without changing component state ownership.
- [ ] **Step 2: Split composables and child components**
For Vue files, move stable repeated UI blocks into child components only when props/events are clear. For script modules, move independent computed builders and action helpers into colocated modules.
- [ ] **Step 3: Remove proven redundant frontend code**
Use `rg` to confirm an export, class, helper, CSS hook, or branch is unused before deleting it. If a usage is dynamic, keep it unless a regression test proves it is dead.
- [ ] **Step 4: Verify frontend source limit**
```bash
node --test web/tests/code-size-limits.test.mjs
```
Expected final result: PASS.
- [ ] **Step 5: Run targeted frontend regression tests**
```bash
node --test web/tests/workbench-ai-mode-switch.test.mjs web/tests/expense-application-fast-preview.test.mjs web/tests/expense-profile-detail-modal.test.mjs web/tests/finance-dashboard-ranking.test.mjs
npm --prefix web run build
```
Expected final result: PASS.
### Task 4: Performance And Cleanup Pass
**Files:**
- Modify only files already touched by Tasks 2 and 3 unless a usage check proves a separate dead module can be removed.
- [ ] **Step 1: Remove repeated computation inside hot paths**
Cache local computed values inside functions, avoid repeated JSON/string/date parsing loops, and prefer early returns for blocked states.
- [ ] **Step 2: Delete redundant private helpers**
Delete helpers only when all of these checks are true:
```bash
rg "helperName" server web
node --test affected-web-test.mjs
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q affected_server_test.py
```
- [ ] **Step 3: Final verification**
```bash
node --test web/tests/code-size-limits.test.mjs
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_code_size_limits.py
npm --prefix web run build
```
Expected final result: PASS.

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB