Nonmotor 开发手册
NONMOTOR / ENGINEERING GUIDE
面向后端工程师 · 从需求到交付更新于 2026.10.09

Nonmotor 前端开发指南:从需求到交付#

本文面向准备参与 Nonmotor 前端开发的后端工程师。你可以从熟悉的业务流程和接口出发,逐步掌握页面定位、需求拆解、Journey 配置、页面开发、联调和交付。

阅读后应能独立回答四个问题:这个需求改哪里?哪些能力已经存在?数据怎样从用户输入到达后端?怎样证明改动可以交付?

文档依据为当前 nonmotor_h5 仓库、用户提供的《admin后端开发流程》页面正文,以及用户确认的分支与 Casement 部署流程和截图,核对日期为 2026-10-09。命令与代码路径已按源码核对,尚未进行新环境安装、页面启动和部署实测。登录操作、Reviewer 与部署负责人等尚未确认的信息列在文末待补充表中。

当前要做的事 阅读位置
第一次认识项目 第 1 章项目介绍、第 4 章代码定位
在本地打开页面 第 2—3 章环境与启动
开始实现需求 第 5—8 章开发流程、Journey、约定与案例
联调、排障和交付 第 9—10 章验证与发布
使用 AI 或检查完成度 第 11—12 章工具与完成标准

1. Nonmotor 项目介绍#

1.1 先认识用户走过的业务链路#

Nonmotor H5 承载非车险相关的前端页面。以产品工厂投保流程为例,用户通常先查看产品和保障方案,再填写投保信息,确认后进入收银台。不同产品可能合并步骤,或增加健康声明、被保人信息、目的地选择等步骤。

流程示意
  1. 产品详情 PDP
    1. 填写投保信息 Purchase
      1. 确认信息 Confirmation
        1. 收银台 Checkout
          1. 后续支付与结果流程

这张图用于建立业务认知,具体页面顺序以目标产品的 Journey 和实现为准。

环节 页面主要职责 开发时要核对的数据
产品详情 展示保障、选择方案、呈现报价、引导投保 产品、Plan、保障期间、报价和准入状态
投保信息 预填、用户输入、字段联动、校验与步骤切换 投保人/被保人字段、显示值与接口值、缓存
信息确认 展示本次投保内容、声明和确认操作 前序输入、展示格式、协议和最终提交内容
收银台 展示金额、支付相关信息并衔接后续流程 订单参数、报价、优惠和支付渠道等

前端负责交互和及时反馈,后端负责最终业务校验。例如,前端可以提示邮箱格式错误、阻止空字段进入下一步;接口仍应校验请求是否合法,金额、资格等权威结果也应遵循后端契约。

1.2 页面由哪些部分共同决定#

实际页面来自几个部分的组合:前端代码、产品 Journey、接口数据、翻译、PFC 配置以及运行环境。

因此,“页面不对”不一定意味着要修改 React 代码。某个字段没有出现,可能是 Journey 没有配置、显隐条件未命中、组件名未匹配,也可能是当前产品或市场选错。

还要区分两个常见概念:

1.3 技术栈与运行方式#

当前工程主要使用 React 18、TypeScript、Webpack 5、SCSS,采用多入口多页面架构。每个页面有自己的入口和 HTML,构建时按应用与市场选择页面集合。

页面可以运行在浏览器或 App WebView 中。项目通过 Bridge 封装页面跳转、返回和其他宿主能力。浏览器能打开页面,并不代表 App 中的返回、登录和支付链路已经验证完成。

后端熟悉的概念 在本项目前端中如何理解
服务启动入口 index.tsx 挂载页面,并进行页面级初始化
业务用例编排 App、业务组件和 Hook 组织数据、交互与页面状态
下游接口客户端 service/model 调用统一 request,封装接口协议
请求上下文 props、state、Context 和持久化缓存有不同生命周期
配置驱动 Journey 决定部分页面结构;PFC 提供命中条件下的配置
日志与调用链 Network、Console、IDAP 与后端日志结合排查

前端组件会随状态变化重复渲染,不能把组件函数当作“只执行一次的服务初始化”。跨页面跳转后,组件状态也不能自然保留,需要明确缓存与参数传递方式。

2. 项目环境搭建#

2.1 开始前准备的信息和权限#

先拿到仓库访问权限,以及一个可以复现的非生产产品入口。开发样例至少要包含:市场、环境、产品、页面 URL、测试账号获取方式,必要时还包括后端 PFB。

需要访问的能力包括公司 npm 源、项目启动所需的 KMS、产品工厂配置、翻译平台,以及联调使用的后端环境。具体权限申请入口由团队维护人提供。

本文示例从已拉取的 nonmotor_h5 仓库根目录执行。开发者可使用自己的 IDE,但终端工作目录必须正确。

2.2 Node 与依赖#

仓库 .nvmrc 当前声明 v20。已安装 nvm 的同学可以执行:

bash
nvm install
nvm use
node -v
npm -v

使用其他 Node 版本管理器时,同样以项目版本文件为依据。package.json 中较宽泛的最低版本声明,不代表所有更低版本都已验证可用。

部署安装脚本使用以下依赖安装方式,本地可以据此准备依赖:

bash
npm install --registry https://npm.shopee.io --legacy-peer-deps

安装失败时,先根据错误区分 npm 源访问、权限、Node 版本和原生依赖编译问题。不要通过随意升级依赖或删除锁文件来跳过原因分析。安装后检查 package-lock.json 差异,确认是否属于本次需求。

2.3 环境变量分别控制什么#

配置 作用 需要注意
APP_NAME 选择应用及入口配置 本项目目标服务选择 nonmotor
REGION 选择市场入口和区域实现 使用目标市场,例如 my、id;并非每个应用都支持菜单中的全部市场
ENV 选择开发/构建环境 对应 mock、dev、test、uat、live 等;日常联调选已约定的非生产环境
BUILD_ENV 选择构建环境与相关运行配置 按目标业务选择 spin 或 spic
BROKER_NAME 部分 spic 场景的主体配置 仅按实际业务选择
TRANSIFY_REPORT 本地翻译使用上报开关 启动菜单可选择,默认 off
后端 PFB 指定联调的后端分支环境 不等于前端 ENV;必须结合实际请求验证

