初始提交:全国记者站管理系统
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# ADR-RSMS-001:技术栈选型
|
||||
|
||||
> ADR 编号:ADR-001
|
||||
> 状态:已决策(代码已先行,补录)
|
||||
> 日期:2026-07-31
|
||||
> 项目:RSMS
|
||||
|
||||
## 背景
|
||||
|
||||
项目启动时需要确定前端框架、后端框架和数据库选型。项目为内部管理后台,初期规模可控,但需考虑 37 个站点、约 500 名记者的数据增长。
|
||||
|
||||
## 选项
|
||||
|
||||
### 前端
|
||||
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|---|---|---|
|
||||
| A. React + Vite + TypeScript | 生态成熟、类型安全、Vite 热重载快、团队熟悉度高 | 学习曲线存在(对新手) |
|
||||
| B. Vue + Vite + TypeScript | 上手快、单文件组件直观 | 团队 React 经验更丰富 |
|
||||
| C. 原生 HTML + JS | 无依赖 | 不可维护 |
|
||||
|
||||
### 后端
|
||||
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|---|---|---|
|
||||
| A. Express.js + Node.js | 轻量、路由灵活、JSON 原生、团队熟悉 | 需自行处理结构化代码 |
|
||||
| B. Spring Boot (Java) | 生态完善、企业级 | 需要 JDK 环境、启动慢 |
|
||||
| C. Django (Python) | 快速开发、内置 ORM | GIL 限制并发、对团队熟悉度低 |
|
||||
|
||||
### 数据库
|
||||
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|---|---|---|
|
||||
| A. SQLite(WAL 模式) | 零配置、文件级、无服务进程、适合本地开发 | 并发写入受限(当前规模可接受) |
|
||||
| B. PostgreSQL | 关系型权威、功能强大、并发好 | 需要安装运行、增加运维成本 |
|
||||
| C. JSON 文件 | 零配置 | 无查询能力、无法处理关联 |
|
||||
|
||||
## 决策
|
||||
|
||||
- **前端**:React + Vite + TypeScript(选项 A)
|
||||
- **后端**:Express.js + Node.js(选项 A)
|
||||
- **数据库**:SQLite(WAL 模式)(选项 A)
|
||||
|
||||
## 理由
|
||||
|
||||
1. **React + Vite**:团队已有 React 经验;Vite 提供极快的热重载体验;TypeScript 提供编译期类型检查,减少运行时错误;Recharts 作为数据可视化方案与 React 生态无缝集成。
|
||||
2. **Express.js**:轻量、路由直观;JSON 作为 API 响应格式零序列化成本;`node --watch` 支持开发热重载;无额外配置。
|
||||
3. **SQLite**:零运维成本,文件即数据库;WAL 模式支持读写并发(读不阻塞写);数据文件可随 Git 管理(需注意 .gitignore);当前规模(37 站 x 500 人)完全在 SQLite 处理能力内。
|
||||
|
||||
## 升级路径
|
||||
|
||||
| 组件 | 升级触发条件 | 目标方案 |
|
||||
|---|---|---|
|
||||
| 数据库 | 并发写入成为瓶颈(预估 > 100 并发写入/秒) | 迁移至 PostgreSQL |
|
||||
| 后端 | 业务逻辑复杂度增加 | 考虑 NestJS 或 DDD 架构重构 |
|
||||
| 前端 | 页面数量 > 30 或团队 > 5 人 | 引入 React Router、状态管理(Redux Toolkit) |
|
||||
|
||||
## 风险
|
||||
|
||||
- SQLite 在极高并发写入场景下可能成为瓶颈(当前评估:低风险)
|
||||
- 前后端均使用 JS/TS,技术栈统一,全栈可复用类型定义(未来引入 tRPC 可进一步增强类型安全)
|
||||
@@ -0,0 +1,56 @@
|
||||
# ADR-RSMS-002:认证方案
|
||||
|
||||
> ADR 编号:ADR-002
|
||||
> 状态:已决策(角色模拟)
|
||||
> 日期:2026-08-01
|
||||
> 项目:RSMS
|
||||
|
||||
## 背景
|
||||
|
||||
系统需要识别用户身份并实施数据权限隔离。在 MVP 阶段无需接入真实身份认证体系,但需设计一个可升级的认证架构。
|
||||
|
||||
## 选项
|
||||
|
||||
| 选项 | 描述 | 适用阶段 |
|
||||
|---|---|---|
|
||||
| A. 角色模拟(header 传参) | 前端切换角色,HTTP header `x-user-role` 传递值,后端按值查询数据 | MVP / 演示 |
|
||||
| B. Session + Cookie | 后端维护 session,基于用户名密码登录 | 首版上线 |
|
||||
| C. JWT Token | 无状态令牌,携带用户 ID 和角色,可扩展 | 生产环境 |
|
||||
| D. 微信 OAuth2 | 微信账号登录,与人员档案绑定 | 移动端小程序 |
|
||||
|
||||
## 决策
|
||||
|
||||
**MVP(当前)**:选项 A — 角色模拟(header 传参)
|
||||
|
||||
**二期目标**:选项 C — JWT Token + 真实登录
|
||||
|
||||
**三期目标**:选项 D — 微信 OAuth2(若实现小程序端)
|
||||
|
||||
## 选项 A 的实施
|
||||
|
||||
```
|
||||
前端 role-switcher(<select>)
|
||||
↓
|
||||
x-user-role: headquarters | station | reporter
|
||||
↓
|
||||
后端中间件读取 header → 注入 req.user 对象
|
||||
↓
|
||||
数据访问层按 req.user.role + req.user.station + req.user.name 过滤
|
||||
```
|
||||
|
||||
- **优点**:零门槛,无需注册账号;方便演示和开发测试
|
||||
- **缺点**:安全性极低,header 可被任意伪造;仅适合内部演示环境
|
||||
|
||||
## 升级至 JWT 的迁移路径
|
||||
|
||||
1. 新增 `/api/auth/login` 接口,接收用户名密码,返回 JWT
|
||||
2. 新增 JWT 中间件,验证令牌并注入 `req.user`
|
||||
3. 保留 header `x-user-role` 作为兼容层(降级方案)
|
||||
4. 前端将 token 存储于 `localStorage` 或 `httpOnly` Cookie
|
||||
5. 移除前端 role-switcher,替换为登录页
|
||||
|
||||
## 风险
|
||||
|
||||
- **选项 A 当前风险**:任何人可以通过修改 header 访问任意角色数据
|
||||
- **缓解**:当前环境为本地开发/内网,不暴露于公网;上线前必须完成 JWT 改造
|
||||
- **硬编码人员**:`server/index.js` 中的 `identities` 对象需改为从数据库读取真实用户表
|
||||
Reference in New Issue
Block a user