Skip to content

Commit 515446f

Browse files
Restore legacy visibility metadata on Waterline v2 reads
Restore legacy visibility metadata on Waterline v2 reads
1 parent 3372144 commit 515446f

5 files changed

Lines changed: 86 additions & 0 deletions

File tree

app/Http/Controllers/WorkflowsController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Waterline\Support\ActionabilityContract;
2424
use Waterline\Support\ActionabilityVisibilityFilters;
2525
use Waterline\Support\CompatibilitySemantics;
26+
use Waterline\Support\VisibilityMetadataBridge;
2627
use Waterline\Waterline;
2728

2829
class WorkflowsController extends Controller
@@ -625,6 +626,10 @@ private function listResponse(string $bucket, WorkflowRepositoryInterface $repos
625626
private function listItemView(WorkflowRunSummary $summary): array
626627
{
627628
$item = RunListItemView::fromSummary($summary);
629+
$item['search_attributes'] = VisibilityMetadataBridge::preserve(
630+
$item['search_attributes'] ?? null,
631+
$summary->getRawOriginal('search_attributes'),
632+
);
628633
$item['history_budget_indicator'] = $this->historyBudgetIndicator($item);
629634
$item = CompatibilitySemantics::annotateListItem($item);
630635
$item['actionability'] = ActionabilityContract::annotateRun($item)['actionability'];

app/Http/Resources/V2StoredWorkflowResource.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Waterline\Support\ActionabilityContract;
99
use Waterline\Support\CompatibilitySemantics;
1010
use Waterline\Support\RunDiagnostics;
11+
use Waterline\Support\VisibilityMetadataBridge;
1112

1213
/**
1314
* @mixin WorkflowRun
@@ -26,6 +27,7 @@ public function toArray($request)
2627
$this->resource,
2728
$this->timelineLimit($request),
2829
);
30+
$detail = $this->withLegacyVisibilityMetadata($detail);
2931
$detail = $this->withTimelineWindow($detail, $request);
3032
$detail['run_diagnostics'] = app(RunDiagnostics::class)->forRun($this->resource, $detail);
3133
$detail = CompatibilitySemantics::annotateRun($detail);
@@ -64,6 +66,29 @@ private function withTimelineWindow(array $detail, $request): array
6466
return $detail;
6567
}
6668

69+
/**
70+
* @param array<string, mixed> $detail
71+
*
72+
* @return array<string, mixed>
73+
*/
74+
private function withLegacyVisibilityMetadata(array $detail): array
75+
{
76+
$summary = $this->resource->summary;
77+
78+
$detail['memo'] = VisibilityMetadataBridge::preserve(
79+
$detail['memo'] ?? null,
80+
$this->resource->getRawOriginal('memo'),
81+
$this->resource->instance?->getRawOriginal('memo'),
82+
);
83+
$detail['search_attributes'] = VisibilityMetadataBridge::preserve(
84+
$detail['search_attributes'] ?? null,
85+
$summary?->getRawOriginal('search_attributes'),
86+
$this->resource->getRawOriginal('search_attributes'),
87+
);
88+
89+
return $detail;
90+
}
91+
6792
private function timelineLimit($request): ?int
6893
{
6994
$requested = $request->query('history_limit', self::DEFAULT_TIMELINE_WINDOW);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Waterline\Support;
4+
5+
final class VisibilityMetadataBridge
6+
{
7+
/**
8+
* Preserve legacy JSON visibility metadata when the resolved workflow package
9+
* returns an empty typed view for persisted runs or summaries.
10+
*
11+
* @return array<string, mixed>
12+
*/
13+
public static function preserve(mixed $current, mixed ...$legacyCandidates): array
14+
{
15+
if (is_array($current) && $current !== []) {
16+
return $current;
17+
}
18+
19+
foreach ($legacyCandidates as $candidate) {
20+
$decoded = self::decode($candidate);
21+
22+
if ($decoded !== []) {
23+
return $decoded;
24+
}
25+
}
26+
27+
return is_array($current) ? $current : [];
28+
}
29+
30+
/**
31+
* @return array<string, mixed>
32+
*/
33+
private static function decode(mixed $value): array
34+
{
35+
if (is_array($value)) {
36+
return $value;
37+
}
38+
39+
if (! is_string($value) || $value === '') {
40+
return [];
41+
}
42+
43+
$decoded = json_decode($value, true);
44+
45+
return is_array($decoded) ? $decoded : [];
46+
}
47+
}

tests/Feature/V2DashboardWorkflowListTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public function testRunningFlowsUseConfiguredRunSummaryModel(): void
6161
'class' => 'WorkflowClass',
6262
'workflow_type' => 'workflow.test',
6363
'business_key' => 'configured-list-business',
64+
'search_attributes' => [
65+
'customer_tier' => 'gold',
66+
],
6467
'status' => RunStatus::Waiting->value,
6568
'status_bucket' => 'running',
6669
'started_at' => $startedAt,
@@ -77,6 +80,7 @@ public function testRunningFlowsUseConfiguredRunSummaryModel(): void
7780
->assertJsonPath('data.0.id', $run->id)
7881
->assertJsonPath('data.0.business_key', 'configured-list-business')
7982
->assertJsonPath('data.0.workflow_type', 'workflow.test')
83+
->assertJsonPath('data.0.search_attributes.customer_tier', 'gold')
8084
->assertJsonPath('data.0.actionability.schema', 'waterline.actionability')
8185
->assertJsonPath('data.0.actionability.repair_state', 'unknown')
8286
->assertJsonPath('visibility_filters.actionability_contract.version', 1)
@@ -1156,6 +1160,7 @@ private function createConfiguredSummaryTable(): void
11561160
$table->string('class');
11571161
$table->string('workflow_type');
11581162
$table->string('business_key')->nullable();
1163+
$table->json('search_attributes')->nullable();
11591164
$table->string('declared_entry_mode')->nullable();
11601165
$table->string('declared_contract_source')->nullable();
11611166
$table->boolean('repair_attention')->default(false);

tests/Feature/V2DashboardWorkflowTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,9 @@ public function testShowUsesConfiguredSummaryAndHistoryModels(): void
14321432
'id' => 123,
14331433
],
14341434
],
1435+
'search_attributes' => [
1436+
'customer_tier' => 'gold',
1437+
],
14351438
'arguments' => Serializer::serialize([]),
14361439
'connection' => 'redis',
14371440
'queue' => 'default',
@@ -1490,6 +1493,7 @@ public function testShowUsesConfiguredSummaryAndHistoryModels(): void
14901493
->assertJsonPath('business_key', 'configured-waterline-business')
14911494
->assertJsonPath('memo.customer.name', 'Taylor')
14921495
->assertJsonPath('memo.order.id', 123)
1496+
->assertJsonPath('search_attributes.customer_tier', 'gold')
14931497
->assertJsonPath('declared_contract_source', 'durable_history')
14941498
->assertJsonPath('declared_signals.0', 'configured-waterline-signal')
14951499
->assertJsonPath('workflow_definition_fingerprint', 'configured-waterline-fingerprint');

0 commit comments

Comments
 (0)