npm run dev 的交互脚本会把所选配置保存到仓库根目录 .env。新任务开始时应核对配置,不要无意复用上一次开发的市场和应用。

npm run start 和 npm run build 都会先执行 scripts/kms.js。KMS 访问失败属于启动前置条件问题,应按团队约定准备对应凭证和网络;凭证不要写进源码、MR 或共享排障日志。

2.4 浏览器代理与 Whistle 分别负责什么#

本地联调使用 ZeroOmega 浏览器代理插件 + Whistle 代理服务 + 本地开发服务。三者职责如下:

工具 职责 本文使用的地址
Proxy SwitchyOmega 3(ZeroOmega) 控制 Chrome 请求是否经过指定代理 指向 127.0.0.1:8899
Whistle 抓包、匹配规则、转发或替换请求响应 默认代理端口 8899,管理后台为 http://127.0.0.1:8899
nonmotor 开发服务 返回本地 HTML、JS/CSS,并通过开发代理处理 /api 默认 localhost:3000

Whistle 是基于 Node.js 的跨平台网络代理与调试工具,支持 macOS、Windows、Linux。日常使用它查看请求、代理页面和接口、mock 响应、模拟弱网以及调试移动端 H5。ZeroOmega 只负责代理选择,安装插件后还需要运行 Whistle。Whistle 项目说明

以 MY Test 的整站代理规则为例:

流程示意
  1. Chrome 访问 MY Test 域名
    1. ZeroOmega
      1. Whistle 8899
        1. 本地开发服务 3000
          1. 返回本地页面与资源
          2. API 经开发代理发往后端

浏览器地址栏仍是业务域名,本地代码通过代理返回。页面 Cookie 和存储仍按浏览器中的域名使用;代理本身不会创建登录态。

2.5 安装 ZeroOmega 插件#

在 Chrome 中打开 Proxy SwitchyOmega 3(ZeroOmega)安装页,安装后进入插件设置,新建一个代理情景模式,例如命名为 Whistle。

设置项 值
代理协议 HTTP
代理服务器 127.0.0.1
端口 8899

将该 HTTP 代理设为默认代理,使目标 HTTP/HTTPS 请求都经过它;若界面分别配置 HTTP、HTTPS 请求代理,两者均指向上述代理服务。这里选择的 HTTP 是浏览器连接代理的方式,不代表目标业务页面必须使用 HTTP。

保存/应用设置。等 Whistle 启动后,再通过插件图标切换到 Whistle 模式。也可以在自动切换模式中仅让目标业务域名走此代理。

2.6 安装并启动 Whistle#

完成 Node 环境准备后,在终端执行:

bash
# 安装命令行版
npm i -g whistle

# 启动并查看状态
w2 start
w2 status

打开 Whistle 本地管理后台。主要使用 Network 查看流量,使用 Rules 编辑代理规则。命令行版的常用管理命令如下:官方命令行文档

bash
# 重启
w2 restart

# 停止
w2 stop

Whistle 也提供桌面客户端,可从官方安装说明进入;本指南统一以命令行版为例。同一套环境选择一种运行方式,避免两个实例竞争端口或误用另一套规则。

2.7 安装证书并开启 HTTPS 抓包#

业务页面使用 HTTPS 时,需要让 Whistle 解密请求,才能按页面路径代理并查看明文请求响应。完成以下设置:

  1. 在 Whistle 管理界面打开 HTTPS,通过 Download RootCA 下载本机 Whistle 根证书。
  2. 在操作系统中安装并信任该证书。macOS 可在“钥匙串访问”中导入并设置证书信任;也可使用下面的官方命令完成安装,按系统提示确认。
  3. 在 Whistle HTTPS 设置中开启 Enable HTTPS (Capture Tunnel Traffic)。
  4. 重新加载目标 HTTPS 页面,检查是否能看到具体 URL、请求头和响应内容。
bash
w2 ca

证书安装与 HTTPS 解密开关需要同时完成。若只看到 Tunnel to 而无法查看目标请求内容,先检查解密开关、证书信任以及请求是否经过当前 Whistle 实例。HTTPS 设置说明、证书安装命令

2.8 配置目标市场的代理规则#

在 Whistle 的 Rules 中按市场与环境建立规则组,例如 nonmotor-my-test,粘贴规则、保存并启用。本地 3000 端口一次运行的是当前选择的应用/市场/环境;日常只启用本次需要的规则组。

以 MY Test 为例,团队材料使用整站转发,本指南整理为显式指定 HTTP 目标的写法:

text
# MY Test:保留请求路径,整站转发到本地开发服务
protection.test.shopee.com.my http://localhost:3000

它会将 /nonmotor/purchase5.html?... 转发到本地相同路径。已有整站规则时,指向相同服务、保留相同路径的 /ins、/nonmotor、/common、/ec、/static 规则可合并,避免重复维护。使用 http:// 明确目标是本地 HTTP 开发服务,URL 路径按规则自动拼接。Whistle HTTP 转发规则

整站转发也包含 /api,接口随后由 scripts/start.js 的开发代理决定最终后端目标。因此需要核对浏览器访问环境、Whistle 规则和本地启动环境。它不是只替换 HTML 的规则。

如果只想代理某个页面目录,可以使用下列规则替代整站规则;资源和其他请求的去向需要另外核对,不要与整站规则一起启用后误以为范围已缩小:

text
# 可选:仅把 nonmotor 路径转发到本地
protection.test.shopee.com.my/nonmotor http://localhost:3000/nonmotor

各市场的整站规则见附录 C。代理规则不会自动启动项目,也不会让未构建的应用页面出现:APP_NAME=nonmotor 时,其他应用入口是否可用仍取决于本地构建内容。

2.9 常用调试能力与手机联调#

场景 用法
查看接口 在 Network 中查看 URL、请求/响应头、响应体和耗时
临时 mock 用限定范围的规则替换目标接口响应,模拟特定数据和错误
弱网验证 用延迟、限速规则检查 loading、超时与重试表现
页面远程调试 按需使用 Whistle 内置 Weinre、Console 能力

