AdoS6FlowAuthorityMigrationLog.cs 4.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. namespace Admin.NET.Plugin.AiDOP.Entity.S6;
  2. /// <summary>
  3. /// S6-LEGACY-SNAPSHOT-MIGRATION-1:S6 存量运行中实例的审批权威快照迁移留证。
  4. ///
  5. /// <para><b>为什么必须留证</b>:<c>ApprovalFlowInstance</c> 没有 version、没有 checksum、
  6. /// 没有并发令牌,<c>UpdateTime</c> 也不是 DB 自动列 —— 裸 UPDATE 之后
  7. /// <b>无法证明改过什么、为什么改、改前是什么</b>。而 <c>FlowJsonSnapshot</c> 同时是
  8. /// 通用审批中心渲染历史流程图的数据源(<c>FlowInstanceService</c> 对外暴露 →
  9. /// 前端 <c>center/index.vue</c> 与 <c>ApprovalPanel.vue</c> 消费)。
  10. /// 没有这张表,这就是一次无法解释的静默改写。</para>
  11. ///
  12. /// <para><b>与 <c>AdoS8ApprovalFlowRepairLog</c> 的关键差异:本表 append-only。</b>
  13. /// S8 那张表每轮 <c>DELETE FROM ... WHERE true</c> 后整体重写(它描述的是「最近一次对账看到了什么」),
  14. /// 迁移留证不能是这种语义 —— 迁移是**一次性历史事件**,记录一旦写下就不允许被后续运行抹掉,
  15. /// 否则回滚依据会随时间消失。故本表独立建立,不复用 S8 那张。</para>
  16. ///
  17. /// <para><b>幂等不依赖本表。</b>「是否已迁」的判据是快照自身内容(Role 节点的 approverIds
  18. /// 是否还存在纯数字 token),不是「本表里有没有这条 InstanceId」——
  19. /// 留证一旦丢失就重复改写,是 S8 先例踩过的坑。</para>
  20. /// </summary>
  21. [SugarTable("ado_s6_flow_authority_migration_log", "S6 存量流程审批权威迁移留证(append-only)")]
  22. public class AdoS6FlowAuthorityMigrationLog
  23. {
  24. [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true, ColumnDataType = "bigint")]
  25. public long Id { get; set; }
  26. /// <summary>迁移批次标识,同一次执行的所有记录共用,便于整批回滚定位。</summary>
  27. [SugarColumn(ColumnName = "migration_batch", Length = 64)]
  28. public string MigrationBatch { get; set; } = string.Empty;
  29. [SugarColumn(ColumnName = "instance_id", ColumnDataType = "bigint")]
  30. public long InstanceId { get; set; }
  31. [SugarColumn(ColumnName = "biz_type", Length = 64)]
  32. public string BizType { get; set; } = string.Empty;
  33. [SugarColumn(ColumnName = "biz_id", ColumnDataType = "bigint")]
  34. public long BizId { get; set; }
  35. /// <summary>由业务实体反查得到,**不取登录用户租户**(实例表自身无 TenantId 列)。</summary>
  36. [SugarColumn(ColumnName = "effective_tenant_id", ColumnDataType = "bigint")]
  37. public long EffectiveTenantId { get; set; }
  38. /// <summary>改前快照全文,逐字保留 —— 第一回滚来源。</summary>
  39. [SugarColumn(ColumnName = "before_snapshot", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
  40. public string? BeforeSnapshot { get; set; }
  41. /// <summary>改后快照全文。回滚前用它比对「现值确实是我改成的那样」。</summary>
  42. [SugarColumn(ColumnName = "after_snapshot", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
  43. public string? AfterSnapshot { get; set; }
  44. [SugarColumn(ColumnName = "before_md5", Length = 32, IsNullable = true)]
  45. public string? BeforeMd5 { get; set; }
  46. [SugarColumn(ColumnName = "after_md5", Length = 32, IsNullable = true)]
  47. public string? AfterMd5 { get; set; }
  48. /// <summary>逐节点映射:<c>node=N2_SUP_REVIEW;1329916010002=&gt;ROLE_S6_IPQC_SUPERVISOR@848643233415237</c>。</summary>
  49. [SugarColumn(ColumnName = "authority_mapping", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
  50. public string? AuthorityMapping { get; set; }
  51. /// <summary>第二回滚来源:可反查出原始 FlowJson 的 ApprovalFlowVersion 行 Id。</summary>
  52. [SugarColumn(ColumnName = "rollback_source", Length = 128, IsNullable = true)]
  53. public string? RollbackSource { get; set; }
  54. /// <summary>为什么改 / 为什么没改:判据与依据。</summary>
  55. [SugarColumn(ColumnName = "reason", Length = 1024, IsNullable = true)]
  56. public string? Reason { get; set; }
  57. /// <summary>APPLIED / SKIPPED_ALREADY_MIGRATED / BLOCKED_TARGET_AUTHORITY / BLOCKED_ROLLBACK_SOURCE / BLOCKED_CONCURRENT_MODIFICATION。</summary>
  58. [SugarColumn(ColumnName = "outcome", Length = 48)]
  59. public string Outcome { get; set; } = string.Empty;
  60. [SugarColumn(ColumnName = "created_at")]
  61. public DateTime CreatedAt { get; set; } = DateTime.Now;
  62. }