Skip to content

Commit 5b825fb

Browse files
committed
fix(schema): migrate v4 — await_mechanism column for upgraded installs
Task 7 added await_mechanism to the canonical long_processes schema and ProcessRepository writes it unconditionally, but DDD_SCHEMA_VERSION stayed at 3. ddd_maybe_migrate()'s fast path bails for any consumer already at v3, so dbDelta never re-runs and the column never lands — every process insert/update then silently fails (return value ignored) and sagas never persist. Fresh installs were unaffected (dbDelta covers the full schema on install), which is why existing tests passed. Bump DDD_SCHEMA_VERSION to 4 and add the v4 explicit migration entry using the existing v2/v3 idiom (ddd_add_column_if_missing), so consumers parked at v3 get healed on their next admin_init. Verified against the shared ddev DB: all real consumers were recorded at v3 with the column genuinely missing — this is not a theoretical gap.
1 parent 6b10736 commit 5b825fb

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

ddd-wordpress/migrations.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
* - 1: original 6 tables
3333
* - 2: command_audit gains causation_id + causation_type (+ idx_causation)
3434
* - 3: behaviour_workflows gains correlation_id (+ idx_correlation)
35+
* - 4: long_processes gains await_mechanism
3536
*/
36-
const DDD_SCHEMA_VERSION = 3;
37+
const DDD_SCHEMA_VERSION = 4;
3738

3839
/**
3940
* Per-prefix option holding the installed schema version.
@@ -83,6 +84,15 @@ function ddd_explicit_migrations(): array {
8384
ddd_add_column_if_missing($table, 'correlation_id', 'CHAR(36) NULL', 'is_failed');
8485
ddd_add_index_if_missing($table, 'idx_correlation', '`correlation_id`');
8586
},
87+
88+
// v4 — await_mechanism on long_processes. Additive; dbDelta covers fresh
89+
// installs; explicit entry guarantees the column for consumers already at
90+
// v3, whose fast-path in ddd_maybe_migrate() would otherwise never
91+
// re-run dbDelta and leave ProcessRepository writing to a missing column.
92+
4 => static function (IDDDConfig $config): void {
93+
$table = $config->table('long_processes');
94+
ddd_add_column_if_missing($table, 'await_mechanism', 'JSON NULL', 'match_criteria');
95+
},
8696
];
8797
}
8898

tests/Unit/WordPress/MigrationsTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
namespace TangibleDDD\Tests\Unit\WordPress;
44

55
use PHPUnit\Framework\TestCase;
6+
use TangibleDDD\Tests\Fakes\FakeDDDConfig;
67

8+
use function TangibleDDD\WordPress\ddd_explicit_migrations;
79
use function TangibleDDD\WordPress\ddd_pending_migrations;
810

11+
use const TangibleDDD\WordPress\DDD_SCHEMA_VERSION;
12+
913
// migrations.php is a procedural ddd-wordpress file; load it directly for the
1014
// pure-logic test (no WP/DB needed for ddd_pending_migrations).
1115
if (!function_exists('TangibleDDD\\WordPress\\ddd_pending_migrations')) {
@@ -39,4 +43,36 @@ public function test_installed_ahead_never_runs_backward(): void {
3943
// Downgrade / weird state must not produce negative or backward work.
4044
$this->assertSame([], ddd_pending_migrations(3, 2));
4145
}
46+
47+
public function test_current_schema_version_is_4(): void {
48+
// Regression guard for the v3-fast-path bug: a consumer already recorded
49+
// as v3 must NOT be treated as up to date once await_mechanism ships.
50+
$this->assertSame(4, DDD_SCHEMA_VERSION);
51+
}
52+
53+
public function test_v4_migration_adds_await_mechanism_after_match_criteria_on_long_processes(): void {
54+
$migrations = ddd_explicit_migrations();
55+
$this->assertArrayHasKey(4, $migrations, 'ddd_explicit_migrations() must define a v4 entry so consumers already at v3 actually get the column.');
56+
57+
// Spy wpdb: report the column as absent (get_var => 0) so the guarded
58+
// helper proceeds to the ALTER, and capture the SQL it issues.
59+
$spy = new class extends \wpdb {
60+
public array $queries = [];
61+
public function get_var(?string $query = null, int $x = 0, int $y = 0) {
62+
return 0;
63+
}
64+
public function query(string $query) {
65+
$this->queries[] = $query;
66+
return true;
67+
}
68+
};
69+
$GLOBALS['wpdb'] = $spy;
70+
71+
$migrations[4](new FakeDDDConfig());
72+
73+
$this->assertCount(1, $spy->queries);
74+
$this->assertStringContainsString('wp_test_long_processes', $spy->queries[0]);
75+
$this->assertStringContainsString('ADD COLUMN `await_mechanism` JSON NULL', $spy->queries[0]);
76+
$this->assertStringContainsString('AFTER `match_criteria`', $spy->queries[0]);
77+
}
4278
}

0 commit comments

Comments
 (0)