Files
insar-management-system-v2/docs/RESULT_DELIVERY_DOWNLOAD_DESIGN_20260630.md
T

10 KiB
Raw Blame History

成果交付与本地下载设计

日期:2026-06-30

背景

当前“结果提取”页面同时承载了两个不同概念:

  1. 生产结果入库:从 LandSAR/ENVI/Gamma 等生产目录提取结果并登记到 catalog。
  2. 成果交付导出:用户从已登记 catalog 中选择成果,下载或复制到本地使用。

现有 POST /api/dinsar-results/export 是同步文件复制接口,并且要求 admin。这个模型不适合普通用户下载大体量成果:请求容易超时,目标路径由用户输入也不利于审计和权限控制。

目标

  • 所有登录用户都可以申请成果交付。
  • D-InSAR 已登记成果接入真实交付下载。
  • LT-1 正射与 GF3 正射接入真实交付下载。
  • SBAS 与 Sentinel-1 正射在页面和接口中保留清晰占位,不暴露假执行能力。
  • 大文件交付改为后台任务,不再由 HTTP 请求同步复制。
  • 用户最终可以把成果下载到本地;服务器交付区只是临时缓存。
  • 每次交付可审计、可过期清理、可校验。
  • 数据库变更必须接入现有自维护机制。

非目标

  • 本阶段不实现 Sentinel-1 正射生产。
  • 本阶段不实现 SBAS 成果交付打包,只显示目录已接入但交付未接入。
  • 本阶段不触发 GF3 生产;GF3 交付只面向已经登记的 SARscape 标准化正射成品。
  • 本阶段不做跨节点对象存储或外部网盘。
  • 本阶段不把普通用户开放到任意服务器路径写入。

权限模型

当前系统只有 adminviewer。本阶段不强制新增角色,采用能力约定:

  • 登录用户:可查看已授权 catalog,可创建自己的成果交付任务,可查看和下载自己的交付包。
  • admin:除普通用户能力外,可查看所有交付任务,可配置交付根目录,可清理或取消交付任务。

后续如果拆角色,建议增加:

  • exporter:可创建成果交付任务。
  • operator:可做生产、入库和成果交付。
  • admin:用户、系统配置和全局清理。

交付模式

正射成果口径

  • LT-1 正射:由服务器侧单景正射流水线生产,登记在 sar_scene_geo,主交付物是 analysis_ready.tif,随包包含预览、manifest、quality 等 sidecar 文件。
  • GF3 正射:系统拿到的就是外部 SARscape 已生产成品,当前可登记为 GF3_SARSCAPE_NATIVE_PREVIEW,标准化后也可登记为 GF3_SARSCAPE_L2;交付阶段只做受控打包和下载,不触发 GF3 生产。
  • Sentinel-1 正射:生产链尚未接入,结果提取页面保留占位,避免用户误操作。
  • SBAS-InSAR:成果目录可查,但交付打包尚未接入。

1. 目录交付

默认模式。后台将选中的结果文件复制到:

{RESULT_DELIVERY_ROOT}/{username}/{delivery_id}/

目录内包含:

  • manifest.json
  • checksums.sha256
  • 结果文件或结果子目录

适合几十 GB 到 TB 级数据。用户可以通过共享目录或逐文件 HTTP 下载到本地。

2. 压缩包交付

可选模式。只允许低于阈值的交付包生成 zip:

{RESULT_DELIVERY_ROOT}/{username}/{delivery_id}.zip

阈值由环境变量控制,例如 RESULT_DELIVERY_ZIP_MAX_BYTES。超过阈值时,接口返回明确错误,要求使用目录交付或逐文件下载。

3. HTTP 下载

下载不由 FastAPI 直接流式传大文件。推荐 Nginx 静态服务交付区,并支持 Range 断点续传。

第一版接口可以返回文件下载 URL,由后端验证交付归属后通过 FileResponse 交付;后续切到 Nginx X-Accel-Redirect 或专门静态路径。

数据模型

新增两张表:

result_delivery_requests

  • delivery_id:业务 ID。
  • owner_user_id / owner_username:申请人。
  • channeldinsarsbaslt1_orthos1_orthogf3_ortho
  • statusPENDINGRUNNINGREADYFAILEDCANCELLEDEXPIRED
  • package_modedirectoryzip
  • item_counttotal_bytescopied_bytes
  • delivery_rootdelivery_dirzip_pathmanifest_path
  • expires_at
  • task_idjob_id
  • error_message
  • request_jsonsummary_json

result_delivery_items

  • delivery_id
  • source_product_id / source_result_id
  • source_radar_data_id / source_scene_geo_id:用于 LT-1/GF3 单景正射资产追踪。
  • display_name
  • source_path
  • relative_path
  • file_size
  • checksum_sha256
  • statusPENDINGCOPIEDFAILEDSKIPPED
  • error_message

数据库自维护

新增 migration

backend/migrations/013_result_delivery_requests.sql

并加入 backend/app/db_maintenance.py 的维护文件列表。迁移必须幂等:

  • CREATE TABLE IF NOT EXISTS
  • ALTER TABLE ... ADD COLUMN IF NOT EXISTS
  • CREATE INDEX IF NOT EXISTS

ORM 同步也要定义对应模型,避免启动时 metadata 检查缺表。

API 设计

获取通道能力

GET /api/result-deliveries/channels

返回:

  • dinsar: ready
  • sbas: planned
  • lt1_ortho: ready
  • s1_ortho: placeholder
  • gf3_ortho: ready

获取可交付目录

GET /api/result-deliveries/catalog/{channel}

