Files
baiyue-firstleg/file/AGENTS.md
T
2026-08-05 16:26:10 +08:00

7.2 KiB
Raw Blame History

File Service 模块指引

职责边界

  • File 服务是企业资质文件的唯一公开上传入口。必须先持久化并验证真实文件,再调用 IAM 内部接口登记元数据;禁止只生成或改写一个不存在文件的 URL。

  • 负责企业资质文件、公共导出文件和二期入库测量图片的上传、存储、读取及访问鉴权;当前文件内容使用本地磁盘,不能进入 Git。

  • src/main/resources/db/file.sql 中的 file_object 已由测量图片链路通过 FileObjectEntity、FileObjectMapper 接入,导出任务表也已接入;企业资质文件元数据仍归 IAM,不能把不同文件链路的持久化状态混为一谈。

  • 企业资质审核状态和元数据归 iam/;本模块通过 IAM 客户端校验访问权限,不跨库读取 IAM 数据。

  • 入库单和测量状态归 firstleg/,重量识别适配归 integration-service/;File 只保存图片对象、返回逻辑文件 ID 并代理受控 OCR 调用。

快速索引

功能 入口
模块使用、RocketMQ 部署与导出排查 README.md;完整架构与接口契约见 ../docs/公共导出与下载中心接入说明.md
商户资质上传与读取 src/main/java/com/baiyue/file/controller/QualificationFileController.java
平台资质上传、替换与查看 controller/PlatformQualificationFileController.java;POST /{tenantId} 支持 qualificationType、certificateNo、validTo、replace,下载为 GET /{tenantId}/{fileName}
服务状态 controller/FileHealthController.java
当前本地磁盘实现 service/LocalQualificationStorage.java
公共导出 API controller/PlatformExportTaskController.java、service/ExportTaskService.java
可靠调度 service/ExportStateService.java、mq/ExportOutboxPublisher.java、mq/ExportCommandConsumer.java、service/ExportReconciler.java
通用 Provider/XLSX client/ExportProviderClient.java、service/GenericXlsxExportRunner.java、公共契约 ../common-core/.../export/ExportContracts.java
毒消息隔离 mq/ExportDlqHandler.java;定位必须使用四个 User Properties,不解析损坏 body
未被当前 Controller 使用的旧实现 service/QualificationFileStorage.java
IAM 权限协作 client/IamQualificationClient.java;商户登记 /qualifications,平台登记/替换 /platform-qualifications
平台称重图片上传、OCR 重试与查看 controller/PlatformMeasurementImageController.java(/api/platform/v1/files/measurements)→ service/MeasurementImageService.java
Firstleg 第三方测量证据图片 controller/InternalMeasurementImageController.java(/internal/file/v1/measurement-images)→ MeasurementImageService.uploadMeasurementEvidence/deleteMeasurementEvidence;必须校验内部令牌
测量图片磁盘与元数据 service/MeasurementImageStorage.java、entity/FileObjectEntity.java、mapper/FileObjectMapper.java;表结构 src/main/resources/db/file.sql
重量 OCR 下游 client/WeightOcrClient.java → integration-service 的 /internal/integrations/weight-ocr/single;尺寸测量证据不触发重量 OCR
测量图片测试 controller/PlatformMeasurementImageControllerContractTest.java、InternalMeasurementImageControllerTest.java、service/MeasurementImageServiceEvidenceTest.java
历史资质文件迁移 ../scripts/migrate-local-qualification-file.ps1、../docs/企业资质文件迁移说明.md;只适用于当前本地/共享目录存储实现
本地/Nacos 配置 src/main/resources/application.yml、../config/nacos/{local,cn}/file-service.yml
上传契约与存储测试 src/test/java/com/baiyue/file/controller/QualificationFileContractTest.java、service/LocalQualificationStorageTest.java

修改与验证

  • 严格校验客户归属、文件名/路径、大小、类型和读取权限,防止目录穿越、跨客户访问和任意文件上传;接口和存储路径中的 tenantId、tenant_id 当前是客户隔离兼容字段。
  • 企业资质文件只接受 PDF、JPG 和 PNG,单个文件上限 5MB;Client、Admin 与 LocalQualificationStorage 的限制和提示必须保持一致。
  • 生产存储应使用对象存储或共享文件存储;容器本地目录仅适合当前本地实现,不得硬编码环境路径。
  • 企业资质元数据后续若迁入 File,需同时实现 Entity、Mapper、Repository、事务和迁移验证,并同步检查 IAM 资质流程及平台/商户 Controller;不得复用测量图片 file_object 的已接入状态宣称资质元数据已迁移。
  • 测量图片必须同时按 tenantId + inboundId + fileId + businessType 校验归属。平台称重图片使用 INBOUND_WEIGHT_IMAGE 并可调用 OCR;第三方尺寸证据使用 INBOUND_MEASUREMENT_IMAGE,只允许内部上传/删除且不得触发重量 OCR。
  • 平台测量图片权限与 Firstleg 权限码保持一致:上传和重试要求 platform:firstleg:inbound:weight:edit,查看要求 platform:firstleg:inbound:measure:view;内部证据接口只信任共享内部令牌和明确操作人。
  • OCR 失败时保留已落盘文件和 file_object 元数据供重试或人工录入;删除第三方证据采用逻辑删除并校验业务类型,不能删除称重图片或其他客户文件。
  • 从父目录运行 mvn -pl file -am test,并按接口影响验证商户/平台上传、替换、预览、无权限、签名伪造和磁盘故障场景。
  • 非本地环境必须显式配置 FILE_STORAGE_ROOT 并挂载持久化可写目录;服务启动时会校验目录,存储不可用时直接启动失败,避免健康检查正常而首次上传才返回 HTTP 200 + S0503。
  • 文件写入失败属于基础设施故障,统一返回 S0503,服务日志保留实际目录和底层异常;禁止将磁盘故障包装成 B0001。
  • 迁移历史 /phase1-seed/... 路径时必须先写入并校验真实脱敏图片,再按 id + tenant_id + 旧 URL 更新 IAM 元数据;禁止只改 URL。对象存储环境必须改走 File 上传接口。
  • 上传需先写新文件,再调用 IAM 登记;收到明确业务拒绝时删除新文件,传输异常、空响应或缺少 data 时远端结果未知,必须保留文件并记录兼容字段 tenant/documentUrl 供重试或对账,避免 IAM 已提交却被 File 删除。replace=true 成功时 IAM 返回 replacedDocumentUrl,File 只能在新元数据落库后按目标客户安全清理旧 UUID 文件。
  • 旧文件清理只接受 File 自身生成的 /api/merchant/v1/files/qualifications/{uuid}.{ext},并且不得删除本次新上传的 documentUrl;不能仅从任意 URL 截取文件名后删除。
  • 平台上传要求平台身份以及 platform:customer:create 或 platform:customer:edit,平台下载属于客户档案只读能力并要求 platform:customer:view;不得复用审核权限,也不能只依赖 Gateway 路由或前端按钮隐藏。
  • LocalQualificationStorage 当前生成的 documentUrl 使用商户读取路径,但文件实际按 storage-root/qualifications/{tenantId}/{uuid.ext} 隔离;变更 URL 形态时同步检查 IAM 已存元数据、平台下载路由和迁移脚本。