这些能力可以在不修改业务代码的情况下调整网络行为,规则使用后应关闭,避免影响下一轮真实接口验证。Whistle 快速上手

手机调试时,手机与电脑需网络互通;将手机 Wi-Fi 的手动代理设为电脑的局域网 IP + 8899,不能填写手机自己的 127.0.0.1。手机也需要安装并信任该 Whistle 根证书,iOS 安装描述文件后还需开启完全信任。部分 App 的证书策略可能限制抓包,应以实际运行结果为准。移动端抓包说明

结束调试时,先将 ZeroOmega 切回原先的正常模式,再按需执行 w2 stop;手机或系统若设置了手动代理,也应恢复原配置。本文浏览器方案不要求同时开启系统代理,只有配置过的代理入口才需要恢复。

2.10 安装 iOS Simulator 与 Shopee App#

本节适用于 macOS + Xcode 的 iOS 模拟器,用于验证 Shopee App 内的 H5 展示、返回与 Bridge 交互。安装入口和内部 App 下载方式来自团队提供的截图;截图中的设备、iOS 和 App 版本只是示例,选择时以当前测试要求和兼容性为准。

第一步:安装 Xcode 并启动模拟器#

  1. 从团队材料中的 Xcode 下载目录获取适配当前 Mac 的 Xcode,完成安装及首次启动要求的组件安装。
  2. 在 Xcode 中确认已安装目标 iOS Simulator runtime。如果没有可选的 iOS 设备,先在 Xcode 设置的运行时/组件管理界面下载所需版本;不同 Xcode 版本的菜单名称可能不同。Apple 运行时安装说明
  3. 搜索并打开 Simulator.app,或通过 Xcode 的 Open Developer Tool → Simulator 打开。
  4. 选择并启动一个目标 iPhone 模拟设备,等待进入 iOS 主屏幕。

Simulator 是 Xcode 自带的开发工具。仅有命令行工具不等于已经准备好完整的模拟器环境。Apple Simulator 说明

第二步:下载对应市场的 Simulator App 包#

进入团队 App 平台 app.sea.com,选择需要调试的 Shopee 市场 App。截图给出的示例为 Shopee ID App 页面,其他市场选择各自对应的 App。

在 iOS 版本列表中搜索 simula 或 simulator,找到团队要求的模拟器构建版本并下载。不要把截图中的历史版本号作为统一安装要求;也不要仅凭市场一致就选择任意 Native Feature Build,应使用本次测试约定的构建。

安装包需要明确支持 iOS Simulator,并与当前 Mac 架构及模拟器运行时兼容。普通真机安装包不能通过改扩展名变成 Simulator 包。

第三步:解压并安装 App#

  1. 若下载的是可直接使用的 .app 应用包,直接进入安装步骤。
  2. 若是压缩包,先解压。团队材料中的“改后缀为 .zip”适用于内容本身为 ZIP 归档、但下载扩展名不便解压的包;已经是 .zip 的文件直接解压即可。
  3. 在解压目录中找到 .app 应用包,将它拖到已经启动的 Simulator 设备窗口中安装。
  4. 等待主屏幕出现 App 图标,打开并检查能否正常启动。

如果安装失败,先核对是否误下真机包、市场/构建是否正确、Mac 架构及 runtime 是否兼容。App 安装完成后,再按团队测试账号流程登录;账号获取和登录操作另行补充。

第四步:为模拟器开启系统代理#

第 2.5 节的 ZeroOmega 控制 Chrome 请求,不能代替模拟器 App 的代理设置。按团队材料,模拟器联调通过 Whistle 设置 Mac 系统代理:

bash
# 启动 Whistle
w2 start

# 设置 Mac 系统代理,指向运行中的 Whistle
w2 proxy

默认 Whistle 使用 127.0.0.1:8899。开启系统代理会影响使用该系统代理的其他应用,操作前保留原代理配置,结束后恢复。Whistle 系统代理命令

同时完成以下配置:

浏览器 ZeroOmega、Mac 系统代理和实体手机 Wi-Fi 代理是不同的流量入口,按调试设备选择;三者可以指向同一个 Whistle 服务。

第五步:验证并结束调试#

在 Whistle Network 中观察请求,并核对:

检查项 通过标准
模拟设备 能进入 iOS 主屏幕,目标 App 能正常启动
代理 模拟器访问目标页面时,Whistle 能捕获对应请求
HTTPS 能查看具体请求与响应内容,无证书信任错误
页面版本 目标业务域名返回本地修改后的页面
业务链路 登录、接口环境、页面返回与相关 Bridge 行为符合本次需求

若 Safari 请求可抓取、但目标 App 请求不可抓取,应继续检查 App 的网络及证书策略,不把浏览器验证结果当作 App 已通过。模拟器用于日常开发验证,依赖真实设备能力的场景仍需按验收要求在真机验证。

调试结束,或其他软件因系统代理出现网络问题时,关闭本次启用的系统代理:

bash
w2 proxy 0

# 不再需要 Whistle 时再停止服务
w2 stop

截图使用 w2 proxy off,本文统一采用官方当前文档列出的 w2 proxy 0。若原来已有公司代理或其他网络工具,应恢复原设置;Chrome 的 ZeroOmega 若仍选着 Whistle 模式,也需要切回正常模式。Whistle 命令说明

团队安装材料截图#

团队提供的 Xcode、Shopee Simulator App 安装与模拟器代理步骤

截图中的内部下载地址作为团队提供的安装入口保留,本次未登录这些平台确认可下载版本,也未实际安装 Xcode、App、证书或修改系统代理。

3. 启动项目与打开第一个页面#

3.1 使用交互入口启动#

bash
npm run dev

依次选择“开发”、目标环境、Transify 上报设置、目标市场、服务 nonmotor、构建环境;需要时再选择主体。首次启动应显式选择,确认无误后才使用“使用上一个命令”。

脚本随后调用 npm run start。默认端口为 3000,端口变更时以终端输出为准。

