Files
insar-management-system-v2/docs/archive/SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md
T
Harmon d108b33f80 docs: govern and archive superseded notes
- add documentation governance and cleanup audit documents

- update README and docs index to distinguish current vs historical sources

- move superseded planning, SBAS, Gamma, and experiment notes into docs/archive

- fix remaining archive text garbling in two documents
2026-04-27 08:06:09 +08:00

13 KiB
Raw Blame History

SBAS 系统集成与数据管理审计报告

更新日期:2026-04-06

1. 审计范围

本次审计聚焦三件事:

  • 当前 ISCE2 SBAS 实验是否已经真实读取并使用精密轨道
  • 现有系统的数据管理方案是否适合承接 SBAS/PS-InSAR 生产口
  • 如果后续要把实验方案嵌入系统,推荐怎样分阶段落地

本报告基于当前仓库实现与已成功的实验产物,不涉及对现有 D-InSAR 生产链的破坏性修改。

2. 结论摘要

  • 结论 1:当前 SBAS 实验已经真实读取并使用精密轨道,不只是“数据库里有轨道路径”。
  • 结论 2:当前系统可以完成 PS/SBAS 选片和实验产物生成,但还不能把 psinsar 产物作为正式生产结果注册、编目、健康检查和发布。
  • 结论 3:当前数据管理整体偏“路径驱动”,原始数据身份、存储位置、运行产物三层边界不够清晰,因此用户会感到“数据管理比较松散”。
  • 结论 4:轨道管理反而是当前较完整的一块,已经具备源目录扫描、池同步、一致性检查和数据库状态统计能力。

3. 审计发现

P0 / 高优先级

3.1 结果编目和发布入口仍然是 D-InSAR 专用,psinsar 实验产物无法直接接入系统

