# V1 数据库物理字段字典 本文档冻结 SmartFarm V1 新增表和 CRMEB 必要兼容变更的物理字段基线。它不是可执行 SQL,不写数据库;开发时应按本字典生成版本化 migration,并执行 `up → verify → rollback boundary`。 ## 一、物理约定 ### 1. 类型与缩写 | 缩写/类型 | 含义 | | --- | --- | | `PK` | `bigint unsigned AUTO_INCREMENT` 主键 | | `RID` | 新农业表逻辑外键,`bigint unsigned` | | `CID` | CRMEB 既有主键,实际 migration 必须与来源列的 unsigned/长度完全一致,当前基线按 `int unsigned` | | `NO` | 业务编号 `varchar(40)`,ASCII、非空、唯一 | | `CODE` | 稳定代码 `varchar(32)`,ASCII、非空 | | `STATE` | 状态码 `varchar(32)`,ASCII、非空;API 原样返回,不在数据库另存中文状态 | | `MONEY` | `decimal(14,2)`,非空默认 `0.00` | | `CALC` | `decimal(20,8)`,计算中间值 | | `QTY` | `decimal(14,3)`,非空默认 `0.000` | | `EQTY` | `decimal(20,6)`,用户经济等价数量;不得作为实体库存扣减数量 | | `RATE` | `smallint unsigned` 基点,`0..10000` | | `DT` | `datetime(3)`;发生时间无默认值,明确由业务服务写入 | | `JSON` | MySQL `json`;业务服务必须写合法对象/数组,不依赖数据库隐式字符串转换 | | `HASH` | `char(64)`,小写 SHA-256 | | `VER` | `int unsigned NOT NULL DEFAULT 1` | 本字典用 `NN` 表示 `NOT NULL`,`NULL` 表示可空。未写默认值的 `NN JSON/DT/varchar` 必须由创建命令显式赋值。 ### 2. 公共列模板 | 模板 | 列 | | --- | --- | | `CORE` | `_id PK`、`status STATE`、`version VER`、`create_time DT`、`update_time DT NULL` | | `MASTER` | `CORE` + `is_del tinyint unsigned NN default 0`、`delete_time DT NULL`、`create_admin_id CID NULL`、`update_admin_id CID NULL` | | `IMMUTABLE` | `
_id PK`、`create_time DT`;无 `is_del`、无业务更新入口 | | `SNAPSHOT` | `snapshot_schema_version smallint unsigned NN default 1`、`snapshot_hash HASH NN`、`source_version int unsigned NN`、`snapshot_created_at DT` | 交易、库存、账本、状态迁移、审计、Outbox 和证据引用不设物理删除入口。主数据只允许软删除且有关联历史时仍不得删除。 ### 3. 通用数据库规则 - 新表统一 `InnoDB`、`utf8mb4`;业务号、状态码、幂等键、事件名等 ASCII 列使用区分大小写的 ASCII collation。 - V1 不建立数据库级级联删除。逻辑外键由 Repository 校验,所有历史引用永久保留。 - 金额、数量均加应用层非负/方程校验;MySQL 8 migration 可补 `CHECK`,但代码不得仅依赖 `CHECK`。 - JSON 只存快照、步骤参数、展示材料和第三方摘要;可筛选、可排序、参与金额/数量计算的字段必须独立成列。 - 每个唯一业务结果都先有唯一键,再写幂等代码;只加普通索引不能替代并发唯一约束。 - 大表索引只按已冻结查询建立;开发环境用代表数据执行 `EXPLAIN` 后再签 G3 数据门。 ## 二、CRMEB 既有表兼容变更 | 表 | 变更 | 上线前验证 | 回退边界 | | --- | --- | --- | --- | | `eb_user` | `now_money decimal(14,2) NN default 0.00` | 无负溢出、余额与账单尾值一致 | 产生超旧字段容量的金额后不可缩回 | | `eb_user_bill` | `number/balance decimal(14,2) NN default 0.00` | 抽样复算方向、金额、余额 | 同上 | | `eb_merchant` | `mer_money decimal(14,2) NN default 0.00` | 商户余额与财务流水一致 | 同上 | | `eb_financial_record` | `number decimal(14,2) NN default 0.00` | 抽样结单入账精度 | 同上 | | `eb_store_service` | 增加 `uk_service_account(account)` | 空字符串先规范为 `NULL`;任一非空重复账号阻断升级 | 未发新 Token 前可删索引;产生冲突依赖后不可盲回 | 空账号规范化仅对真正空白值执行;非空重复账号不得自动改名或合并,必须在迁移前停止并报告。 ## 三、商品、云仓活动与供货 ### 1. 商品农业扩展 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_product_agriculture_profile` | `MASTER` | `product_id CID NN`;`source_type CODE NN`;`farm_id RID NULL`;`supplier_name varchar(120) NULL`;`origin_province/city/district varchar(64) NULL`;`origin_address varchar(255) NULL`;`public_summary text NULL`;`supply_eligible tinyint unsigned NN default 0`;`trace_archive_id RID NULL`;`material_status CODE NN default 'missing'`;`submitted_by/submitted_at CID/DT NULL`;`audit_by/audit_at CID/DT NULL`;`audit_remark varchar(1000) NULL` | `uk_product(product_id)`;`idx_source_status(source_type,status,product_id)`;`idx_farm(farm_id,status)`;`idx_review(status,submitted_at,product_agriculture_profile_id)` | | `eb_farm_product_material` | `CORE` | `product_id CID NN`;`material_type CODE NN`;`material_no varchar(80) NULL`;`attachment_id CID NN`(逻辑引用 `eb_system_attachment.attachment_id`);`issuer varchar(160) NULL`;`effective_at DT NULL`;`expire_at DT NULL`;`audit_status STATE NN`;`audit_by CID NULL`;`audit_at DT NULL`;`source_material_id RID NULL` | `idx_product_type_status(product_id,material_type,status,expire_at)`;`idx_expiry(status,expire_at,product_material_id)` | ### 2. 活动与规则 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_activity` | `MASTER` | `activity_no NO`;`name varchar(120) NN`;`preview_at DT NULL`;`start_at/end_at DT NN`;`payment_timeout_minutes smallint unsigned NN`;`choice_days_default smallint unsigned NN`;`publish_at/closed_at DT NULL`;`rule_snapshot JSON NULL` + `SNAPSHOT`(发布后必填) | `uk_activity_no(activity_no)`;`idx_status_time(status,start_at,end_at,cloud_activity_id)` | | `eb_farm_cloud_activity_product` | `CORE` | `activity_id RID NN`;`product_id CID NN`;`display_title varchar(160) NN`;`cover_image varchar(255) NULL`;`supports_shipping/supports_pickup/supports_consign tinyint unsigned NN default 0`;`choice_days/pickup_days smallint unsigned NULL`;`rule_version int unsigned NN`;`publish_snapshot JSON NULL` + `SNAPSHOT`(发布后必填) | `uk_activity_product(activity_id,product_id)`;`idx_activity_status(activity_id,status,cloud_activity_product_id)` | | `eb_farm_cloud_activity_sku` | `CORE` | `activity_product_id/supply_id RID NN`;`source_product_id/source_value_id CID NN`;`source_unique varchar(128) NN`;`source_sku_text varchar(255) NN`;`source_snapshot JSON NN`;`source_snapshot_hash HASH NN`;`source_sync_status STATE NN`;`source_checked_at DT NULL`;`activity_unit_price/supply_unit_price MONEY`;`activity_qty/per_user_limit QTY`;`expected_sale_days smallint unsigned NN`;`maturity_resolution_days smallint unsigned NN default 30`;`settlement_mode CODE NN`;`user_profit_rate/platform_profit_rate/buyback_rate RATE NN`;`platform_cost_policy_snapshot JSON NN`;`primary_after_sale_days/secondary_after_sale_days smallint unsigned NN`;`resale_product_id/resale_sku_value_id CID NULL`;`rule_version int unsigned NN`;`publish_snapshot JSON NULL` + `SNAPSHOT`(发布后必填) | `uk_activity_source(activity_product_id,source_snapshot_hash)`;`idx_supply_status(supply_id,status)`;`idx_source_check(source_sync_status,source_checked_at,cloud_activity_sku_id)`;`idx_resale_map(resale_product_id,resale_sku_value_id)` | | `eb_farm_cloud_user_quota` | `CORE` | `activity_sku_id RID NN`;`user_id CID NN`;`limit_qty/locked_unpaid_qty/paid_qty/refunded_qty QTY` | `uk_sku_user(activity_sku_id,user_id)`;`idx_user(user_id,status,cloud_user_quota_id)` | 约束:`start_at < end_at`;发布活动 `supports_consign=1`;利润分成合计 `10000`;`buyback_rate` 为 `1..10000`;所有数量非负。 ### 3. 供货、交付、验收和材料 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_supply` | `CORE` | `supply_no NO`;`source_type CODE NN`;`merchant_id CID NULL`;`product_id/source_sku_value_id CID NN`;`source_sku_unique_snapshot varchar(128) NN`;`source_sku_snapshot JSON NN`;`supply_price MONEY`;`proposed_qty/approved_qty/source_reserved_qty/delivered_qty/accepted_qty/pending_inspection_qty/rejected_qty/shortage_qty/allocated_activity_qty/cloud_available_qty/cancelled_qty/return_pending_qty/returned_qty/platform_acquired_qty QTY`;`fulfillment_type CODE NN`;`shipping_responsible_party/quality_responsible_party/after_sale_responsible_party CODE NN`;`responsibility_snapshot JSON NULL`;`after_sale_days smallint unsigned NN`;`audit_by CID NULL`;`audit_at/accepted_at DT NULL`;`audit_remark varchar(500) NULL` | `uk_supply_no(supply_no)`;`idx_merchant_status(merchant_id,status,cloud_supply_id)`;`idx_source(product_id,source_sku_value_id,status)`;`idx_eligibility(status,accepted_at,merchant_id,cloud_supply_id)` | | `eb_farm_cloud_supply_delivery` | `CORE` | `delivery_no NO`;`supply_id RID NN`;`dispatch_qty/received_qty/shortage_qty QTY`;`carrier_code varchar(32) NULL`;`tracking_no varchar(80) NULL`;`handover_method CODE NN`;`dispatch_at/received_at DT NULL`;`dispatch_evidence JSON NULL`;`receive_evidence JSON NULL`;`created_merchant_user_id CID NULL`;`received_admin_id CID NULL` | `uk_delivery_no(delivery_no)`;`uk_carrier_tracking(carrier_code,tracking_no)`(允许 NULL); `idx_supply_status(supply_id,status,cloud_supply_delivery_id)` | | `eb_farm_cloud_supply_inspection` | `CORE` | `inspection_no NO`;`supply_id/delivery_id RID NN`;`received_qty/accepted_qty/pending_inspection_qty/rejected_qty QTY`;`unit_code varchar(16) NN`;`warehouse_id/location_id RID NULL`;`quality_result CODE NN`;`evidence_snapshot JSON NN`;`review_by CID NN`;`review_at DT NN` | `uk_inspection_no(inspection_no)`;`idx_delivery(delivery_id,status)`;`idx_warehouse(warehouse_id,location_id,status)` | | `eb_farm_cloud_supply_material` | `CORE` | `supply_id RID NN`;`material_type CODE NN`;`source_material_id RID NULL`;`attachment_id CID NN`(逻辑引用 `eb_system_attachment.attachment_id`);`material_no varchar(80) NULL`;`issuer varchar(160) NULL`;`effective_at/expire_at DT NULL`;`audit_status STATE NN`;`snapshot_version int unsigned NN`;`material_snapshot JSON NN` | `idx_supply_type(supply_id,material_type,status)`;`idx_expiry(status,expire_at,cloud_supply_material_id)` | | `eb_farm_cloud_supply_return` | `CORE` | `return_no NO`;`supply_id RID NN`;`merchant_id CID NN`;`reason_code CODE NN`;`return_qty/dispatched_qty/received_qty/difference_qty/restored_source_qty QTY`;`handover_method CODE NN`;`carrier_code varchar(32) NULL`;`tracking_no varchar(80) NULL`;`dispatch_evidence/receive_evidence/difference_snapshot JSON NULL`;`created_by/audited_by/acknowledged_by CID NULL`;`dispatch_at/received_at/acknowledged_at/completed_at DT NULL`;`ack_result CODE NULL`;`result_key varchar(160) NN` | `uk_return_no(return_no)`;`uk_result_key(result_key)`;`idx_supply_status(supply_id,status,cloud_supply_return_id)`;`idx_merchant_status(merchant_id,status,cloud_supply_return_id)`;`idx_carrier_tracking(carrier_code,tracking_no)`(NULL 可重复) | | `eb_farm_cloud_supply_acquisition` | `CORE` | `acquisition_no NO`;`supply_id RID NN`;`merchant_id CID NULL`;`acquisition_qty QTY`;`acquisition_unit_price/acquisition_amount MONEY`;`target_product_id/target_sku_value_id CID NN`;`calculation_snapshot/evidence_snapshot JSON NN`;`prepared_by/reviewed_by/executed_by CID NULL`;`prepared_at/reviewed_at/executed_at/completed_at DT NULL`;`review_remark varchar(500) NULL`;`platform_inventory_flow_id RID NULL`;`result_key varchar(160) NN` | `uk_acquisition_no(acquisition_no)`;`uk_result_key(result_key)`;`idx_supply_status(supply_id,status,cloud_supply_acquisition_id)`;`idx_target_sku(target_product_id,target_sku_value_id,status)` | `source_type='merchant'` 时 `merchant_id` 必填;交付、验收、退回、平台承接和供货汇总的数量方程由同事务校验。`returned_qty` 只累计完成退回的 `restored_source_qty`,`platform_acquired_qty` 只累计完成承接的 `acquisition_qty`。 ### 4. 云仓批次和库存 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_batch` | `CORE` | `batch_no NO`;`activity_id/activity_product_id/activity_sku_id/supply_id RID NN`;`source_product_id/source_value_id CID NN`;`source_unique varchar(128) NN`;`source_snapshot JSON NN`;`merchant_id CID NULL`;`resale_stock_id RID NULL`;`purchase_unit_price/supply_unit_price MONEY`;`activity_qty/locked_unpaid_qty/gross_paid_qty/primary_refunded_qty/net_paid_qty/shipping_qty/pickup_qty/consign_qty/secondary_locked_qty/gross_effective_sold_qty/secondary_reversed_qty/net_effective_sold_qty/buyback_qty/remaining_qty/platform_assumed_inflight_qty QTY`;`confirmed_sales_amount/distributable_profit/platform_operating_cost_amount MONEY`;`platform_cost_snapshot JSON NULL`;`choice_deadline_at/consign_start_at/maturity_at/maturity_grace_deadline_at/ownership_cutover_at/closed_at DT NULL`;`current_milestone tinyint unsigned NN default 0`;`settlement_mode CODE NN`;`user_profit_rate/buyback_rate RATE NN`;`suspended_from STATE NULL` | `uk_batch_no(batch_no)`;`uk_activity_sku(activity_sku_id)`;`idx_resale_fefo(resale_stock_id,status,maturity_at,cloud_batch_id)`;`idx_activity(activity_id,activity_product_id,status)`;`idx_maturity(status,maturity_grace_deadline_at,cloud_batch_id)` | | `eb_farm_cloud_batch_pool_balance` | `CORE` | `batch_id RID NN`;`pool_code CODE NN`;`qty QTY`;`last_flow_id RID NULL` | `uk_batch_pool(batch_id,pool_code)`;`idx_pool_status(pool_code,status,batch_id)` | | `eb_farm_cloud_inventory_flow` | `IMMUTABLE` | `flow_no NO`;`supply_id/activity_sku_id/batch_id RID NULL`;`warehouse_id/location_id RID NULL`;`pool_from/pool_to CODE NULL`;`unit_code varchar(16) NN`;`change_qty QTY`;`before_qty/after_qty QTY`;`business_type CODE NN`;`business_id RID NN`;`idempotency_key varchar(160) NN`;`occurred_at DT`;`operator_type CODE NN`;`operator_id bigint unsigned NULL` | `uk_flow_no(flow_no)`;`uk_idempotency(idempotency_key)`;`idx_batch_time(batch_id,occurred_at,cloud_inventory_flow_id)`;`idx_supply_time(supply_id,occurred_at,cloud_inventory_flow_id)`;`idx_business(business_type,business_id)` | 库存流水要求 `change_qty > 0`,且 `supply_id/activity_sku_id/batch_id` 至少一个非空。池余额表只保存当前值,任何变化都必须先创建唯一业务流水。 ## 四、首次订单、去向与持仓 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_order_item` | `CORE` | `group_order_id/order_id/order_product_id CID NN`;`user_id CID NN`;`activity_id/activity_product_id/activity_sku_id/batch_id RID NN`;`product_id/source_sku_value_id CID NN`;`sku_snapshot JSON NN`;`purchase_unit_price MONEY`;`purchase_qty QTY`;`gross_goods_amount/discount_amount/principal_amount/goods_paid_amount MONEY`;`disposition CODE NN default 'unselected'`;`choice_status STATE NN`;`choice_version VER`;`choice_deadline_at/choice_at DT NULL`;`choice_operator_type CODE NULL`;`current_freight_order_id/shipping_fulfillment_id/pickup_id/holding_id RID NULL`;`freight_status STATE NULL`;`freight_amount MONEY`;`pickup_deadline_at/primary_completed_at/primary_settlement_eligible_at DT NULL`;`primary_refund_status STATE NN default 'none'`;`primary_refund_qty QTY`;`rule_snapshot JSON NN` + `SNAPSHOT` | `uk_order_product(order_product_id)`;`idx_user_status(user_id,status,cloud_order_item_id)`;`idx_choice(status,choice_deadline_at,cloud_order_item_id)`;`idx_pickup(status,pickup_deadline_at,cloud_order_item_id)`;`idx_batch(batch_id,status)` | | `eb_farm_cloud_freight_order` | `CORE` | `freight_order_no NO`;`cloud_order_item_id RID NN`;`user_id CID NN`;`choice_version/quote_version int unsigned NN`;`address_snapshot/freight_rule_snapshot/charge_basis_snapshot JSON NN`;`freight_template_id CID NULL`;`quote_hash HASH NN`;`freight_amount/paid_amount/callback_amount/refund_amount MONEY`;`business_status/pay_status/close_status/refund_status STATE NN`;`pay_type/pay_driver CODE NULL`;`provider_transaction_id varchar(96) NULL`;`pay_time/callback_at/expired_at/cancelled_at DT NULL`;`error_code varchar(64) NULL`;`error_message varchar(500) NULL` | `uk_freight_no(freight_order_no)`;`uk_provider_tx(provider_transaction_id)`(NULL 可重复);`idx_item_status(cloud_order_item_id,status)`;`idx_pay_repair(pay_status,update_time,cloud_freight_order_id)`;`idx_expiry(pay_status,expired_at,cloud_freight_order_id)`;`expired_at` 必须等于活动支付超时点和去向截止点的较早值 | | `eb_farm_cloud_freight_refund` | `CORE` | `freight_refund_no NO`;`freight_order_id RID NN`;`user_id CID NN`;`reason_type CODE NN`;`reason_snapshot JSON NN`;`refund_amount MONEY`;`pay_type/pay_driver CODE NN`;`provider_refund_id varchar(96) NULL`;`attempt_count smallint unsigned NN default 0`;`next_retry_at/requested_at/completed_at DT NULL`;`operator_type CODE NN`;`operator_id bigint unsigned NULL`;`error_code varchar(64) NULL`;`error_message varchar(500) NULL` | `uk_refund_no(freight_refund_no)`;`uk_freight(freight_order_id)`;`uk_provider_refund(provider_refund_id)`(NULL 可重复);`idx_retry(status,next_retry_at,cloud_freight_refund_id)` | | `eb_farm_cloud_pickup` | `CORE` | `pickup_no NO`;`cloud_order_item_id RID NN`;`user_id CID NN`;`pickup_point_id RID NN`;`pickup_point_snapshot JSON NN`;`pickup_qty/verified_qty/remaining_qty/refunded_qty/converted_shipping_qty/exception_buyback_qty QTY`;`voucher_code_hash HASH NN`;`voucher_version int unsigned NN`;`valid_from/expires_at/last_verified_at/overdue_at DT NULL`;`last_verified_by_type CODE NULL`;`last_verified_by_id bigint unsigned NULL`;`exception_event_id RID NULL` | `uk_pickup_no(pickup_no)`;`uk_item_active(cloud_order_item_id,status)`;`uk_voucher(voucher_code_hash,voucher_version)`;`idx_point_status(pickup_point_id,status,expires_at)` | | `eb_farm_cloud_pickup_verification` | `IMMUTABLE` | `verification_no NO`;`pickup_id RID NN`;`verified_qty/before_verified_qty/after_verified_qty QTY`;`voucher_version int unsigned NN`;`service_id CID NN`;`pickup_point_id RID NN`;`operation_type CODE NN default 'verify'`;`reversal_of_id RID NULL`;`evidence_hash HASH NULL`;`idempotency_key varchar(160) NN`;`occurred_at DT` | `uk_verification_no(verification_no)`;`uk_idempotency(idempotency_key)`;`idx_pickup_time(pickup_id,occurred_at,cloud_pickup_verification_id)`;`idx_reversal(reversal_of_id)` | | `eb_farm_cloud_holding` | `CORE` | `holding_no NO`;`user_id CID NN`;`batch_id/cloud_order_item_id RID NN`;`initial_qty/active_qty QTY`;`sold_equivalent_qty/unsold_equivalent_qty/buyback_equivalent_qty EQTY`;`unit_principal/total_principal/returned_principal/recognized_profit/settled_profit/buyback_amount/normal_refund_offset_amount/platform_risk_absorbed_amount MONEY`;`settlement_mode CODE NN`;`user_profit_rate/buyback_rate RATE NN`;`rule_snapshot JSON NN` + `SNAPSHOT` | `uk_holding_no(holding_no)`;`uk_order_item(cloud_order_item_id)`;`idx_user_status(user_id,status,cloud_holding_id)`;`idx_batch_status(batch_id,status,cloud_holding_id)` | | `eb_farm_cloud_primary_refund_impact` | `IMMUTABLE` | `refund_order_id CID NN`;`cloud_order_item_id RID NN`;`refund_qty QTY`;`refund_principal_amount MONEY`;`activity_return_qty/source_return_qty QTY`;`merchant_ledger_adjustment_id RID NULL`;`disposition_snapshot/inventory_snapshot JSON NN`;`idempotency_key varchar(160) NN`;`status STATE NN`;`occurred_at DT`;`reversal_of_id RID NULL` | `uk_refund_item(refund_order_id,cloud_order_item_id)`;`uk_idempotency(idempotency_key)`;`idx_item(cloud_order_item_id,occurred_at)` | `discount_amount` 在 V1 云仓首次订单强制为 `0.00`;`principal_amount=gross_goods_amount=goods_paid_amount`。`disposition` 只允许 `unselected/shipping/pickup/consign`,且最终关联 `shipping_fulfillment_id/pickup_id/holding_id` 至多一个非空。 ## 五、二次零售和进度 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_resale_stock` | `CORE` | `resale_stock_no NO`;`resale_product_id/resale_sku_value_id CID NN`;`resale_sku_unique_snapshot varchar(128) NN`;`stock_source CODE NN default 'cloud_only'`;`published_qty/available_qty/locked_qty/effective_sold_qty/returned_qty QTY`;`is_visible/is_saleable tinyint unsigned NN default 0`;`last_reconciled_at DT NULL` | `uk_resale_no(resale_stock_no)`;`uk_product_sku(resale_product_id,resale_sku_value_id)`;`idx_saleable(status,is_saleable,resale_stock_id)` | | `eb_farm_cloud_resale_allocation` | `CORE` | `secondary_group_order_id/secondary_order_id/secondary_order_product_id CID NN`;`resale_stock_id/batch_id RID NN`;`allocated_qty QTY`;`goods_paid_amount/platform_subsidy_amount/recognized_sales_amount MONEY`;`gross_effective_qty/reversed_qty/net_effective_qty QTY`;`effective_at/observation_end_at DT NULL`;`allocation_version int unsigned NN` | `uk_order_product_batch(secondary_order_product_id,batch_id)`;`idx_stock_status(resale_stock_id,status,cloud_resale_allocation_id)`;`idx_batch_status(batch_id,status,observation_end_at,cloud_resale_allocation_id)` | | `eb_farm_cloud_resale_refund_allocation` | `IMMUTABLE` | `secondary_refund_order_id/secondary_order_product_id CID NN`;`resale_allocation_id/batch_id RID NN`;`refund_qty QTY`;`refund_goods_amount/platform_subsidy_reversal/recognized_sales_reversal MONEY`;`status STATE NN`;`effective_at DT NULL`;`idempotency_key varchar(160) NN` | `uk_refund_allocation(secondary_refund_order_id,resale_allocation_id)`;`uk_idempotency(idempotency_key)`;`idx_batch(batch_id,create_time)` | | `eb_farm_cloud_batch_progress` | `IMMUTABLE` | `batch_id RID NN`;`trigger_type CODE NN`;`trigger_id RID NN`;`effective_sold_qty/consign_qty QTY`;`progress_rate decimal(9,4) NN`;`confirmed_sales_amount/sold_principal_amount/distributable_profit MONEY`;`previous_milestone/reached_milestone tinyint unsigned NN`;`crossed_milestones JSON NN`;`is_settlement_trigger tinyint unsigned NN default 0`;`calculation_version int unsigned NN`;`idempotency_key varchar(160) NN` | `uk_idempotency(idempotency_key)`;`idx_batch_version(batch_id,calculation_version,cloud_batch_progress_id)`;`idx_trigger(trigger_type,trigger_id)` | 一个 `group_order_id` 的所有子订单和明细必须指向同一 `finance_policy`。`resale_stock.stock_source` 固定为 `cloud_only`,不得与普通商品库存混算。 ## 六、用户账本、商户货款和回购 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_cloud_user_ledger` | `CORE` | `ledger_no NO`;`user_id CID NN`;`holding_id/batch_id RID NN`;`ledger_type/direction CODE NN`;`milestone varchar(16) NN`;`amount MONEY`;`cumulative_effective_qty EQTY`;`cumulative_due_amount/historical_ledger_amount/pending_posting_amount/rounding_adjustment_amount/normal_refund_offset_amount/platform_risk_absorbed_amount MONEY`;`calculation_version int unsigned NN`;`calculation_snapshot/platform_cost_policy_snapshot JSON NN`;`ledger_status/posting_status STATE NN`;`posting_id RID NULL`;`balance_bill_id CID NULL`;`idempotency_key varchar(160) NN`;`settled_at DT NULL` | `uk_ledger_no(ledger_no)`;`uk_idempotency(idempotency_key)`;`idx_user_status(user_id,ledger_status,cloud_user_ledger_id)`;`idx_posting(posting_status,status,cloud_user_ledger_id)`;`idx_batch(batch_id,holding_id,cloud_user_ledger_id)` | | `eb_farm_cloud_buyback` | `CORE` | `buyback_no NO`;`batch_id/holding_id RID NN`;`user_id CID NN`;`remaining_equivalent_qty EQTY`;`unit_principal/buyback_amount MONEY`;`buyback_rate RATE NN`;`calculation_snapshot JSON NN`;`calculation_version int unsigned NN`;`target_platform_product_id/target_platform_sku_id CID NN`;`platform_stock_flow_id/ledger_id RID NULL`;`prepared_by/reviewed_by/executed_by CID NULL`;`prepared_at/reviewed_at/executed_at/completed_at DT NULL`;`review_remark varchar(500) NULL`;`failure_step CODE NULL`;`last_error varchar(1000) NULL` | `uk_buyback_no(buyback_no)`;`uk_holding(holding_id)`;`idx_batch_status(batch_id,status,cloud_buyback_id)`;`idx_execute(status,update_time,cloud_buyback_id)` | | `eb_farm_merchant_supply_ledger` | `CORE` | `ledger_no NO`;`merchant_id CID NN`;`supply_id/batch_id/cloud_order_item_id RID NN`;`effective_qty QTY`;`supply_unit_price/gross_supply_amount/refund_deduction/merchant_charge_amount/settle_amount MONEY`;`warehouse_accepted_at/primary_completed_at/after_sale_end_at/eligible_at/settled_at DT NULL`;`eligible_reason CODE NULL`;`freeze_reason varchar(500) NULL`;`dispute_status STATE NN default 'none'`;`calculation_snapshot JSON NN`;`ledger_version int unsigned NN`;`ledger_status STATE NN`;`statement_item_id/posting_id RID NULL`;`financial_record_id CID NULL`;`idempotency_key varchar(160) NN` | `uk_ledger_no(ledger_no)`;`uk_idempotency(idempotency_key)`;`idx_eligible(ledger_status,eligible_at,merchant_id,merchant_supply_ledger_id)`;`idx_merchant_status(merchant_id,ledger_status,merchant_supply_ledger_id)` | | `eb_farm_merchant_supply_statement` | `CORE` | `statement_no NO`;`merchant_id CID NN`;`period_start/period_end DT NN`;`currency char(3) NN default 'CNY'`;`ledger_count int unsigned NN default 0`;`gross_amount/deduction_amount/settle_amount MONEY`;`posting_id RID NULL`;`financial_record_id CID NULL`;`generated_at/reviewed_at/posted_at DT NULL`;`reviewed_by CID NULL`;`review_remark varchar(500) NULL` | `uk_statement_no(statement_no)`;`uk_merchant_period(merchant_id,period_start,period_end,currency)`;`idx_status(status,period_end,merchant_supply_statement_id)` | | `eb_farm_merchant_supply_statement_item` | `IMMUTABLE` | `statement_id/merchant_supply_ledger_id RID NN`;`effective_qty QTY`;`supply_unit_price/gross_amount/deduction_amount/settle_amount MONEY`;`ledger_snapshot JSON NN` | `uk_ledger(merchant_supply_ledger_id)`;`idx_statement(statement_id,merchant_supply_statement_item_id)` | | `eb_farm_financial_posting` | `CORE` | `posting_no NO`;`posting_key varchar(160) NN`;`source_type CODE NN`;`source_id RID NN`;`source_version int unsigned NN`;`target_account_type CODE NN`;`target_id CID NN`;`direction CODE NN`;`amount/balance_before/balance_after MONEY`;`reversal_of_posting_id RID NULL`;`crm_bill_type CODE NULL`;`crm_bill_id CID NULL`;`attempt_count smallint unsigned NN default 0`;`last_error_code varchar(64) NULL`;`last_error_message varchar(1000) NULL`;`next_retry_at/lease_until/requested_at/processing_at/posted_at DT NULL`;`lease_owner varchar(96) NULL`;`operator_type CODE NN`;`operator_id bigint unsigned NULL` | `uk_posting_no(posting_no)`;`uk_posting_key(posting_key)`;`idx_retry(status,next_retry_at,financial_posting_id)`;`idx_lease(status,lease_until,financial_posting_id)`;`idx_source(source_type,source_id)`;`idx_target(target_account_type,target_id,posted_at)` | | `eb_farm_cloud_ledger_adjustment` | `CORE` | `adjustment_no NO`;`target_type CODE NN`;`target_id RID NN`;`adjustment_type CODE NN`;`reason_code CODE NN`;`reason varchar(1000) NN`;`evidence JSON NN`;`preview_snapshot JSON NN`;`requested_by/audited_by CID NULL`;`requested_at/audited_at/executed_at DT NULL`;`audit_remark varchar(500) NULL`;`executed_ledger_id RID NULL` | `uk_adjustment_no(adjustment_no)`;`idx_target(target_type,target_id,status)`;`idx_review(status,requested_at,cloud_ledger_adjustment_id)` | 正式入账表只存正数 `amount`,方向由 `direction` 表示。成功 posting 的金额、目标账户、CRMEB 流水和前后余额不可修改;更正必须新增 `reversal_of_posting_id` 指向原记录。 ## 七、农场、仓储、地块与套餐 ### 1. 农场资产主数据 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_farm` | `MASTER` | `farm_no NO`;`name varchar(120) NN`;`province_code/city_code/district_code varchar(16) NN`;`public_address varchar(255) NN`;`detail_address varchar(255) NULL`;`introduction longtext NULL`;`cover_image varchar(255) NULL`;`manager_admin_id CID NULL`;`longitude/latitude decimal(10,7) NULL`;`coordinate_system varchar(8) NULL`;`public_enabled tinyint unsigned NN default 0` | `uk_farm_no(farm_no)`;`idx_status(status,farm_id)`;`idx_manager(manager_admin_id,status)` | | `eb_farm_zone` | `MASTER` | `farm_id RID NN`;`zone_no varchar(40) NN`;`name varchar(120) NN`;`purpose_code CODE NN`;`area decimal(14,3) NN default 0.000`;`area_unit varchar(16) NN`;`schematic_image varchar(255) NULL`;`longitude/latitude decimal(10,7) NULL`;`coordinate_system varchar(8) NULL` | `uk_farm_zone(farm_id,zone_no)`;`idx_farm_status(farm_id,status,zone_id)` | | `eb_farm_plot` | `MASTER` | `farm_id/zone_id RID NN`;`plot_no varchar(40) NN`;`name varchar(120) NN`;`total_area/rentable_area decimal(14,3) NN`;`area_unit varchar(16) NN`;`soil_code/purpose_code CODE NULL`;`location_description varchar(500) NULL`;`schematic_image varchar(255) NULL`;`longitude/latitude decimal(10,7) NULL`;`coordinate_system varchar(8) NULL`;`maintenance_reason varchar(500) NULL` | `uk_farm_plot(farm_id,plot_no)`;`idx_zone_status(zone_id,status,plot_id)`;`idx_farm_status(farm_id,status,plot_id)` | | `eb_farm_warehouse` | `MASTER` | `warehouse_no NO`;`farm_id RID NN`;`name varchar(120) NN`;`warehouse_type CODE NN`;`manager_admin_id CID NULL`;`internal_address varchar(255) NULL`;`longitude/latitude decimal(10,7) NULL`;`coordinate_system varchar(8) NULL`;`temperature_rule varchar(255) NULL`;`purpose_description varchar(500) NULL` | `uk_warehouse_no(warehouse_no)`;`idx_farm_status(farm_id,status,warehouse_id)` | | `eb_farm_warehouse_location` | `MASTER` | `warehouse_id RID NN`;`location_no varchar(40) NN`;`name varchar(120) NN`;`zone_label/shelf_label/level_label varchar(64) NULL`;`allowed_category_codes JSON NN`;`capacity_description varchar(255) NULL` | `uk_warehouse_location(warehouse_id,location_no)`;`idx_warehouse_status(warehouse_id,status,warehouse_location_id)` | | `eb_farm_pickup_point` | `MASTER` | `pickup_point_no varchar(32) NN`;`owner_type CODE NN default 'platform'`;`owner_id bigint unsigned NN default 0`;`business_types JSON NN`(V1 仅 `['cloud']`);`name varchar(120) NN`;`province_code/city_code/district_code varchar(16) NN`;`public_address/detail_address varchar(255) NN`;`business_hours JSON NN`;`contact_name varchar(80) NN`;`contact_phone varchar(32) NN`;`longitude/latitude decimal(10,7) NULL`;`coordinate_system varchar(8) NULL`;`capacity_description varchar(255) NULL` | `uk_pickup_no(pickup_point_no)`;`idx_owner_status(status,owner_type,owner_id,pickup_point_id)` | 坐标字段必须同时为空或同时非空;启用且公开的农场、自提点必须为合法 `GCJ02`。仓库和库位只在 `ADM-AG-003` 标签中维护。 ### 2. 地块占用、作物和租地 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_plot_occupancy` | `CORE` | `occupancy_no NO`;`plot_id/land_order_id RID NN`;`planting_batch_id RID NULL`;`allocation_type CODE NN`;`occupied_area decimal(14,3) NN`;`area_unit varchar(16) NN`;`start_at/end_at DT NN`;`reservation_token_hash HASH NULL`;`reserved_by_type CODE NULL`;`reserved_by bigint unsigned NULL`;`locked_at/lock_expires_at/actual_end_at DT NULL` | `uk_occupancy_no(occupancy_no)`;`uk_reservation_token(reservation_token_hash)`(NULL 可重复);`idx_plot_overlap(plot_id,status,start_at,end_at,plot_occupancy_id)`;`idx_expiry(status,lock_expires_at,plot_occupancy_id)`;`idx_order(land_order_id,status)` | | `eb_farm_crop` | `MASTER` | `crop_no NO`;`name varchar(120) NN`;`variety varchar(120) NULL`;`expected_cycle_days smallint unsigned NN`;`unit_code varchar(16) NN`;`cover_image varchar(255) NULL`;`default_task_template JSON NULL` | `uk_crop_no(crop_no)`;`uk_name_variety(name,variety)`;`idx_status(status,crop_id)` | | `eb_farm_land_plan` | `MASTER` | `plan_no NO`;`name varchar(160) NN`;`farm_id RID NN`;`zone_id RID NULL`;`allocation_mode CODE NN`;`area decimal(14,3) NN`;`area_unit varchar(16) NN`;`cycle_days smallint unsigned NN`;`price/service_value_amount/delivery_value_amount MONEY`;`promised_qty/min_promised_qty QTY`;`promised_unit varchar(16) NN`;`capacity_qty QTY`;`delay_tolerance_days smallint unsigned NN default 7`;`exception_confirmation_days smallint unsigned NN default 3`;`shipping_rule/exception_rule/service_snapshot/agreement_snapshot JSON NN`;`publish_version int unsigned NN default 0`;`published_at DT NULL` | `uk_plan_no(plan_no)`;`idx_farm_status(farm_id,status,land_plan_id)`;`idx_publish(status,published_at,land_plan_id)` | | `eb_farm_land_plan_crop` | `CORE` | `land_plan_id/crop_id RID NN`;`is_default tinyint unsigned NN default 0`;`service_price_delta MONEY`;`sort int NN default 0` | `uk_plan_crop(land_plan_id,crop_id)`;`idx_crop(crop_id,status)` | | `eb_farm_land_order` | `CORE` | `land_order_no NO`;`group_order_id/order_id/order_product_id CID NN`;`user_id CID NN`;`plan_id/crop_id RID NN`;`current_occupancy_id RID NULL`;`promised_qty/delivered_qty/refunded_unfulfilled_qty QTY`;`promised_unit varchar(16) NN`;`service_refund_base_amount/delivery_refund_base_amount/refunded_unfulfilled_amount MONEY`;`delay_tolerance_days smallint unsigned NN`;`exception_confirmation_days smallint unsigned NN default 3`;`allocated_at/production_started_at/expected_harvest_at/completed_at DT NULL`;`rule_snapshot JSON NN` + `SNAPSHOT` | `uk_land_no(land_order_no)`;`uk_order_product(order_product_id)`;`idx_user_status(user_id,status,land_order_id)`;`idx_plan_status(plan_id,status,land_order_id)`;`idx_allocation(status,land_order_id)` | `start_at < end_at`,`occupied_area > 0` 且不超地块可租面积。V1 不用单纯唯一索引代替时间重叠检查;确认事务锁地块主行后重查。 租地与认养套餐均满足 `price = service_value_amount + delivery_value_amount`。`delay_tolerance_days` 只允许 `0/3/7/15/30`;订单退款基数按订单明细商品实付同比例计算,且 `service_refund_base_amount + delivery_refund_base_amount = goods_paid_amount`。 ## 八、认养资产、套餐和订单 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_adoption_category` | `MASTER` | `category_no NO`;`name varchar(120) NN`;`default_allocation_mode CODE NN`;`sort int NN default 0` | `uk_category_no(category_no)`;`uk_name(name)` | | `eb_farm_breed` | `MASTER` | `breed_no NO`;`category_id RID NN`;`species_name/breed_name varchar(120) NN`;`expected_cycle_days smallint unsigned NN`;`expected_output_snapshot JSON NN`;`cover_image varchar(255) NULL` | `uk_breed_no(breed_no)`;`uk_category_breed(category_id,breed_name)`;`idx_status(status,breed_id)` | | `eb_farm_enclosure` | `MASTER` | `enclosure_no NO`;`farm_id/zone_id RID NN`;`name varchar(120) NN`;`enclosure_type CODE NN`;`capacity_qty QTY`;`unit_code varchar(16) NN`;`current_qty QTY`;`health_status STATE NN`;`maintenance_reason varchar(500) NULL` | `uk_enclosure_no(enclosure_no)`;`idx_farm_status(farm_id,status,enclosure_id)`;`idx_zone(zone_id,status)` | | `eb_farm_animal_asset` | `MASTER` | `asset_no NO`;`breed_id/enclosure_id RID NN`;`ear_tag_no/chip_no varchar(80) NULL`;`birth_date/entry_date date NULL`;`sex_code CODE NULL`;`health_status STATE NN`;`allocation_status STATE NN`;`photo_snapshot JSON NULL`;`current_breeding_batch_id RID NULL` | `uk_asset_no(asset_no)`;`uk_ear_tag(ear_tag_no)`(NULL 可重复);`uk_chip(chip_no)`(NULL 可重复);`idx_enclosure_status(enclosure_id,status,animal_asset_id)`;`idx_allocation(allocation_status,health_status,animal_asset_id)` | | `eb_farm_breeding_batch` | `MASTER` | `batch_no NO`;`breed_id/enclosure_id RID NN`;`total_qty/allocatable_share_qty/reserved_share_qty/allocated_share_qty QTY`;`unit_code varchar(16) NN`;`start_at/expected_end_at/actual_end_at DT NULL`;`health_status STATE NN` | `uk_batch_no(batch_no)`;`idx_enclosure_status(enclosure_id,status,breeding_batch_id)`;`idx_capacity(status,health_status,breeding_batch_id)` | | `eb_farm_adoption_plan` | `MASTER` | `plan_no NO`;`name varchar(160) NN`;`breed_id/farm_id RID NN`;`enclosure_id/breeding_batch_id RID NULL`;`allocation_mode CODE NN`;`cycle_days smallint unsigned NN`;`price/service_value_amount/delivery_value_amount MONEY`;`capacity_qty QTY`;`promised_qty/min_promised_qty QTY`;`promised_unit varchar(16) NN`;`delay_tolerance_days smallint unsigned NN default 7`;`exception_confirmation_days smallint unsigned NN default 3`;`shipping_rule/exception_rule/replacement_rule/service_snapshot/agreement_snapshot JSON NN`;`publish_version int unsigned NN default 0`;`published_at DT NULL` | `uk_plan_no(plan_no)`;`idx_farm_status(farm_id,status,adoption_plan_id)`;`idx_breed_mode(breed_id,allocation_mode,status)` | | `eb_farm_adoption_order` | `CORE` | `adoption_order_no NO`;`group_order_id/order_id/order_product_id CID NN`;`user_id CID NN`;`plan_id RID NN`;`allocation_mode CODE NN`;`current_allocation_id RID NULL`;`promised_qty/delivered_qty/refunded_unfulfilled_qty QTY`;`promised_unit varchar(16) NN`;`service_refund_base_amount/delivery_refund_base_amount/refunded_unfulfilled_amount MONEY`;`delay_tolerance_days smallint unsigned NN`;`exception_confirmation_days smallint unsigned NN default 3`;`allocated_at/production_started_at/expected_output_at/completed_at DT NULL`;`rule_snapshot JSON NN` + `SNAPSHOT` | `uk_adoption_no(adoption_order_no)`;`uk_order_product(order_product_id)`;`idx_user_status(user_id,status,adoption_order_id)`;`idx_plan_status(plan_id,status,adoption_order_id)` | | `eb_farm_adoption_allocation` | `CORE` | `allocation_no NO`;`adoption_order_id RID NN`;`allocation_mode CODE NN`;`animal_asset_id/breeding_batch_id RID NULL`;`share_qty QTY`;`reservation_token_hash HASH NULL`;`reserved_by_type CODE NULL`;`reserved_by bigint unsigned NULL`;`locked_at/lock_expires_at/effective_from/effective_to DT NULL`;`replaces_allocation_id RID NULL`;`replacement_reason varchar(500) NULL` | `uk_allocation_no(allocation_no)`;`uk_reservation_token(reservation_token_hash)`(NULL 可重复);`idx_asset_active(animal_asset_id,status,effective_to)`;`idx_batch_active(breeding_batch_id,status,effective_to)`;`idx_order(adoption_order_id,status)`;`idx_expiry(status,lock_expires_at,adoption_allocation_id)` | | `eb_farm_asset_replacement` | `IMMUTABLE` | `exception_id RID NN`;`adoption_order_id RID NN`;`old_allocation_id/new_allocation_id RID NN`;`old_asset_id/new_asset_id RID NULL`;`reason_code CODE NN`;`reason_snapshot JSON NN`;`effective_at DT`;`idempotency_key varchar(160) NN` | `uk_idempotency(idempotency_key)`;`uk_new_allocation(new_allocation_id)`;`idx_order(adoption_order_id,create_time)` | 单体模式必须仅 `animal_asset_id` 非空且 `share_qty=1.000`;份额模式必须仅 `breeding_batch_id` 非空且 `share_qty>0`。有效+预留份额不得超过 `allocatable_share_qty`。 ## 九、生产、任务、产出和履约 ### 1. 生产与任务 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_production_batch` | `CORE` | `batch_no NO`;`production_type CODE NN`;`farm_id RID NN`;`zone_id RID NULL`;`plan_start_at/plan_end_at DT NN`;`actual_start_at/actual_end_at DT NULL`;`expected_output_qty/actual_output_qty QTY`;`output_unit varchar(16) NN`;`manager_id CID NULL`;`current_stage_code CODE NULL`;`has_open_exception tinyint unsigned NN default 0`;`suspended_from STATE NULL` | `uk_batch_no(batch_no)`;`idx_farm_status(farm_id,status,production_batch_id)`;`idx_manager(manager_id,status,plan_end_at)` | | `eb_farm_production_plant_detail` | `CORE` | `production_batch_id/plot_occupancy_id/crop_id RID NN`;`planting_area decimal(14,3) NN`;`area_unit varchar(16) NN`;`planting_method CODE NULL`;`growth_stage_code CODE NULL`;`seed_batch_no varchar(80) NULL` | `uk_production(production_batch_id)`;`idx_occupancy(plot_occupancy_id)` | | `eb_farm_production_livestock_detail` | `CORE` | `production_batch_id/enclosure_id/breed_id RID NN`;`breeding_batch_id RID NULL`;`livestock_mode CODE NN`;`current_qty QTY`;`unit_code varchar(16) NN`;`growth_stage_code CODE NULL` | `uk_production(production_batch_id)`;`idx_enclosure(enclosure_id,status)`;`idx_breeding_batch(breeding_batch_id,status)` | | `eb_farm_production_right_link` | `CORE` | `production_batch_id RID NN`;`business_type CODE NN`;`business_id RID NN`;`plot_occupancy_id/adoption_allocation_id RID NULL`;`right_rate RATE NN default 10000`;`promised_qty QTY`;`promised_unit varchar(16) NN` | `uk_production_right(production_batch_id,business_type,business_id)`;`idx_business(business_type,business_id,status)` | | `eb_farm_task` | `CORE` | `task_no NO`;`task_type CODE NN`;`farm_id RID NN`;`zone_id RID NULL`;`target_type CODE NN`;`target_id RID NN`;`production_batch_id/output_batch_id/fulfillment_id RID NULL`;`planned_at/due_at/completed_at DT NULL`;`requirement_snapshot JSON NN`;`assignee_service_id CID NULL`;`priority tinyint unsigned NN default 3`;`scope_version int unsigned NULL` | `uk_task_no(task_no)`;`idx_assignee(assignee_service_id,status,due_at,task_id)`;`idx_target(target_type,target_id,status)`;`idx_farm(farm_id,status,due_at)` | | `eb_farm_task_assignment` | `IMMUTABLE` | `task_id RID NN`;`from_service_id/to_service_id CID NULL`;`duty_code CODE NN`;`scope_snapshot JSON NN`;`reason_code CODE NN`;`reason varchar(500) NULL`;`assigned_by_type CODE NN`;`assigned_by bigint unsigned NN`;`started_at DT`;`ended_at DT NULL`;`assignment_version int unsigned NN` | `uk_task_version(task_id,assignment_version)`;`idx_service(to_service_id,ended_at,task_id)` | | `eb_farm_production_event` | `CORE` | `event_no NO`;`production_batch_id RID NN`;`task_id/animal_asset_id RID NULL`;`event_type CODE NN`;`current_version_id RID NULL`;`review_status/publish_status STATE NN`;`occurred_at DT NN` | `uk_event_no(event_no)`;`idx_batch_time(production_batch_id,occurred_at,production_event_id)`;`idx_review(review_status,status,production_event_id)` | | `eb_farm_production_event_version` | `IMMUTABLE` | `production_event_id RID NN`;`version_no int unsigned NN`;`occurred_at DT NN`;`operator_service_id CID NULL`;`content longtext NN`;`material_snapshot JSON NULL`;`visibility CODE NN`;`submitted_by/reviewed_by CID NULL`;`submitted_at/reviewed_at DT NULL`;`review_remark varchar(500) NULL`;`content_hash HASH NN`;`status STATE NN` | `uk_event_version(production_event_id,version_no)`;`uk_content_hash(production_event_id,content_hash)`;`idx_review(status,submitted_at,production_event_version_id)` | ### 2. 产出、库存和分配 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_output_batch` | `CORE` | `output_no NO`;`production_batch_id RID NN`;`output_type CODE NN`;`product_name varchar(160) NN`;`spec varchar(160) NULL`;`unit_code varchar(16) NN`;`total_qty/pending_inspection_qty/qualified_qty/rejected_qty/loss_qty/available_qty/allocated_qty/shipped_qty/cancelled_qty/frozen_qty/disposed_qty QTY`;`produced_at/expire_at DT NULL`;`quality_status STATE NN`;`warehouse_id/warehouse_location_id RID NULL`;`quality_snapshot JSON NULL` | `uk_output_no(output_no)`;`idx_production(production_batch_id,status,output_batch_id)`;`idx_available(status,available_qty,output_batch_id)`;`idx_expiry(status,expire_at,output_batch_id)` | | `eb_farm_output_inventory_flow` | `IMMUTABLE` | `output_batch_id RID NN`;`unit_code varchar(16) NN`;`pool_from/pool_to CODE NULL`;`change_qty/before_qty/after_qty QTY`;`business_type CODE NN`;`business_id RID NN`;`idempotency_key varchar(160) NN`;`occurred_at DT`;`operator_type CODE NN`;`operator_id bigint unsigned NULL` | `uk_idempotency(idempotency_key)`;`idx_output_time(output_batch_id,occurred_at,output_inventory_flow_id)`;`idx_business(business_type,business_id)` | | `eb_farm_output_allocation` | `CORE` | `output_batch_id RID NN`;`business_type CODE NN`;`business_id RID NN`;`allocated_qty QTY`;`unit_code varchar(16) NN`;`fulfillment_id RID NULL`;`allocation_sequence int unsigned NN`;`calculation_version int unsigned NN`;`idempotency_key varchar(160) NN` | `uk_idempotency(idempotency_key)`;`uk_business_sequence(business_type,business_id,allocation_sequence)`;`idx_output_status(output_batch_id,status,output_allocation_id)`;`idx_business(business_type,business_id,status)` | ### 3. 履约、包裹和农业运费 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_fulfillment` | `CORE` | `fulfillment_no NO`;`business_type CODE NN`;`business_id RID NN`;`user_id CID NN`;`sequence_no int unsigned NN`;`planned_qty/shipped_qty/completed_qty/refunded_qty QTY`;`unit_code varchar(16) NN`;`address_status STATE NN`;`address_version int unsigned NN default 0`;`address_snapshot JSON NULL`;`freight_rule_snapshot JSON NN`;`split_reason CODE NN default 'normal'`;`freight_payer CODE NN`;`delivery_type CODE NN default 'express'`;`current_freight_order_id RID NULL`;`address_due_at/receive_due_at/next_reminder_at/completed_at DT NULL` | `uk_fulfillment_no(fulfillment_no)`;`uk_business_sequence(business_type,business_id,sequence_no)`;`idx_user_status(user_id,status,fulfillment_id)`;`idx_reminder(status,next_reminder_at,fulfillment_id)`;`idx_address_due(status,address_due_at,fulfillment_id)`;`idx_receive_due(status,receive_due_at,fulfillment_id)` | | `eb_farm_fulfillment_item` | `CORE` | `fulfillment_id/output_allocation_id/output_batch_id RID NN`;`unit_code varchar(16) NN`;`planned_qty/outbound_qty/returned_qty/refunded_qty QTY` | `uk_fulfillment_allocation(fulfillment_id,output_allocation_id)`;`idx_output(output_batch_id,status)` | | `eb_farm_fulfillment_package` | `CORE` | `package_no NO`;`fulfillment_id RID NN`;`carrier_code varchar(32) NULL`;`tracking_no varchar(80) NULL`;`package_qty QTY`;`weight decimal(14,3) NULL`;`weight_unit varchar(16) NULL`;`shipped_at/received_at DT NULL`;`shipping_evidence JSON NULL` | `uk_package_no(package_no)`;`uk_carrier_tracking(carrier_code,tracking_no)`(NULL 可重复);`idx_fulfillment(fulfillment_id,status,fulfillment_package_id)` | | `eb_farm_fulfillment_package_item` | `IMMUTABLE` | `package_id/fulfillment_item_id RID NN`;`qty QTY`;`unit_code varchar(16) NN` | `uk_package_item(package_id,fulfillment_item_id)`;`idx_item(fulfillment_item_id)` | | `eb_farm_fulfillment_freight_order` | `CORE` | `freight_order_no NO`;`fulfillment_id RID NN`;`user_id CID NN`;`address_version/quote_version int unsigned NN`;`address_snapshot/freight_rule_snapshot/charge_basis_snapshot JSON NN`;`quote_hash HASH NN`;`freight_amount/paid_amount/refund_amount MONEY`;`business_status/pay_status/refund_status STATE NN`;`pay_type/pay_driver CODE NULL`;`provider_transaction_id/provider_refund_id varchar(96) NULL`;`expired_at/paid_at/refunded_at DT NULL`;`error_code varchar(64) NULL`;`error_message varchar(500) NULL` | `uk_freight_no(freight_order_no)`;`uk_provider_tx(provider_transaction_id)`(NULL 可重复);`idx_fulfillment(fulfillment_id,status)`;`idx_repair(pay_status,refund_status,update_time,fulfillment_freight_order_id)` | 农业运费支付 `attach` 固定为 `farm_output_freight`。农业产出只使用快递履约,不写 `eb_farm_cloud_pickup`。 ## 十、溯源与统一异常 ### 1. 溯源 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_trace_archive` | `CORE` | `trace_no NO`;`public_code varchar(48) NN`;`archive_type CODE NN`;`farm_id/production_batch_id/output_batch_id RID NULL`;`current_draft_version_id/current_published_version_id RID NULL`;`public_summary varchar(500) NULL` | `uk_trace_no(trace_no)`;`uk_public_code(public_code)`;`uk_source(archive_type,production_batch_id,output_batch_id)`;`idx_status(status,trace_archive_id)` | | `eb_farm_trace_version` | `IMMUTABLE` | `archive_id RID NN`;`version_no int unsigned NN`;`title varchar(160) NN`;`public_snapshot JSON NN`;`content_hash HASH NN`;`submitted_by/reviewed_by/published_by/withdrawn_by CID NULL`;`submitted_at/reviewed_at/published_at/withdrawn_at DT NULL`;`review_remark/withdraw_reason varchar(500) NULL`;`status STATE NN` | `uk_archive_version(archive_id,version_no)`;`uk_archive_hash(archive_id,content_hash)`;`idx_review(status,submitted_at,trace_version_id)` | | `eb_farm_trace_material` | `CORE` | `archive_id/version_id RID NN`;`material_type CODE NN`;`material_no varchar(80) NULL`;`attachment_id CID NN`(逻辑引用 `eb_system_attachment.attachment_id`);`issuer varchar(160) NULL`;`effective_at/expire_at DT NULL`;`content_hash HASH NN`;`display_name varchar(160) NN` | `idx_archive_version(archive_id,version_id,status)`;`idx_expiry(status,expire_at,trace_material_id)`;`idx_attachment(attachment_id)` | | `eb_farm_trace_link` | `CORE` | `archive_id/version_id RID NN`;`target_type CODE NN`;`target_id bigint unsigned NN`;`relation_type CODE NN`;`valid_from/valid_to DT NULL`;`source_type CODE NN` | `uk_relation(archive_id,version_id,target_type,target_id,relation_type)`;`idx_target(target_type,target_id,status)` | `public_code` 使用不可枚举随机值,不编码内部 ID。撤回不删除档案、版本、材料或二维码入口。 ### 2. 统一异常与执行步骤 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_exception_event` | `CORE` | `event_no NO`;`business_domain CODE NN`;`event_type CODE NN`;`farm_id/production_batch_id RID NULL`;`severity tinyint unsigned NN`;`sla_due_at DT NN`;`owner_type CODE NULL`;`owner_id bigint unsigned NULL`;`reason longtext NN`;`fact_snapshot JSON NN`;`freeze_flags JSON NN`;`current_impact_version int unsigned NN default 0`;`current_plan_version_id RID NULL`;`resolved_at/closed_at DT NULL` | `uk_event_no(event_no)`;`idx_sla(status,sla_due_at,exception_event_id)`;`idx_owner(owner_type,owner_id,status)`;`idx_farm(farm_id,status,exception_event_id)` | | `eb_farm_exception_impact` | `CORE` | `exception_id RID NN`;`impact_version int unsigned NN`;`target_type CODE NN`;`target_id bigint unsigned NN`;`impact_type CODE NN`;`impact_qty QTY`;`impact_amount MONEY`;`unit_code varchar(16) NULL`;`before_snapshot/expected_snapshot JSON NN`;`calculated_at DT NN` | `uk_impact(exception_id,impact_version,target_type,target_id,impact_type)`;`idx_target(target_type,target_id,status)` | | `eb_farm_exception_plan_version` | `IMMUTABLE` | `exception_id RID NN`;`version_no int unsigned NN`;`impact_version int unsigned NN`;`plan_type CODE NN`;`plan_snapshot/expected_result_snapshot/equivalence_snapshot/allocation_snapshot JSON NN`;`affected_qty/refund_qty QTY`;`service_refund_base_amount/delivery_refund_base_amount/cumulative_refund_due/current_refund_amount MONEY`;`requires_user_confirm tinyint unsigned NN default 0`;`confirmation_deadline_at/confirmed_at DT NULL`;`confirmation_result/timeout_policy CODE NULL`;`submitted_by/reviewed_by/confirmed_by CID NULL`;`submitted_at/reviewed_at DT NULL`;`review_remark varchar(500) NULL`;`precheck_hash HASH NULL`;`precheck_expire_at DT NULL`;`status STATE NN` | `uk_exception_version(exception_id,version_no)`;`idx_review(status,submitted_at,exception_plan_version_id)`;`idx_confirm(status,confirmation_deadline_at,exception_plan_version_id)` | | `eb_farm_exception_execution_step` | `CORE` | `exception_id/plan_version_id RID NN`;`step_order smallint unsigned NN`;`step_code CODE NN`;`is_required tinyint unsigned NN default 1`;`input_snapshot/before_snapshot/after_snapshot/compensation_snapshot JSON NULL`;`result_key varchar(160) NN`;`attempt_count smallint unsigned NN default 0`;`next_retry_at/started_at/completed_at DT NULL`;`error_code varchar(64) NULL`;`error_message varchar(1000) NULL` | `uk_plan_step(exception_id,plan_version_id,step_code)`;`uk_result_key(result_key)`;`idx_execute(status,next_retry_at,exception_execution_step_id)`;`idx_plan_order(plan_version_id,step_order)` | 异常影响和方案必须版本化。执行步骤只能使用 `33` 中允许的 `step_code`,不得把任意 SQL、类名、URL 或脚本保存为可执行参数。 ## 十一、订单绑定、幂等、事件和运维支撑 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_order_binding` | `CORE` | `group_order_id/order_id/order_product_id CID NN`;`user_id CID NN`;`merchant_id CID NULL`;`business_type/aggregate_type CODE NN`;`aggregate_id RID NN`;`finance_policy/stock_policy/fulfillment_policy CODE NN`;`payment_status/refund_status STATE NN` | `uk_order_product(order_product_id)`;`idx_group(group_order_id,finance_policy,status)`;`idx_order(order_id,status)`;`idx_aggregate(business_type,aggregate_type,aggregate_id)`;`idx_payment(payment_status,status,binding_id)` | | `eb_farm_idempotency_record` | `CORE` | `operation_code CODE NN`;`actor_type CODE NN`;`actor_id bigint unsigned NN`;`request_id char(36) NN`;`request_hash HASH NN`;`response_status varchar(16) NULL`;`response_snapshot JSON NULL`;`target_type/result_type CODE NULL`;`target_id/result_id bigint unsigned NULL`;`locked_until/expired_at DT NULL` | `uk_http_idempotency(operation_code,actor_type,actor_id,request_id)`;`idx_lease(status,locked_until,idempotency_record_id)`;`idx_expire(status,expired_at,idempotency_record_id)` | | `eb_farm_domain_outbox` | `CORE` | `event_id char(26) NN`;`event_type varchar(96) NN`;`event_version smallint unsigned NN`;`aggregate_type CODE NN`;`aggregate_id bigint unsigned NN`;`aggregate_version int unsigned NN`;`trace_id char(26) NN`;`source CODE NN`;`payload JSON NN`;`occurred_at/published_at/next_retry_at/lease_until DT NULL`;`retry_count smallint unsigned NN default 0`;`lease_owner varchar(96) NULL`;`last_error varchar(1000) NULL` | `uk_event_id(event_id)`;`idx_dispatch(status,next_retry_at,event_id)`;`idx_lease(status,lease_until,event_id)`;`idx_aggregate(aggregate_type,aggregate_id,occurred_at)` | | `eb_farm_event_consume_log` | `CORE` | `event_id char(26) NN`;`consumer_name varchar(96) NN`;`event_type varchar(96) NN`;`event_version smallint unsigned NN`;`started_at/finished_at/next_retry_at DT NULL`;`duration_ms int unsigned NULL`;`retry_count smallint unsigned NN default 0`;`result_business_key varchar(160) NULL`;`last_error varchar(1000) NULL` | `uk_event_consumer(event_id,consumer_name)`;`idx_retry(status,next_retry_at,event_consume_log_id)`;`idx_result(result_business_key)` | | `eb_farm_job_run` | `CORE` | `job_name varchar(96) NN`;`run_key varchar(160) NN`;`scheduled_for DT NN`;`timezone varchar(40) NN default 'Asia/Shanghai'`;`shard_key varchar(80) NULL`;`selector_snapshot JSON NN`;`cursor_value varchar(255) NULL`;`lease_owner varchar(96) NULL`;`lease_until/timeout_at/next_retry_at/started_at/finished_at DT NULL`;`retry_count smallint unsigned NN default 0`;`scanned_count/success_count/failed_count int unsigned NN default 0`;`last_error varchar(1000) NULL` | `uk_job_run(job_name,run_key)`;`idx_lease(status,lease_until,job_run_id)`;`idx_retry(status,next_retry_at,job_run_id)`;`idx_job_time(job_name,scheduled_for,job_run_id)` | | `eb_farm_notification_log` | `CORE` | `template_code varchar(64) NN`;`channel CODE NN`;`receiver_type CODE NN`;`receiver_id bigint unsigned NN`;`business_type CODE NN`;`business_id bigint unsigned NN`;`business_key varchar(160) NN`;`content_snapshot JSON NN`;`provider_message_id varchar(128) NULL`;`scheduled_at/sent_at/next_retry_at DT NULL`;`retry_count smallint unsigned NN default 0`;`last_error varchar(1000) NULL` | `uk_notification(template_code,channel,receiver_type,receiver_id,business_key)`;`idx_send(status,scheduled_at,notification_log_id)`;`idx_business(business_type,business_id)` | | `eb_farm_audit_log` | `IMMUTABLE` | `operator_type CODE NN`;`operator_id bigint unsigned NULL`;`action_code CODE NN`;`target_type CODE NN`;`target_id bigint unsigned NN`;`before_snapshot/after_snapshot JSON NULL`;`reason_code CODE NULL`;`reason varchar(1000) NULL`;`request_id char(36) NULL`;`trace_id char(26) NN`;`ip varchar(45) NULL`;`user_agent varchar(500) NULL`;`occurred_at DT` | `idx_target(target_type,target_id,occurred_at,audit_log_id)`;`idx_operator(operator_type,operator_id,occurred_at,audit_log_id)`;`idx_trace(trace_id)` | | `eb_farm_state_transition` | `IMMUTABLE` | `aggregate_type CODE NN`;`aggregate_id bigint unsigned NN`;`from_status/to_status STATE NULL`;`event_code varchar(96) NULL`;`operation_code CODE NN`;`aggregate_version int unsigned NN`;`idempotency_key varchar(160) NN`;`operator_type CODE NN`;`operator_id bigint unsigned NULL`;`reason_code CODE NULL`;`reason_snapshot JSON NULL`;`occurred_at DT` | `uk_transition(aggregate_type,aggregate_id,idempotency_key)`;`idx_aggregate_time(aggregate_type,aggregate_id,occurred_at,state_transition_id)`;`idx_event(event_code,occurred_at)` | | `eb_farm_async_operation` | `CORE` | `operation_no NO`;`operation_type CODE NN`;`target_type CODE NN`;`target_id bigint unsigned NULL`;`requested_by_type CODE NN`;`requested_by_id bigint unsigned NN`;`request_key varchar(160) NN`;`progress_total/progress_done/success_count/failure_count int unsigned NN default 0`;`current_step CODE NULL`;`result_summary JSON NULL`;`result_file_id CID NULL`(逻辑引用 `eb_system_attachment.attachment_id`);`error_code varchar(64) NULL`;`error_message varchar(1000) NULL`;`lease_owner varchar(96) NULL`;`lease_until/next_retry_at/started_at/finished_at DT NULL` | `uk_operation_no(operation_no)`;`uk_request_key(request_key)`;`idx_owner(requested_by_type,requested_by_id,status,async_operation_id)`;`idx_lease(status,lease_until,async_operation_id)` | `CORE` 模板中的业务 `status` 不替代该表自身列出的细分状态;实现时只保留一列 `status`,不得重复创建 `ledger_status`/`status` 等含义冲突列。对于账本等确需业务状态与 posting 状态并存的表,分别保留明确命名。 ## 十二、服务人员、平台范围和证据 | 表 | 模板 | 业务列(类型、空值、默认) | 唯一键/索引 | | --- | --- | --- | --- | | `eb_farm_service_profile` | 自定义 | `profile_id PK`;`service_id CID NN`;`farm_enabled/mobile_enabled tinyint unsigned NN default 0`;`default_workspace varchar(20) NN default 'chat'`;`scope_version int unsigned NN default 1`;`last_scope_change_at DT NULL`;`create_time DT`;`update_time DT NULL` | `uk_service(service_id)` | | `eb_farm_service_scope` | 自定义 | `scope_id PK`;`service_id CID NN`;`merchant_id CID NN default 0`;`duty_code varchar(40) NN`;`scope_type CODE NN`;`scope_object_id bigint unsigned NN default 0`;`valid_from DT NN`;`valid_to DT NULL`;`status tinyint unsigned NN default 1`;`created_by_type CODE NN`;`created_by_id bigint unsigned NN`;`revoke_reason varchar(255) NULL`;`create_time DT`;`update_time DT NULL` | `uk_service_duty_scope(service_id,duty_code,scope_type,scope_object_id)`;`idx_service_valid(service_id,status,valid_from,valid_to)`;`idx_scope_object(scope_type,scope_object_id,status)` | | `eb_farm_admin_scope` | 自定义 | `scope_id PK`;`admin_id CID NN`;`domain_code CODE NN`;`scope_type CODE NN`;`scope_object_id bigint unsigned NN default 0`;`valid_from DT NN`;`valid_to DT NULL`;`status tinyint unsigned NN default 1`;`scope_set_version int unsigned NN`;`version VER`;`created_by/updated_by CID NN`;`create_time DT`;`update_time DT NULL` | `uk_admin_domain_scope(admin_id,domain_code,scope_type,scope_object_id)`;`idx_admin_scope_valid(admin_id,domain_code,status,valid_from,valid_to)`;`idx_scope_object(scope_type,scope_object_id,status)`;`idx_admin_set_version(admin_id,scope_set_version)` | | `eb_farm_evidence_attachment` | 自定义 | `attachment_id PK`;`attachment_no varchar(32) NN`;`service_id CID NN`;`merchant_id CID NN default 0`;`task_id RID NULL`;`scope_object_type CODE NN`;`scope_object_id bigint unsigned NN`;`storage_type tinyint unsigned NN`;`storage_path varchar(512) NN`;`original_name varchar(255) NN`;`mime_type varchar(100) NN`;`file_ext varchar(20) NN`;`file_size bigint unsigned NN`;`content_hash HASH NN`;`business_type CODE NULL`;`business_id bigint unsigned NULL`;`status STATE NN`;`expires_at/bound_at DT NULL`;`create_time DT`;`update_time DT NULL` | `uk_attachment_no(attachment_no)`;`idx_owner(service_id,status,create_time)`;`idx_expire(status,expires_at,attachment_id)`;`idx_business(business_type,business_id)`;`idx_hash(content_hash)` | `eb_system_attachment.attachment_id` 与 `eb_farm_evidence_attachment.attachment_id` 是两个独立 ID 域:平台/商户商品材料、供货材料、溯源材料和异步结果文件使用前者;服务/现场端离线草稿与证据绑定使用后者。所有 DTO 和 Repository 必须按字段语义分别校验归属,禁止只凭同名数值互换。 权限菜单决定“能否调用”,scope 表决定“能操作哪条数据”。对象越界时详情和写命令统一按不存在处理;内部审计记录真实拒绝原因。 管理员范围唯一键表示一个范围对象始终复用同一行。重新授权已停用范围时更新该行的 `status/valid_from/valid_to/updated_by/version/scope_set_version`;不得插入第二行。一次全量保存的新增、保留、停用和重新启用行统一写相同的新 `scope_set_version`,完整前后历史进入 `eb_farm_audit_log`。 ## 十三、迁移分组与依赖 | 顺序 | migration 组 | 表/变更 | 验证 | | --- | --- | --- | --- | | `M01` | 兼容预检 | CRMEB 金额列容量、服务账号空值/重复 | 全部通过才继续 | | `M02` | 核心支撑 | idempotency、outbox、consume log、job run、audit、transition、async operation | 唯一键和租约扫描 `EXPLAIN` | | `M03` | 权限附件 | service/admin scope、service profile、evidence attachment | 越权/空范围/过期范围 | | `M04` | 农场主数据 | farm、zone、plot、warehouse、location、pickup、crop、认养基础表 | 编号唯一、坐标、停用引用 | | `M05` | 商品/供货 | product profile/material、supply/delivery/inspection/material/return/acquisition | 数量方程、来源 SKU、退回/承接结果键 | | `M06` | 云仓活动库存 | activity/product/sku/quota/batch/pool/flow/resale stock | 活动发布和库存守恒 | | `M07` | 订单与交易 | binding、首次明细、运费/退款、自提、持仓、二次分配/退款/进度 | 创建/支付/取消/退款回归 | | `M08` | 财务 | 用户/商户账本、结单/明细、posting、adjustment、buyback | 入账唯一键和精度算例 | | `M09` | 权益生产 | land/adoption order、occupancy/allocation、production/task/event | 并发预留、替换历史 | | `M10` | 产出履约 | output/flow/allocation、fulfillment/item/package/freight | 数量方程、多包裹、运费 | | `M11` | 异常溯源 | exception/impact/plan/step/replacement、trace 四表 | 版本、步骤结果键、稳定二维码 | | `M12` | 菜单配置 | `system_menu`、权限码、配置项;不写业务交易数据 | 四端菜单与权限矩阵 | ### 回退边界 - `M02~M12` 尚无业务事实时可按逆序移除新表;有任一业务事实后只允许应用版本前滚,禁止删表回滚。 - 可空适配列可在确认无引用后删除;扩大后的 CRMEB 金额列和已经依赖的唯一账号约束不自动缩回。 - 菜单可停用,权限和业务历史不可通过删菜单清除。 ## 十四、字段字典验收 - 每个 `15` 中出现的 `eb_farm_*` 表在本文件恰好有一条物理定义。 - 每个 Model/DAO/Repository 都能在 `21`、`35` 找到对应表;不得出现无表模型或无模型核心表。 - 每个写操作的事务写集都能定位到具体列、唯一键和索引。 - 每个 Job 选择器和游标都有本文件冻结的组合索引。 - 所有金额、数量、比例、状态、时间、快照和操作者列均有明确类型与空值规则。 - migration 注释必须列出状态常量来源,不在 DDL 中复制一套可能漂移的中文状态。 - 开发前执行表名、列名和索引名静态核对;开发完成后在全新库和升级副本各跑一次 migration/verify。 ## 十五、关联文档 - [15-v1-data-model-draft.md](15-v1-data-model-draft) - [31-v1-write-operation-contract-registry.md](31-v1-write-operation-contract-registry) - [32-v1-event-job-operation-registry.md](32-v1-event-job-operation-registry) - [33-v1-state-exception-transaction-matrix.md](33-v1-state-exception-transaction-matrix) - [35-v1-page-api-file-trace.md](35-v1-page-api-file-trace)