DevFlow Harness 全栈实践 · M1.5:用户体系、多对话与聊天分享

线上 Demo: flow.houmq.cn/

前置阅读: M1:Harness 骨架与 SSE 流式对话(SSE、Nginx 流式配置、Docker 双容器部署)


前言

M1 把流式聊天壳子和公网部署跑通了,但对话存在浏览器 localStorage,没有账号、换设备就丢。

M1.5 在原有 SSE 通道上加了四块能力:

  1. 账号体系 --- 注册 / 登录 / JWT,注册时选角色(PM / 前端 / 后端 / QA)
  2. 多对话持久化 --- PostgreSQL 存对话和消息,侧边栏管理
  3. RBAC 框架 --- 权限 seed 可扩展,M1.5 四角色聊天体验一致
  4. 聊天分享 --- 生成只读链接,未登录也能看

这是原路线图 M8「角色协作」的基础部分,提前到 M2 Session 之前做,避免后面反复迁移存储。


一、架构变更概览

层面 M1 M1.5
持久化 localStorage PostgreSQL 16
鉴权 JWT(7 天)
对话 单对话 每用户多条 conversation
Docker 双容器 三容器(+ postgres)
前端路由 单页 react-router-dom(登录/注册/分享)

部署拓扑

bash 复制代码
浏览器 → Nginx → frontend 容器
                    ├─ /api/* → backend (FastAPI)
                    └─ /*     → React SPA
              backend → postgres 容器
                    → LLM API

backend 启动时自动执行 Alembic 迁移并 seed RBAC 权限。


二、数据模型

核心三张业务表:

bash 复制代码
users 1──* conversations 1──* messages
roles *──* permissions (via role_permissions)
  • users:email、password_hash(bcrypt)、role 枚举
  • conversations:user_id、title、share_token(nullable)、updated_at(列表排序)
  • messages:conversation_id、role(user/assistant/system)、content

分享只读 API 不返回 owner email / user_id。


三、后端实现要点

3.1 模块化路由

M1 所有逻辑在 main.py;M1.5 拆成:

bash 复制代码
routers/auth.py          注册 / 登录 / /auth/me
routers/conversations.py 多对话 CRUD + 分享开关
routers/chat.py          SSE 流式(history 从 DB 加载)
routers/shared.py        公开分享只读
deps.py                  JWT 解析 + require_permission()

3.2 JWT + RBAC

注册/登录返回 { token, user, permissions }。受保护路由:

less 复制代码
@router.post("/chat/stream")
def chat_stream(
    body: ChatStreamRequest,
    user: Annotated[User, Depends(require_permission("chat:write"))],
    ...
):

权限数据存在 permissions + role_permissions 表,启动时 seed。M4--M7 加新能力只挂 permission code。

3.3 SSE 请求体变更

M1:

json 复制代码
{ "message": "...", "history": [...] }

M1.5:

json 复制代码
{ "conversation_id": "uuid", "message": "..." }

后端从 DB 加载 history,流开始前写 user message,流结束后写 assistant message。前端不再维护 history 数组。


四、前端实现要点

4.1 AuthContext

  • token 存 localStorage
  • 启动时调 /auth/me 恢复登录态
  • 401 → clearToken() → 跳转 /login

4.2 路由

路径 页面
/login 登录
/register 注册 + 角色下拉
/ 聊天(ProtectedRoute)
/share/:token 只读分享

4.3 ChatPage

  • 侧边栏 ConversationSidebar:新建 / 切换 / 重命名 / 删除
  • 无对话时自动 POST /conversations
  • ShareButton:开启/关闭分享,复制 APP_PUBLIC_URL/share/{token}

storage.ts 已移除,消息持久化完全由后端负责。



五、部署变更

5.1 docker-compose 新增 postgres

yaml 复制代码
postgres:
  image: postgres:16-alpine
  environment:
    POSTGRES_DB: devflow
    POSTGRES_USER: devflow
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
  volumes:
    - pgdata:/var/lib/postgresql/data
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U devflow -d devflow"]

backend depends_on: postgres: condition: service_healthy

5.2 新增环境变量

ini 复制代码
POSTGRES_PASSWORD=
DATABASE_URL=postgresql://devflow:${POSTGRES_PASSWORD}@postgres:5432/devflow
JWT_SECRET=
JWT_EXPIRE_DAYS=7
APP_PUBLIC_URL=https://flow.houmq.cn

六、与路线图关系

原里程碑 M1.5 覆盖 剩余
M1 对话通道 保留 SSE ---
M8 角色协作 用户/角色/RBAC 基础 多人同 Session、状态机
M10 生产级 PostgreSQL 持久化 HTTPS、审计、refresh token
M2 Session conversations 可演进 文件树、Agent Loop

七、总结

M1.5 看起来是「给聊天页加了个登录」,实质是把 Harness 从 Demo 壳子推进到多用户产品雏形:服务端持久化、权限框架、分享------都是 M2 Session 和 M8 协作的前置。

SSE 流式通道和 Nginx 配置没动,增量开发的好处就在这里:内核通道不变,外围能力叠上去。


附录

  • GitHub:github.com/MingQi39/de...
  • 设计规格:仓库内 docs/superpowers/specs/2026-09-16-m1-user-auth-design.md
  • 架构文档:仓库内 docs/architecture.md
相关推荐
SL_staff1 天前
战略落地的最后一公里:从目标到个人日历的自动化链路实现
java·github·全栈
Ticnix1 天前
RAG 的坑不在检索,在"对齐":pgvector 实战手记
python·agent·全栈
EatFan1 天前
多租户系统到底怎么设计?从 tenant_id 到 JWT 租户隔离的真实实践
前端·后端·全栈·多租户
EatFan1 天前
我为什么把患者与病例从 1:1 改成 1:N?一次真实数据库模型重构记录
数据库·后端·重构·健康医疗·全栈
狼爷2 天前
硅谷爆火的FDE是AI新风口,还是高级外包?
后端·全栈
狂师2 天前
最近火爆出圈的,FDE 到底是个什么岗位?
人工智能·程序员·全栈
万敏5 天前
Vue3 全栈实战:第一阶段复盘(第1-8周)
vue.js·node.js·全栈
先吃饱再说6 天前
从本地跑通到公网访问:前后端项目部署实战
运维·全栈