v1.0.51: 批次1架构筑基 - 1)版本迁移(common/migrate.php+schema_versions+natsort迁移文件);2)登录安全(bcrypt平滑迁移login/user_add/user_update旧sha1命中自动重写+system_login_attempts限流+session加固httponly/samesite/secure);3)CSRF Token(服务端checkCsrf+auth/csrf.php登录页取token+前端common.js/login.js统一携带X-CSRF-Token);4)统一基座common/Api.php并存量强制迁移全部70个endpoint(Api::boot按public/super/module/permissions分流,写接口强制checkAjax+checkCsrf,全局异常处理);5)前端收敛(common.js新增esc转义别名);6)REV-4硬数据来源渠道可编辑(hard_update+补全弹窗下拉);7)prepared卫生(soft_update.php修复+analysis.php表名白名单REV-9)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
# SuperLink 架构与功能优化设计方案(草案 v0.1 · 待评审)
|
||||
|
||||
> 原则:**先文档 · 后评审 · 再写代码**。
|
||||
> 本文档为实施前的设计草案 + 现状评审发现,供项目负责人评审拍板。评审通过前不改动代码。
|
||||
> 关联:`docs/superlink_产品评测与优化路线图_2026.md`(战略总览);本文档为落地执行细案。
|
||||
|
||||
- 撰写:2026-09
|
||||
- 目标版本:v1.0.51 起
|
||||
- 状态:**DRAFT — 待评审**
|
||||
|
||||
---
|
||||
|
||||
## 0. 评审结论速览(TL;DR)
|
||||
|
||||
| 主题 | 结论 | 建议动作 |
|
||||
|---|---|---|
|
||||
| 迁移管理 | ⚠️ 无版本表,多环境易漏跑迁移 | 第一批落地 |
|
||||
| 鉴权 | 🔴 login 用 `sha1`(无盐),CSRF 仅靠请求头 | 第一批加固 |
|
||||
| 样板代码 | 🔴 每个接口重复堆"鉴权+校验+JSON+日志" | 抽出统一定义层 |
|
||||
| 前端 | 🟡 单文件过大、字符串拼 HTML | 组件化收敛 |
|
||||
| 官网承诺 vs 代码 | 🔴 AI 触达/线索流转/ROI 是营销态,代码未实现 | 第二批功能闭环 |
|
||||
| 差异化 | 🟢 碎片治理/完整度/渠道归因已是独特资产 | 放大 + 产品化 |
|
||||
| 数据库 | 🟡 索引/口径/预算备份表待清理 | 第三批打磨 |
|
||||
|
||||
> 🔴=高优先级 · 🟡=中 · 🟢=已具备/优
|
||||
|
||||
---
|
||||
|
||||
## 1. 现状评审发现(问题清单)
|
||||
|
||||
> 依据源码精读(文件行号截至 v1.0.50)。
|
||||
|
||||
### 1.1 安全
|
||||
- **[REV-SEC-1]🔴 密码仅 `sha1` 无加盐**(`api/auth/login.php:37` `hash_equals($user['password'], sha1($password))`)。撞库成本极低。
|
||||
- **[REV-SEC-2]🟡 CSRF 仅靠 `X-Requested-With` 头**(`common/auth.php::checkAjax`),无真正的 CSRF Token,敏感写操作可被跨站伪造(头只能防"简单表单")。
|
||||
- **[REV-SEC-3]🟡 登录无速率限制/失败锁定**,可被爆破。
|
||||
- **[REV-SEC-4]🟡 `session` 默认配置**,未设 cookie httponly/samesite,未设会话超时/固定防护。
|
||||
|
||||
### 1.2 可维护性 / 架构
|
||||
- **[REV-ARCH-1]🔴 无数据库迁移版本表**。`sql/migration_v1.0.XX.sql` 需手工依次执行,无 `schema_versions` 记录、无校验、无回滚;v1.0.48 遗留 `preliminary_data_bak_*` 冗余备份表。
|
||||
- **[REV-ARCH-2]🔴 样板重复**:每个 `api/<模块>/<动作>.php` 重复 `require db/response/auth + checkAjax + checkPermission + SQL + logAction + Response`,约十余个接口高度同构,改一处规范需改 N 处。
|
||||
- **[REV-ARCH-3]🟡 无集中错误/慢查询观测**,仅靠 `system_logs` 业务审计,无技术异常日志。
|
||||
- **[REV-ARCH-4]🟡 前端 `static/js/fragment.js` 单文件承载硬/软两套逻辑,`common.js` 用字符串拼 HTML,难维护难测试。
|
||||
- **[REV-ARCH-5]🟢 统一 JSON 规范(`code/msg/data`)、字段白名单(`helpers.php`)、完整度引擎(`completeness.php`)、审计(`logger.php`)已具备且质量良好**——是很好的可扩展地基。
|
||||
|
||||
### 1.3 数据 / 性能
|
||||
- **[REV-DATA-1]🟡 `social_accounts` 多态 owner,跨表统计口径绕**;高频过滤列(`is_incomplete`/`source_channel`/`owner_type+owner_id`/`platform`)索引不明确。
|
||||
- **[REV-DATA-2]🟡 `ammer_time` 历史遗留:`tools/migrate_time_to_date.php` 已有迁移脚本,但未见在迁移流程中统一执行。
|
||||
- **[REV-DATA-3]🟢 `phone.dat`(4.5MB)已打包,可做成离线手机归属地查询能力,无外部依赖。
|
||||
|
||||
### 1.4 功能缺口(对照官网承诺)
|
||||
- **[REV-FN-1]🔴 "AI 补全" 是占位**(`fragment.js` 操作列),未真正调用任何 AI/RAG。
|
||||
- **[REV-FN-2]🔴 EDM 只有"筛选+导出"**(`marketing/edm.php`),无真实发送/回传。
|
||||
- **[REV-FN-3]🔴 无"线索→商机→成交"状态机与跟进轨迹时间线**,与官网"线索自动流转、全程记录跟进轨迹"不符。
|
||||
- **[REV-FN-4]🟡 无 ROI 面板**(dashboard 有统计卡,无"获客成本/转化率/成交额")。
|
||||
- **[REV-FN-5]🟡 舆情监测/竞品分析多为占位**;EAV 产品参数已建模但"行业对比"视图未落地。
|
||||
- **[REV-FN-6]🟢 人脉亲密度算法已实现**(`person/connections.php`),可产品化为可视化图谱放大差异化。
|
||||
|
||||
### 1.5 代码级评审发现(已核实 v1.0.50 · 2026-09 补充 code review)
|
||||
|
||||
> 由评审会对 `common/ auth/ fragment/ channel/ system/user_add` 逐一核实到行号得出。
|
||||
|
||||
**🔴 严重(安全)**
|
||||
- **[REV-1]** 密码 `sha1` 无加盐:`login.php:37`、`user_add.php:48`。离线可撞库。
|
||||
- **[REV-2]** CSRF 仅 `X-Requested-With` 头(`auth.php::checkAjax`),无随机 Token。
|
||||
- **[REV-3]** 前端字符串拼 `innerHTML` 渲染服务器字段 → **潜在存储型 XSS(待确认 C1)**,缺统一转义。
|
||||
|
||||
**🟠 高(一致性/正确性)**
|
||||
- **[REV-4]** 硬碎片来源不可编辑:`hard_update.php:89-111` 的 UPDATE 装列不含 `source_channel`,只能 add 不能改。
|
||||
- **[REV-5]** 碎片录入被主表全局唯一性"拦死"(`hard_add/soft_update` 对 `companies/social_accounts` 判重):**业务口径需确认 C2**。同邮箱/电话跨企业、多电话同人时新线索录不进。
|
||||
- **[REV-6]** `soft_update.php:77` `$id` 以字符串拼进 SQL(已 int 强转不可注入,但破坏 prepared 风格,卫生项)。
|
||||
|
||||
**🟡 中**
|
||||
- **[REV-7]** 渠道分析 N+1:`analysis.php:59-69` 循环内逐条查 source_detail。
|
||||
- **[REV-8]** 登录无限流/无失败锁定、`startSession` 未设 httponly/samesite。
|
||||
- **[REV-9]** `analysis.php` 表名 `$table` 直接拼 SQL(当前仅内部常量调用安全,属 footgun)。
|
||||
|
||||
**🔵 低**
|
||||
- **[REV-10]** `hard_convert.php:141` `$resolveCompany` 先查后插,并发同名称可能建重复企业。
|
||||
- **[REV-11]** `user_add.php:23` 密码仅长度校验。
|
||||
- **[REV-12]** phone/email 全库跨企业+人员全局判重,交叉占用会互相阻断(同 REV-5)。
|
||||
|
||||
**待确认项**
|
||||
- **C1** 前端渲染是否逐处转义(决定 REV-3 是否为已存在 XSS)。
|
||||
- **C2** 全局唯一性是"阻断"还是"提示"(决定碎片录入产品语义,涉及 REV-5/REV-12)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 目标架构设计
|
||||
|
||||
### 2.1 目录结构(目标)
|
||||
|
||||
```
|
||||
api/
|
||||
common/
|
||||
Api.php # 新增:统一接口基座(鉴权 + 参数 + JSON + 日志 + 分页)
|
||||
migrate.php # 新增:迁移执行器(配合 sql/schema_versions)
|
||||
security.php # 新增:CSRF Token、限流、Session 安全配置
|
||||
auth/ channel/ ... # 业务模块(逐步接入 Api.php,非一次性重写)
|
||||
tools/
|
||||
migrate.php # 新增/改造:命令行跑迁移
|
||||
bump_version.php # 改造:同时同步 config.js
|
||||
sql/
|
||||
schema_versions.sql # 新增:建版本表 + 首次基线
|
||||
```
|
||||
|
||||
### 2.2 评审通过的决策点(由你拍板)
|
||||
|
||||
- **D1 迁移方案**:采用「版本表 + 顺序执行脚本」最小方案(A),暂不引入 php-migrations 等第三方依赖,保持纯 PHP 极简。
|
||||
- **D2 密码升级**:`password_hash(password_verify)`,存量 sha1 用户在登录命中时平滑迁移到新哈希(登录一次即升级,无需批量重写密码)。
|
||||
- **D3 CSRF**:Session 绑定随机 Token,前端 `common.js` AJAX 统一追加 `X-CSRF-Token` 头;保持现有 `checkAjax()` 兼容。
|
||||
- **D4 是否抽统一 `Api.php` 基座**:建议抽;新接口必须走它,存量接口"用到的先迁、不动的不强制迁移",避免大爆炸式重写。
|
||||
- **D5 AI 补全如何接入**:接千视 RAG/大模型(需提供 API),输出"带置信度的建议字段",用户一键采纳/拒绝。**若暂无 AI API,可先做"规则式自动补全"(手机归属地→城市、行业字号→行业、国家→地址缺省)占位过渡。**
|
||||
- **D6 触达通道**:EDM 发送优先(可邮件模板 + SMTP/第三方),企微/短信二期。
|
||||
|
||||
### 2.3 统一接口基座(`common/Api.php` 设计)
|
||||
|
||||
```php
|
||||
class Api {
|
||||
// 用法:Api::handle('fragment', function(PDO $pdo, array $in){ ... return $data; })
|
||||
// 内部统一:requireLogin + checkPermission + checkAjax(写) + 参数默认 + Response + 异常兜底(log) + logAction
|
||||
}
|
||||
```
|
||||
- 收敛 `checkAjax/checkPermission/logAction` 重复样板;
|
||||
- 统一异常→JSON、SQL 错误→技术日志 + 友好提示;
|
||||
- 提供 `paged()` 输出,统一 list 分页结构。
|
||||
|
||||
### 2.4 迁移执行器(`tools/migrate.php` + `sql/schema_versions`)
|
||||
|
||||
- 建 `schema_versions(id, version, applied_at, checksum)`;
|
||||
- `php tools/migrate.php up` 顺序执行 `sql/migration_*.sql` 中未应用者,记录版本与文件 checksum(防改旧脚本);
|
||||
- 提供 `php tools/migrate.php down <version>`(可选,先支持正向即可);
|
||||
- 首次基线收录现有 migration_*.sql;清理 `preliminary_data_bak_*` 用一条收敛迁移。
|
||||
|
||||
---
|
||||
|
||||
## 3. 功能设计(第二批)
|
||||
|
||||
### 3.1 AI/规则补全(P0,破局)
|
||||
- 数据表:无需新表,落在 `preliminary_data` / 主表字段。
|
||||
- 接口:`api/fragment/ai_suggest.php`
|
||||
- 入参:`target_type / fragment_id / 已有字段`
|
||||
- 出参:`suggestions:[{field, value, confidence, reason}]`
|
||||
- 前端:硬/软碎片"AI 补全"按钮 → 弹窗展示建议列表 → 采纳/拒绝 → 回写 `hard_update/soft_update`。
|
||||
- 过渡:权限/hook 式——**有千视 API 走 AI,无则走规则引擎**(手机归属地→工作地/国家;`cn_to_en` 已有能力复用)。
|
||||
|
||||
### 3.2 EDM 真实触达 + ROI 面板(P0/P1)
|
||||
- EDM:`edm.php` 增 `发送/模板/任务`,`edm_export` 保持;发送回执写回 `system_logs` 或新 `edm_tasks`。
|
||||
- ROI:dashboard 增加"渠道 ROI"卡片/图表(数据来自 `source_channel` × 商机状态 × 预估成交额),复用已引入的 ECharts。
|
||||
|
||||
### 3.3 线索状态机 + 跟进轨迹(P1)
|
||||
- 新表 `leads(id, ref_table, ref_id, status[初访/跟进中/已商机/已成交/放弃], owner_user_id, pipeline...)`,或直接在 `companies/persons` 加 `lead_status`。
|
||||
- `system_logs` 扩展 `follow_status`,形成按线索的时间线。
|
||||
- 意向识别(`is_incomplete` 由 1→0、完整度晋升、EDM 打开/回复)→ 自动创建 lead 并推送 `owner_user_id`。
|
||||
|
||||
### 3.4 舆情监测 + 竞品参数对比 + 人脉图谱(P1/P2,差异化)
|
||||
- 舆情:接入千视舆情能力 → `media_opinion` 真实成单页。
|
||||
- 竞品对比:EAV 行转列,同行业 `company_products_attr_value` 对比表 → `competitor_data` 落地。
|
||||
- 人脉图谱:`person/connections.php` 亲密度 → ECharts 关系图(graph)→ `person` 详情页增强。
|
||||
|
||||
---
|
||||
|
||||
## 4. 落地路线图(3 个批次)
|
||||
|
||||
> 每批独立可发布、可评审、可回滚。
|
||||
|
||||
### 批次 1 · 架构筑基(v1.0.51)
|
||||
| 项 | 涉及文件 | 说明 |
|
||||
|---|---|---|
|
||||
| 迁移版本管理 | 新增 `tools/migrate.php`、`sql/schema_versions.sql`;收敛旧 migration | 先建基座 |
|
||||
| 登录安全 | `login.php`(bcrypt 平滑迁移)、`auth.php`、新增 `security.php` | bcrypt + 限流 + session 加固(REV-1/REV-8) |
|
||||
| CSRF Token | `auth/auth.php`/`session.php` + `common.js` | 写接口头校验(REV-2) |
|
||||
| 统一 Api 基座 | 新增 `common/Api.php`;先迁 `fragment/hard_*` 或 `system/*` 一个模块试点 | 收敛样板 |
|
||||
| 前端收敛 | `common.js` 拆表格/弹窗/分页 helper + 统一 `esc()` 转义 | 可增量(REV-3/C1) |
|
||||
| 碎片来源可编辑 | `fragment/hard_update.php` 更新装列加入 `source_channel` | 一致性(REV-4) |
|
||||
| prepared 卫生 | `soft_update.php:77` 等残余字符串拼参改占位符 | 卫生项(REV-6/REV-9) |
|
||||
|
||||
**验收**:①能 `up`/`down` 跑迁移;②新用户密码为 bcrypt、老用户登录后被平滑升级;③写接口带 CSRF Token 合法可过、缺失被拒;④至少 1 个模块接入 Api 基座且行为不变;⑤硬碎片来源可新增/修改;⑥统一 `esc()` 后抽查模块无未转义渲染(此需求取决于 C1 确认)。
|
||||
|
||||
### 批次 2 · 功能闭环(v1.0.52)
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| AI/规则补全落地 | `ai_suggest.php` + 前端弹窗(接千视 API 或规则兜底) |
|
||||
| EDM 真实触达 | 模板/发送/回执 |
|
||||
| ROI 面板 | dashboard 渠道 ROI 图表 |
|
||||
|
||||
### 批次 3 · 销售闭环 + 差异化(v1.0.53+)
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| 线索状态机 + 跟进时间线 | `leads` 表 + 自动流转 |
|
||||
| 舆情监测 / 竞品参数对比 / 人脉图谱 | 差异化成单模块 |
|
||||
| 索引 / 性能 / 导入即治理 | 打磨 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 需要你拍板的决策(评审门槛)
|
||||
|
||||
1. **D5 关键**:AI 补全——是否已有千视 RAG/大模型 API 可接?若暂缺,**是否接受先用"规则式补全"过渡**?(决定批次 2 的 AI 项怎么落地)
|
||||
2. **D4**:是否同意新增 `common/Api.php` 统一基座并"用到的先迁、存量不强制"?
|
||||
3. **D2**:密码升级方案(bcrypt 平滑迁移)是否认可?(会改变存量用户密码存储格式)
|
||||
4. **批次节奏**:是否按「批次1 架构筑基 → 批次2 功能闭环 → 批次3 差异化」推进?可只做其中某批次。
|
||||
5. 优先级冲突时:**先保架构地基(批次1)还是先上能对外演示的功能(批次2)?**
|
||||
6. **C2(评审 REV-5/12)**:手机/邮箱/企业名等**全局唯一性校验**遇到主表已有记录时,是保持"**阻断**新增"(当前行为)还是降级为"**提示但允许继续**"?(后者更贴合"碎片=待审线索"语义,但会让同一电话挂在多个主体下)
|
||||
|
||||
> 附:C1(前端转义是否已存在 XSS)需现场确认后再决定批次1「前端收敛」是否纳入 REV-3 修复。
|
||||
|
||||
> 评审意见请直接回复上表的决策项编号与结论(例如"D5 暂无AI,先规则补全;按批次1→2→3 推进")。通过后我按批次开始写代码。
|
||||
|
||||
---
|
||||
|
||||
## 6. 批次1 实现记录(v1.0.51 · 已实现并验证)
|
||||
|
||||
已拍板的批次1范围,本版本全部落地。服务器端验证通道:`ssh ubuntu@106.55.169.92` → docker `php:8.2-cli php -l`(95/95 通过)+ CSRF/bcrypt CLI 冒烟(ALL PASS)。
|
||||
|
||||
| 项 | 落地文件 | 验证 |
|
||||
| --- | --- | --- |
|
||||
| ①版本迁移 | `sql/schema_versions.sql`、`sql/migration_v1.0.51.sql`、`tools/migrate.php`(`up/status/down`、natsort、md5 checksum) | lint 通过 |
|
||||
| ②登录安全 | bcrypt 平滑迁移(`api/auth/login.php`:旧 sha1 命中→`password_verify`→自动重写 bcrypt;`user_add/user_update` 新强度规则+`password_hash`)+ 限流/session 加固(`api/common/security.php`) | 冒烟 PASS |
|
||||
| ③CSRF Token | 服务端 `csrfToken()/checkCsrf()`(`security.php`),GET 取 token(`auth/csrf.php` public)、写接口统一校验;前端 `common.js` httpPost 携带 `X-CSRF-Token`、`login.js` 登录页取 token | 冒烟 PASS(错误 token → 403) |
|
||||
| ④统一基座+强制迁移 | `common/Api.php` `Api::boot(['public'/'super'/'module'/'permissions'])`,**全部 70 个 endpoint 存量强制迁移**(脚本转换,逐一审计无遗漏、无误删 include);`hard_common.php` 等纯 include 保留 | 全局 require 审计干净 |
|
||||
| ⑤前端收敛 | `common.js` 新增 `esc` 别名(现即统一转义入口);统一 `escHtml` | — |
|
||||
| ⑥REV-4 来源渠道可编辑 | `hard_update.php` 支持 `source_channel` + 前端补全弹窗新增来源渠道下拉(回显) | — |
|
||||
| ⑦prepared 卫生 | `soft_update.php` 违规 `$pdo->query` 修为 prepared(REV-6);`analysis.php` 表名白名单(REV-9) | lint 通过 |
|
||||
|
||||
**明确延后(记录在案,建议下批次处理)**:
|
||||
- REV-7:`analysis.php` 渠道详情 N+1(`LIMIT 10` 内子查询,量级可控,批内不动)。
|
||||
- REV-3/C1:XSS 前端收敛——已提供统一 `esc()` 转义入口,但存量页面 JS 的逐个改逃逸需下批次;新写代码一律用 `esc()`。
|
||||
- REV-5/12:手机/邮箱/企业名全局唯一性 **保持"阻断新增"**(已拍板)。
|
||||
- REV-10:并发下企业重名竞态(可在 `company/add` 加唯一索引兜底,下批次)。
|
||||
- 部署形态:确认长期部署目标为服务器 106.55.169.92;`config/database.php` 当前写死 `127.0.0.1/mysuperlink/...`,容器化部署需改为 env 注入(下批次随 docker-compose 落地)。
|
||||
|
||||
---
|
||||
|
||||
## 附录 A:与战略文档的关系
|
||||
本《设计方案》是把战略文档第四部分(架构+功能优化)细化到"改哪些文件、怎么改、能否回滚、验收标准"的可执行层。两文档共用同一结论:**先补齐迁移/安全/样板三块地基,再用 AI 补全 + EDM + 线索流转 + ROI 兑现官网承诺,最后用舆情/竞品/人脉图谱做出差异化。**
|
||||
Reference in New Issue
Block a user