3.2 页面 URL 也要选对#

开发环境生成的 HTML 路径带应用前缀。例如,MY 的 purchase5 在默认端口下对应:

text
http://localhost:3000/nonmotor/purchase5.html?product_id=<目标产品ID>

这是路径示意,<目标产品ID> 必须替换成实际值,其他必要参数应从有效业务入口保留。该页依赖产品配置、登录态和前序流程数据时,应从产品详情进入;直接打开中间页不能替代完整链路验证。

完成第 2 章代理配置后,日常联调在浏览器打开对应环境的原始业务地址,例如 MY Test:

text
https://protection.test.shopee.com.my/nonmotor/purchase5.html?product_id=<目标产品ID>

浏览器通过 Whistle 获取本地页面,地址栏保持 MY Test 域名。直接访问 localhost 可用于检查本地页面服务,但两者的 Cookie/存储域不同,不能把 localhost 能打开视为业务域名登录已完成。

仓库旧 README 中的 /ins/ 和根路径示例不能直接套用到 nonmotor。开发路径依据 config/webpack.config.js,页面名单依据 config/nonmotor/{region}.json。

3.3 本地页面如何请求后端#

scripts/start.js 已包含开发代理:非 mock 环境根据 BUILD_ENV、REGION、ENV 等选择后端域名,并代理 /api 请求;mock 环境将 /api 指向本地 3001 端口。

启动后先查看终端输出的请求转发域名,再在浏览器 Network 面板核对具体请求。页面加载成功、代理目标正确、登录成功是三个不同检查点。

使用第 2 章的整站规则时,请求链路是“浏览器 → Whistle → 本地开发服务 → 开发 API 代理”。登录 Cookie 的域、环境和账号必须匹配当前打开的页面;后端使用 PFB 时,验证实际链路是否命中目标 PFB。

用户提供的浏览器域名与当前 scripts/start.js 的部分 API 目标存在差异:

市场/环境 材料中的浏览器域名 当前 spin 开发代理目标
TH Test protection.test.shopee.co.th protection.test.moneeinsurebroker.co.th
TH UAT protection.uat.seainsurebroker.co.th protection.uat.moneeinsurebroker.co.th
SG Test / UAT test.moneeinsureagency.sg / uat.moneeinsureagency.sg test.seainagency.sg / uat.seainagency.sg
PH Test / UAT protection.test.moneeinsurebroker.com.ph / protection.uat.moneeinsurebroker.com.ph protection.test.seainsureagency.com.ph / protection.uat.seainsureagency.com.ph

此表记录材料和源码的差异,不据此认定域名不可用或需要替换。目标环境是否通过别名或迁移实现兼容,需要实际联调确认。浏览器域名正确仍不足以证明 API 目标正确,本次文档整理未修改代理源码。

3.4 首次启动验收#

