吸收数字员工跨设备调度派发策略冲突预览
This commit is contained in:
@@ -51,6 +51,16 @@ public class DigitalEmployeePolicySnapshotRowDto {
|
||||
private Boolean autoDecisionDisabled;
|
||||
@JsonProperty("policy_reason")
|
||||
private String policyReason;
|
||||
@JsonProperty("dispatch_policy_key")
|
||||
private String dispatchPolicyKey;
|
||||
@JsonProperty("max_per_sweep")
|
||||
private Long maxPerSweep;
|
||||
@JsonProperty("auto_dispatch_ready_steps")
|
||||
private Boolean autoDispatchReadySteps;
|
||||
@JsonProperty("catch_up_on_startup")
|
||||
private Boolean catchUpOnStartup;
|
||||
@JsonProperty("max_run_history")
|
||||
private Long maxRunHistory;
|
||||
@JsonProperty("sync_record_url")
|
||||
private String syncRecordUrl;
|
||||
@JsonProperty("client_key_masked")
|
||||
|
||||
@@ -614,6 +614,11 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye
|
||||
.batchAcceptRemoteDisabled(nullableBooleanValue(firstPresent(latestView.get("batch_accept_remote_disabled"), latestView.get("batchAcceptRemoteDisabled"))))
|
||||
.autoDecisionDisabled(nullableBooleanValue(firstPresent(latestView.get("auto_decision_disabled"), latestView.get("autoDecisionDisabled"))))
|
||||
.policyReason(firstString(latestView.get("policy_reason"), latestView.get("policyReason")))
|
||||
.dispatchPolicyKey(firstString(latestView.get("dispatch_policy_key"), latestView.get("dispatchPolicyKey")))
|
||||
.maxPerSweep(numberValue(firstPresent(latestView.get("max_per_sweep"), latestView.get("maxPerSweep"))))
|
||||
.autoDispatchReadySteps(nullableBooleanValue(firstPresent(latestView.get("auto_dispatch_ready_steps"), latestView.get("autoDispatchReadySteps"))))
|
||||
.catchUpOnStartup(nullableBooleanValue(firstPresent(latestView.get("catch_up_on_startup"), latestView.get("catchUpOnStartup"))))
|
||||
.maxRunHistory(numberValue(firstPresent(latestView.get("max_run_history"), latestView.get("maxRunHistory"))))
|
||||
.syncRecordUrl(syncRecordUrl(latest.getOutboxId()))
|
||||
.clientKeyMasked(maskClientKey(latest.getClientKey()))
|
||||
.deviceId(latest.getDeviceId())
|
||||
@@ -687,7 +692,9 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye
|
||||
"policy_source",
|
||||
"auto_create_governance_commands",
|
||||
"max_per_sweep",
|
||||
"auto_dispatch_ready_steps",
|
||||
"catch_up_on_startup",
|
||||
"max_run_history",
|
||||
"approval_required_risk_levels",
|
||||
"approval_required_actions",
|
||||
"auto_reject_actions",
|
||||
|
||||
@@ -1882,6 +1882,82 @@ class DigitalEmployeeSyncApplicationServiceImplTest {
|
||||
assertThat(row.getRecommendedResolution()).isEqualTo("review_latest_policy_snapshot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryAdminPolicySnapshotsSummarizesDispatchAndSchedulerPolicyConflicts() {
|
||||
DigitalEmployeeSyncRecord dispatchA = record("outbox-dispatch-policy-a", "event", "event-dispatch-policy-a", 101L, new Date(10_000),
|
||||
Map.of(
|
||||
"entity_type", "event",
|
||||
"category", "policy_snapshot",
|
||||
"kind", "plan_step_dispatch_policy_pulled",
|
||||
"policy_kind", "dispatch",
|
||||
"policy_key", "plan_step_dispatch",
|
||||
"enabled", true,
|
||||
"max_per_sweep", 3,
|
||||
"auto_dispatch_ready_steps", true,
|
||||
"dispatch_policy_key", "plan_step_dispatch"
|
||||
),
|
||||
Map.of("kind", "plan_step_dispatch_policy_pulled"));
|
||||
dispatchA.setDeviceId("device-a");
|
||||
DigitalEmployeeSyncRecord dispatchB = record("outbox-dispatch-policy-b", "event", "event-dispatch-policy-b", 101L, new Date(11_000),
|
||||
Map.of(
|
||||
"entity_type", "event",
|
||||
"category", "policy_snapshot",
|
||||
"kind", "plan_step_dispatch_policy_pulled",
|
||||
"policy_kind", "dispatch",
|
||||
"policy_key", "plan_step_dispatch",
|
||||
"enabled", true,
|
||||
"max_per_sweep", 8,
|
||||
"auto_dispatch_ready_steps", false,
|
||||
"dispatch_policy_key", "plan_step_dispatch"
|
||||
),
|
||||
Map.of("kind", "plan_step_dispatch_policy_pulled"));
|
||||
dispatchB.setDeviceId("device-b");
|
||||
DigitalEmployeeSyncRecord schedulerA = record("outbox-scheduler-policy-a", "event", "event-scheduler-policy-a", 101L, new Date(12_000),
|
||||
Map.of(
|
||||
"entity_type", "event",
|
||||
"category", "policy_snapshot",
|
||||
"kind", "scheduler_policy_snapshot",
|
||||
"policy_kind", "scheduler",
|
||||
"policy_key", "scheduler",
|
||||
"enabled", true,
|
||||
"catch_up_on_startup", true,
|
||||
"max_run_history", 20
|
||||
),
|
||||
Map.of("kind", "scheduler_policy_snapshot"));
|
||||
schedulerA.setDeviceId("device-a");
|
||||
DigitalEmployeeSyncRecord schedulerB = record("outbox-scheduler-policy-b", "event", "event-scheduler-policy-b", 101L, new Date(13_000),
|
||||
Map.of(
|
||||
"entity_type", "event",
|
||||
"category", "policy_snapshot",
|
||||
"kind", "scheduler_policy_snapshot",
|
||||
"policy_kind", "scheduler",
|
||||
"policy_key", "scheduler",
|
||||
"enabled", true,
|
||||
"catch_up_on_startup", false,
|
||||
"max_run_history", 50
|
||||
),
|
||||
Map.of("kind", "scheduler_policy_snapshot"));
|
||||
schedulerB.setDeviceId("device-b");
|
||||
|
||||
when(repository.queryBusinessRecords(eq(101L), eq(null), eq(null), eq("event"), eq(null), eq(null), eq(null), eq(null), eq(1L), eq(100L)))
|
||||
.thenReturn(page(List.of(dispatchA, dispatchB, schedulerA, schedulerB)));
|
||||
|
||||
DigitalEmployeePolicySnapshotPageDto dispatchResult = service.queryAdminPolicySnapshots(null, null, "conflict", "dispatch", null, null, 1L, 20L);
|
||||
DigitalEmployeePolicySnapshotPageDto schedulerResult = service.queryAdminPolicySnapshots(null, null, "conflict", "scheduler", null, null, 1L, 20L);
|
||||
|
||||
DigitalEmployeePolicySnapshotRowDto dispatchRow = dispatchResult.getRecords().get(0);
|
||||
assertThat(dispatchRow.getPolicyKind()).isEqualTo("dispatch");
|
||||
assertThat(dispatchRow.getConflictKeys()).contains("max_per_sweep", "auto_dispatch_ready_steps");
|
||||
assertThat(dispatchRow.getDispatchPolicyKey()).isEqualTo("plan_step_dispatch");
|
||||
assertThat(dispatchRow.getMaxPerSweep()).isEqualTo(8L);
|
||||
assertThat(dispatchRow.getAutoDispatchReadySteps()).isFalse();
|
||||
DigitalEmployeePolicySnapshotRowDto schedulerRow = schedulerResult.getRecords().get(0);
|
||||
assertThat(schedulerRow.getPolicyKind()).isEqualTo("scheduler");
|
||||
assertThat(schedulerRow.getConflictKeys()).contains("catch_up_on_startup", "max_run_history");
|
||||
assertThat(schedulerRow.getCatchUpOnStartup()).isFalse();
|
||||
assertThat(schedulerRow.getMaxRunHistory()).isEqualTo(50L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordDailyReportSendResultStoresRecordedObservation() {
|
||||
DigitalEmployeeAdminRecordRequestDto request = adminRecordRequest("daily_report", "report-1");
|
||||
|
||||
Reference in New Issue
Block a user