Просмотр исходного кода

test(s8): add debug cleanup for watch mapping fixtures

YY968XX 3 месяцев назад
Родитель
Сommit
9b7e038dea

+ 21 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S8/AdoS8WatchDebugController.cs

@@ -48,4 +48,25 @@ public class AdoS8WatchDebugController : ControllerBase
             })
         });
     }
+
+    /// <summary>
+    /// S2-EW:仅供 e2e fixture 使用的 TEST_G09_ 数据软删入口。
+    /// 安全契约:
+    /// - 与 run-once 共用 _debugEndpointEnabled;未启用时 404。
+    /// - tenantId / factoryId 必须显式传入(无默认值),缺参由 ASP.NET 返回 400。
+    /// - 前缀 TEST_G09_ 在 service 端硬编码,本接口不接受 prefix 入参。
+    /// - 仅 soft delete(SET IsDeleted=true),不触发物理 DELETE。
+    /// </summary>
+    [HttpDelete("test-cleanup")]
+    public async Task<IActionResult> TestCleanupAsync(
+        [FromQuery] long? tenantId,
+        [FromQuery] long? factoryId,
+        [FromServices] S8ExceptionService exceptionSvc)
+    {
+        if (!_debugEndpointEnabled) return NotFound();
+        if (tenantId is null || factoryId is null)
+            return BadRequest(new { message = "tenantId and factoryId are required (no defaults)." });
+        var deletedCount = await exceptionSvc.SoftDeleteTestPrefixAsync(tenantId.Value, factoryId.Value);
+        return Ok(new { deletedCount });
+    }
 }

+ 24 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/S8ExceptionService.cs

@@ -209,4 +209,28 @@ public class S8ExceptionService : ITransient
             }
         }
     }
+
+    /// <summary>
+    /// S2-EW:debug-only 软删 RelatedObjectCode 以 "TEST_G09_" 开头的异常。
+    /// 调用方仅限 <see cref="Controllers.S8.AdoS8WatchDebugController"/>,由其 _debugEndpointEnabled 守门。
+    /// 实现纪律:
+    /// - 仅 SET IsDeleted=true,不动业务字段(status/closed_at/source_rule_id 等)。
+    /// - 前缀字面量硬编码,不接受外部 prefix;防止前缀注入。
+    /// - 不联动 timeline / decision / evidence;业务读路径以父 IsDeleted 屏蔽。
+    /// </summary>
+    public async Task<int> SoftDeleteTestPrefixAsync(long tenantId, long factoryId)
+    {
+        const string prefix = "TEST_G09_";
+        var affected = await _rep.AsUpdateable()
+            .SetColumns(e => new AdoS8Exception { IsDeleted = true })
+            .Where(e => e.TenantId == tenantId
+                     && e.FactoryId == factoryId
+                     && !e.IsDeleted
+                     && e.RelatedObjectCode != null
+                     && e.RelatedObjectCode.StartsWith(prefix))
+            .ExecuteCommandAsync();
+        System.Diagnostics.Trace.TraceWarning(
+            $"[S2-EW] soft-deleted {affected} TEST_G09_ exceptions, tenant={tenantId} factory={factoryId}");
+        return affected;
+    }
 }