# SmartFarm V1 API 字段契约登记表 本文档补足 `19-v1-api-contract-draft.md` 的字段级契约。`19` 是路由目录,`31` 是写操作事务契约,本文件固定请求 DTO、响应 DTO、字段来源和禁止由客户端提交的事实。三者共同构成开发基线。 ## 一、统一字段规则 ### 1. 请求信封 | DTO | 字段 | 规则 | | --- | --- | --- | | `ListQuery` | `page, limit, keyword, status, date_start, date_end, sort_field, sort_order` | `page>=1`,`1<=limit<=100`,排序字段白名单 | | `CommandMeta` | `request_id` | UUID;与 `Idempotency-Key` Header 相同 | | `VersionedCommand` | `request_id, version` | `version` 为当前聚合正整数 | | `ReasonCommand` | `request_id, version, reason_code, remark` | 高风险操作必填稳定原因码;备注最多 1000 字 | | `ReviewCommand` | `request_id, version, decision, reason_code, remark` | `decision=approve/reject`;审核请求不得携带被审内容 | | `AsyncCommand` | `request_id, version, filters, confirm_token` | 服务端重算对象集合;`confirm_token` 只引用短期预演 | ### 2. 响应信封 | DTO | 必含字段 | | --- | --- | | `ListResult` | `list, count, page, limit, filter_counts, action_count` | | `DetailResult` | 聚合字段、`status, version, allowed_actions, timeline, warnings, related` | | `CommandResult` | `id, business_no, status, version, allowed_actions, next_action, completed_at` | | `AsyncAccepted` | `operation_no, status=pending, detail_url, poll_after_ms` | | `OperationDetail` | `operation_no, operation_type, status, progress_total, progress_done, success_count, failure_count, result_summary, result_file, error_code, started_at, finished_at, allowed_actions` | | `PayResult` | `business_type, business_id, group_order_id, pay_status, paid_at, next_action, return_path` | 所有 ID 以字符串返回;金额返回两位小数字符串,数量返回定点小数字符串,比例返回基点整数,时间返回 `Asia/Shanghai` 的 `YYYY-MM-DD HH:mm:ss`。响应中的 `allowed_actions` 是当前可用动作集合,不是长期授权凭证。 `OperationDetail` 与 `eb_farm_async_operation` 物理列一一同名;`result_file_id` 逻辑引用现有 `eb_system_attachment.attachment_id`,`result_file` 经文件服务实时换取短时签名响应,数据库不保存 URL。`progress_done` 必须等于 `success_count + failure_count` 且不大于 `progress_total`。 附件 ID 域固定如下:平台端和商户端的商品/供货/溯源材料、导入源文件、导出/异步结果使用 `system_attachment_id`(物理列仍为 `attachment_id/result_file_id`,逻辑引用 `eb_system_attachment.attachment_id`);服务/现场端离线证据使用 `farm_evidence_attachment_id`(逻辑引用 `eb_farm_evidence_attachment.attachment_id`)。单一来源 DTO 必须使用这两个语义名;平台与现场共用的动作使用 `evidence_refs[{source_type(system/farm_service), attachment_id}]`,并按当前端限制可选来源。Controller 再映射到物理列,禁止只提交含义不明的通用 `attachment_id`。 ### 3. 客户端禁止提交 任何请求不得接受以下字段作为最终事实: - `status`、`paid_at`、`completed_at`、`settled_at` 等最终状态和事实时间。 - 可用库存、已售数量、进度、应结本金、收益、商户货款和账户余额。 - `supply_eligible`、审核人、入账人、CRMEB 流水 ID 和渠道成功状态。 - 订单归属 `uid/mer_id/admin_id/service_id`;全部从登录态取得。 - `allowed_actions`、数据范围 SQL、目标账户、最终回购金额和最终退款金额。 ## 二、商品农业资料与权限范围 ### 1. DTO | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `ProductAgricultureDraftInput` | `CommandMeta + version? + source_type(platform_self/merchant_supplier/farm_output), farm_id?, supplier_name?, origin_province, origin_city, origin_district, origin_address, public_summary, trace_archive_id?, material_ids[]` | `product_id, profile_id, status=draft, version, completeness, material_status, allowed_actions` | | `ProductAgricultureSubmitInput` | `VersionedCommand` | `product_id, status=pending_review, submitted_at, version` | | `ProductAgricultureReviewInput` | `ReviewCommand` | `product_id, status=approved/rejected, material_status, supply_eligible, audit_at, version` | | `AdminScopeSaveInput` | `CommandMeta + scope_set_version + reason_code + remark + scopes[]` | `admin_id, scope_set_version, scopes, added, reactivated, disabled, unchanged` | | `AdminScopeItem` | `domain_code, scope_type, scope_object_id, valid_from, valid_to?` | 返回时增加 `scope_id, object_name, status` | `source_type=platform_self/farm_output` 时 `farm_id` 必填;`merchant_supplier` 时商户由商品归属反查。`supply_eligible` 由审核、材料有效性和商品状态共同计算。 ### 2. 路由映射 | 路由 | 请求 DTO | 响应 DTO | | --- | --- | --- | | `GET farm/agriculture/product_profile/detail/:product_id`、`GET farm/catalog/product_agriculture/detail/:product_id` | Path `product_id` | 商品基本摘要 + profile + materials + audit history + `allowed_actions` | | `POST farm/agriculture/product_profile/save/:product_id`、`POST farm/catalog/product_agriculture/save/:product_id` | `ProductAgricultureDraftInput` | `CommandResult + completeness` | | `POST farm/agriculture/product_profile/submit/:product_id`、`POST farm/catalog/product_agriculture/submit/:product_id` | `ProductAgricultureSubmitInput` | `CommandResult` | | `POST farm/agriculture/product_profile/review/:product_id` | `ProductAgricultureReviewInput` | `CommandResult + supply_eligible` | | `GET farm/support/admin_scope/options` | `keyword?, domain_code?` | 业务域、农场、仓库树和操作者可授予上限 | | `GET farm/support/admin_scope/detail/:admin_id` | Path `admin_id` | `admin_id, admin_name, scope_set_version, scopes, warnings` | | `POST farm/support/admin_scope/save/:admin_id` | `AdminScopeSaveInput` | 范围差异和新集合版本 | ## 三、农业主数据 ### 1. 主数据输入 | 资源 | 创建/修改字段 | 列表/详情响应核心字段 | | --- | --- | --- | | farm | `farm_no, name, short_name, address, longitude?, latitude?, coordinate_system=GCJ02, contact_name?, contact_phone?, description?, cover_image?, gallery[], sort, enabled` | ID/编号/名称、地址点位、区域/地块/仓库/在产批次数量、状态、版本 | | zone | `farm_id, zone_no, name, zone_type, description?, schematic_image?, sort, enabled` | 农场、区域编号/名称/类型、地块/栏舍数、状态 | | plot | `zone_id, plot_no, name, area, area_unit, capacity, capacity_unit, soil_type?, schematic_image?, sort, enabled` | 农场/区域、面积容量、当前占用、未来冲突、状态 | | warehouse | `farm_id, warehouse_no, name, warehouse_type, address?, manager_name?, manager_phone?, enabled` | 农场、库位数、当前库存摘要、状态 | | warehouse_location | `warehouse_id, location_no, name, location_type, capacity?, capacity_unit?, enabled` | 仓库、库位、占用/可用摘要、状态 | | pickup_point | `farm_id, name, address, longitude, latitude, coordinate_system=GCJ02, contact_name, contact_phone, opening_hours, pickup_days, enabled` | 点位、营业时间、待核销量、状态 | | crop | `crop_no, name, variety?, category, growth_days, output_unit, cover_image?, description?, enabled` | 作物/品种、周期、单位、套餐引用数 | | enclosure | `zone_id, enclosure_no, name, enclosure_type, capacity, capacity_unit, schematic_image?, enabled` | 农场/区域、容量、当前个体/批次、状态 | | breed | `category_id, breed_no, name, species, cycle_days, output_type, output_unit, cover_image?, enabled` | 分类/品种、周期、个体/批次和套餐引用 | | animal | `farm_id, enclosure_id, breed_id, asset_no, ear_tag?, born_at?, sex?, source, health_status, weight?, weight_unit?, enabled` | 个体身份、位置、健康、当前认养占用、版本 | | breeding_batch | `farm_id, enclosure_id, breed_id, batch_no, started_at, planned_end_at?, total_share, available_share, unit_name, enabled` | 批次、容量/可用份额、周期、当前分配 | ### 2. 通用主数据路由 `farm/agriculture/{farm|zone|plot|warehouse|warehouse_location|pickup_point|crop|enclosure|breed|animal|breeding_batch}` 使用: | 后缀 | 请求 | 响应 | | --- | --- | --- | | `GET lst` | `ListQuery` + `farm_id?, zone_id?, warehouse_id?, enabled?` | `ListResult` | | `GET detail/:id` | Path ID | `DetailResult` | | `POST create` | `CommandMeta + 对应资源字段` | `CommandResult` | | `POST update/:id` | `VersionedCommand + 可编辑资源字段` | `CommandResult` | | `POST status/:id` | `ReasonCommand + enabled` | `CommandResult + reference_warnings` | 停用操作不接受前端传“引用数”;后端返回套餐、活动、生产、任务或库存引用阻断明细。动物三段导入额外使用 `upload_token → validation_operation_no → confirm_token`,最终返回 `AsyncAccepted`。 动物导入字段契约: | DTO/路由 | 请求字段 | 响应 | | --- | --- | --- | | `AnimalImportValidateInput` / `POST farm/agriculture/animal/import/validate` | `CommandMeta + system_attachment_id, content_hash, farm_id, default_enclosure_id?, column_mapping?` | `AsyncAccepted`,`operation_type=animal_import_validate` | | `GET farm/agriculture/animal/import/preview/:operation_no` | Path `operation_no` | `status, content_hash, row_count, valid_count, error_count, columns, preview_rows<=100, error_file?, confirm_token?, target_versions` | | `AnimalImportConfirmInput` / `POST farm/agriculture/animal/import/confirm/:operation_no` | `CommandMeta + confirm_token` | `AsyncAccepted`,`operation_type=animal_import_confirm` | `confirm_token` 绑定校验操作、文件哈希、字段映射、目标农场/栏舍版本和有效期;确认请求不携带动物行数据。 ## 四、租地与认养 ### 1. 套餐和订单 DTO | DTO | 请求字段 | 响应核心字段 | | --- | --- | --- | | `LandPlanInput` | `CommandMeta/version? + farm_id, name, cover_image, gallery[], area, area_unit, service_days, price, service_value_amount, delivery_value_amount, delay_tolerance_days, allocation_mode, selectable_crop, crop_ids[], planting_service, output_rule, fulfillment_rule, sale_start_at, sale_end_at, stock, per_user_limit, description` | plan ID/no、价值拆分校验、发布状态、容量预检、版本 | | `AdoptionPlanInput` | `CommandMeta/version? + farm_id, category_id, breed_id, allocation_mode(individual/share), share_qty?, service_days, price, service_value_amount, delivery_value_amount, delay_tolerance_days, output_rule, replacement_rule, fulfillment_rule, sale_start_at, sale_end_at, stock, per_user_limit, description` | plan ID/no、价值拆分/个体或份额容量预检、版本 | | `FarmOrderCheckInput` | `plan_id, quantity=1, crop_id?, address_id?, request_id` | `check_key, plan_snapshot, amount_breakdown, capacity_summary, expires_at` | | `FarmOrderCreateInput` | `check_key, request_id, user_remark?` | CRMEB `group_order_id, order_id, order_product_id, pay_price, pay_options, business_order_no` | | `AllocationReserveInput` | `request_id, order_id, candidate_id, version` | `reservation_no, expires_at, candidate_snapshot` | | `AllocationConfirmInput` | `request_id, order_id, reservation_no, version` | allocation/occupancy ID、真实资产摘要、状态 | ### 2. 路由映射 | 路由族 | 请求 | 响应 | | --- | --- | --- | | 平台 `farm/land/plan/*` | `LandPlanInput`;publish 使用 `VersionedCommand` | 列表/详情、发布预检、`CommandResult` | | 平台 `farm/adoption/plan/*` | `AdoptionPlanInput`;publish 使用 `VersionedCommand` | 列表/详情、发布预检、`CommandResult` | | 平台 `farm/{land|adoption}/order/lst|detail` | `ListQuery` 或 Path ID | 订单、支付、真实分配、生产、产出、履约、异常 | | 平台 `farm/{land|adoption}/allocation/candidates/:order_id` | `farm_id?, date_range?` | 候选 ID、容量、冲突原因;不创建占用 | | `reserve/confirm/release/:order_id` | `AllocationReserveInput`、`AllocationConfirmInput`、`ReasonCommand` | 预留/分配结果 | | 用户 `farm/{land|adoption}/plan/lst|detail` | `ListQuery`/Path ID | 仅已发布套餐和规则快照 | | 用户 `farm/{land|adoption}/order/check|create` | `FarmOrderCheckInput`/`FarmOrderCreateInput` | 价格校验或支付入口 | | 用户 `farm/{land|adoption}/order/pay_result/:group_order_id` | Path ID | `PayResult` | | 用户 `farm/{land|adoption}/order/lst|detail/:id` | `ListQuery`/Path ID | 本人订单、分配、生产、产出、履约和动作 | 租地和认养每次下单只允许一个套餐且数量为 1;具体地块、动物或份额在付款后分配,不在下单请求中承诺。 ## 五、云仓活动、供货与库存 ### 1. 活动和 SKU | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `CloudActivityInput` | `CommandMeta/version? + name, preview_at?, start_at, end_at, payment_timeout_minutes, choice_days_default, cover_image?, description?, sort` | activity ID/no、状态、版本、预检摘要 | | `CloudActivityProductInput` | `CommandMeta/version? + activity_id, product_id, display_title, cover_image?, supports_shipping, supports_pickup, supports_consign=true, choice_days?, pickup_days?` | activity product ID、SKU 数、完整性 | | `CloudActivitySkuRuleInput` | `VersionedCommand + supply_id, activity_unit_price, activity_qty, per_user_limit, expected_sale_days, maturity_resolution_days, settlement_mode, milestones[], user_profit_rate, buyback_rate, primary_after_sale_days, secondary_after_sale_days, shipping_rule, pickup_point_ids[], resale_product_id, resale_sku_value_id` | SKU 规则校验、来源诊断、预计金额示例 | | `CloudActivityPublishInput` | `VersionedCommand + precheck_hash` | 发布版本、批次草稿、库存占用摘要 | 平台成本比例和最终可售量不由客户端提交。`settlement_mode` 三选一;`milestones` 只对分期模式有效,严格递增且最后为 `10000`。 ### 2. 供货生命周期 | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `CloudSupplyDraftInput` | `CommandMeta/version? + product_id, source_sku_value_id, supply_price, proposed_qty, fulfillment_type, proposed_shipping_party, proposed_quality_party, proposed_after_sale_party, expected_delivery_at?, material_ids[], remark?` | supply ID/no、来源 SKU 快照、完整性、版本 | | `CloudPlatformSupplyCreateInput` | `CommandMeta + product_id, source_sku_value_id, proposed_qty, fulfillment_type, shipping_responsible_party, quality_responsible_party, after_sale_responsible_party, after_sale_days, material_ids[], remark?` | `source_type=platform, merchant_id=null` 的 supply ID/no、来源预占和农业库存流水摘要 | | `CloudSupplyAuditInput` | `ReviewCommand + approved_qty?, shipping_responsible_party?, quality_responsible_party?, after_sale_responsible_party?, after_sale_days?` | 审核状态、批准/预留数量、责任快照 | | `SupplyDeliveryInput` | `CommandMeta/version? + dispatch_qty, handover_method, carrier_code?, tracking_no?, system_attachment_ids[]` | delivery ID/no、累计发运和剩余可交付量 | | `SupplyReceiveInput` | `VersionedCommand + received_qty, shortage_qty, system_attachment_ids[]` | 实收、短少和待检数量 | | `SupplyInspectionInput` | `VersionedCommand + accepted_qty, rejected_qty, pending_inspection_qty, warehouse_id, location_id, quality_result, system_attachment_ids[]` | 验收方程、云仓可用量、拒收待办 | | `SupplyReturnInput` | `ReasonCommand + qty, handover_method?, carrier_code?, tracking_no?, system_attachment_ids[]` | 退回/争议/完成状态和来源恢复量 | | `SupplyAcquisitionPrepareInput` | `ReasonCommand + acquisition_qty, acquisition_unit_price, target_product_id, target_sku_value_id, system_attachment_ids[]` | 承接编号、待复核金额、目标平台库存和版本 | | `SupplyAcquisitionReviewInput` | `ReviewCommand` | `approved/rejected`、复核人和版本;不得修改数量、价格或目标 SKU | | `SupplyAcquisitionExecuteInput` | `VersionedCommand + precheck_hash` | 完成承接、平台库存流水、供货汇总和版本 | | `CloudFulfillmentShipInput` | `VersionedCommand + package_id, carrier_code, tracking_no, system_attachment_ids[]?` | 包裹、出库数量、物流版本和履约状态 | | `CloudFulfillmentLogisticsInput` | `ReasonCommand + package_id, carrier_code, tracking_no` | 变更前后物流快照、包裹版本和风险提示 | | `CloudFulfillmentEvidenceInput` | `VersionedCommand + evidence_type, system_attachment_ids[], remark?` | 新增证据关联、证据版本和完整性 | | `CloudFulfillmentReturnReceiveInput` | `VersionedCommand + after_sale_id, received_qty, shortage_qty, quality_result, system_attachment_ids[]` | 退回实收/差异、待检或异常 ID、下一动作 | | `CloudFulfillmentExceptionInput` | `ReasonCommand + exception_type, severity, fact_description, system_attachment_ids[]` | 统一异常 ID/no、冻结建议和状态 | 供货审核 `decision=reject` 时不接受批准量和责任方;`approve` 时三类责任方、批准量和观察期必填。所有数量由后端以当前累计值重新校验。 ### 3. 路由映射 | 路由族 | 请求/响应 | | --- | --- | | `farm/cloud/activity/lst|filter|detail|chart` | `ListQuery`/Path ID;返回活动摘要、SKU/库存/订单/批次指标和下钻键 | | activity `create|update|precheck|publish|close|copy` | 对应 Activity DTO;close 使用 `ReasonCommand`,copy 使用 `CommandMeta` | | activity product/SKU `lst|detail|create|update|remove|source_check|resale_map` | 对应 Product/SKU DTO;检查返回 `matched/changed/missing/ambiguous` | | 商户 supply `product_candidates|lst|detail|create|update|submit` | 候选只返回本商户 SKU;写入使用 `CloudSupplyDraftInput` | | 商户 delivery `lst|create|update|dispatch|cancel` | `SupplyDeliveryInput` 或 `ReasonCommand` | | 商户 fulfillment `lst|detail|ship|logistics|evidence|return_receive|exception` | 查询按当前商户和责任快照过滤;写入依次使用五类 `CloudFulfillment*Input`,不得由客户端提交出库汇总、库存恢复量或异常影响金额 | | 平台 supply `lst|detail|platform/create|audit|receive|inspection|release|return|platform_acquire/prepare|platform_acquire/review|platform_acquire/execute|freeze` | `platform/create` 使用 `CloudPlatformSupplyCreateInput`;承接三步使用对应 Acquisition DTO;其余使用审核、数量、责任、仓储和证据 DTO;详情返回完整数量链 | | `farm/cloud/batch/lst|detail|flows` | 批次摘要、规则快照、池余额、不可变流水、进度和恒等式 | | batch `freeze|resume|reconciliation/*` | `ReasonCommand` 或 `AsyncCommand`;最终修复只接受已审核预演 ID | ## 六、用户云仓订单与去向 ### 1. DTO | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `CloudOrderCheckInput` | `activity_sku_id, purchase_qty, request_id` | `check_key, sku_snapshot, rule_snapshot, principal_amount, quota, stock, expires_at` | | `CloudOrderCreateInput` | `check_key, request_id, user_remark?` | CRMEB 订单三层 ID、云仓明细 ID、支付选项 | | `CloudDispositionPreviewInput` | `cloud_order_item_id, disposition, address_id?, pickup_point_id?` | 可行性、运费承担、报价/自提点/代销规则、截止时间 | | `CloudDispositionConfirmInput` | `request_id, cloud_order_item_id, choice_version, disposition, preview_token, address_id?, pickup_point_id?` | 最终去向;需补运费时返回运费单而不提前生效邮寄 | | `CloudFreightPayInput` | `request_id, freight_order_id, version, pay_type, return_path?` | 支付参数或余额支付最终状态 | | `CloudPrimaryRefundInput` | `request_id, cloud_order_item_id, version, reason_code, reason, pics[]?` | 退款申请 ID、冻结范围、状态;`pics` 沿用 CRMEB 用户售后图片格式和上传白名单 | | `CloudPickupVerifyInput` | `request_id, pickup_id, version, voucher_code, verify_qty` | 核销流水 ID/no、累计核销量、剩余量、明细完成状态 | | `CloudPickupResolveInput` | `CommandMeta + pickup_id, version, remaining_qty, resolution_type(extend/ship/refund/buyback), plan_version, user_confirmation_id?` | 异常方案/运费单/退款/回购结果,不接受客户端金额 | ### 2. 查询响应 | 接口 | 核心响应字段 | | --- | --- | | activity current/config/product | 活动/场次、SKU、倒计时、限购、可抢库存、三种去向、预计周期、分成、回购和风险提示 | | order list/detail/action_count | 首次本金、支付、选择截止、去向、运费、自提、持仓、退款、规则快照、`allowed_actions` | | freight detail/pay_result/refund_result | 金额、报价快照、支付渠道、渠道事实摘要、超时/迟到退款状态 | | pickup voucher/verification list | 点位快照、有效期、脱敏凭证展示值、应提/已核销/退款/改寄/回购/剩余数量和不可变核销历史 | | holding list/detail/progress | 本金、实体批次数量、已售/未售经济等价数量、真实累计进度、节点、预计到期、所有权切换、回购和账本摘要 | | user ledger list/detail | 本金/收益/回购类型、累计公式输入、分钱尾差、正常退款抵扣、平台风险承担、审核、入账、冲正和 CRMEB 流水摘要 | 去向确认一次只处理完整订单明细;`purchase_qty` 不允许拆分为多种去向。用户可以支付后继续抢购,订单中心通过 `action_count.pending_choice` 找回待选明细。 ## 七、二次销售、账本、结单与对账 | 命令 DTO | 请求字段 | 响应 | | --- | --- | --- | | `LedgerReviewInput` | `ReviewCommand + source_calculation_version` | 审核状态、重算差异和下一动作 | | `LedgerExecuteInput` | `CommandMeta + source_ids[], version_map, review_remark?` | 逐条 `source_id, posting_id, status, crm_bill_id, error_code` | | `LedgerAdjustmentInput` | `CommandMeta + source_ledger_id, direction, reason_code, reason, evidence_ids[]` | 调整申请 ID、影响预览;不得提交最终账户余额 | | `StatementGenerateInput` | `CommandMeta + merchant_id, period_start, period_end, currency=CNY` | statement ID/no、明细数和金额 | | `ReconciliationExecuteInput` | `CommandMeta + reconciliation_id, version, approved_action_ids[], reason_code, remark` | `AsyncAccepted`;每项按原结果键修复 | | `BuybackReviewInput` | `ReviewCommand + calculation_version` | 审核状态和执行前置;金额、比例、平台目标库存均从快照读取 | 列表与详情必须返回公式快照,至少包括 `source_qty, batch_effective_qty, sold_equivalent_qty, unsold_equivalent_qty, unit_price, principal, recognized_sales, distributable_profit, cumulative_due, historical_settled, current_due, normal_refund_offset_amount, platform_risk_absorbed_amount, rounding_adjustment`。执行接口只接收来源 ID,不接收最终金额、目标账号或 CRMEB 流水 ID。 ## 八、生产、产出、履约、异常与溯源 ### 1. 生产与现场记录 | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `ProductionBatchInput` | `CommandMeta/version? + production_type, farm_id, zone_id?, plot_id?, enclosure_id?, animal_asset_id?, breeding_batch_id?, planned_start_at, planned_end_at, expected_output_qty?, output_unit, right_links[]` | batch ID/no、占用/权益预检、状态 | | `FarmTaskInput` | `CommandMeta/version? + task_type, target_type, target_id, requirement_snapshot, planned_start_at, due_at, priority, assignee_ids[]?` | task ID/no、分派和版本 | | `ProductionEventInput` | `CommandMeta/version? + task_id?, production_batch_id, event_type, occurred_at, content, metric_items[], farm_evidence_attachment_ids[], visibility` | event/version ID、审核状态 | | `AssetHealthInput` | `CommandMeta + task_id?, animal_asset_id?, breeding_batch_id?, health_type, occurred_at, result, treatment?, farm_evidence_attachment_ids[]` | 健康记录 ID、是否触发异常 | | `OutputBatchInput` | `CommandMeta/version? + production_batch_id, harvested_at, gross_qty, unit_code, warehouse_id?, location_id?, quality_note?, farm_evidence_attachment_ids[]` | output ID/no、待检数量和状态 | `metric_items` 使用白名单 `{metric_code, value_decimal|string, unit_code}`;现场提交人不能在审核接口修改原内容。生产类型扩展字段按 `plant/livestock` 二选一。 ### 2. 产出分配与履约 | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `OutputQualityInput` | `VersionedCommand + accepted_qty, loss_qty, pending_qty, warehouse_id, location_id, quality_result, system_attachment_ids[]` | 数量方程、可分配量、状态 | | `OutputAllocationConfirmInput` | `CommandMeta + output_batch_id, calculation_version, preview_token` | 分配列表、库存流水和履约草稿 | | `FulfillmentAddressInput` | `VersionedCommand + address_id` | 不可变地址版本、是否需运费 | | `FarmFreightCreateInput` | `CommandMeta + fulfillment_id, address_version, quote_token` | 农业运费单、金额、支付期限 | | `FulfillmentPackageInput` | `VersionedCommand + items[{fulfillment_item_id, qty}], warehouse_id, location_id` | 包裹 ID/no、待出库数量 | | `FulfillmentShipInput` | `VersionedCommand + package_id, carrier_code, tracking_no, shipped_at?, evidence_refs[]?` | 包裹、物流和履约状态;平台入口只收 `system`,现场入口只收 `farm_service` | | `FulfillmentRefundInput` | `CommandMeta + fulfillment_id, refund_qty, reason_code, reason, evidence_ids[]?` | 承诺/已履约/已退数量、服务/交付退款基数、累计应退、历史/在途退款、本次后端计算金额和售后编号 | 租地/认养产出 V1 只允许邮寄。地址、运费、包裹和售后均按履约单,不修改原租地/认养交易金额。 ### 3. 异常和溯源 | DTO | 请求字段 | 成功响应 | | --- | --- | --- | | `ExceptionCreateInput` | `CommandMeta + business_domain, event_type, severity, target_type, target_id, occurred_at, reason, fact_items, evidence_refs[]` | exception ID/no、SLA、初始影响;按平台/商户/现场端限制证据来源 | | `ExceptionPlanInput` | `CommandMeta + exception_id, impact_version, plan_type, affected_qty, replacement_target_id?, proposed_delay_days?, steps[{step_order, step_code, input}], expected_result` | 后端等价校验、短缺分配、退款计算、是否需用户确认、确认截止、超时策略、plan version ID | | `ExceptionReviewInput` | `ReviewCommand + precheck_hash` | 审核状态 | | `ExceptionUserConfirmInput` | `request_id, plan_version_id, decision(accept/reject), version` | 确认事实、下一动作;不得提交替代金额或直接改方案 | | `TraceVersionInput` | `CommandMeta/version? + archive_id?, target_type, target_id, title, public_summary, sections[], material_ids[], link_targets[]` | archive/version ID、完整性、审核状态 | | `TraceMaterialInput` | `CommandMeta/version? + material_type, material_no?, system_attachment_id, issuer?, effective_at?, expire_at?, applicable_targets[]` | material ID、有效性和引用数 | | `TraceLinkInput` | `CommandMeta + archive_id, version_id, target_type, target_id, relation_type, valid_from?, valid_to?` | link ID 和公开影响 | 异常执行接口只接受 `plan_id/step_id + version + request_id`,不接受任意类名、SQL、URL、脚本、最终退款金额或回购金额。完全等价且未超延期容忍期的方案可在 3 个自然日后按快照自动接受;降级、减量、超期或补款方案超时默认拒绝并转未履约退款。溯源审核、发布、撤回是三个独立权限;公开接口只返回当前发布版本。 ## 九、服务/现场端字段契约 | 接口族 | 请求字段 | 响应字段 | | --- | --- | --- | | `GET farm/context`, `GET farm/me` | 无业务对象参数 | service ID、职责、能力码、scope 摘要/版本、默认入口、地图/扫码能力 | | `GET farm/order/search|detail/:type/:id` | `keyword/type/status/page/limit` | 脱敏用户、订单、分配、生产、履约和 `allowed_actions` | | `GET farm/cloud/order/search|detail/:id` | 同上 | 首次订单、去向、批次、持仓、账本和责任快照;默认脱敏 | | `POST farm/scan/resolve` | `request_id, code, expected_types[]?, task_id?` | `object_type, object_id, display_no, summary, context, allowed_actions` | | task `lst|detail|start|complete` | 列表查询或 `VersionedCommand + result/farm_evidence_attachment_ids` | 任务、要求快照、分派、时间线和下一动作 | | cloud pickup verify | `CloudPickupVerifyInput`,并额外强制当前网点/仓库 scope | 核销流水、累计/剩余数量和明细状态 | | event/health/output/warehouse/fulfillment | 使用第八节对应 DTO,并额外强制当前 task/scope | 业务结果和任务进度 | | `POST farm/attachment/upload` | multipart:`file, task_id?, scope_object_type, scope_object_id, request_id` | `farm_evidence_attachment_id, attachment_no, mime_type, size, content_hash, expires_at, bind_status=unbound` | | review `lst|detail|approve|reject` | 查询或 `ReviewCommand` | 原提交内容、证据、差异、审核结果 | | exception `create|evidence|propose` | `ExceptionCreateInput` 或证据/建议字段 | 异常/建议 ID;不能修改最终方案、金额或库存 | 服务端对象越界统一返回 `COMMON_NOT_FOUND`;只有对象已确认可见但动作不允许时返回 `SERVICE_PERMISSION_DENIED`。离线草稿只存在 IndexedDB,正式提交仍使用上述 DTO 和原 `request_id`。 ## 十、公开查询、地图与文件 | 接口 | 请求 | 响应/限制 | | --- | --- | --- | | `farm/agriculture/home|farm/lst|farm/detail/:id` | 公开分页、位置筛选可选 | 已启用农场、已发布套餐和公开材料;不返回内部容量/联系人 | | `farm/trace/public/:archive_no` | 稳定随机公开码 | 当前发布版本、公开材料、过程时间线和撤回状态 | | `farm/trace/qrcode/:archive_no` | 公开码 | 二维码图片或稳定跳转;不编码内部主键 | | `farm/map/geocode|reverse_geocode|suggest` | 地址/关键词或 `longitude,latitude,coordinate_system=GCJ02` | 规范化候选;不返回 Key、SK、完整供应商报文 | | `GET farm/operation/detail/:operation_no` | 业务号 | `OperationDetail`;四端各自鉴权,只限发起人或有权范围 | 文件响应按来源返回 `system_attachment_id`、`farm_evidence_attachment_id` 或只读 `file_id`,并附 `url, thumbnail_url?, mime_type, size, expires_at?`。存储物理路径、对象存储密钥和永久私有 URL 不得进入客户端。 ## 十一、列表与详情投影最低字段 每个 `19` 中的 `lst/search` 接口必须至少返回: `id, business_no/code, display_name/title, status, status_text, primary_summary, warning_codes[], updated_at, allowed_actions` 并补齐 `30-v1-p0-page-matrix.md` 对应页面“信息字段”列。每个详情接口必须至少返回: `id, business_no, status, version, base, rule_snapshot?, quantity_summary?, money_summary?, ownership, related, timeline, audit_summary, warnings, allowed_actions` Serializer 按终端裁剪: - 平台:再按管理员业务域和对象范围。 - 商户:强制当前 `mer_id`,隐藏平台成本、其他商户和用户完整隐私。 - 用户:强制本人资源,隐藏供货成本、内部备注和责任人员联系方式。 - 服务端:按职责、对象范围和 PII 权限脱敏。 - 公开端:只读发布版本和公开字段。 ## 十二、实现验收 1. `19` 的每个路由必须映射到本文件一个 DTO 或明确的通用资源模式。 2. `31` 的每个操作码必须有请求字段、响应字段、幂等键和版本规则。 3. Controller 只把校验后的 DTO 交给 Application Service,不把原始 Request 数组传入 Repository。 4. Serializer/Presenter 负责金额字符串、ID 字符串、隐私裁剪和 `allowed_actions`。 5. OpenAPI 或接口管理平台的 schema 名称必须沿用本文件 DTO 名;变更时同步更新 `19`、`31`、`35` 和测试。 6. 契约测试逐路由校验必填、禁止字段、类型、空值、错误码和响应快照;不能只测 HTTP 200。 ## 十三、关联文档 - [19-v1-api-contract-draft.md](19-v1-api-contract-draft) - [30-v1-p0-page-matrix.md](30-v1-p0-page-matrix) - [31-v1-write-operation-contract-registry.md](31-v1-write-operation-contract-registry) - [33-v1-state-exception-transaction-matrix.md](33-v1-state-exception-transaction-matrix) - [34-v1-database-field-dictionary.md](34-v1-database-field-dictionary) - [35-v1-page-api-file-trace.md](35-v1-page-api-file-trace)