第一版支持:

  • dinsar:兼容已有 D-InSAR catalog。
  • lt1_ortho:读取 sar_scene_geolt_gamma / lt1_gamma_geocoded_mliDONE 的分析就绪 GeoTIFF。
  • gf3_ortho:读取 radar_data.source_format in (GF3_SARSCAPE_NATIVE_PREVIEW, GF3_SARSCAPE_L2)geocoded_flag = true 的 SARscape 正射成品。

返回统一字段包括 item_idsource_kindproduct_iddisplay_nameprimary_asset_pathpublish_dirradar_data_idscene_geo_id

创建交付任务

POST /api/result-deliveries

请求:

{
  "channel": "dinsar",
  "product_ids": ["..."],
  "compat_result_ids": [1, 2, 3],
  "item_ids": [101, 102],
  "package_mode": "directory",
  "include_manifest": true,
  "include_checksums": true
}

约束:

  • 普通用户只创建自己的任务。
  • dinsar 使用 compat_result_idsproduct_ids
  • lt1_ortho 使用 item_ids = sar_scene_geo.id
  • gf3_ortho 使用 item_ids = radar_data.id
  • 每次最大数量由 RESULT_DELIVERY_MAX_ITEMS 控制。
  • 不允许传入任意服务器输出路径。

列出交付任务

GET /api/result-deliveries?mine=true

普通用户只能看到自己的任务,admin 可查看全部。

查看交付详情

GET /api/result-deliveries/{delivery_id}

返回交付状态、文件清单、下载 URL、过期时间。

下载文件

GET /api/result-deliveries/{delivery_id}/files/{item_id}/download
GET /api/result-deliveries/{delivery_id}/archive/download
GET /api/result-deliveries/{delivery_id}/manifest

第一版由后端验证权限后返回文件。后续可迁移到 Nginx token 或 X-Accel-Redirect

后台任务

新增 job type

RESULT_DELIVERY_BUILD

处理流程:

  1. 将 delivery 标记为 RUNNING
  2. 按 channel 解析可交付源文件路径。
  3. 复制到交付目录。
  4. 生成 manifest.json
  5. 可选计算 checksum。
  6. 可选生成 zip。
  7. 更新状态为 READYFAILED

任务日志应写清:

  • 总项目数。
  • 已复制数量。
  • 总大小。
  • 失败项和原因。
  • 交付目录。
  • 过期时间。

存储与清理

环境变量建议:

RESULT_DELIVERY_ROOT=D:\Result_Delivery
RESULT_DELIVERY_PUBLIC_BASE_URL=/deliveries
RESULT_DELIVERY_RETENTION_DAYS=7
RESULT_DELIVERY_MAX_ITEMS=500
RESULT_DELIVERY_ZIP_MAX_BYTES=21474836480
RESULT_DELIVERY_CHECKSUM_ENABLED=true

清理策略:

  • expires_at < nowREADY/FAILED/CANCELLED 交付包可清理。
  • 清理后状态改为 EXPIRED,保留数据库审计记录。
  • 正式成果 catalog 原文件绝不能被清理任务删除。

前端设计

结果提取页面改名语义:

  • “生产结果入库”:保留现有 D-InSAR 入库入口,admin 可用。
  • “成果交付下载”:所有登录用户可用。

页面结构:

  • 通道栏:D-InSAR、LT-1 正射、GF3 正射可用;SBAS/Sentinel-1 显示未接入交付。
  • 成果选择区:D-InSAR 复用现有 catalog 列表,LT-1/GF3 使用统一交付 catalog 查询。
  • 交付选项:目录交付 / 压缩包交付。
  • 我的交付包:状态、大小、文件数、过期时间、下载入口。

交互约束:

  • 不再让普通用户输入服务器路径。
  • 创建后显示任务 ID 和交付 ID。
  • 对大文件提示“建议使用逐文件下载或共享目录复制”。
  • 下载入口只在 READY 状态显示。

与用户管理联动

第一版:

  • viewer 也可以创建自己的成果交付任务。
  • 前端不再用 readOnly 禁用成果交付下载。
  • 生产结果入库、删除、系统配置仍要求 admin。

后续:

  • 增加 exporter/operator 角色后,前端用户管理页需要增加角色选项。
  • 后端新增能力级依赖,例如 require_capability("result.delivery.create")

风险与防护

  • 大文件复制拖慢生产盘:限制 worker 并发,交付任务可单独限流。
  • 用户重复申请导致空间膨胀:按用户限制未过期交付包数量和总大小。
  • 任意路径写入风险:只允许系统配置的交付根目录。
  • HTTP 下载超时:优先 Nginx Range,后端只负责授权。
  • catalog 文件被移动:任务记录 item 失败,不影响其他文件。

实施阶段

阶段 1

  • 文档落地。
  • 数据表和自维护 migration。
  • D-InSAR、LT-1 正射、GF3 正射目录交付后台任务。
  • 我的交付包列表和详情。

阶段 2

  • zip 打包阈值和下载。
  • manifest/checksum 下载。
  • Nginx 静态交付路径或 X-Accel-Redirect

阶段 3

  • SBAS 交付接入。
  • Sentinel-1 正射在生产 catalog 完成后接入。
  • exporter/operator 角色拆分。

验收标准

  • 普通登录用户能创建 D-InSAR、LT-1 正射、GF3 正射成果交付任务。
  • HTTP 请求只排队任务,不再同步复制大文件。
  • 交付完成后用户能下载到本地。
  • 普通用户不能指定任意服务器目录。
  • admin 能看到所有交付任务。
  • 数据库重启自维护能创建交付相关表和索引。
  • Sentinel-1 正射通道显示占位,不可误点击执行。