feat(workflow-executor): add RunStore implementations (InMemoryStore + DatabaseStore)#1506
Merged
matthv merged 11 commits intofeat/prd-214-setup-workflow-executor-packagefrom Mar 25, 2026
Conversation
|
Coverage Impact Unable to calculate total coverage change because base branch coverage was not found. Modified Files with Diff Coverage (5)
🤖 Increase coverage with AI coding...🚦 See full report on Qlty Cloud » 🛟 Help
|
Member
Author
|
Both Macroscope comments addressed in 29f7cba:
14 tests pass, lint clean. |
Scra3
reviewed
Mar 25, 2026
c788c67 to
e772931
Compare
…+ DatabaseStore) - InMemoryStore: simple Map-based store for unit tests - DatabaseStore: Sequelize-based store with auto-migration via umzug - Single table `workflow_step_executions` with JSON `data` column - Indexed by `run_id` for fast lookups, unique on `(run_id, step_index)` - Dialect-agnostic upsert (delete + insert) - Migration applied automatically at startup via `store.migrate()` - 13 tests (SQLite for DatabaseStore, pure unit for InMemoryStore) fixes PRD-221 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wrap DELETE + INSERT in a transaction to make upsert atomic (Macroscope) - Sort InMemoryStore results by stepIndex to match DatabaseStore contract (Macroscope) - Add ordering test for InMemoryStore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…config
Runner now accepts either:
- runStore: RunStore (injected, as before)
- database: { dialect, uri } (Runner creates DatabaseStore + auto-migrates on start)
DatabaseStore is closed on stop(). Both options are mutually exclusive
via a discriminated union on RunnerConfig.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add init() and close() to RunStore interface
- InMemoryStore: no-op init/close
- DatabaseStore: rename migrate() → init()
- Remove Sequelize/DatabaseStore knowledge from Runner (no more union type)
- Runner calls runStore.init() on start and runStore.close() on stop
- Add factory functions buildDatabaseRunStore / buildInMemoryRunStore
- RunnerConfig back to simple { runStore: RunStore }
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
If store.init() throws, close the Sequelize connection before re-throwing to avoid leaking a database connection. (Macroscope) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add tests verifying that Runner.start() calls runStore.init() and Runner.stop() calls runStore.close(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…files RunStore interface now requires init() and close(). Update all makeMockRunStore/createMockRunStore helpers across test files to include these methods as jest.fn() no-ops. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2f5b4e1 to
a36fce9
Compare
…atabaseRunStore Replace custom DatabaseConfig with Sequelize's own Options type. Callers now pass standard Sequelize options (dialect, storage, host, etc.) directly. logging: false is applied as default. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scra3
reviewed
Mar 25, 2026
Comment on lines
+70
to
+73
| init: jest.fn().mockResolvedValue(undefined), | ||
| close: jest.fn().mockResolvedValue(undefined), | ||
| init: jest.fn().mockResolvedValue(undefined), | ||
| close: jest.fn().mockResolvedValue(undefined), |
- RunStore interface: init() and close() now accept optional Logger - DatabaseStore: logs migration failures in init(), catches and logs close() errors instead of throwing - Runner passes its logger to runStore.init() and runStore.close() - Fix duplicate init/close mocks from rebase conflict Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scra3
approved these changes
Mar 25, 2026
After PR #1503 moved userConfirmed from ExecutionContext to pendingData, these tests still passed it in makeContext(). Remove all occurrences. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
packages/workflow-executor/test/executors/trigger-record-action-step-executor.test.ts
Show resolved
Hide resolved
…tests After PR #1503 moved userConfirmed from ExecutionContext to pendingData, the Branch A confirmation tests were missing userConfirmed in their mock execution pendingData — causing all confirmation flows to return awaiting-input instead of proceeding. - Add userConfirmed: true to accepted/error-path tests - Add userConfirmed: false to rejected tests - Update "no execution found" tests to expect awaiting-input Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
50583e8
into
feat/prd-214-setup-workflow-executor-package
29 of 30 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Map-basedRunStoreimplementation for unit testsRunStorewith auto-migration via umzugworkflow_step_executionswith JSONdatacolumn for flexible schemarun_idfor fast lookups, unique constraint on(run_id, step_index)store.migrate()(idempotent)Test plan
fixes PRD-221
🤖 Generated with Claude Code
Note
Add
InMemoryStoreandDatabaseStoreimplementations ofRunStoreInMemoryStore(in-memory-store.ts) using nested Maps with upsert-by-stepIndexand sorted retrieval, andDatabaseStore(database-store.ts) backed by Sequelize with Umzug-managed migrations and a transactional delete-then-insert upsert.buildInMemoryRunStoreandbuildDatabaseRunStorefactory functions that initialize the store before returning it;buildDatabaseRunStorecloses the Sequelize connection if initialization fails.RunStoreinterface withinit(): Promise<void>andclose(): Promise<void>lifecycle methods;Runner.start()now callsrunStore.init()andRunner.stop()callsrunStore.close()viaPromise.allSettled.Runner.stop()now usesPromise.allSettledfor shutdown, so a failure inaiClient.closeConnections()no longer preventsrunStore.close()from being called (and vice versa) — previously the first rejection would short-circuit the other.Changes since #1506 opened
DatabaseConfiginterface with nativesequelizeOptionsinterface forbuildDatabaseRunStorefunction [cab9e38]RunStoreinterface to accept optionalLoggerparameter ininitandclosemethods, updatedRunnerto pass its logger instance torunStore.initandrunStore.close, and enhancedDatabaseStoreimplementation to log migration failures duringinitand database connection closure failures duringcloseusing the provided logger [75510d5]initandclosemock definitions from mockRunStoreimplementations in test files [75510d5]userConfirmedproperty frommakeContexthelper function calls across all step executor test files [153b647]userConfirmedboolean field topendingDataobjects in test setups and assertions [bb168ff]Macroscope summarized a36fce9.