From 49d0c5d2df637f45be825bc81b5f9a3bf920f591 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Wed, 29 Jul 2026 08:23:42 +0800 Subject: [PATCH] =?UTF-8?q?docs(claude):=20=E8=AE=B0=20iOS=20=E7=9C=9F?= =?UTF-8?q?=E6=9C=BA=E8=A3=85=E6=9C=BA(local=5Ftest.sh=20ipad,=E8=80=81?= =?UTF-8?q?=E5=BF=98)+=20CI=20=E5=8F=91=E7=89=88(tag=E8=A7=A6=E5=8F=91+?= =?UTF-8?q?=E7=A7=81=E6=9C=89=E4=BE=9D=E8=B5=96=E9=89=B4=E6=9D=83)+=20?= =?UTF-8?q?=E5=8F=AF=E9=85=8D=E7=BD=AE=E5=88=86=E6=B5=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移动端段加真机装机:API_URL=... local_test.sh ipad <设备>(公司分发证书/签名核验/xcurl 装机); iOS libbox gitignore 产物从主仓拷免重建;新设备 -allowProvisioningDeviceRegistration。 - CI/CD 段更新:tag 触发发版(server-v*/client-v*/site-v* → compile→test→release→deploy pangolin1 备份+migrate+回滚+healthz),取代过时的「仅校验无部署」;私有依赖 github.com/wangjia/codes→gitea 鉴权(GOPRIVATE+insteadOf,冷缓存 runner 必踩);发版排障(gitea actions API + rbw gitea 读写key)。 - server/ 加可配置分流小节:routing_profiles/GET-POST me/routing/BuildClientConfig 翻译(层级/三模式/ IP直连 route_exclude 在 tunIn/域名直连 reverse_mapping/nil 逐字节不变)/system_locked_domains。 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo --- CLAUDE.md | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bddda7f..f124b1e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,11 +66,39 @@ server 已与具体 DB 解绑(裸 SQL + 薄方言层,`internal/db/dialect.go`): `dialect.LockForUpdate()`;时间等一律 Go 端算好传 `?`,**不要**用 `UTC_TIMESTAMP()`/ `NOW()`/`FIELD()` 等 MySQL 专属构造(已全部清除,加回会破坏可移植性)。 +### 可配置分流(routing profile,类 Shadowrocket) + +用户自定义路由规则(域名/IP/GeoIP/GeoSite × 直连/走隧道/拒绝),有序首命中,存服务端 per-user 档案: +- 表 `routing_profiles`(迁移 000028)· `internal/routing`(Profile/校验/Store)· `GET/POST /v1/me/routing` + (`httpapi/routing.go`)。写操作走 **POST**(仓库无 PUT 先例);校验非法整体 400 逐条错误、不半保存。 +- **客户端不拼配置(铁律 ARCHITECTURE.md §3.1)**:客户端只编辑/存取档案,`BuildClientConfig` + (`httpapi/clientconfig.go`)在 connect 时读档案翻译进 `route.rules`——层级 **系统强制层**(hijack-dns/ + LAN 直连/私有服务走隧道,恒在、用户不可越)→ **用户规则** → geoip-cn 国内分流 → FINAL;三模式 + rule/global/direct(global/direct 忽略用户规则只改 FINAL)。 +- **直连真生效**:IP 直连 value 并入 `route_exclude_address`(在 **TUN inbound** `tunIn` 非顶层 `route`)、 + 域名直连开 `dns.reverse_mapping`。**fail-safe**:档案空/坏/取失败 → 回退默认,`Profile==nil` 逐字节 + 等价旧行为(有测试钉)。GET 附只读 `system_locked_domains`(私有域名清单,PUT 不持久化)供 UI 标「系统强制不生效」。 +- 客户端:设置页「分流规则」下钻(`routing_screen.dart` + `routing_provider`,Riverpod);改档案后连接态 + 自动重连使新规则生效。设计/计划见 `docs/configurable-proxy-{spec,plan}.html`。 + ## CI/CD -`.gitea/workflows/ci.yml`(runner label `nas`):shellcheck(bootstrap/single-node 脚本)、 -OpenAPI 结构校验、UI 文案脱敏扫描、Flutter analyze+test。**仅校验,无部署动作。** -- 节点部署是手动/按需的(scp+ssh 跑 bootstrap / single-node),不走 CI 自动推送。 +`.gitea/workflows/`(runner = 家里 NAS 上的 act_runner;job `runs-on: ubuntu-latest` 由它在 +`catthehacker/ubuntu:act-latest` 容器承接): +- **`ci.yml`**(push/PR,**仅校验**):shellcheck、OpenAPI 结构校验、UI 文案脱敏扫描、Flutter + analyze+test、codegen 漂移闸(`ci/check-codegen-drift.sh`:token/l10n/原型 i18n)。 +- **发版走 tag 触发**(cicd-design 已落地,取代旧「无部署」):`server-vX.Y.Z` → `deploy-server.yml` + = compile-backend → `test.sh server`(**`go test ./...`**,全绿才继续)→ Forgejo release → + `deploy-server.sh` 到 pangolin1(**备份DB→migrate up→换二进制→重启→本地 `/healthz` 权威闸**, + migrate 失败自动回滚DB+重启旧二进制)。同理 `client-v*`(deploy-client.yml)、`site-v*`。 +- **⚠️ 发版必踩的私有依赖坑**:go.mod 依赖 **私有** `github.com/wangjia/codes`(真源在自建 gitea + `git.51yanmei.com/wangjia/codes`)。冷缓存 runner 上 `go build` 会走 direct git 到 github → 无凭证 + 挂(`could not read Username, terminal prompts disabled`)。`deploy-server.yml` 已加「私有依赖鉴权」步: + `GOPRIVATE=github.com/wangjia/codes` + `git config url."/wangjia/codes.git".insteadOf https://github.com/wangjia/codes`。**新增任何私有 Go 依赖,编译前照此配鉴权。** +- **发版排障**:gitea `https://git.51yanmei.com/wangjia/pangolin/actions`;日志用 rbw「gitea 读写key」查 + `/api/v1/repos/wangjia/pangolin/actions/runs//jobs`(step 结论)+ + `/wangjia/pangolin/actions/runs//jobs//logs`(原始日志)。 +- 节点**新机初始化**仍手动(scp+ssh 跑 bootstrap / single-node),不走 CI。 ## 设计 Token 单源模型 @@ -179,6 +207,11 @@ cd web/website && npm run gen:tokens - Android:`bash scripts/build-libbox.sh android` → `Libbox.aar`,**重命名小写** `libbox.aar` 放 `app/kernel/dist/android/`。⚠️ gomobile 编 Android **强制 JDK 17**(JDK 21 直接拒);`export JAVA_HOME=/opt/homebrew/opt/openjdk@17/...` 再编。 - ⚠️ **Android libbox Java 包名是 `io.nekohasekai.libbox`**(不是 `libbox`),Kotlin import 用前者。 +**真机装机(老忘——有现成脚本,别手搓 xcodebuild/签名)**: +- **iOS**:`API_URL=https://api.yanmeiai.com bash scripts/local_test.sh ipad "<设备名/id>"`(`local_test.sh ios-devices` 列已连设备)。脚本自动:flutter build ipa(**公司分发证书** Apple Distribution: Yanmei / Team `BYL4KQHMTN`,ad-hoc)→ 核验签名主体(防无声退回个人证书)→ `xcrun devicectl` 装机。`API_URL` 决定客户端连哪个控制面(prod = `https://api.yanmeiai.com`)。 +- iOS libbox 是 **gitignore 产物**,新 worktree 常缺 → 从主仓拷免重建:`cp -R /Users/wangjia/code/pangolin/client/ios/Frameworks/Libbox.xcframework client/ios/Frameworks/`(routing 等功能不碰 libbox 接口,主仓那份兼容)。 +- 新设备首次装报 `0xe8008012`(描述文件不含 UDID)→ 需 xcodebuild `-allowProvisioningUpdates -allowProvisioningDeviceRegistration`(脚本 die 里给了兜底命令);chen 的设备(chen-macbook/chen-iphone)已注册。装机走**公司**分发证书,禁个人开发证书(记忆 `ios-install-team-cert`)。 + ## 跨端实时统计 + urltest 延迟(连接页"延迟"的唯一正解) 连接页"延迟"= 内核 urltest(经 REALITY 真实出站测 RTT);**坑很深,改前必读**