feat(m0): 后端骨架 + Web/安卓前端骨架 + 设计文档

- backend: FastAPI 应用工厂、统一错误信封、JWT、短信登录、工作区/成员/邀请、幂等中间件
- alembic 0001: workspace/member/invitation/audit_log/app_user + RLS 策略 + 双角色 GRANT
- tests: 认证/工作区/租户隔离/幂等 四组用例(尚未在本机执行)
- web: React18+Vite 骨架(登录、工作区、邀请落地页)
- android: Compose 骨架(登录、工作区列表)
- 2.Design: PRODUCT-PLAN / ROADMAP-M0-M1 / NAMING / DEVELOPMENT
This commit is contained in:
Steven
2026-10-28 02:38:53 +08:00
commit 0c53aa7062
72 changed files with 5320 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
# 开发环境(M0)
> 目标:新人在 20 分钟内把后端跑起来并让 `pytest` 全绿。
## 1. 依赖
| 组件 | 版本 | 说明 |
|---|---|---|
| Python | 3.10+(CI 用 3.11) | 后端 |
| Node | 20+ | 前端 |
| Docker Desktop | 任意近期版本 | 只用来跑 Postgres / Redis |
## 2. 端口约定(别改用默认端口)
| 服务 | 端口 | 为什么 |
|---|---|---|
| PostgreSQL | **5433** | 避开机器上可能已有的 5432 |
| Redis | **6380** | 同上 |
| 后端 API | **8100** | 前端 dev 代理指向它 |
| 前端 dev | **5180** | 与 CORS 默认值一致 |
## 3. 起基础设施
```bash
cd deploy
docker-compose -f docker-compose.dev.yml up -d # 老版 CLI 是 docker-compose,新版是 docker compose
```
首次初始化会自动执行 `deploy/postgres/init/01-roles.sql`,创建两个角色:
- `dadao_owner` —— 拥有库、可以建表,**只有 alembic 用**。
- `dadao_app` —— 应用连接用,无 DDL、无 BYPASSRLS,行级安全对它生效。
> 为什么必须两个角色:PostgreSQL 的 RLS 会对表 owner 和 superuser **直接跳过**。
> 如果应用用 owner 连库,多租户隔离就是摆设,而且测试会"假通过"。
## 4. 后端
```bash
cd backend
python -m venv .venv
.venv\Scripts\activate # Linux/macOS: source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # Windows: copy .env.example .env
alembic upgrade head # 建表 + RLS 策略(人工复核过再上)
uvicorn app.main:app --reload --port 8100
```
自检:
```bash
curl http://127.0.0.1:8100/health
curl http://127.0.0.1:8100/version # commit 必须等于 git rev-parse --short HEAD
```
开发环境验证码固定为 `SMS_DEV_CODE`(默认 `123456`),且 `/auth/sms/send` 会把 `dev_code` 回显在响应里——
**只有 `ENV=dev` 才允许**,`ENV=prod` 时启动即失败。
## 5. 前端
```bash
cd web
npm install
npm run dev # http://127.0.0.1:5180,/api 代理到 8100
npm run build # 产物必须在仓库 HEAD 上构建,禁止本地构建后上传
```
## 6. 测试
```bash
cd backend
pytest -q # 必须全绿才能提交
ruff check . && ruff format --check .
```
测试会真连数据库、真跑迁移、真走 HTTP 栈。跑之前确保 Postgres 在 5433。
隔离测试(`tests/test_tenant_isolation.py`)是本仓库最重要的一组用例,改动任何租户表都必须重跑它。
## 7. 常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
| `pytest` 报 `attached to a different loop` | 连接池跨事件循环复用 | 测试环境已用 NullPool,别改回去 |
| 迁移报 `permission denied for schema public` | 用的是应用角色 | `MIGRATION_DATABASE_URL` 必须指向 owner |
| 接口返回空列表而不是报错 | 忘了 `bind_tenant`,RLS 过滤掉了一切 | 走 `MemberDep` / `TenantDep` 依赖 |
| `pip` 报 `UnicodeDecodeError: 'gbk' codec` | requirements.txt 里有非 ASCII | 该文件保持纯 ASCII |
| `docker compose` 报 `unknown command` | 只装了 compose v1 | 用 `docker-compose` |
| Docker 起不来 | Docker Desktop 未启动 / 需要管理员 | 先启动 Desktop,`docker info` 有输出再继续 |
## 8. 提交前自检清单
1. `pytest` 全绿,`ruff` 无告警。
2. 新增租户表时:`workspace_id NOT NULL` + RLS 策略 + 跨租户测试,三者齐全。
3. 迁移文件提交前人工复核(`alembic revision --autogenerate` 只做草稿)。
4. 改了接口就更新 `2.Design/API.md`(M1 建立该文档)。
5. 推送到远端,生产部署后 `curl /version` 校验 commit。