From 7518dc23072191b7cca6a2c9063f73a3ea3ba8ac Mon Sep 17 00:00:00 2001 From: xsl Date: Sun, 11 Oct 2026 22:59:21 +0800 Subject: [PATCH] fix(h5): sync latest report copy and deployment verification --- docs/微信登录接入与公网部署说明.md | 2 + docs/线上微信登录部署记录-2026-10-11.md | 66 + docs/线上闭环测试-2026-10-11.md | 69 + graphify-out/.graphify_labels.json | 48 +- graphify-out/.graphify_labels.json.sig | 2 +- graphify-out/GRAPH_REPORT.md | 214 ++- graphify-out/graph.html | 8 +- graphify-out/graph.json | 2107 +++++++++++++++-------- graphify-out/manifest.json | 45 +- h5/js/report-copy.js | 2 +- h5/test/analyze-timeout.js | 54 + h5/test/browser-failures.mjs | 79 + h5/test/production-loop.mjs | 144 ++ h5/test/ui-20261009.mjs | 4 +- 14 files changed, 1981 insertions(+), 863 deletions(-) create mode 100644 docs/线上微信登录部署记录-2026-10-11.md create mode 100644 docs/线上闭环测试-2026-10-11.md create mode 100644 h5/test/analyze-timeout.js create mode 100644 h5/test/browser-failures.mjs create mode 100644 h5/test/production-loop.mjs diff --git a/docs/微信登录接入与公网部署说明.md b/docs/微信登录接入与公网部署说明.md index 8d495e2..7523991 100644 --- a/docs/微信登录接入与公网部署说明.md +++ b/docs/微信登录接入与公网部署说明.md @@ -2,6 +2,8 @@ 更新:2026-10-11。当前环境为 Windows 宿主机 + 内网 WSL。 +线上状态补充:`https://1me.xajuzi.com/state/` 已部署并配置真实微信凭据,服务器检查记录见 `线上微信登录部署记录-2026-10-11.md`。下文的内网缺配置说明针对本机开发环境。真实微信授权尚待客户端验证。 + ## 结论与当前阻碍 已完成微信网页授权代码,但**没有完成真实微信账号联调**。当前未配置 `WECHAT_APP_ID`、`WECHAT_APP_SECRET`、`PUBLIC_BASE_URL`,也没有可验证的公众号网页授权域名配置。内网 `http://192.168.3.25:8080/` 不能作为本次正式授权部署地址。因此本地启用「本机浏览器登录」,不会模拟微信登录成功。 diff --git a/docs/线上微信登录部署记录-2026-10-11.md b/docs/线上微信登录部署记录-2026-10-11.md new file mode 100644 index 0000000..cf6138c --- /dev/null +++ b/docs/线上微信登录部署记录-2026-10-11.md @@ -0,0 +1,66 @@ +# 线上微信登录部署记录 + +时间:2026-10-11(北京时间)。服务器:`ubuntu@1me.xajuzi.com`,页面:`https://1me.xajuzi.com/state/`。 + +## 后续更新:已配置真实凭据 + +用户提供凭据后,已将其写入 `/etc/juzi/wechat.env` 并重启服务。该文件仅 root 可读写(600),目录为 700;临时凭据文件已移除,未写入代码库或前端。 + +- 公网健康检查正常;`/state/api/auth/config` 返回 `wechat: true`。 +- 真实登录入口返回微信授权 URL;AppID 与配置匹配,作用域为 `snsapi_base`,回调为 `https://1me.xajuzi.com/state/api/auth/wechat/callback`。 +- OAuth 绑定 Cookie 确认为 HttpOnly、Secure、SameSite=Lax,路径 `/state/`;回调无效 code 后返回登录错误,重复 state 被拒绝,未错误发放登录会话。 +- 微信网页授权换码接口使用诊断用无效 code 返回 `40029 invalid code`,未返回 IP 白名单错误。这只验证端点连通和错误处理,不能证明 AppSecret 正确或真实授权成功(无效 Secret 对照也返回相同错误)。 +- 微信基础接口 `/cgi-bin/stable_token` 返回 `40164`,服务器出口 IP `49.233.222.47` 不在公众号 IP 白名单。须由公众号管理员加入后,才能完成这项基础凭据校验;不能直接把此错误认定为网页授权登录必然失败。 +- 自动浏览器能够从真实页面发起微信跳转,但无法取得真实微信客户端授权 code,因此没有伪造生产微信身份或宣称真人登录已通过。 + +剩余验证:公众号管理员添加基础接口 IP 白名单;在真实微信内完成一次授权,确认权限与网页授权域名,并检查首页和报告列表。非登录功能的真实闭环结果见 `线上闭环测试-2026-10-11.md`。 + +### 用户确认加入白名单后的复测 + +2026-10-11 14:50 UTC,从同一生产服务器间隔复测:`stable_token` 和标准 `cgi-bin/token` 均仍返回 `40164`,提示 `49.233.222.47` 不在白名单。已确认服务器读取的 AppID 与用户提供的 `wx645d9a7573f1fe9a` 一致;未输出密钥或令牌。仍需核对是在该 AppID 对应账号的 **IP 白名单** 中添加并保存,而非网页授权域名/业务域名或其他微信应用的白名单。 + +网页授权端点返回的 HTML 仅做微信客户端环境判断,并未提供账号权限/域名是否合规的诊断结果;伪造 User-Agent 无法完成真实授权。换码负向测试仍正常,因此上述基础接口错误不能替代真实微信登录的验收结果。 + +## 已执行 + +- 确认服务器仓库为 `55b3a45`,包含 `ce8d0ff` 登录和 UI 更新;未覆盖服务器仓库文件。 +- 原 Node 进程仍运行旧版本,重启 `juzi-h5.service` 后新账号接口生效。 +- 新增 `/etc/systemd/system/juzi-h5.service.d/wechat.conf`,设置实际 HTTPS 站点地址、回环监听、代理信任和私有环境文件加载。 +- 初次准备 `/etc/juzi/wechat.env` 时两个微信变量为空;随后已配置真实凭据。目录权限 700、文件 600,均为 root 所有。 +- 修改 `/etc/nginx/sites-available/juzi`:为 `/state/api/admin/` 增加 Basic Auth(原先只有 `/api/admin/` 受保护);兼容旧路径,覆盖真实 IP 请求头;请求体上限调整为 20 MB,读取超时调整为 150 秒。 +- `nginx -t` 通过后平滑 reload,原证书、管理员密码文件和域名验证文件未改动。 +- Node 确认仅监听 `127.0.0.1:8080`。 + +备份:`/etc/juzi-deploy-backup.3ipdsA/`,含修改前 nginx 配置和 systemd 主服务文件。新增 systemd drop-in 为独立文件,可单独回退;数据目录未移动或删除。 + +## 初次部署的线上检查(历史结果) + +| 检查 | 结果 | +|---|---| +| `/state/`、`/state/api/health` | 200 | +| `/state/api/auth/config` | 200,wechat=false,明确缺配置 | +| 匿名读取报告 | 401 | +| `/state/api/admin/stats`、`/api/admin/stats`、后台页面 | 401 | +| 数据目录、编码斜杠源码路径 | 404 | +| 同站但未同意协议的登录请求 | 400 | +| 跨站登录请求 | 403 | +| 微信登录请求(尚无凭据) | 503,未伪装登录成功 | +| 无效微信回调 | 302,返回 `/state/?login_error=state` | +| 根目录微信验证文件 | 200 | + +## 初次部署时的凭据查找记录(现已由用户提供) + +查找到的是 `MP_verify_kpx234XimQGtFPo6.txt`,只有 16 字符校验串;本地与服务器相关目录均未找到同名 `.md`。它用于域名验证,不包含 AppID/AppSecret,也不能用于换取微信用户身份。 + +在服务器运行 `sudoedit /etc/juzi/wechat.env`,填写对应公众号凭据: + +```ini +WECHAT_APP_ID=公众号AppID +WECHAT_APP_SECRET=公众号AppSecret +``` + +保存后执行 `sudo systemctl restart juzi-h5.service`。无需在聊天中发送 AppSecret,也不要将该私有文件加入 Git。然后重新检查 `/state/api/auth/config`,并在微信内访问站点完成真实授权测试。 + +同时须确认该公众号具备网页授权权限,公众号后台的「网页授权域名」是 `1me.xajuzi.com`。目前仅确认校验文件可访问,尚无法确认公众号后台实际设置。回调 URL 已准备为 `https://1me.xajuzi.com/state/api/auth/wechat/callback`。 + +初次部署阶段没有触发收费 Face++ 检测,没有更改既有报告或真实用户账号。后续闭环测试使用独立测试身份调用一次真实 Face++,详见闭环测试记录。真实微信账号联调仍待完成,不能将接口部署成功视为微信授权成功。 diff --git a/docs/线上闭环测试-2026-10-11.md b/docs/线上闭环测试-2026-10-11.md new file mode 100644 index 0000000..fdacc89 --- /dev/null +++ b/docs/线上闭环测试-2026-10-11.md @@ -0,0 +1,69 @@ +# 线上闭环测试(不含真实微信授权) + +测试时间:2026-10-11;站点:`https://1me.xajuzi.com/state/`。 + +## 结论 + +真实线上测肤、完整报告存储与回看已跑通。测试使用项目自带的 C3 三视角示例照片和新建的独立浏览器身份,没有修改或删除既有用户报告。除明确标注的故障注入/演示测试外,真实闭环经过公网 HTTPS、nginx、生产 Node 服务和真实 Face++ 接口。 + +## 发现并修复 + +前端原先 45 秒取消测肤请求;后端两次 60 秒请求加 4 秒重试间隔,最长约 124 秒,导致网络慢或重试时前端提前失败。前端调整为 150 秒,与已部署的 nginx 150 秒超时配合,并新增请求成功、超时、过期响应丢弃及计时器清理回归测试。 + +线上已同步 `h5/js/app.js`,原文件备份为 `/home/ubuntu/juzi-app-before-closedloop-20261011.js`。静态 JS 响应 `Cache-Control: no-cache`。该超时修复已包含在提交 `3dda4ec` 中;本次将新增测试和记录同步纳入 Git,统一本地和线上版本。 + +## 话术及仓库同步 + +以线上提交 `3dda4ec` 中的最新 `reference/AI测肤报告页话术修改.md` 为准,其 SHA-256 与用户附件完全一致(`c871de9ac3ddd40410653da904cb0b800e24bdf550df53d60602645bab2aafbb`)。本地拉取时先备份并恢复了原有测试、文档及知识图谱改动,未丢弃未提交工作。 + +运行 `python3 tools/build_report_copy.py` 重新生成 `h5/js/report-copy.js`,将水分「改善」结论中的「水分分 {water_score}」同步到页面实际使用的话术。评分和推荐算法不变。部署后重启服务,让服务端新报告使用更新文案;已保存的历史报告继续读取原有快照。 + +## 已通过的检查 + +| 场景 | 验证方式与结果 | +|---|---| +| 核心评分 | 服务器运行 83 项引擎自测、86 项回归断言,全部通过 | +| 账号和报告 | 服务器隔离测试验证授权同意、CSRF、账号隔离、完整快照、最近 5 份、重启持久化、身份恢复及 OAuth 状态绑定/防重放 | +| 公网页面 | Chromium 经真实 HTTPS 访问登录、首页、隐私协议、档案、报告列表和报告;320/390/480 宽度无横向溢出 | +| 三连拍与语音 | 模拟摄像头完整正脸→右脸→左脸流程;14 条音频可获取、引导顺序正确、三次完成播报、无语音截断 | +| 档案保护 | 未同意隐私协议不能继续;未填写档案不能启动拍摄 | +| 相机降级 | 注入相机拒绝及模型不可用,系统相机文件输入仍可完成三视角流程;坏图提示错误后可重新选择 | +| 真实测肤 | 三视角样例经页面压缩上传,真实 Face++ 返回成功,记录已完成,服务记录耗时 1281 ms,综合分 74 | +| 完整报告 | 七张检测图加载、七个标签切换、图片放大及浏览器返回通过;后端保存三张照片、完整可视化数据与文案 | +| 历史恢复 | 清除会话 Cookie 后由浏览器本地身份恢复;从服务端再次打开报告,七张图片与文案和首次展示逐项一致 | +| 历史异常 | 浏览器侧注入列表 503 错误,错误提示与刷新重试恢复正常 | +| 检测异常 | 浏览器侧分别注入业务失败、断网和超时,均关闭分析弹层、保留档案并允许重拍;不产生虚假报告 | +| 人脸模型 | 公网真实模型加载正常,示例图能实际识别人脸并输出 68 个关键点 | +| 权限隔离 | 匿名读报告 401,另一个已登录身份读测试报告 404;跨站检测请求 403;缺图请求 400 | +| 文件/后台保护 | 后台接口、后台页面需认证;数据、源码、编码斜杠访问被拒绝 | +| 服务状态 | nginx 配置检查通过;nginx 和 juzi-h5 均 active;Node 仅监听 127.0.0.1:8080 | + +真实调用记录:`R20261011-193351-PD7P`。本次只有一笔真实 Face++ 检测请求;故障测试不调用收费接口。测试报告保留在独立测试身份下,未清理或改写其他数据。 + +## 可复现命令 + +```bash +node h5/test/accounts.js +node h5/js/skin-score.js +node h5/test/regression.js +node h5/test/analyze-timeout.js +node h5/test/report-persistence.mjs +node h5/test/wechat-browser.mjs + +BASE_URL=https://1me.xajuzi.com/state node h5/test/e2e-browser.mjs +H5_BASE_URL=https://1me.xajuzi.com/state/ H5_ARTIFACT_DIR=/tmp/juzi-production-ui-20261011 node h5/test/ui-20261009.mjs +H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/browser-failures.mjs + +# 显式开启:会新增独立测试身份和报告,并实际消耗一次 Face++ 调用。 +RUN_LIVE_ANALYZE=1 H5_BASE_URL=https://1me.xajuzi.com/state/ node h5/test/production-loop.mjs +``` + +浏览器测试依赖全局 Playwright 和 Chromium。`wechat-browser.mjs` 使用隔离 HTTPS 及模拟微信响应,只验证我们的跳转、会话和身份流程,不代表真实微信授权通过。 + +本机截图/结果:`/tmp/juzi-production-loop-LqVf32/`、`/tmp/juzi-production-ui-20261011/`、`/tmp/juzi-e2e-report.png`。不记录身份凭证或密钥,不将报告快照/照片加入 Git。 + +## 验证边界 + +- 真实微信授权尚未完成:后续用户提供 AppID/AppSecret 后已配置并启用;基础接口凭据校验受到 IP 白名单限制,网页授权换码负向测试正常,真实微信授权仍需客户端完成。详见微信部署记录。 +- 自动化不等同于真实手机相机验收。微信内置浏览器的权限、前后镜头、实际光线/姿态下自动抓拍和系统相机交互,需要最终真机验证。 +- 这次是功能闭环和异常恢复检查,不是高并发压力测试或完整安全审计。 diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index 7b28bd1..98a09d0 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -1,52 +1,52 @@ { "0": "face-api.js", - "1": "t", + "1": "线上闭环测试(不含真实微信授权)", "2": "app.js", "3": "skin-score.js", "4": "n", "5": "normalize", - "6": "drawFaceExpressions", - "7": "Box", + "6": "getContext2dOrThrow", + "7": "extractFaces", "8": "admin.js", "9": "__awaiter", "10": "AgeGenderNet", "11": "lib/accounts.js", "12": "server.js", "13": "files", - "14": ".predictAgeAndGender", + "14": "FaceLandmarks", "15": ".runAndExtendWithFaceDetection", "16": "巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范", - "17": "extractFaces", + "17": "getEnv", "18": "1'me 在线肌肤测试 H5", "19": "head-pose.js", "20": "build_fixtures.py", "21": "disposeUnusedWeightTensors", - "22": ".loadFromDisk", + "22": ".computeFaceDescriptor", "23": "facepp-skinanalyze(旷视皮肤分析专业版调用技能)", "24": "巨子测肤 · 1'me 语音播报内容设计文档 V1.0", "25": "mobile-select.iife.min.js", "26": "wi", "27": "gen_voice.py", - "28": "i", + "28": "wn", "29": "face-api.js 本地化依赖(h5/vendor/faceapi/)", "30": "ui-20261009/manifest.json", - "31": ".toString", + "31": "browser-failures.mjs", "32": "FaceMatcher", "33": "build-fixture.py", "34": "smoke-test.js", "35": "DetectSingleFaceLandmarksTask", - "36": "C", + "36": "so", "37": "UI 外发版 10.09 图片资源", - "38": "TinyYolov2", + "38": "PredictSingleAgeAndGenderWithFaceAlignmentTask", "39": "UI交互界面调整", - "40": "ComputeAllFaceDescriptorsTask", - "41": ".draw", + "40": "extractAllFacesAndComputeResults", + "41": "initialize", "42": "export_psd_assets.py", "43": "FaceLandmark68Net", "44": "start-local.sh", "45": "PredictAllAgeAndGenderWithFaceAlignmentTask", "46": "PredictAllFaceExpressionsWithFaceAlignmentTask", - "47": "k", + "47": "TinyYolov2Base", "48": "PredictSingleFaceExpressionsWithFaceAlignmentTask", "49": "mobile-select/README.md", "50": "call_skinanalyze_3view.sh", @@ -54,24 +54,30 @@ "52": "region-data.js", "53": "护理建议(全量文本,按需求摘抄)", "54": "UI 对齐 10.09 设计稿:调研与实施计划", - "55": "FaceLandmarks68", - "56": ".forwardInput", + "55": "NeuralNetwork", + "56": "convLayer", "57": "regression.js", "58": ".dispose", "59": "call_skinanalyze.sh", "60": "report-fixture.js", - "61": "NeuralNetwork", + "61": ".extractWeights", "62": "提交前 Review(2026-10-11)", "63": "e2e-browser.mjs", "64": "account-client.js", - "65": "PredictSingleFaceExpressionsTask", - "66": ".runAndExtendWithFaceDetections", + "65": "tt", + "66": "cn", "67": "ui-20261009.mjs", - "68": "ComputeSingleFaceDescriptorTask", + "68": "analyze-timeout.js", "69": "misans/README.md", - "71": "extractFaceTensors", + "70": "decodeBoxesLayer", + "71": "dr", "72": "build_report_copy.py", "73": "camera-geometry.js", "74": "report-copy.js", - "75": "prepare_h5_assets.py" + "75": "prepare_h5_assets.py", + "76": "TinyYolov2", + "77": "FaceDetection", + "79": "isValidNumber", + "80": "线上微信登录部署记录", + "83": "Yo" } diff --git a/graphify-out/.graphify_labels.json.sig b/graphify-out/.graphify_labels.json.sig index 90ee6f7..6d3bbc6 100644 --- a/graphify-out/.graphify_labels.json.sig +++ b/graphify-out/.graphify_labels.json.sig @@ -1 +1 @@ -{"0": "796f85041a70fce3", "1": "966174ef01534051", "2": "9cf893b45c314643", "3": "271a5f5154afbdcd", "4": "e8b7c34edb5e6b25", "5": "163ce3e95fc46466", "6": "979dcc63399620ad", "7": "3a3e5d3e70ed45d6", "8": "cf2aba493368e557", "9": "94b2884fbd0d3d50", "10": "d982c7c094e0d01c", "11": "1c4f17c3d154962f", "12": "ab705784bbd1dbdc", "13": "7e3b558a587a4ebe", "14": "a2b13160223b5a98", "15": "5a9014c4a7f87699", "16": "95add6a975c0cb72", "17": "2405e1edb003a83e", "18": "5aa9c1fc3b3c8196", "19": "0a373ad2197fd1a6", "20": "aecf2fce44ba49c5", "21": "8835aeeaa165e9f9", "22": "b683919fcbe30647", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "3ca8c23d3e8220ec", "27": "eab427ce9a5219e9", "28": "536a3a2cb7285674", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "cd6f168abba94fea", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "23f1d406f6c779ae", "36": "92f5f0a14da5908e", "37": "cb8f26249485324a", "38": "29790cf710874dd0", "39": "fdd95375b4a5ddb3", "40": "3dd68cce72af5314", "41": "bf75bfc99d4f9e34", "42": "ffd960136fde00ad", "43": "9a25b1230b5fe649", "44": "852c1bb2446edd9c", "45": "92ab3e5134ed8685", "46": "65718282b3c32109", "47": "188dd5e33354e35d", "48": "8c471c7baeaaca54", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "15606ce5d8eec23a", "56": "880a74c6d255e5cc", "57": "f2a40b5f1b29f669", "58": "de5c2bc5e6fe8070", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "81661714a80b3097", "62": "1366ae24c7e5897d", "63": "c256b43f75d7809e", "64": "86101547c05f96b9", "65": "cb5ac3401283c378", "66": "46204fb2e4d50c53", "67": "98f88c09f1236577", "68": "7ac475ea9bc280f8", "69": "e511846eeba03076", "71": "0b63a2ad1a11ce27", "72": "c84f196a7bd35861", "73": "2b887bf601ccfb9f", "74": "ae2a154311e1f53a", "75": "69fdd23278518884"} \ No newline at end of file +{"0": "69ee47981e97a7eb", "1": "cb6ea50bd4e4a5ca", "2": "9cf893b45c314643", "3": "8ac814cdb72a1a7d", "4": "0f24ec9aab01e512", "5": "0e8200cefc11b932", "6": "1169f97bb458af6f", "7": "c1ae3952d970e510", "8": "cf2aba493368e557", "9": "8abf7998360e0ccc", "10": "c796af251148a471", "11": "79c3e26b93d030ce", "12": "ab705784bbd1dbdc", "13": "7e3b558a587a4ebe", "14": "186e1f68d4b2dfe9", "15": "5a9014c4a7f87699", "16": "95add6a975c0cb72", "17": "773ca6b3d5102a78", "18": "5aa9c1fc3b3c8196", "19": "0a373ad2197fd1a6", "20": "aecf2fce44ba49c5", "21": "5d94cf57d5d1a6fb", "22": "444ef0744645f5ac", "23": "90fac00055070ce2", "24": "f85b5b1634224c86", "25": "46e8db3e6e3f37ea", "26": "83b0fd3b14363e4d", "27": "eab427ce9a5219e9", "28": "cf86030ab36386aa", "29": "c608f1c6492e1cb1", "30": "73c13793fca09f56", "31": "fbbcfc059751cc6a", "32": "f6bcf56c4589316b", "33": "75f750c5b7d9f63d", "34": "f024ff7942935690", "35": "23f1d406f6c779ae", "36": "c55f872b3e16ab6f", "37": "cb8f26249485324a", "38": "01f68dfc34a29d32", "39": "fdd95375b4a5ddb3", "40": "3a68564642f68c0d", "41": "eb3733e409dc7411", "42": "ffd960136fde00ad", "43": "9a25b1230b5fe649", "44": "852c1bb2446edd9c", "45": "92ab3e5134ed8685", "46": "65718282b3c32109", "47": "41f3bef447e57f23", "48": "8c471c7baeaaca54", "49": "1f976711cda158dc", "50": "bbb2b57d72922b16", "51": "eb6a182204867275", "52": "2ec3c8c088568ba9", "53": "68c45056378341a7", "54": "c58d41e8e580fdc6", "55": "d96493a5f110bd4c", "56": "e649ddeadda89cbb", "57": "f2a40b5f1b29f669", "58": "73a31170f76a338b", "59": "891f59cda3708718", "60": "a505b7de6257a4e8", "61": "400fa8ac8b726a66", "62": "1366ae24c7e5897d", "63": "c256b43f75d7809e", "64": "86101547c05f96b9", "65": "3088ae48043ee39d", "66": "932f010dc6115fb4", "67": "3e126d8deaf6e200", "68": "6b91f3679541de79", "69": "e511846eeba03076", "70": "c396c038e5f5007f", "71": "2bfc96d4090afd84", "72": "c84f196a7bd35861", "73": "2b887bf601ccfb9f", "74": "ae2a154311e1f53a", "75": "69fdd23278518884", "76": "29790cf710874dd0", "77": "287d60115d9acda8", "79": "8f647d3ce08ecd2b", "80": "059d6ba8ca7ec3a0", "83": "a54008a71fdd44fa"} \ No newline at end of file diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index e56e781..d09553c 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,88 +1,94 @@ # Graph Report - juzi (2026-10-11) ## Corpus Check -- 59 files · ~4,180,488 words +- 64 files · ~4,182,459 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 1133 nodes · 2496 edges · 75 communities (57 shown, 18 thin omitted) -- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 178 edges (avg confidence: 0.53) +- 1164 nodes · 2523 edges · 81 communities (63 shown, 18 thin omitted) +- Extraction: 93% EXTRACTED · 7% INFERRED · 0% AMBIGUOUS · INFERRED: 179 edges (avg confidence: 0.53) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `ee744b6b` +- Built from commit: `3dda4ec7` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). ## Community Hubs (Navigation) - face-api.js -- t +- 线上闭环测试(不含真实微信授权) - app.js - skin-score.js - n - normalize -- drawFaceExpressions -- Box +- getContext2dOrThrow +- extractFaces - admin.js - __awaiter - AgeGenderNet - lib/accounts.js - server.js - files -- .predictAgeAndGender +- FaceLandmarks - .runAndExtendWithFaceDetection - 巨子测肤 · 1'me 在线肌肤测试 — UI 设计规范 -- extractFaces +- getEnv - 1'me 在线肌肤测试 H5 - head-pose.js - build_fixtures.py - disposeUnusedWeightTensors -- .loadFromDisk +- .computeFaceDescriptor - facepp-skinanalyze(旷视皮肤分析专业版调用技能) - 巨子测肤 · 1'me 语音播报内容设计文档 V1.0 - mobile-select.iife.min.js - wi - gen_voice.py -- i +- wn - face-api.js 本地化依赖(h5/vendor/faceapi/) - ui-20261009/manifest.json -- .toString +- browser-failures.mjs - FaceMatcher - build-fixture.py - DetectSingleFaceLandmarksTask -- C +- so - UI 外发版 10.09 图片资源 -- TinyYolov2 +- PredictSingleAgeAndGenderWithFaceAlignmentTask - UI交互界面调整 -- ComputeAllFaceDescriptorsTask -- .draw +- extractAllFacesAndComputeResults +- initialize - export_psd_assets.py - FaceLandmark68Net - start-local.sh - PredictAllAgeAndGenderWithFaceAlignmentTask - PredictAllFaceExpressionsWithFaceAlignmentTask -- k +- TinyYolov2Base - PredictSingleFaceExpressionsWithFaceAlignmentTask - mobile-select/README.md - call_skinanalyze_3view.sh - 护理建议(全量文本,按需求摘抄) - UI 对齐 10.09 设计稿:调研与实施计划 -- FaceLandmarks68 -- .forwardInput +- NeuralNetwork +- convLayer - regression.js - .dispose - call_skinanalyze.sh -- NeuralNetwork +- .extractWeights - 提交前 Review(2026-10-11) - e2e-browser.mjs - account-client.js -- PredictSingleFaceExpressionsTask -- .runAndExtendWithFaceDetections +- tt +- cn - ui-20261009.mjs -- ComputeSingleFaceDescriptorTask +- analyze-timeout.js - misans/README.md -- extractFaceTensors +- decodeBoxesLayer +- dr - build_report_copy.py +- TinyYolov2 +- FaceDetection +- isValidNumber +- 线上微信登录部署记录 +- Yo ## God Nodes (most connected - your core abstractions) 1. `__awaiter()` - 59 edges @@ -111,15 +117,15 @@ ## Import Cycles - None detected. -## Communities (75 total, 18 thin omitted) +## Communities (81 total, 18 thin omitted) ### Community 0 - "face-api.js" Cohesion: 0.02 -Nodes (32): cn(), computeReshapedDimensions(), createBrowserEnv(), createFileSystem(), createNodejsEnv(), dr(), en(), extractBoundingBoxes() (+24 more) +Nodes (57): bn(), Bo(), ca(), cd(), ce(), computeReshapedDimensions(), dn(), ee() (+49 more) -### Community 1 - "t" -Cohesion: 0.08 -Nodes (33): be(), bi(), Bo(), ce(), de(), e(), Ef(), er() (+25 more) +### Community 1 - "线上闭环测试(不含真实微信授权)" +Cohesion: 0.25 +Nodes (7): 发现并修复, 可复现命令, 已通过的检查, 线上闭环测试(不含真实微信授权), 结论, 话术及仓库同步, 验证边界 ### Community 2 - "app.js" Cohesion: 0.06 @@ -130,20 +136,20 @@ Cohesion: 0.12 Nodes (44): acneGrade(), buildViewModel(), calcAcne(), calcContour(), calcSens(), calcSmooth(), calcTone(), calcWrinkles() (+36 more) ### Community 4 - "n" -Cohesion: 0.17 -Nodes (32): a(), ae(), bf(), cf(), d(), drawContour(), dt(), ea() (+24 more) +Cohesion: 0.07 +Nodes (88): a(), ae(), ao(), b(), ba(), be(), bf(), bi() (+80 more) ### Community 5 - "normalize" -Cohesion: 0.09 -Nodes (26): conv(), conv$1(), convDown(), convLayer(), convLayer$1(), convNoRelu(), convWithBatchNorm(), denseBlock3() (+18 more) +Cohesion: 0.11 +Nodes (17): conv(), conv$1(), convDown(), convLayer$1(), convNoRelu(), denseBlock3(), denseBlock4(), depthwiseSeparableConv() (+9 more) -### Community 6 - "drawFaceExpressions" -Cohesion: 0.22 -Nodes (6): DrawBox(), drawDetections(), drawFaceExpressions(), DrawFaceLandmarks(), FaceExpressions(), isWithFaceExpressions() +### Community 6 - "getContext2dOrThrow" +Cohesion: 0.12 +Nodes (15): DetectAllFacesTask(), DrawBox(), drawDetections(), drawFaceExpressions(), DrawFaceLandmarks(), DrawTextField(), extendWithFaceDetection(), FaceExpressions() (+7 more) -### Community 7 - "Box" -Cohesion: 0.13 -Nodes (6): Box(), DetectAllFaceLandmarksTask(), extendWithFaceLandmarks(), FaceLandmarks(), minBbox(), ObjectDetection() +### Community 7 - "extractFaces" +Cohesion: 0.15 +Nodes (5): Box(), DetectAllFaceLandmarksTask(), extractFaces(), extractFaceTensors(), isTensor3D() ### Community 8 - "admin.js" Cohesion: 0.25 @@ -151,15 +157,15 @@ Nodes (23): api(), bind(), closeDetail(), collectFilters(), dimsHtml(), doRetry( ### Community 9 - "__awaiter" Cohesion: 0.14 -Nodes (12): __awaiter(), extendWithFaceDescriptor(), extractSingleFaceAndComputeResult(), FaceRecognitionNet(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow() (+4 more) +Nodes (12): __awaiter(), ComposableTask(), fetchImage(), fetchJson(), fetchNetWeights(), fetchOrThrow(), __generator(), getModelUris() (+4 more) ### Community 10 - "AgeGenderNet" -Cohesion: 0.10 -Nodes (6): AgeGenderNet(), extractParams$1(), FaceExpressionNet(), FaceLandmark68NetBase(), FaceLandmark68TinyNet(), FaceProcessor() +Cohesion: 0.11 +Nodes (5): AgeGenderNet(), FaceExpressionNet(), FaceLandmark68NetBase(), FaceLandmark68TinyNet(), FaceProcessor() ### Community 11 - "lib/accounts.js" -Cohesion: 0.07 -Nodes (40): build(), count(), fill(), numeric(), atomic(), body(), cookie(), cookies() (+32 more) +Cohesion: 0.06 +Nodes (43): build(), count(), fill(), numeric(), atomic(), body(), cookie(), cookies() (+35 more) ### Community 12 - "server.js" Cohesion: 0.08 @@ -169,9 +175,9 @@ Nodes (48): accounts, appendRecord(), callFacepp(), CRED, csvCell(), DATA_DIR, d Cohesion: 0.12 Nodes (15): files, analyze-fail, analyzing, countdown-321, hint-far, hint-front, hint-hold, hint-near (+7 more) -### Community 14 - ".predictAgeAndGender" -Cohesion: 0.28 -Nodes (4): extendWithAge(), extendWithGender(), PredictAllAgeAndGenderTask(), PredictSingleAgeAndGenderTask() +### Community 14 - "FaceLandmarks" +Cohesion: 0.10 +Nodes (9): bgrToRgbTensor(), extendWithFaceLandmarks(), FaceLandmarks(), FaceLandmarks5(), FaceLandmarks68(), getCenterPoint(), isDimensions(), minBbox() (+1 more) ### Community 15 - ".runAndExtendWithFaceDetection" Cohesion: 0.33 @@ -181,9 +187,9 @@ Nodes (5): allFacesMtcnn(), allFacesSsdMobilenetv1(), allFacesTinyYolov2(), dete Cohesion: 0.15 Nodes (12): 1. 基准与尺寸换算, 2. 色彩规范, 3. 字体规范, 4. 组件切图(assets/svg/), 5. 图片素材(assets/images/,共 15 张), 6. 页面清单(design/ 下有整屏 PNG 预览), 7. 目录结构, 8. 还原建议 (+4 more) -### Community 17 - "extractFaces" +### Community 17 - "getEnv" Cohesion: 0.19 -Nodes (19): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractFaces(), extractImagePatches(), getContext2dOrThrow(), getEnv() (+11 more) +Nodes (14): awaitMediaLoaded(), bufferToImage(), createCanvas(), createCanvasFromMedia(), extractImagePatches(), getEnv(), getMediaDimensions(), imageTensorToCanvas() (+6 more) ### Community 18 - "1'me 在线肌肤测试 H5" Cohesion: 0.07 @@ -199,11 +205,11 @@ Nodes (9): build_case1(), build_case2(), build_truth(), col(), dump(), main(), p ### Community 21 - "disposeUnusedWeightTensors" Cohesion: 0.09 -Nodes (24): disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$2() (+16 more) +Nodes (23): disposeUnusedWeightTensors(), extractorsFactory$3(), extractorsFactory$5(), extractorsFactory$7(), extractorsFactory$9(), extractParamsFromWeigthMap(), extractParamsFromWeigthMap$1(), extractParamsFromWeigthMap$2() (+15 more) -### Community 22 - ".loadFromDisk" -Cohesion: 0.25 -Nodes (3): ComposableTask(), getModelUris(), TinyFaceDetector() +### Community 22 - ".computeFaceDescriptor" +Cohesion: 0.18 +Nodes (4): ComputeAllFaceDescriptorsTask(), ComputeSingleFaceDescriptorTask(), extendWithFaceDescriptor(), FaceRecognitionNet() ### Community 23 - "facepp-skinanalyze(旷视皮肤分析专业版调用技能)" Cohesion: 0.20 @@ -218,16 +224,16 @@ Cohesion: 0.20 Nodes (16): _arrayLikeToArray(), _arrayWithHoles(), _arrayWithoutHoles(), _classCallCheck(), _createClass(), _defineProperties(), h(), _iterableToArray() (+8 more) ### Community 26 - "wi" -Cohesion: 0.32 -Nodes (8): Ci(), Ei(), Fi(), Ii(), ki(), ri(), wi(), Xt() +Cohesion: 0.28 +Nodes (9): Ci(), Ei(), Fi(), Ii(), ki(), pe(), ri(), wi() (+1 more) ### Community 27 - "gen_voice.py" Cohesion: 0.30 Nodes (11): ndarray, Path, gen_countdown(), main(), normalize_clip(), 倒计时单独按字生成再拼接,避免「三、二、一」整句被读成播报腔、与提示音气质漂移。 与提示音共用同一 speaker + instruct;句间留约…, 裁掉过长首尾静音,保留 ≤150ms 边沿,避免提示显迟钝。, 响度归一 −16 LUFS + 转 MP3 48k CBR mono 22050Hz。 (+3 more) -### Community 28 - "i" -Cohesion: 0.08 -Nodes (32): ba(), bn(), ca(), cl(), da(), dn(), ee(), et() (+24 more) +### Community 28 - "wn" +Cohesion: 0.67 +Nodes (3): wl(), wn(), xn() ### Community 29 - "face-api.js 本地化依赖(h5/vendor/faceapi/)" Cohesion: 0.29 @@ -237,17 +243,13 @@ Nodes (6): face-api.js 本地化依赖(h5/vendor/faceapi/), 为什么本地 Cohesion: 0.33 Nodes (5): assets, document_size, layers, pages, source -### Community 31 - ".toString" -Cohesion: 0.33 -Nodes (5): FaceMatch(), la(), pr(), pt(), vt() - ### Community 33 - "build-fixture.py" Cohesion: 0.60 Nodes (4): main(), 递归缩放 result 内全部坐标:{left,top,width,height} 矩形与 {x,y} 点,与原数据同为整数。, scale_coords(), to_data_url() -### Community 36 - "C" -Cohesion: 0.08 -Nodes (29): ao(), C(), cd(), co(), Do(), eo(), fo(), Ft() (+21 more) +### Community 36 - "so" +Cohesion: 0.50 +Nodes (4): Do(), io(), so(), To() ### Community 37 - "UI 外发版 10.09 图片资源" Cohesion: 0.40 @@ -257,6 +259,14 @@ Nodes (4): UI 外发版 10.09 图片资源, 前端素材对应, 文件位置, Cohesion: 0.40 Nodes (4): 1meAI测肤旷视UI问题反馈, UI交互界面调整, 交互, **设计** +### Community 40 - "extractAllFacesAndComputeResults" +Cohesion: 0.13 +Nodes (9): extendWithAge(), extendWithFaceExpressions(), extendWithGender(), extractAllFacesAndComputeResults(), extractSingleFaceAndComputeResult(), PredictAllAgeAndGenderTask(), PredictAllFaceExpressionsTask(), PredictSingleAgeAndGenderTask() (+1 more) + +### Community 41 - "initialize" +Cohesion: 0.29 +Nodes (7): createBrowserEnv(), createFileSystem(), createNodejsEnv(), initialize(), isBrowser(), monkeyPatch(), setEnv() + ### Community 42 - "export_psd_assets.py" Cohesion: 0.70 Nodes (4): bounds(), layer_at(), main(), save_image() @@ -265,10 +275,6 @@ Nodes (4): bounds(), layer_at(), main(), save_image() Cohesion: 0.50 Nodes (3): HOST, PORT, start-local.sh script -### Community 47 - "k" -Cohesion: 0.18 -Nodes (11): b(), gn(), k(), kn(), ne(), tt(), wo(), Yt() (+3 more) - ### Community 53 - "护理建议(全量文本,按需求摘抄)" Cohesion: 0.10 Nodes (19): 5\.1 轮廓(紧塑力), 5\.2 皱纹(紧塑力), 5\.3 肤色(透亮感), 5\.4 平滑度(透亮感), 5\.5 水分(透亮感), 5\.6 泛红(稳韧力), 5\.7 痘痘(稳韧力), 6\.1 轮廓 (+11 more) @@ -277,25 +283,21 @@ Nodes (19): 5\.1 轮廓(紧塑力), 5\.2 皱纹(紧塑力), 5\.3 肤色 Cohesion: 0.11 Nodes (17): 1. 结论和依据, 2. 统一比较口径, 3. 逐页差异和调整内容, 4. 报告数据如何接到新 UI, 5. 登录与“我的报告”的真实能力缺口, 6. 原稿中需要整理的内容, 7. 实施顺序与交付物, 8. 验收定义 (+9 more) -### Community 55 - "FaceLandmarks68" -Cohesion: 0.19 -Nodes (3): FaceLandmarks5(), FaceLandmarks68(), getCenterPoint() - -### Community 56 - ".forwardInput" -Cohesion: 0.22 -Nodes (9): boxPredictionLayer(), decodeBoxesLayer(), depthwiseConvLayer(), getCenterCoordinatesAndSizesLayer(), getStridesForLayerIdx(), mobileNetV1(), outputLayer(), pointwiseConvLayer() (+1 more) +### Community 56 - "convLayer" +Cohesion: 0.15 +Nodes (17): boxPredictionLayer(), convLayer(), convWithBatchNorm(), depthwiseConvLayer(), depthwiseSeparableConv$1(), fullyConnectedLayer(), getStridesForLayerIdx(), leaky() (+9 more) ### Community 57 - "regression.js" Cohesion: 0.60 Nodes (5): diffCtx(), loadJSON(), main(), okNum(), okStr() ### Community 58 - ".dispose" -Cohesion: 0.15 -Nodes (12): getSizesForScale(), iou(), nonMaxSuppression(), nonMaxSuppression$1(), normalize$1(), rescaleAndNormalize(), scale(), SsdMobilenetv1() (+4 more) +Cohesion: 0.21 +Nodes (11): getSizesForScale(), iou(), NetInput(), nonMaxSuppression(), nonMaxSuppression$1(), normalize$1(), rescaleAndNormalize(), scale() (+3 more) -### Community 61 - "NeuralNetwork" -Cohesion: 0.05 -Nodes (32): bgrToRgbTensor(), createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), Dimensions() (+24 more) +### Community 61 - ".extractWeights" +Cohesion: 0.09 +Nodes (25): createFaceDetectionNet(), createFaceRecognitionNet(), createMtcnn(), createSsdMobilenetv1(), createTinyFaceDetector(), createTinyYolov2(), extractConvParamsFactory(), extractFCParamsFactory() (+17 more) ### Community 62 - "提交前 Review(2026-10-11)" Cohesion: 0.40 @@ -309,24 +311,52 @@ Nodes (4): EXPECTED, fails, pageErrors, pwRoot Cohesion: 0.90 Nodes (4): browser(), init(), read(), request() -### Community 71 - "extractFaceTensors" -Cohesion: 0.18 -Nodes (9): extendWithFaceDetection(), extendWithFaceExpressions(), extractAllFacesAndComputeResults(), extractFaceTensors(), isTensor3D(), isWithFaceDetection(), isWithFaceLandmarks(), PredictAllFaceExpressionsTask() (+1 more) +### Community 65 - "tt" +Cohesion: 0.50 +Nodes (4): kn(), tt(), wo(), z() + +### Community 66 - "cn" +Cohesion: 0.67 +Nodes (3): cn(), en(), yn() + +### Community 68 - "analyze-timeout.js" +Cohesion: 0.20 +Nodes (7): assert, end, fs, path, source, start, vm + +### Community 70 - "decodeBoxesLayer" +Cohesion: 0.67 +Nodes (3): decodeBoxesLayer(), getCenterCoordinatesAndSizesLayer(), outputLayer() + +### Community 71 - "dr" +Cohesion: 0.67 +Nodes (3): dr(), na(), ta() + +### Community 79 - "isValidNumber" +Cohesion: 0.50 +Nodes (4): Dimensions(), isValidNumber(), isValidProbablitiy(), isWithGender() + +### Community 80 - "线上微信登录部署记录" +Cohesion: 0.29 +Nodes (6): 初次部署时的凭据查找记录(现已由用户提供), 初次部署的线上检查(历史结果), 后续更新:已配置真实凭据, 已执行, 用户确认加入白名单后的复测, 线上微信登录部署记录 + +### Community 83 - "Yo" +Cohesion: 0.67 +Nodes (3): qo(), Xo(), Yo() ## Knowledge Gaps -- **152 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+147 more) +- **173 isolated node(s):** `source`, `document_size`, `pages`, `assets`, `layers` (+168 more) These have ≤1 connection - possible missing edges or undocumented components. - **18 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `k()` connect `k` to `face-api.js`, `t`, `app.js`, `n`, `lib/accounts.js`, `i`?** - _High betweenness centrality (0.078) - this node is a cross-community bridge._ -- **Why does `renderReport()` connect `app.js` to `t`, `k`?** - _High betweenness centrality (0.058) - this node is a cross-community bridge._ -- **Why does `rate()` connect `lib/accounts.js` to `k`?** - _High betweenness centrality (0.055) - this node is a cross-community bridge._ +- **Why does `k()` connect `n` to `face-api.js`, `app.js`, `lib/accounts.js`?** + _High betweenness centrality (0.083) - this node is a cross-community bridge._ +- **Why does `rate()` connect `lib/accounts.js` to `n`?** + _High betweenness centrality (0.061) - this node is a cross-community bridge._ +- **Why does `renderReport()` connect `app.js` to `n`?** + _High betweenness centrality (0.056) - this node is a cross-community bridge._ - **Are the 24 inferred relationships involving `n()` (e.g. with `newRecordId()` and `ae()`) actually correct?** _`n()` has 24 INFERRED edges - model-reasoned connections that need verification._ - **Are the 27 inferred relationships involving `r()` (e.g. with `handleExport()` and `handleRecordsQuery()`) actually correct?** @@ -334,4 +364,4 @@ _Questions this graph is uniquely positioned to answer:_ - **Are the 7 inferred relationships involving `t()` (e.g. with `renderReport()` and `e()`) actually correct?** _`t()` has 7 INFERRED edges - model-reasoned connections that need verification._ - **What connects `source`, `document_size`, `pages` to the rest of the system?** - _152 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file + _173 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html index 440296b..a583114 100644 --- a/graphify-out/graph.html +++ b/graphify-out/graph.html @@ -63,12 +63,12 @@
-
1133 nodes · 2496 edges · 75 communities
+
1164 nodes · 2523 edges · 81 communities