25 KiB
头程与海外仓后端项目指引
当前为单 TEST、统一 Gateway/Auth 会话/Nacos 与业务 Outbox 直接投递。架构规则及部署/验收状态唯一见
../docs/测试环境单机部署与配置契约.md、../docs/统一认证与服务通信契约.md。模块旧双区域说明不能覆盖这两份契约;构建、部署与整体验收分别核对。
根 POM 当前聚合 20 个模块(7 个公共/依赖模块、13 个服务),部署映射见 deploy/service-map.yml。gateway-overseas/ 与 event-bridge-service/ 为退役待清理源码,不是当前构建或部署单元。
适用范围与定位
- 本文件适用于
baiyue-firstleg/Maven 多模块仓库,包含国内头程与海外区域服务;进入具体服务后继续读取该服务的AGENTS.md。 - 本层只负责:服务边界、跨服务契约、数据库部署总入口、阶段路由和通用验证。Controller、Service、DTO、SQL 细节以模块级指引为准。
- 普通任务先读本文件和目标模块指引;聚合构建/架构问题再读
README.md、pom.xml、docs/头程项目目录结构与服务说明.md。 - 平台/客户层级与权限公共语义见
../docs/平台客户层级与权限契约.md;统一 Token、API 和可靠直接投递公共契约见../docs/统一认证与服务通信契约.md。本文件只保留后端执行所需摘要。
不可突破的产品与数据边界
- 当前产品只有“平台—客户”两级。
tenant_id=0是平台技术作用域;tenant_id>0是客户隔离键,不得新增租户切换、租户选择或租户级 RBAC。 - 公共仓库、往来单位、快递、托盘、库位统一归属
tenant_id=0;订单、文件、费用等客户数据按客户tenant_id>0隔离。不得跨库 Join 或信任客户端客户 ID。 - 国内订单交易状态归
order,头程履约/入库状态归firstleg,财务账期、账单、收款、成本与核销归finance;全部仓库 ID、类型、状态、地址和能力主档归国内warehouse,海外warehouse-overseas-service只维护引用同一国内 warehouseId 的库位、托盘和资源锁。海外尾程订单、入仓计划、库存业务与海外本土业务归lastleg-service,所有端公网入口归gateway。文件对象归file,第三方适配归integration-service;跨服务通过内部客户端、DTO、事件和服务令牌协作。 - 普通业务成功/失败使用 HTTP 200 + body
code(成功为字符串"200");认证、基础设施和网关拒绝可使用真实 401/403/503。
服务路由(按关键词定位)
本表只保留定位入口;命中业务后用 rg -n -F '关键词' docs/backend-business-index.md 读取对应行/段的详细约束,再沿代码引用追踪;不默认全文加载详细索引。已知目标文件时直接定位,并定向核对该业务约束。
后端任务最小读取集
- 单服务 Controller/Service/Mapper 任务:本文件、目标服务
AGENTS.md、目标类及其直接调用点。 - 跨服务 API/事件任务:在上述基础上增加直接调用方、被调用方及受影响的 OpenAPI/事件契约;公开路径、访问域或入口鉴权变化才增加 Gateway,内部调用和事件不经公网 Gateway。不因业务关键词自动加载整个业务专题。
- 只有状态、权限、数据库或验收边界无法从上述入口确定时,才读取
docs/业务快速索引.md、专题 README 或完整契约。 - 读取预算遵循工作区根指引:超过约 250 行或 8000 字符时先读职责、硬边界和验证章节,再检索任务命中段;不得仅因行数少而全文加载长业务表。聚合构建或架构任务才读取相关
README.md、pom.xml和目录结构文档,已知单模块任务不增加概览文档。
| 任务关键词 | 首选服务 |
|---|---|
| 登录、Token、密码、注册与顶层授权快照 | auth/ |
| 客户档案、成员、审核、RBAC、授权快照 | iam/ |
| 客户建档默认箱规与权重系数初始化及补偿 | iam/、firstleg/ |
| 消息中心、站内通知、消息模板、收件箱 | iam/ |
| 订单、货物、快照、状态、幂等、Outbox | order/ |
| 客户头程订单中文批量导入 | order/ |
| 平台修改客户原始申报、履约渠道变更与跨服务同步 | order/、firstleg/ |
| 平台订单批量审核预览 | order/ |
| 履约分配、入库、测量、箱规算法、审核、FBA 计费 | firstleg/ |
| 入库单扣货、解除、凭证与履约门禁 | firstleg/、file/ |
| 称重确认、整票库位块与 PDA 资源结算 | firstleg/、warehouse/ |
| 客户专属价格簿、柜级阶梯运费与受控调价 | firstleg/ |
| Firstleg 内部模块化与依赖基线 | firstleg/ |
| Mapper 新增、移动、Bean 缺失与扫描遗漏 | 目标持久化服务 |
| 脚本管理、全量验证、测试造数与诊断 | 仓库根 scripts/;服务专属脚本留在 <service>/scripts/ |
| 分柜、柜次、智能排柜、预装/装柜清单、真实柜号后补、PDA | firstleg/ |
| 合柜报关 / 同柜不可拆组、跨客户合柜、整组分配/移除 | firstleg/ |
| 全局智能装柜候选、柜次、占位与移除 | firstleg/、order/ |
| 客户入库结果与头程费用确认 | firstleg/ |
| 订舱资料/打印、船期、订舱级拖车、报关 | firstleg/ |
| 目的港码头拖车与还空预警 | firstleg/ |
| 客户账期、费用池、账单、入仓码联查、收款、成本、核销 | finance/ |
| 客户资金账户、充值、授信、冻结、结算与跨区资金指令 | finance/、lastleg-service/、common-event-contract/ |
| 柜级公共费用跨客户分摊 | firstleg/、finance/ |
| 海外业务费用来源跨区入池 | lastleg-service/、common-event-contract/、finance/ |
| 入库/柜次应付、直接已付、付款流水与凭证 | firstleg/、finance/、file/ |
| 仓库、往来单位、快递、托盘、库位 | warehouse/ |
| 供应商、国内整柜库存与出入库 | warehouse/ |
| 客户运营统计、在途柜量 | firstleg/ |
| 平台操作日志与审计查询 | audit-service/ |
| 资质、导出、导出退避重试、测量图片、文件下载 | file/ |
| 路由、CORS、JWT 入口、访问域 | gateway/ |
| 百度/Amazon/OCR/第三方适配 | integration-service/ |
| 统一 API 路由、Token、Audience/JWKS | gateway/、auth/、common-security/ |
| 统一会话与账号/客户权限撤销 | auth/、iam/、common-security/ |
| 尾程订单、海外入仓计划、换标、库存、采购、本土卡车 | lastleg-service/ |
| 尾程订单控制、柜级预览与入仓计划转换 | lastleg-service/、warehouse-overseas-service/ |
| 海外入仓分页、FBA 预约、PDA 柜号签收与入仓 | lastleg-service/ |
| 海外仓排车查询、候选与智能预排 | lastleg-service/ |
| 海外排车执行、PDA 出库、派送与一件代发 | lastleg-service/ |
| 海外异常退回、库存恢复与客户回访 | lastleg-service/、file/ |
| 一件代发 SKU/箱唛与暂扣跨区协同 | order/、firstleg/、common-event-contract/、lastleg-service/ |
| 客户海外仓贴标、转运、废弃与退货换标 | lastleg-service/ |
| 海外仓 PDA 盘点、移库、托盘、换标与查询 | lastleg-service/、warehouse-overseas-service/ |
| 国内船节点向海外接柜门禁事件 | firstleg/、common-event-contract/、lastleg-service/ |
| 海外仓库目录、海外库位、海外托盘、资源锁 | 国内仓库目录归 warehouse/,海外资源归 warehouse-overseas-service/ |
| Lastleg 内部模块化与依赖基线 | lastleg-service/ |
| 自营领星采集、经营统计、SKU 日销量 | lastleg-service/selfoperated/ 查询与采集编排;领星签名/分页/外部接口查 integration-service/,不因采集页面任务同时读取两服务 |
| 跨客户同仓预约、预约跟进、到港日历 | lastleg-service/inboundplan/、appointmentplanning/;到港事实查 firstleg/portschedule/ |
| 车辆、司机证照、车次、外接预订、车队报价、出车记录 | lastleg-service/fleet/;先读 lastleg-service/AGENTS.md 对应入口,客户排车关联再沿 dispatch/fleet/ 实际调用 |
| PDF 标签、审计、业务事件直投 | print/、audit-service/、common-event-contract/ |
公共模块快速索引
| 关键词 | 模块与入口 |
|---|---|
| 公共依赖版本 | platform-bom/pom.xml;统一管理公共组件版本,不放业务实现 |
| 通用响应、分页、异常、基础实体与导出契约 | common-core/;从 ApiResponse.java、PageResult.java、BizException.java、ExportContracts.java 定位 |
| Web 异常、请求关联/Trace、同步出站传播、Long ID 序列化 | common-web/;从 GlobalExceptionHandler.java、CorrelationIdFilter.java、TraceParent.java、FeignTraceRequestInterceptor.java、RestClientTraceInterceptor.java、LongIdJacksonConfiguration.java 定位 |
| JWT、JWKS、会话校验与认证用户 | common-security/;从 JwtAuthenticationFilter.java、JwtClaimsMapper.java、AccessTokenSessionValidator.java 定位 |
| Springdoc/OpenAPI 自动配置 | common-openapi/;从 BaiyueOpenApiAutoConfiguration.java、OpenApiProperties.java 定位 |
| 业务审计注解、脱敏、Outbox 与投递 | common-audit/;从 BusinessAudit.java、BusinessAuditAspect.java、SensitiveDataSanitizer.java、AuditOutboxPublisher.java 定位 |
| 跨区域事件信封、Payload 与哈希 | common-event-contract/;继续读该目录 AGENTS.md |
全量验收路由
- 当前订单与客户、入库测量与计费、国内货柜履约、海外仓业务及财务统一进入全量验收;按本次链路读取对应业务域/专题文档,不以历史规划终点阻断跨服务联调或回归。
auth、iam、warehouse、order、firstleg、file、finance、integration-service及出仓相关能力按各自模块契约协作;状态、权限、数据库和 OpenAPI 以当前实现及已确认契约为准。
国内头程与海外仓协同
- Auth 是唯一用户账号与 Token 签发方;目标为各端共用 Gateway 和 Redis 会话,保留 RS256/JWKS、客户隔离、权限撤销、PDA 仓绑定及服务身份校验。当前源码已移除旧海外会话验证与 Lastleg 安全投影,改为 Auth 权威会话校验;本地验证不等于测试环境部署验收。
- 装柜、船节点、卸柜、暂扣、派送、费用与资金按统一通信契约的逐事件表直接投递。保留本地 Outbox、消费幂等、重试与失败处置,不携带用户 JWT;旧 Bridge 源码已退出聚合和发布清单,退役待清理;实际停机仍须替代链验证与授权,不得据源码状态认定已部署。
lastleg-service不读取头程数据库,warehouse-overseas-service不读取尾程订单库。共用测试 MySQL 实例不改变服务数据归属。准确路由、ACK、撤销矩阵和切换门槛只维护在新的两份主契约中。
数据库访问与中文代码注释(所有服务及公共模块强制)
- 本节适用于全部后端服务和公共模块;新增代码遵守下列规范,存量分层仅在影响本次正确性或用户明确要求时整改,不因局部修改迁移整条链路;以上为目标规范,不代表存量均已达标。
- 生产代码的关系型数据库读写统一经 MyBatis/MyBatis-Plus Mapper 执行;Controller、Service、定时任务、消费者、编号生成器和公共基础组件不得直接使用
JdbcTemplate、NamedParameterJdbcTemplate、原生 JDBC/Connection/Statement 或其他通道执行 SQL。仅改成 Repository 包装 JDBC 不算整改,SQL 必须进入 Mapper;无数据库职责的模块不得为满足本条新增数据库访问。 - 正常业务数据库访问路径统一为
Controller → Service → Repository → Mapper,四层职责明确,不得省略 Repository,也不得由 Controller 直接调用 Repository/Mapper,或由 Service 直接调用 Mapper。定时任务、消费者等非 HTTP 入口从 Service 进入,同样经 Repository → Mapper 完成持久化访问。 - Controller 负责请求接收、参数校验、入口权限和响应转换;Service 负责业务规则、编排及业务事务;Repository 负责领域数据访问封装、查询组合与持久化模型转换,对 Service 提供有业务含义的数据操作;Mapper 负责 SQL 执行及数据库记录映射。Repository 不承载业务状态流转,不直接用 JDBC 执行 SQL;Service 不继承 MyBatis-Plus
ServiceImpl等方式绕过 Repository。 - 复杂查询、批量处理、原子计数、锁定读取、Outbox 和数据库监控查询同样经 Repository → Mapper,不以 SQL 特殊或实现方便为由跳层。公共模块需要数据库能力时,按现有模块边界定义 Repository/持久化接口,由所属服务的 Repository → Mapper 实现,禁止借此跨服务读库。
- 迁移数据库操作须保留客户隔离条件、事务传播、行锁、幂等和并发语义;
LAST_INSERT_ID()等连接级操作必须在同一事务连接完成,并明确关闭相关读取缓存,不能仅机械搬移 SQL。Mapper 注册及扫描仍遵守下文统一规范。 - 测试代码可用
JdbcTemplate创建隔离测试表、准备数据及核对结果;被测生产路径仍必须调用实际 Mapper,不得把测试造数做法带入生产。数据库基线和迁移脚本按现有部署契约管理。 - 本次新增或修改的手写方法及构造器须有简短中文业务注释,通常 1—3 行;接口与 Mapper 方法优先用中文 Javadoc,覆盖方法同样适用,关键规则就地说明。不补齐未修改或自动生成方法的注释。
- 核心业务、复杂 SQL、状态流转、资金与库存变更、权限隔离、事务、锁、幂等、并发、重试和补偿逻辑,须在关键代码前增加适量中文注释,解释业务规则、处理原因、约束边界及失败影响;不逐行翻译代码,不添加无信息量或与实现不符的注释。
- 新增和修改的代码说明注释统一使用中文;必要的技术标识、协议名、类名可保留原文,第三方许可证和生成标记保持原样。修改方法时同步更新相关存量英文或过期说明;审查时同时核对 Controller → Service → Repository → Mapper 分层及中文方法、核心逻辑注释。
契约、数据库与验证入口
-
对外 Controller/API 新增、改名或删除时,同时核对调用端、统一 Gateway、OpenAPI 和权限;提交前运行
node --test scripts/gateway-route-contract.test.mjs,自动发现生产 Controller 并校验网关目标服务与内部路径隔离。失败不得提交或标记完成;网关配置变化必须列入部署清单,不以业务服务单测代替入口检查。 -
跨服务修改先检查调用方
client/、被调用方 Controller/DTO、src/main/resources/openapi/和双方契约测试;禁止共享领域 Entity。 -
修改 Java 方法、构造器、Controller、Client、DTO 或 Mapper 参数签名时,先用
rg定向查找符号及旧参数形态,并同步更新src/main/、src/test/、Mock、Fixture、契约测试和脚本中的全部调用点。新增可选参数也必须补齐旧测试调用,不能因生产调用已更新就视为完成。 -
所有生产 MyBatis Mapper 接口必须显式标记
@Mapper;每个持久化服务只允许在启动类使用一次服务根包@MapperScan(..., annotationClass = Mapper.class),不得新增子域包白名单或分散的*MapperConfiguration。新增、移动 Mapper 或修改扫描配置后运行node scripts/mapper-scan-contract.mjs;全量后端回归已在 Maven 前执行该门禁时复用结果,输入未变不重复执行。 -
平台后台存在正式列表页时,
*:list同时授权列表、详情及只读辅助接口;create、edit、delete、status、approve、review、export、upload、complete等操作保持独立。当前正式权限契约不保留旧独立*:view;Controller 不得使用hasAnyAuthority(list, view),OpenAPI 和角色初始化只保留*:list。若外部已有不可变权限契约,先按当前对话建立单独兼容规则。 -
供应商查询接口固定只使用
platform:supplier:list;IAM 中platform:supplier:list是正式菜单资源,platform:supplier:view必须停用/移除,不得重新提升或兼容。 -
权限语义变更必须同步 Controller
@PreAuthorize、OpenAPI、模块权限 SQL、IAM 菜单资源、统一增量脚本和契约测试。并行模块任务不得覆盖菜单与权限总控已写入共享 SQL 或权限契约的改动。 -
数据库只访问所属服务库。模块表结构位于
<module>/src/main/resources/db/;开发环境按最新模块基线和deploy/sql/头程数据库统一增量-MySQL8.sql收敛,不为历史开发数据新增兼容迁移。已有名称含migration的脚本仅作结构来源和追溯,部署说明见deploy/sql/README.md;生产升级另按明确发布规则处理。 -
后端同样遵守根指引中的“开发数据和上传文件可丢弃”边界:不得为现有开发库孤儿文件、旧文件归属或历史部分失败新增删除补偿接口、兼容复用、回填或清理链路;只修复当前正式上传与持久化路径,既有开发文件由人工重新上传。
-
通用配置在
config/nacos/test/;服务日志、上传文件、target/、reports/不属于源码。 -
后端本地验证默认使用
scripts/backend-check.ps1,必须显式指定-Modules,不传模块直接拒绝;命令及参数见scripts/README.md的“后端分层检查”。入口自动经local-check.ps1限流,-DryRun只检查选择范围,不代表测试通过。 -
开发迭代使用
-Mode Focused -Tests <精确测试类名>,覆盖修改行为及直接调用点;Java 签名变化至少使用-Mode Compile编译生产与测试源码(等价于mvn -pl <modules> -am test-compile)。单服务行为变更收尾使用默认Module模式执行该服务及上游依赖测试;跨服务 DTO、接口或事件变化必须显式列入生产者和受影响消费者。-am只补上游构建依赖,不自动包含下游服务或 HTTP/事件消费者;不能以单类测试代替模块收尾。 -
仅注释/文档调整不触发 Java 回归;脚本调整执行受影响脚本测试和登记合同。API、Mapper、AGENTS 等静态合同仍按各自触发条件执行。纯重构也应覆盖受影响行为,不能只用编译宣称回归通过。
-Dmaven.test.skip=true跳过测试编译,不得作为签名变更交付验证。 -
全仓回归只在以下情况触发:根 POM/统一依赖版本/聚合拓扑/测试基础配置变化;公共认证、序列化、基础模型等影响广泛且不能可靠限定消费者;跨多域批次集成验收;用户明确要求全量回归。使用
scripts/backend-full-regression.ps1,保留当前 CI 全量验证。普通单服务任务、单次提交或对话收尾不自动触发全仓;已明确消费者的公共或跨服务变更按受影响模块验证。同批同一相关输入只跑一次,输入变化后补跑受影响范围,触及上述全量条件再重跑全量。 -
不以缩短耗时为由删除金额、库存、权限隔离、状态流转、幂等和并发测试;冗余测试须根据重复场景及维护成本单独评估。不要在本地启动 Java/Nacos/数据库,除非用户明确要求。
-
同一批
AGENTS.md索引修改完成后从后端根统一运行一次./scripts/agents-index-contract.ps1;脚本只读源码目录和指定指引,不访问 HTTP、数据库或部署环境。 -
Mapper 注册静态合同为
scripts/mapper-scan-contract.mjs、mapper-scan-contract.test.mjs:自动发现聚合模块、生产*Mapper接口、服务启动类和分散扫描配置,不启动 Spring、不连接数据库;遗漏注解、扫描根漂移或重新引入子域扫描时直接失败并输出类与文件路径。 -
单服务镜像构建/部署从
Jenkinsfile.service、deploy/docker/Dockerfile、deploy/scripts/deploy-built-service.sh进入;新镜像启动失败或健康检查失败时只允许回滚到同服务先前镜像,并保持任务失败,离线合同见scripts/deploy-built-service-rollback.test.mjs。实际部署仍须当前对话明确授权。
全量 HTTP 验收脚本路由
- 脚本管理的唯一总索引是
scripts/README.md,最近执行规则是scripts/AGENTS.md。仓库级脚本、Admin 内部模块、服务局部合同和部署脚本的目录归属以这两个文件为准,不再通过无范围搜索猜测入口。 - 全量验收唯一指向测试环境 HTTP:平台端执行
scripts/admin-test-env-acceptance.mjs,客户端执行scripts/client-test-env-acceptance.mjs;入库测量与计费专项场景才单独执行scripts/client-phase2-test-env-acceptance.mjs,不替代客户端全量入口。 - Client 快速下单定向验收使用
scripts/client-quick-order-test-env-acceptance.mjs,只验证批量草稿接口、逐行隔离和幂等行为,不提交、不审核,也不替代 Client 全量入口。 - 固定客户待审核订单使用
scripts/create-pending-review-orders.mjs;固定“IT测试”与“义乌仓”、随机真实线路并推进至WAIT_SPLIT使用scripts/it-test-wait-split-bulk.mjs。二者都是造数入口,不属于全量验证;会写目标环境且不自动清理成功数据。 - Admin 总入口默认按模块列表覆盖平台全链路;需要定位单个业务时使用
--modules <name>,模块名称和静态合同先查scripts/admin-test-env-modules/README.md。 - 订舱与拖车跨服务完整状态链由 Admin 注册模块
service-center-flow验证,必须复用本轮已放舱订舱并由总入口展开依赖,不得直接执行模块文件或借历史数据。 - 尾程公网控制由
phase4-tail-order-controls在海外 PDA 前验证整柜接柜仓变更与恢复、单/批目的仓变更、单/批合托标记、CSV 导出、订单费用、暂扣/解除、八个人工节点和逐票人工计划;目的港码头拖车由phase5-terminal-drayage在卸柜后验证选车队、预约提柜、实际提柜和实际还柜,phase4-carrier-nodes只读核验最终船节点终态。 - 这些脚本会创建、更新或最终停用测试数据;指定测试环境和服务后,本轮非破坏性写入复用一次授权,删除、重置、SQL、部署或发布仍逐项授权,并保存 JSON 报告;未授权不得请求 Gateway。
- 后端 Maven、前端
pnpm test/typecheck、PDAnode --test和数据库 Dry-run 都是本地质量检查,不属于全量 HTTP 验收。 - Java 模块、OpenAPI 覆盖、JaCoCo 与 SpotBugs 聚合摘要使用
node scripts/java-quality-summary.mjs;默认仅报告存量缺口,是否阻断由显式--require-*参数决定,输出位于target/时不得作为业务事实或提交物。 - HTTP 全量通过后,才进入 Admin/Client 真实页面调用、浏览器样式和 PDA 页面/设备验收;自动化 HTTP 通过不代表视觉验收完成。
- 修改脚本目录、入口或说明后,至少运行
node --test scripts/script-documentation-contract.test.mjs;修改AGENTS.md后继续运行./scripts/agents-index-contract.ps1。两者均为离线只读合同,不能代替真实 HTTP 验收。
业务域文档入口
- 订单与客户:
../docs/订单与客户/README.md、../docs/订单与客户/订单与客户头程订单闭环设计.md - 入库测量与计费:
../docs/入库测量与计费/README.md;流程细节按../docs/头程到尾程/README.md指向的当前阶段文档读取,需求确认和联调报告仅在历史追溯或验收证据任务中读取 - 国内货柜履约:
../docs/国内货柜履约/README.md,报关规则变化再查../docs/国内货柜履约/报关资料与船期价格接入梳理.md。规划、确认与验收材料按归档位置及文档角色判断,当前入口指定的有效规则仍按需核对,历史材料只用于追溯或证据任务 - 海外仓业务:
../docs/海外仓业务/README.md;统一入口gateway/,尾程与入仓库存lastleg-service/,海外仓储资源warehouse-overseas-service/ - 海外仓全流程:以正式 Controller、前端路由、权限、SQL 与跨区事件契约为范围依据;海外接柜、入仓、库存、库内服务、排车、出库、派送、一件代发、异常退回和客户回访进入
lastleg-service/,国内 SKU/箱唛及暂扣协同进入order/、firstleg/、common-event-contract/ - 财务:
../docs/财务管理/README.md中已确认的范围、对象、状态和接口约束
全量验收需要证据时再读取对应阶段报告和证据矩阵;普通代码定位只读取当前链路涉及的范围、契约、模块指引和代码。