首次开发不以“终端没有报错”为结束,应完成以下检查:

  1. Webpack 编译完成,目标 /nonmotor/*.html 可以打开。
  2. 当前应用、市场、环境和产品与需求一致。
  3. 页面能获取正确 Journey 或业务数据,接口没有登录失败。
  4. 修改一处目标页面代码后,能够确认浏览器运行的是本地版本。
  5. 至少完成目标产品的一段真实交互,核对请求和页面结果。

代理链路还应检查:

若 Whistle 看不到请求,先查插件模式和代理端口;能看到请求但页面未替换,查规则命中、缓存和本地路径;接口报登录错误则继续核对账号、Cookie 域和 API 目标,代理工具不会代替登录步骤。

4. 项目结构:从 URL 找到需要修改的代码#

4.1 常用目录#

目录或文件 主要职责
config/nonmotor/{region}.json nonmotor 各市场的 entry 和 HTML 配置
config/bizConfig.js 根据 APP_NAME、REGION 读取并组装入口配置
src/pages/ 页面实现,包含历史页面、市场页面和工厂页面
src/pages/factory/、src/pages/factoryV2/ 产品工厂页面、组件、解析和业务实现
src/pages/checkoutV2/ 收银台页面及相关业务代码
src/service/ 按领域组织的接口封装
页面内的 model/、service/ 部分既有页面的请求与数据处理,阅读时沿实际 import 查找
src/common/request.ts 请求、登录检测、签名等公共行为
src/InsEntry/ 动态表单、字段组件和校验能力
src/MoneeDesign/ 基础 UI 控件、图标及样式能力
src/components/ 共享组件和业务组件
src/module/ URL、存储、日期、Cookie 等公共工具
src/bridge/ App 宿主交互封装
src/locales/ 文案格式化与翻译读取
runbooks/、docs/automation/ 回归用例与 UI 自动化规范
deploy/ 安装、构建和部署配置

仓库保留了 ins_h5 的名称、工具和其他业务源码。判断一个页面是否属于当前 nonmotor 构建,要查入口配置,不能仅靠目录名或文件是否存在。

4.2 实例:定位 MY 投保信息页#

打开 config/nonmotor/my.json,先找到 filename 为 purchase5.html 的 htmlPlugin,再查看它的 chunks。当前对应关系为:

text
purchase5.html
  → chunks: purchase5
  → entry: factoryV2/purchase5/index.tsx
  → src/pages/factoryV2/purchase5/index.tsx

然后按以下顺序阅读:

  1. index.tsx:创建 React 根节点、挂载 BaseComponent 和 App、初始化页面埋点。
  2. App.tsx:请求 queryFactoryProductDetail('purchase', true),按 Journey 组织页面步骤与组件。
  3. 请求实现:沿 import 到 src/pages/factory/model/queryProductFactoryJourney.ts,查看请求及 pages/blocks/entries 的解析。
  4. 组件实现:根据 block 的组件名查页面组件导出和 factoryV2/components 中的实现。
  5. 表单与缓存:继续跟踪当前字段的读取、校验和提交处理,直到下一步消费它的位置。

终端中可以先搜索:

bash
rg -n 'purchase5' config/nonmotor/my.json
rg -n 'queryFactoryProductDetail' src/pages/factoryV2/purchase5
rg -n 'query_product_factory_journey' src/pages/factory/model

4.3 阅读旧代码与编写新代码的区别#

历史页面可能存在不同目录布局、旧接口封装或宽泛类型。阅读时跟随真实调用链;新增代码时遵守当前项目规范,复用既有工具,并保持本次改动范围清晰。

例如,公共 API 通常放在 src/service/{domain};维护一个已有页面时,不应仅为统一目录把整页 model 全部搬迁。

5. 一个需求到手后的开发流程#

5.1 第一步:把业务需求变成前端影响清单#

编码前,先确认以下信息:

维度 要明确的问题
范围 哪个市场、产品、渠道、App/浏览器场景?哪些不受影响?
页面 从哪里进入?经过哪些页面?返回、刷新、重新进入如何表现?
设计 默认、加载、空数据、错误、禁用状态如何展示?
数据 来源是接口、Journey、PFC、缓存还是用户输入?
契约 字段类型、枚举、空值、业务码、时间和金额口径是什么?
配置 是否修改 Journey、翻译、图片、开关或准入配置?
验收 正常路径、异常路径、埋点和关联产品如何验证?

接口有某个字段,并不意味着前端该直接展示或提交它。要同时确定展示规则、交互规则和业务含义。

5.2 第二步:判断修改配置还是代码#

需求情况 优先处理方式
已有字段的文案、显隐、支持范围内的校验调整 核对 Journey/i18n 和组件能力,优先配置
现有组件已有能力,但当前产品尚未启用 配置接入并验证数据契约
现有组件缺少交互或展示能力 评估扩展现有组件,列出其他调用方
独立业务区块 复用基础控件,新增或调整业务组件及配置接入
新页面或流程步骤 先评估现有模板,再处理入口、导航、缓存和埋点
接口新增或变更字段 对齐类型、请求映射、响应处理和全部消费方

如果需求只涉及 Journey,也要验证运行时页面和接口行为;如果修改公共组件,回归范围要覆盖复用方。

5.3 第三步:形成方案并开始开发#

小需求可以用一份简明方案说明目标页面、字段映射、改动文件和验收场景。复杂需求需要 TD,把页面、组件、接口、配置、缓存和发布依赖拆清楚。

开发顺序建议为:确认契约 → 获取当前配置 → 选择复用能力 → 实现页面与数据流 → 联调 → 自测 → Review → 提测。接口尚未就绪时,可以用明确契约的 mock 并行开发,真实接口就绪后补齐联调。

5.4 分支与 MR#

团队在 Casement 中建立迭代,迭代分支命名为 release-v1.x.xxx;本地开发分支命名为 dev-v1.x.xxx,版本号与目标迭代保持一致。例如,release-v1.3.318 对应 dev-v1.3.318。

分支 用途 代码流向
dev-v1.x.xxx 开发者本地开发、提交 commit 和自测 自测完成后发起 MR,合入对应 release 分支
release-v1.x.xxx 汇集当前迭代的改动,供版本发布与部署使用 合入并发布后,在 Casement 部署对应版本

完整流程如下:

流程示意
  1. Casement 建立 release 迭代
    1. dev 分支开发与提交 commit
      1. 本地自测完成
        1. 提交 MR:dev → release
          1. MR 合入 release 并发布
            1. Casement 部署对应版本
              1. 检查部署结果与页面行为

开始修改前检查工作区和当前分支,确认本次需求所属的迭代:

bash
git status --short
git branch --show-current

在对应的 dev-v1.x.xxx 分支完成开发和 commit,本地开发、自测完成后推送分支并提交 MR。MR 的 source 选择 dev-v1.x.xxx,target 选择同版本的 release-v1.x.xxx。

提交 MR 前同步目标分支并处理冲突,不把无关工作区变更混入本次需求。确认 MR 已成功合入 release 并完成发布后,再进入 Casement 部署;只有本地 commit 或 MR 尚未合入时,release 版本还不包含本次改动。

Reviewer、审批要求及多人同时使用开发分支时的远端协作约定,按团队安排执行,具体规则待补充。

6. Journey、动态表单和数据流#

6.1 Journey 的三层结构#

层次 含义 阅读重点
page 一个页面或配置中的页面节点 页面名、步骤、页面属性
block 页面中的业务区块 组件名、所在步骤、区块属性和字段集合
entry 区块中的字段或渲染元素 component_name、field_name、props、依赖和约束

可以将其理解为“配置描述界面需要什么,代码提供可执行的组件能力”。配置写入了某个 component_name,还需要确认目标页面能够解析并加载该组件。

6.2 从配置到页面的过程#

流程示意
  1. Admin / O 端 Journey 配置
    1. 后端 Journey 响应
      1. 页面 model 解析 pages / blocks / entries
        1. 业务组件与 InsEntry 渲染
          1. 用户输入及校验
            1. 当前步骤规范化并写入缓存
              1. 后续页面读取、确认与提交

以 purchase5 为例,调用 Journey 解析时传入 true,entry 的运行时 name 会使用 field_name。排查字段联动时,应核对运行时表单标识,而不是只看 Admin 上显示的 entry 名称。

6.3 配置源与本地 mock#

当前项目约定:

修改 Journey 时要同步源配置和生成的 view。找不到当前产品的配置时,应先取得有效配置来源,不能根据页面外观拼出一份“看起来合理”的配置。

图片使用经过指定上传流程得到的 CDN 地址;不把 Figma 临时链接或本地路径当作正式 Journey 图片。产品差异优先通过配置表达,配置确实不能承接时再说明代码适配的原因与范围。

6.4 数据闭环要在当前步骤完成#

新增字段时,至少追踪:输入值 → 校验结果 → 缓存位置 → 下游读取 → 展示值 → 请求值。

每个步骤负责把自己的输出处理成下游可直接消费的结构。不要把前序步骤遗漏的字段转换、默认值和业务规则统一堆到最后创单时补救。

项目已有存储工具和 Road Cache helper。阅读具体产品时还要核对缓存 key 与产品、流程、续保等参数的关系。返回修改、切换产品和重新进入,都可能暴露只验证单次向前流程时发现不了的问题。

7. 页面、组件与接口开发的基本约定#

7.1 页面与组件如何分工#

层次 应承担的职责
页面入口 index.tsx 挂载页面、页面级埋点及初始化
App / 页面业务层 页面数据、状态组合、业务交互与流程
业务组件 一个可独立理解的业务区块及其交互
基础控件 输入、按钮、图标、状态 UI 等通用表现
service/model 接口类型、参数映射和数据处理;新 Service 不承载 Toast、跳转或 React 逻辑

新增基础 UI 优先查 src/MoneeDesign/;新增业务能力先查已有组件。复杂页面可以使用 reducer 和 Context,局部状态尽量留在负责它的组件中,不为一个小需求引入新的全局状态库。

7.2 新建页面的入口注册#

nonmotor 新页面应注册在 config/nonmotor/{region}.json,其中 entry 路径相对 src/pages,htmlPlugin 的 chunks 必须对应 entry key。涉及多个市场时逐个核对目标市场的配置,修改入口后重启开发服务。

现有 npm run template 页面模板脚本仍向 config/bizConfig/{country}.json 写入注册。 使用它生成文件后,必须检查并调整 nonmotor 的入口归属,避免页面建好了却未进入目标构建,或把页面误加到其他应用。

7.3 接口调用#

统一使用 @/common/request,沿用项目登录、签名等公共行为,不在页面中直接另起 axios/fetch 调用业务接口。

前后端联调时逐项确认:请求 URL、HTTP 方法、字段名称与类型、业务成功码、可选字段、错误处理。HTTP 200 与业务成功是不同条件;errFirst 等封装选项也会影响调用方如何接收结果,阅读时以实际调用契约为准。

金额、日期、证件和较长 ID 的转换优先使用已有工具及协议。产品/Journey 等大整数 ID 不能随意转换为 JavaScript Number。若后续生成 API 代码,遵循项目规范中对生成目录的约束,通过生成流程更新,不手工修改生成结果;当前工作区未包含 src/api/ 目录。

7.4 文案、样式与跳转#

7.5 nonmotor 迁移相关行为#

src/common/nonmotor.ts 根据 nonmotorMigration 配置处理部分旧页面及 API 地址:pages/force_pages 控制页面迁移,apis 控制指定 standalone API 的迁移。API 改写在统一 request 中调用。

因此排查“源码里是旧地址,Network 里是新地址”时,应同时检查迁移配置。不要把所有 /ins/ 或 standalone URL 全局替换成 nonmotor,也不要假定所有旧地址都会自动迁移。

7.6 埋点和监控#

新增或改变交互时,核对页面、点击和一级业务模块曝光。页面入口负责初始化,事件名称按已确认的 TMS 定义,避免重复上报公共字段或在重复渲染时反复曝光。

性能链路按项目约定覆盖 JS_START、BEFORE_MAIN、AFTER_MAIN、RENDER。业务异常使用带稳定 unique_key 的日志,记录定位所需上下文,避免静默吞错或记录凭证、敏感表单原文。

8. 实战示例:投保信息增加联系邮箱#

本节是教学需求,帮助理解实施过程,不代表某个线上产品已有该需求。真实产品 ID、字段路径、文案 key 和接口应在实施时从配置与协议确认。

8.1 把一句需求写完整#

假设需求为:用户在投保信息页填写联系邮箱;该字段必填,格式不正确时提示;确认页展示邮箱;返回修改后保留最新值;提交时传递给后端。

先确认联系邮箱属于投保人还是其他对象,是否已有接口字段、是否自动预填、能否编辑,以及服务端错误如何反馈。如果这些含义没有确认,先不要用另一个产品的字段路径代替。

8.2 定位页面和已有能力#

从有效 URL 确定市场、产品和页面,按第 4 章定位入口;获取当前产品 Journey,找到目标步骤和字段区块。

仓库已有 src/InsEntry/validate/email.ts,可以检查现有邮箱校验的适用性。同时查看当前产品所用输入组件和约束注册方式。新增字段不等于新增一个输入框组件,也不等于必须改动公共校验。

8.3 建立字段映射表#

项目 本次必须确认的内容
展示 标签、占位文案、错误文案及对应翻译
Journey 所属 page/block、entry 标识、component_name、field_name
数据来源 用户输入,是否由已有接口或缓存预填
校验 必填、格式、长度及校验触发时机
缓存 当前步骤写入路径、读取时机、覆盖和清理策略
确认展示 下一页从哪里读取,是否需要格式化
接口 具体请求、字段路径、string 类型及空值策略

同一个字段在 Journey、表单、缓存和接口中的名字可能不同。表格中的路径必须逐项从真实配置、代码和协议核对。

8.4 实现并闭合数据流#

先通过现有 Journey 能力配置输入和约束,生成对应可读 view 和本地 mock。若确认页已有支持该字段的展示能力,同步配置;能力不足时,再扩展相应组件并评估复用产品。

接着检查提交当前步骤时是否会把字段校验、转换并写入正确缓存。进入确认页后应读到相同值;返回编辑再次前进,应读到修改后的值。最后核对真实请求体,确认字段归属和类型与后端一致。

8.5 自测案例#

场景 预期
首次进入,无预填值 展示空字段,行为符合设计
留空并继续 阻止进入下一步,显示必填提示
输入无效格式并继续 显示格式提示,不发送无效的业务提交
输入合法邮箱 校验通过,下一页展示一致
从确认页返回修改 再次前进展示新值,最终请求使用新值
接口返回业务错误 用户能理解结果并按约定重试,不无反馈卡住
重新进入或切换产品 缓存行为符合该产品约定,不出现错误串用
其他复用产品 原有字段和交互不被本次公共改动影响

这个需求的完成证据包括:配置/代码差异、页面截图、字段请求核对结果、异常与返回路径结果,以及发布时需要同步的翻译和 Journey。

9. 联调、自测与问题定位#

9.1 先分清在哪一层失败#

现象 首先检查
页面 404 当前 APP_NAME、市场入口、路径前缀、是否重启开发服务
页面白屏 Console、JS 资源、初始化异常和主请求结果
修改没有生效 是否运行本地版本、代理规则、当前产品配置、缓存
请求未命中预期服务 ENV、代理目标、PFB、迁移配置和实际请求 URL
HTTP 200 但页面报错 业务码、响应结构、必需数据与调用方处理
字段不出现 Journey 数据、组件匹配、显隐依赖、当前步骤
输入正确但请求值错误 field_name、缓存路径、类型转换和下游组装
返回后信息丢失 步骤离开时写回、返回时读取、缓存 key 和清理时机
浏览器正常、App 异常 Bridge、WebView 返回行为、登录和真实运行环境
某一市场正常、其他市场异常 市场入口、条件编译、区域配置、翻译和组件依赖

先复现并确认请求、响应和状态,再决定改动层次。不要因为错误出现在页面上就直接修改组件。

9.2 Mock 与真实联调#

Mock 用于接口未完成时的并行开发,以及稳定复现空数据、异常和特定分支。响应需要遵守真实契约,并把作用范围限定到目标接口/产品。

验证记录应写清哪些结果来自 mock、哪些已经通过真实接口。Mock 成功只能证明页面在该响应下的行为;真实登录、网关、PFB、后端校验和 App 行为需要相应环境的证据。

9.3 代码检查与运行验收#

依赖安装完成后,可执行项目工具。以下代码检查命令中路径需要替换为本次真实改动文件:

bash
npx tsc --noEmit
npx eslint <本次修改的TS或TSX文件>
npx prettier --check <本次修改的文件>
git diff --check

执行 npm run dev,在菜单选择“构建”并明确选择目标环境、市场和 nonmotor,完成目标构建检查。多个市场共用的改动,按影响范围验证对应构建和页面。

命令失败时区分本次引入的问题、已有问题和环境阻塞,保留准确结论。构建通过仍需浏览器验收。前端不默认要求新增单测文件,已有相关测试按需运行,业务路径以目标环境和页面验证为依据。

9.4 使用已有自动化用例#

优先查找 runbooks/ 中已有的页面用例,确认场景、市场、环境和预期与需求一致。执行时按 runbooks/index.json 的 executionOwner 选择对应 Skill,不混用两条执行链的 session 和结果。

新增交互应补充对应验收场景;自动化报告要能定位到步骤、截图、请求或其他证据。登录失败、配置缺失等阻塞不能被记录成业务通过。

10. 提测、部署与发布物料#

10.1 MR 应让 Reviewer 看懂什么#

MR 描述应包含业务问题、最终行为、影响页面/产品/市场、代码与配置改动,以及验证结果。涉及公共能力时列明调用方影响,涉及协议时说明字段变化。

提交前检查:有无无关文件、临时日志、账号或凭证;新增类型与真实数据是否一致;配置与 mock 是否按约定同步;自测是否覆盖用户回退和错误路径。

10.2 前端交付物不只有代码#

物料 交付时核对
前端代码包 分支、版本、APP_NAME、市场、环境
Journey 目标产品、配置版本、组件兼容性、发布状态
i18n / Transify key、目标语言、插值和实际下发
图片 正式 CDN 地址、尺寸、加载效果
PFC 下发范围、字段结构、预期命中行为
后端接口 环境、版本、字段契约和发布依赖
QA 验证资料 完整入口、场景、预期、自测证据与限制

物料范围按实际产品和市场确定,不照搬 Admin 后端所有物料全地区同步的要求。

10.3 在 Casement 部署迭代版本#

部署前先完成第 5.4 节的开发、自测、MR 合入与发布流程。然后在 Casement 中选择 nonmotor_h5 应用,进入对应 release-v1.x.xxx 迭代,部署该迭代对应的分支代码版本。

Casement 中选择 nonmotor_h5 应用、release 迭代并查看部署记录

图为用户提供的 release-v1.3.318 Test 环境示例。使用时替换为当前迭代和目标环境,不直接沿用截图中的版本、PFB 或部署状态。

操作顺序:

  1. 在 My Application 中选择 nonmotor_h5,进入本次迭代的 release 页面。
  2. 确认当前环境,并检查本次需求需要的配置、Release Note 等发布物料。
  3. 在 Deployment → Service Deployment 中找到目标服务,使用 Deploy 进入部署操作,核对本次版本和目标环境后提交。
  4. 在部署记录中核对 Region、Env 和 Parameters (Git/PFB/ImageTag),确认版本、PFB 与本次联调或验证计划一致。
  5. 观察 Status,必要时通过 Detail 查看详情。deploying 表示仍在部署,不能视为完成;部署成功后再验证目标页面及业务链路。

MR 合入、版本发布、部署成功和业务验收分别是不同检查点。部署记录中的 Git/版本、PFB 和镜像信息应与预期对应,避免代码已合入但实际验证的仍是其他版本。

部署负责人、审批要求,以及发布版本/Tag 的具体生成操作仍需按团队约定补充。截图中的 Rollback 是平台入口,实际回滚前仍需检查代码与配置的兼容关系。

10.4 构建产物与市场范围#

deploy/nonmotor.json 定义了 nonmotor 部署模块。deploy/space_build.sh 读取部署环境中的 CID 作为 REGION,并设置 APP_NAME 进行构建;产物目录为 dist/nonmotor,部署使用 /nonmotor/ 页面路径,静态资源路径也包含环境和市场信息。

这意味着发布时要核对目标市场与应用,不能仅凭某一次构建完成就认定所有市场都已覆盖。Casement 的一条部署记录可以包含多个 Region,也可以只包含一个市场;以本次选择和部署结果为准,不要求开发者机械地逐市场点击部署。

10.5 发布顺序与回退#

发布前把代码、配置和接口依赖放在一起 Review。例如,Journey 引用了新组件时,需要确保目标代码包能够加载它;接口字段变化时,需要确认前后端版本组合的兼容性。

回退方案也要覆盖配置和接口配套关系。不能只回退前端包,却保留仅新包能处理的 Journey。

上线后检查目标入口、主流程、资源加载、业务错误和关键埋点。监控与验收范围应对应本次改动的市场、产品和场景。

11. 常用工具与 AI 协作#

11.1 按问题选择工具#

要解决的问题 工具或入口
找代码和调用方 IDE 全局搜索、rg、Git diff
看页面请求与响应 浏览器 DevTools Network
看样式、布局和运行错误 Elements、Console、断点调试
核对视觉与交互设计 Figma 及目标页面实际渲染
查询产品 Journey Admin 产品工厂及仓库配置同步 Skill
管理翻译 Transify、Journey i18n 及项目读取链路
核对埋点 TMS 定义与实际事件
排查线上表现 IDAP 与必要的后端日志
执行回归 现有 Runbook 与对应执行 Skill

具体平台 URL 和权限申请方式应从团队入口表获取,本文不把其他项目或旧环境的链接当作 nonmotor 当前入口。

11.2 给 AI 的输入要覆盖开发上下文#

可以使用下面的任务描述模板:

text
请在 nonmotor_h5 中实现以下需求。
市场、环境、构建环境:……
产品与完整页面入口:……
需求正文、设计来源:……
当前 Journey 来源:……
接口协议、字段与业务码:……
预期交互、错误和返回行为:……
影响范围与不应改动的部分:……
验收场景:……

先判断配置与代码的改动边界,列出影响文件和字段数据流,
按仓库 AGENTS.md 与本地 Skills 实现,提供验证结果和未解决项。

仓库已有需求分析、TD、代码生成、Journey 查询/更新、mock、UI 验证、Runbook 和代码 Review 等 Skills。根据任务选择相应入口,编码前仍需应用完整工程规范。AI 不能替代开发者确认字段语义、配置范围和最终运行效果。

11.3 后端同学建议的上手顺序#

第一个需求可以选择已有组件支持的文案或字段配置调整,熟悉运行环境和交付流程;随后完成本指南中类似的字段数据流;再承接需要扩展组件的小型业务模块。

学习前端基础时,优先覆盖对象/数组、可选值、Promise、TypeScript 类型、React props/state、事件、Effect、Context/reducer 和基础布局。每个概念都回到当前页面找一个真实使用点。

12. 第一个需求的完成标准#

附录 A:团队操作信息待补充#

这些信息影响实际操作,在确认前不将示例或历史约定作为当前流程:

信息 当前状态 需要补齐的内容
分支与 Review dev/release 命名和 MR 方向已确认 Reviewer、审批要求、多人开发分支的远端协作约定
本地代理 ZeroOmega、Whistle、证书和市场规则已整理 按目标环境实测;确认 TH/SG/PH 浏览器域名与 API 目标的对应关系
iOS 模拟器 Xcode、Simulator App 安装和系统代理步骤已整理 当前推荐的 App 构建、iOS runtime、Mac 架构兼容性及目标 App 业务入口
本地登录 待补充 测试账号获取、目标域名登录和登录态验证步骤
PFB 联调 需按目标环境确认 设置方式、有效性检查、后端命中验证
部署与回滚 Casement 应用、迭代入口及部署流程已确认 平台 URL、操作人、审批、版本/Tag 生成与具体回滚步骤
培训演示产品 待选定 市场、产品、完整入口、设计截图和演示数据
常用平台 能力已列出,链接待补齐 Admin、Transify、TMS、IDAP、KMS 与权限申请入口

附录 B:依据与维护范围#

主要核对文件:.nvmrc、package.json、scripts/prompt.js、scripts/start.js、scripts/create-template.js、config/bizConfig.js、config/paths.js、config/webpack.config.js、config/nonmotor/my.json、deploy/nonmotor.json、deploy/space_build.sh、deploy/space_install.sh。

页面与数据流依据:src/pages/factoryV2/purchase5/index.tsx、App.tsx、src/pages/factory/model/queryProductFactoryJourney.ts、src/common/request.ts、src/common/nonmotor.ts、src/module/storage/helper.ts、src/InsEntry/validate/email.ts。

开发规范依据:本仓库 AGENTS.md 及 .agents/skills/ 下的工程、Journey、Service、React、样式、MoneeDesign、运行时集成与埋点规范。后续维护应以当前源码和规范为准。

文档编排参考:admin后端开发流程,内容由用户提供的 HTML 读取。代理章节结合用户材料、ZeroOmega 安装页和随文引用的 Whistle 官方说明整理。本文未执行真实产品配置修改、业务操作或发布,也未代用户安装插件、根证书或切换代理。

分支及部署流程依据:用户确认的 dev-v1.x.xxx → release-v1.x.xxx → Casement 部署 流程,以及随文保存的 Casement 截图。截图仅用作操作位置说明,不作为当前部署结果或权限状态的证明。

模拟器流程依据:用户提供的模拟器安装截图,以及随文引用的 Apple 和 Whistle 官方说明;内部下载入口来自截图正文,版本与页面可用性未独立验证。

附录 C:市场代理规则#

以下按用户提供的域名整理,保留原有整站转发意图,目标统一为本地 HTTP 3000 服务;没有实际联网验证这些业务域名。每个市场/环境单独保存为规则组,按本次开发选择启用,不要把所有环境同时指向一套本地构建后混用。

text
# BR UAT
protection.uat.shopee.com.br http://localhost:3000

# TH Test
protection.test.shopee.co.th http://localhost:3000

# TH UAT
protection.uat.seainsurebroker.co.th http://localhost:3000

# SG Test
test.moneeinsureagency.sg http://localhost:3000

# SG UAT
uat.moneeinsureagency.sg http://localhost:3000

# MY Test
protection.test.shopee.com.my http://localhost:3000

# MY UAT
protection.uat.shopee.com.my http://localhost:3000

# VN Test
insurance.test.shopee.vn http://localhost:3000

# VN UAT
insurance.uat.shopee.vn http://localhost:3000

# ID Test
insurance.test.shopee.co.id http://localhost:3000

# ID UAT
insurance.uat.shopee.co.id http://localhost:3000

# PH Test
protection.test.moneeinsurebroker.com.ph http://localhost:3000

# PH UAT
protection.uat.moneeinsurebroker.com.ph http://localhost:3000

整理时处理了以下重复与不一致:

↑