证据:

  • backend/app/services/result_catalog_service.py:707-713
    • _load_manifest() 只接受 product_type == dinsar
  • backend/app/services/result_catalog_service.py:750-753
    • 即使读入 manifest,也把 product_type 固定写成 dinsar
  • backend/app/routers/dinsar_products.py:107-140
    • 现有编目 API 和后台任务只暴露 /dinsar-products/*
  • backend/app/services/health_service.py:124-170
    • 结果目录健康检查只统计 catalog_name == dinsar
  • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/publish/mintpy_sbas_unified_v1/manifest.json:2-9
    • 当前实验成功产物的 manifest 是 schema_version = psinsar.publish.v1catalog_name = psinsar

影响:

  • 实验已经能产出发布级 bundle,但系统当前不会把它识别为正式产品
  • 不能复用现有结果页、目录重建、健康检查、产品详情接口
  • 后续如果直接“硬塞”进 D-InSAR 目录,会污染现有 D-InSAR 语义

建议:

  • Phase 1 不要新建一套完全独立的产品表,继续复用 result_products / result_assets
  • 但必须让 catalog 服务显式支持 catalog_name = psinsar
  • 最小可行改造是新增 psinsar manifest 解析路径,或把当前 catalog service 抽象成多 catalog 分发器

3.2 ps_task_batches / ps_task_items 目前只是选片快照,不是生产记录

证据:

  • backend/app/models/orm.py:516-550
    • PsTaskBatchORM / PsTaskItemORM 只保存批次、file_path、日期、极化、是否有轨道和状态
  • backend/app/routers/task_batches.py:281-320
    • 创建 /task-batches/ps 时只是把选中的影像元数据写入 ps_task_items
  • backend/app/routers/pairing.py:124-147
    • 现有 find-ps-timeseries 只负责找 stack
  • backend/app/services/spatial_service.py:444-481
    • find_ps_timeseries_data() 只返回按轨道方向分组的影像栈
  • backend/app/services/job_handlers.py:306-321
    • PS_STACK 的后台处理目前只是复制选中的影像路径

影响:

  • 系统里没有“某次 SBAS 生产运行”的业务主记录
  • 无法稳定记录 work_dirpublish_dir、运行环境、参数版本、DEM、轨道来源、水体掩膜来源
  • 无法形成真正可追溯、可重跑、可审计的生产口

建议:

  • 新增业务表 ps_timeseries_runs
  • 保留 ps_task_batches 作为“输入栈定义”
  • 把真正的处理运行、产物发布、失败重试、步骤状态全部挂到 ps_timeseries_runs + workflow_runs

3.3 数据身份与存储路径耦合过深,迁移和重构成本偏高

证据:

  • backend/app/models/orm.py:22-40
    • RadarDataORM 直接保存 file_pathorbit_file_pathpreview_cache_path
  • backend/app/models/orm.py:82-101
    • ResultProductORM 直接保存 publish_dirmanifest_pathsource_primary_pathprimary_asset_path
  • backend/app/models/orm.py:182-195
    • ResultAssetORM 保存 absolute_path
  • backend/app/services/data_service.py:621-668
    • unique_id 通过 os.path.relpath() 生成,并按 unique_id 做 upsert

影响:

  • 数据身份会受存储根目录变化影响
  • Windows 根目录变更、WSL 路径调整、NAS 迁移时,数据库主身份和存储位置语义混在一起
  • 产物迁移到正式发布目录后,历史绝对路径会变成系统耦合点

建议:

  • 把“数据身份”和“存储位置”拆开
  • 原始影像层至少补充稳定的 scene_uidproduct_uid
  • 结果层至少补充稳定的 run_id / product_id 业务主键,把绝对路径退化为可替换的存储定位信息

P1 / 中优先级

3.4 原始影像与轨道的关联粒度偏粗,缺少轨道版本与来源追踪

证据:

  • backend/app/services/data_service.py:611-612
    • 影像是否有轨道仅按 (satellite, imaging_date) 关联
  • backend/app/services/data_service.py:688-692
    • 后续补关联时也是按同一键更新

影响:

  • 当同一天存在多个候选轨道版本时,数据库层无法区分来源和版本
  • 无法在结果层明确回答“本次 SBAS 用的是哪份轨道文件、其 checksum 是多少、来自 source 目录还是 ISCE2 pool”

建议:

  • 最小可行做法:在 RadarDataORM 或新表中增加
    • orbit_stem
    • orbit_checksum
    • orbit_source_type
    • orbit_pool_path
  • 更完整做法:单独建 orbit_assets / orbit_bindings

3.5 数据扫描服务职责过重,扫描、轨道同步、预览缓存、数据库写入耦合在一起

证据:

  • backend/app/services/data_service.py:426-463
    • 扫描原始轨道并同步 ENVI / ISCE2 池
  • backend/app/services/data_service.py:568-699
    • 同一流程里完成影像元数据读取、轨道关联、数据库 upsert
  • backend/app/services/data_service.py:709-739
    • 后面又继续做缓存重建候选收集

影响:

  • 这个服务变成“总装配间”,测试和回归都更困难
  • 后续要引入 SBAS 生产口时,很容易继续把更多责任塞进同一个服务

建议:

  • 拆分为至少四块:
    • radar_inventory_service
    • orbit_inventory_service
    • radar_catalog_service
    • preview_cache_service

3.6 Windows/WSL 双路径模型是当前现实,但需要收口到专门的路径层

证据:

  • backend/app/config.py:150-186
    • 同时维护 Windows 轨道池、DEM、IDL、WSL distro、WSL Python 等配置
  • experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:140-149
    • 实验准备阶段会解析 orbit XML
  • experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:171-193
    • 同时生成 Windows 路径和 WSL 路径
  • experiments/isce2_sbas_timeseries/scripts/materialize_lt1_stack_scenes.py:98-103
    • 物化阶段直接把 orbit XML 传给 ISCE2 sensor

影响:

  • 当前方案能跑通,但如果没有统一的路径转换层,后续每个服务都可能自己拼接 /mnt/*
  • 这会继续加重“数据管理松散”的体感

建议:

  • 保留当前双路径现实,不要硬回避
  • 但把路径转换统一收敛到 timeseries_paths.py 或类似组件
  • 生产口只暴露业务字段,不让上层 UI 和业务逻辑直接感知 /mnt/zF:\

P2 / 正向发现

3.7 轨道管理是当前系统里相对成熟的一块

证据:

  • backend/app/services/data_service.py:426-463
    • 已有源目录扫描与 ENVI / ISCE2 轨道池同步
  • backend/app/routers/orbit.py:27-108
    • 已有数据库统计、池一致性检查、缺口汇总

结论:

  • 不需要为 SBAS 重新发明一套轨道管理
  • 更合理的方向是复用现有轨道池和一致性检查能力,再补生产级 provenance

4. 关于“现在实验读取精密轨道了吗”

答案:是,已经读取,而且已进入实际处理链。

证据链如下:

  1. 轨道解析入口:
    • backend/app/isce2_pipeline/lt1_input_resolver.py:165-201
    • ensure_lt1_orbit_xml() 会优先取已有 XML,找不到才从 LT-1 轨道 txt 生成 XML
  2. Stack 准备阶段:
    • experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:140-149
    • 每景影像都调用 ensure_lt1_orbit_xml()
  3. Stack 物化阶段:
    • experiments/isce2_sbas_timeseries/scripts/materialize_lt1_stack_scenes.py:98-103
    • sensor.orbitFile = orbit_xml
  4. 实验 manifest 证据:
    • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:92-95
    • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:123-126
    • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:154-157
    • manifest 已明确记录 D:\\orbit_pools\\isce2\\LT1A_GpsData_GAS_C_*.xml
  5. 运行日志证据:
    • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_work/logs/run_01_reference.log:18
    • experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_work/logs/run_03_geo2rdr_coarseResamp.log:6
    • 日志中已出现 Orbit interpolation method: hermite

结论补充:

  • 当前 SBAS 实验使用的是 ISCE2 轨道池中的 XML 精轨
  • 因此“精轨是否已读入”这件事在实验层已经成立
  • 真正缺的不是“有没有轨道”,而是“系统如何把这次运行及其轨道 provenance 规范地登记为生产记录”

5. 集成设计建议

5.1 集成边界

当前最合理的系统集成边界不是 MintPy 运行目录,而是发布级 bundle:

  • 入口文件:manifest.json
  • 目录结构:assets/preview/metadata/

这与现有产品规范一致:

  • docs/ISCE2_SBAS_PRODUCT_SPEC.md:69-88

因此:

  • 不要直接注册 stack_work/mintpy_sbas_*
  • 要注册 publish/.../manifest.json 所代表的一整个 bundle

5.2 推荐最小落地架构

层 1:规划层,继续复用现有能力

  • 继续使用 find-ps-timeseries
  • 继续使用 ps_task_batches / ps_task_items
  • 其职责只保留为“选片与栈定义”

层 2:生产层,新增业务主记录

新增 ps_timeseries_runs,至少包含:

  • run_id
  • batch_id
  • catalog_name
  • engine_code
  • processor_code
  • env_name
  • wsl_distro
  • work_dir
  • publish_dir
  • manifest_path
  • reference_date
  • direction
  • params_json
  • summary_json
  • orbit_summary_json
  • dem_path
  • water_mask_source
  • status
  • error_message
  • started_at
  • ended_at

层 3:编目层,扩展现有结果目录

不要单独再造一套产品表,继续复用:

  • result_products
  • result_assets
  • result_issues

但要新增 psinsar catalog 入口,支持:

  • 解析 psinsar.publish.v1
  • 注册 catalog_name = psinsar
  • 单独的 catalog status / rebuild / health-check

层 4:接口层

建议新增:

  • POST /timeseries-production/runs
  • GET /timeseries-production/runs
  • GET /timeseries-production/runs/{run_id}
  • POST /timeseries-production/runs/{run_id}/retry-step
  • GET /ps-products
  • GET /ps-products/{product_id}
  • POST /ps-products/rebuild-catalog

5.3 与当前设计文档的一致性

当前仓库里的 SBAS 设计文档已经提前写出了这条路线:

  • docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:227
    • 建议新增 ps_timeseries_runs
  • docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:292-296
    • 建议新增 SBAS 相关 job types
  • docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:306-313
    • 建议新增 timeseries_production / ps_products / psinsar_catalog_service
  • docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:563-575
    • TODO 中已明确列出 ORM、路由、job handler、catalog 扩展和健康检查

所以本次审计的判断不是与现有设计冲突,而是说明:

  • 实验层已经坐实
  • 代码现实也证明下一步确实该进入“生产层与 catalog 层补齐”

6. 建议 TODO

6.1 立即做

  • 新增 ps_timeseries_runs ORM / schema / migration
  • 新增 timeseries_production router
  • 新增 PUBLISH_PSINSAR_PRODUCTS 及相关 job handlers
  • 让 catalog 服务支持 psinsar.publish.v1
  • publish/.../manifest.json 作为唯一注册入口

6.2 紧接着做

  • ps_timeseries_runs 记录 DEM、轨道、水体掩膜、运行环境版本
  • 给轨道绑定补 provenance 字段或单独轨道资产表
  • 把 Windows/WSL 路径转换收敛到独立路径服务
  • psinsar 增加 catalog health-check 与 rebuild

6.3 暂缓做

  • 不要现在就改动现有 D-InSAR 生产链
  • 不要把 SBAS 运行目录直接暴露为产品目录
  • 不要为了 SBAS 先拆掉现有 result_products

7. 审计结论

如果现在问“SBAS 能不能开始往系统里接”,答案是:

  • 能,但应该先接“发布 bundle + 生产记录 + psinsar catalog”
  • 不能直接把实验目录粗暴塞进现有 D-InSAR 产品体系

如果现在问“系统的数据管理为什么显得松散”,核心原因是:

  • 原始数据身份、物理存储路径、生产产物目录三层目前还没有彻底分开

如果现在问“下一步最值得做什么”,答案是:

  • 先把 ps_timeseries_runs + psinsar catalog 这两个缺口补上

这样既不会动坏现有 D-InSAR 生产,又能把已经验证成功的 SBAS 实验稳稳接成系统能力。