Skip to content

fix: consolidate reliability and safety fixes - #199

Open
flemzord wants to merge 23 commits into
mainfrom
feat/consolidate-reliability-fixes
Open

fix: consolidate reliability and safety fixes#199
flemzord wants to merge 23 commits into
mainfrom
feat/consolidate-reliability-fixes

Conversation

@flemzord

@flemzord flemzord commented Aug 5, 2026

Copy link
Copy Markdown
Member

Summary

Integration fixes

  • validate every redirect target used by link() and pin configured stack URLs to their exact scheme and host
  • reload persisted instances and stages on idempotent insert conflicts so original timestamps are preserved
  • validate temporal-max-parallel-activities and map it to MaxConcurrentActivityExecutionSize
  • bound every v1 list endpoint while preserving the top-level data field and exposing pageSize, hasMore, next, and previous
  • validate page sizes embedded in client-controlled cursors and align the OpenAPI maximum with the runtime limit
  • make wait_event react to workflow cancellation through a signal-or-cancellation selector
  • isolate the stack HTTP client from the JWT client with an Fx name tag
  • migrate imports reintroduced by older branches to the go-libs v5 package layout

Included pull requests

Supersedes the now-closed #180, #181, #182, #183, #184, #185, #186, #187, #188, #189, #190, #191, #192, #193, and #194.

Validation

  • nix develop --impure --command just pre-commit
  • nix develop --impure --command just tests
  • cd pkg/client && go test ./...
  • Speakeasy OpenAPI lint: 0 errors
  • git diff --check

flemzord and others added 16 commits August 5, 2026 13:01
The name filter used Where("Name ILIKE '%?%';", name): bun substitutes
the ? placeholder even inside the string literal, producing invalid SQL
(the value is quoted inside the literal and the stray ; lands mid-WHERE).
Any GET /triggers?name=... request therefore returned a 500.

Use a proper parameterized predicate with the wildcards on the argument,
and add an integration test covering substring/case-insensitive matching.
The link() expression function performed an HTTP GET using the
fx-provided *http.Client, which in production is the OAuth2
client-credentials client carrying the stack bearer token (broad
ledger/wallets/payments scopes). Because link() targets a URI taken
from a user-controlled trigger expression (reachable via
POST /v2/triggers/{id}/test, which also returns the response body),
an authenticated caller could point it at an arbitrary host and
exfiltrate the stack token, or reach internal-only services (SSRF).

Restrict link() to an allow-listed host (the configured stack URL),
reject non-http(s) schemes, and close the response body. With no
allow-listed host configured, link() network calls are denied.

The allowlist is threaded through triggers.NewModule(stack, stackURL,
taskQueue).
…andling

Initiate starts the real Run workflow as a detached child with id
"<instanceID>-main" (ParentClosePolicy ABANDON) and returns as soon as
that child has started. The Initiate workflow (id == instanceID) is thus
already completed by the time the API calls Wait/AbortRun:

- AbortRun cancelled the completed Initiate execution, so cancellation
  never reached the running stages (wait_event/delay were unabortable).
- Wait returned immediately on the completed Initiate execution, so
  ?wait=true returned a non-terminated instance.

Both now target "<instanceID>-main" (matching ReadInstanceHistory).

Wait also mishandled errors: errors.Is(err, &serviceerror.NotFound{})
can never match (no Is/Unwrap on that type) and errors.Unwrap(err)
returned nil for non-wrapped errors, turning a failure into a success.
Use errors.As for NotFound and return the original error otherwise.

Adds TestWait covering both the terminate-wait and not-found paths.
…retries

The event bus is at-least-once. Previously only SAVED_PAYMENT/SAVED_ACCOUNT
got a deterministic, dedup-ing Temporal workflow id; every other event type
ran with a server-generated id, so a redelivery (or a partial-failure NACK
after some triggers had already started) re-executed triggers and replayed
side-effecting stages such as money movements.

- listener: derive a deterministic workflow id for ALL events
  (taskIDPrefix-triggerID-<objectID|msg.UUID>) with REJECT_DUPLICATE, so a
  redelivery is rejected as a duplicate instead of starting a second run. (H1)

- occurrence id: ExecuteTrigger built the occurrence with uuid.NewString()
  in workflow code, yielding a different id on every Temporal replay. Use the
  (deterministic) workflow execution id instead. (M4)

- insert activities: InsertNewInstance, InsertNewStage and
  InsertTriggerOccurrence now use ON CONFLICT DO NOTHING. With deterministic
  primary keys, a retry after a lost ack (row committed, result lost) would
  otherwise fail forever on the duplicate key and wedge the workflow. (M2)

Adds a redelivery regression test for a non-payment event.
…events

handleMessage had an unnamed error return, so its recover() returned nil
and watermill ACKed the message. getWorkflowIDFromEvent deliberately
panicked on (un)marshal failures (e.g. a SAVED_PAYMENT payload whose id is
not a string), so a malformed event was permanently dropped with only a
stdout print.

- getWorkflowIDFromEvent now returns an error instead of panicking.
- handleMessage uses a named return so a recovered panic is converted into
  a returned error (NACK + redelivery/DLQ) and logged with its stack via
  the structured logger.

Adds a test asserting a malformed payment payload returns an error.

Note: overlaps internal/triggers/listener.go with #184 (idempotence); the
two are independent and may need a trivial merge.
RunWaitEvent called channel.ReceiveAsync inside a workflow.Await
predicate. An Await predicate is only evaluated once per workflow-task
wakeup, so if a non-matching signal and the matching signal were
delivered in the same workflow task, the predicate consumed the
non-matching one, returned false, and the matching signal stayed
buffered with nothing left to re-wake the coroutine -- blocking the
stage forever. Non-matching events were also silently destroyed.

Replace it with the canonical blocking Receive loop that drains signals
one at a time until the expected event arrives.

Adds a regression test signaling a non-matching then matching event in
the same task.
…text

When a Run workflow is cancelled, config.run returns a CanceledError and
the run context is already cancelled. The subsequent UpdateStage /
SendWorkflowStageTerminationEvent and UpdateInstance /
SendWorkflowTerminationEvent activities were executed on that cancelled
context, so they failed immediately: the instance/stage rows were left
stuck "running" and no FAILED_WORKFLOW(_STAGE) event was published.

Add terminationContext(), which returns the original context normally but
a workflow.NewDisconnectedContext when the workflow has been cancelled,
and use it for the terminal bookkeeping activities in both run() and Run.

The normal (non-cancelled) path is unchanged (still uses the live
context); covered by the existing end-to-end TestConfig.
RunWorkflow and ReadWorkflow selected by id only, so a soft-deleted
workflow could still be executed (POST /workflows/{id}/instances) and
read. DeleteWorkflow had no deleted_at guard, so re-deleting rewrote the
timestamp instead of returning not-found. And the trigger-matching
queries filtered only trigger.deleted_at, so triggers attached to a
deleted workflow kept firing instances forever.

- RunWorkflow / ReadWorkflow: add deleted_at IS NULL.
- DeleteWorkflow: add deleted_at IS NULL guard (re-delete -> ErrWorkflowNotFound).
- listMatchingTriggers / Activities.ListTriggers: exclude triggers whose
  workflow is soft-deleted.

Tests: TestListMatchingTriggers gains a soft-deleted-workflow case, and
TestSoftDeletedWorkflowIsNotUsable covers read/run/re-delete.
ReadInstanceHistory and ReadStageHistory ran inside HTTP handlers but
panicked on json.Unmarshal failures and on any DescribeWorkflowExecution
error other than NotFound, and indexed Input.Payloads[0] / Result.Payloads[0]
without a length check (index out of range when a workflow/activity was
started with no payload). chi's Recoverer turned each into an opaque 500.

- Add unmarshalFirstPayload(), which tolerates a nil/empty payload set and
  returns the decode error instead of panicking.
- Replace all four panic sites with wrapped returned errors; the
  DescribeWorkflowExecution NotFound case still maps to ErrInstanceNotFound.

Adds TestUnmarshalFirstPayload (nil/empty/malformed/well-formed).

Note: overlaps internal/workflow/manager.go with other PRs in this series
(different functions); independent.
Most read/write handlers mapped every backend error to 500, and the
trigger/workflow create+test handlers returned 500 for malformed request
bodies. Unknown ids therefore looked like server faults and bad client
payloads were misclassified.

- Add api.WriteError(), mapping sql.ErrNoRows, the workflow not-found
  sentinels and Temporal NotFound to 404, ErrInvalidConfig to 400, and
  everything else to 500. Use it in readInstance, readWorkflow, runWorkflow,
  postEvent, abortWorkflowInstance, readInstanceHistory and testTrigger
  (v1 + v2).
- createTrigger / testTrigger: malformed body -> 400 (was 500).
- createWorkflow: wrap validation failures as workflow.ErrInvalidConfig so
  they surface as 400; drop two panics (post-wait GetInstance, json.Marshal)
  in favour of returned error responses.

Tests: TestGetInstanceNotFound (404) and TestCreateWorkflowValidationError (400).

Note: edits internal/workflow/manager.go (Create + new sentinel) and many
v1/v2 handlers shared with other PRs in this series; independent, different
regions.
The flag is registered as a float64 in go-libs, but it was read with
GetInt, which fails on a float64 flag and returns 0. The worker option was
therefore always 0 (Temporal default = unlimited), so the operator-set
limit never took effect.

Read it with GetFloat64, and wire it to MaxConcurrentActivityExecutionSize
(activity concurrency) rather than TaskQueueActivitiesPerSecond (a
queue-wide rate limit), which is what "max parallel activities" means.

Behavioural note: the default (10) now actually caps activity concurrency
where it previously had no effect.
…iles

pkg/client is a separate (nested) Go module, so neither the root build nor
CI ever compiled it. It was left inconsistent between two Speakeasy
generations: formance.go declared 'package client' with
github.com/formancehq/flows/pkg/client/... import paths, while sdk.go and
the rest declare 'package openapi' (matching .speakeasy/gen.yaml's
packageName: openapi and the README's openapi.New entrypoint).

formance.go was a leftover duplicate of sdk.go (same ServerList,
sdkConfiguration, helpers; SDK renamed to Formance) and nothing referenced
it. Remove it and run 'go mod tidy' to restore the missing go.sum entries
(cenkalti/backoff/v4, ericlagergren/decimal). The module now builds and
vets cleanly.

Note: this module is not covered by CI (nested module); verified locally
with 'go build ./...' and 'go vet ./...' inside pkg/client.
The v1 listInstances and listWorkflows handlers passed a zero-value query,
and bunpaginate applies no LIMIT when PageSize == 0 -- so each request
loaded the entire workflow_instances / workflows table into memory.

Read the page size via bunpaginate.GetPageSize (default 15, max 100,
overridable with ?pageSize=), as the v2 handlers already do, while keeping
the v1 flat-array response shape.

Behavioural note: v1 list responses are now bounded to one page; clients
needing more pass ?pageSize=. Adds TestListInstancesIsBounded.
Migration 8 dropped the (trigger_id, event_id) primary key in favour of
(id), leaving trigger_id unindexed. ListTriggersOccurrences filters
WHERE trigger_id = ? ordered by date, so every page was a sequential scan
over an ever-growing table.

Add a migration creating the composite index, built CONCURRENTLY (the
migrator runs each migration on a dedicated non-transactional connection)
and IF NOT EXISTS for idempotency.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR migrates the service from go-libs v3 to v5. It also adds API error mapping and cursor pagination, safer workflow cleanup and payload handling, deterministic trigger processing, link host validation, and a trigger-occurrence index.

Changes

Application and library migration

Layer / File(s) Summary
Runtime module wiring
cmd/*, internal/api/*, internal/storage/*, internal/workflow/*, internal/triggers/*
Application modules, shared types, tests, and integrations use go-libs v5 package paths and APIs.
Worker configuration
cmd/worker.go, cmd/worker_test.go
Worker options validate positive whole-number concurrency values and configure Temporal activity concurrency.
Storage index
internal/storage/migrations.go
Migration 9 creates a concurrent index on trigger occurrence lookup columns.

API behavior

Layer / File(s) Summary
Error mapping
internal/api/errors.go, internal/api/v1/*, internal/api/v2/*
Backend errors map to 404, 400 validation, or 500 responses. Several panic paths now return HTTP errors.
Cursor pagination
internal/api/v1/handler_list_*.go, internal/api/v1/pagination.go, internal/api/v1/*test.go
List endpoints validate pageSize, pass bounded queries to backends, and return cursor metadata.
API validation tests
internal/api/v2/*test.go
Tests cover invalid workflow configuration, missing instances, and API response handling.

Workflow and trigger execution

Layer / File(s) Summary
Workflow lifecycle and persistence
internal/workflow/manager.go, internal/workflow/config.go, internal/workflow/run.go, internal/workflow/activities.go
Soft-deleted workflows are excluded. Detached main workflows handle waiting and aborting. Cancellation-safe contexts preserve termination activities. Duplicate inserts preserve existing records and timestamps.
Trigger delivery and links
internal/triggers/expression.go, internal/triggers/listener.go, internal/triggers/trigger.go, internal/triggers/workflow_trigger.go
link() validates hosts and redirects. Message errors support redelivery. Trigger occurrence and workflow execution IDs are deterministic.
Signal consumption and filtering
internal/workflow/stages/wait_event/*, internal/triggers/manager.go, internal/triggers/*test.go
Wait-event signals are consumed sequentially. Trigger name filtering supports case-insensitive substring matching. Tests cover deleted workflows and duplicate delivery.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Poem

A rabbit checks each link with care,
And bounds each page before the query runs.
Workflows keep their timestamps,
Retries keep occurrence IDs.
Version five wires the service tight.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes trigger, workflow, pagination, API error, concurrency, and storage changes beyond linked issue #180's go-libs upgrade scope. Link the related issues or split the reliability and safety changes into separate pull requests.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The summaries show the v5 import and FX wiring migration, but they do not verify version v5.3.0 or complete removal of all v3 dependencies. Provide manifest evidence confirming go-libs v5.3.0 and no remaining go-libs/v3 dependency.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the consolidation of reliability and safety fixes, which matches the main purpose of the changeset.
Description check ✅ Passed The description clearly explains the go-libs v5 upgrade and the reliability, safety, pagination, workflow, and validation changes.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/consolidate-reliability-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@NumaryBot

NumaryBot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🛑 Changes requested — automated review

All previously raised blockers and major issues (duplicate *http.Client Fx provider, CREATE INDEX CONCURRENTLY in transaction, v1 pagination truncation, empty event object ID, HTTP scheme allowance, test DB connection leak, float→int overflow) have been confirmed resolved by the author. One remaining issue stands: in the wait-event stage, the return value of channel.Receive is not checked. When a workflow is canceled or aborted, the call returns false but the code continues with a zero-value signal on an already-canceled context, which can leave wait-event stages stuck during termination. This needs to be addressed before merging.

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 1 new inline finding.

Summary: #199 (comment)

Comment thread cmd/root.go

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 2 new inline findings.

Summary: #199 (comment)

Comment thread cmd/root.go
Comment thread internal/api/v1/handler_list_instances.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/worker.go`:
- Around line 38-49: Update workerOptions in cmd/worker.go to validate the
temporalMaxParallelActivities flag value before building
temporalworker.NewWorkerModule and worker.Options. Reject any non-positive or
fractional value read via
cmd.Flags().GetFloat64(temporal.TemporalMaxParallelActivitiesFlag) instead of
casting it directly to int, and only pass an integer
MaxConcurrentActivityExecutionSize when the flag is a valid positive whole
number.

In `@internal/triggers/expression.go`:
- Around line 38-42: Update checkLinkURL to accept only the https scheme for the
initial link target, and enforce the same HTTPS-only requirement in its
CheckRedirect handling before following redirects. Revise the allowed-by-host
test to use an HTTPS/TLS test server while preserving the existing
host-allowlist assertions.

In `@internal/triggers/listener.go`:
- Around line 39-47: Update the event payload parsing flow around the local
object type and json.Unmarshal to reject payloads whose o.ID is empty, including
missing or null id values, by returning an appropriate error before
pointer.For(o.ID). Add coverage for a saved-event payload without an id.

In `@internal/workflow/manager_test.go`:
- Around line 160-165: Update TestSoftDeletedWorkflowIsNotUsable to close the
database returned by bunconnect.OpenSQLDB after the test completes, using
deferred cleanup immediately after successful creation while preserving the
existing migration and assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fca805b2-9a74-4702-816a-6241858b8328

📥 Commits

Reviewing files that changed from the base of the PR and between d36343e and cd45ca6.

⛔ Files ignored due to path filters (103)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • pkg/client/README.md is excluded by !pkg/client/**
  • pkg/client/USAGE.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/v1/README.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/v2/README.md is excluded by !pkg/client/**
  • pkg/client/formance.go is excluded by !pkg/client/**
  • pkg/client/go.mod is excluded by !**/*.mod, !pkg/client/**
  • pkg/client/go.sum is excluded by !**/*.sum, !**/*.sum, !pkg/client/**
  • pkg/client/internal/hooks/clientcredentials.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/form.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/json.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/pathparams.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/queryparams.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/retries.go is excluded by !pkg/client/**
  • pkg/client/models/components/activitystripetransfer.go is excluded by !pkg/client/**
  • pkg/client/models/components/assetholder.go is excluded by !pkg/client/**
  • pkg/client/models/components/creditwalletrequest.go is excluded by !pkg/client/**
  • pkg/client/models/components/debitwalletrequest.go is excluded by !pkg/client/**
  • pkg/client/models/components/monetary.go is excluded by !pkg/client/**
  • pkg/client/models/components/payment.go is excluded by !pkg/client/**
  • pkg/client/models/components/paymentadjustment.go is excluded by !pkg/client/**
  • pkg/client/models/components/posting.go is excluded by !pkg/client/**
  • pkg/client/models/components/posttransaction.go is excluded by !pkg/client/**
  • pkg/client/models/components/security.go is excluded by !pkg/client/**
  • pkg/client/models/components/stage.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagedelay.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagesend.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagestatus.go is excluded by !pkg/client/**
  • pkg/client/models/components/subject.go is excluded by !pkg/client/**
  • pkg/client/models/components/transaction.go is excluded by !pkg/client/**
  • pkg/client/models/components/trigger.go is excluded by !pkg/client/**
  • pkg/client/models/components/triggeroccurrence.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2activitystripetransfer.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2assetholder.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2creditwalletrequest.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2debitwalletrequest.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2monetary.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2payment.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2paymentadjustment.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2posting.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2posttransaction.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stage.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagedelay.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagesend.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagestatus.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2subject.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2transaction.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2trigger.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2triggeroccurrence.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2volume.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2wallet.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2walletwithbalances.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2workflow.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2workflowinstance.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2workflowinstancehistory.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2workflowinstancehistorystage.go is excluded by !pkg/client/**
  • pkg/client/models/components/volume.go is excluded by !pkg/client/**
  • pkg/client/models/components/wallet.go is excluded by !pkg/client/**
  • pkg/client/models/components/walletwithbalances.go is excluded by !pkg/client/**
  • pkg/client/models/components/workflow.go is excluded by !pkg/client/**
  • pkg/client/models/components/workflowinstance.go is excluded by !pkg/client/**
  • pkg/client/models/components/workflowinstancehistory.go is excluded by !pkg/client/**
  • pkg/client/models/components/workflowinstancehistorystage.go is excluded by !pkg/client/**
  • pkg/client/models/operations/cancelevent.go is excluded by !pkg/client/**
  • pkg/client/models/operations/createtrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/createworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/deletetrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/deleteworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getinstance.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getinstancehistory.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getinstancestagehistory.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getserverinfo.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listinstances.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listtriggers.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listtriggersoccurrences.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listworkflows.go is excluded by !pkg/client/**
  • pkg/client/models/operations/options.go is excluded by !pkg/client/**
  • pkg/client/models/operations/readtrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/runworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/sendevent.go is excluded by !pkg/client/**
  • pkg/client/models/operations/testtrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2cancelevent.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2createtrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2createworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2deletetrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2deleteworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2getinstance.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2getinstancehistory.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2getinstancestagehistory.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2getserverinfo.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2getworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listinstances.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listtriggers.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listtriggersoccurrences.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listworkflows.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2readtrigger.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2runworkflow.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2sendevent.go is excluded by !pkg/client/**
  • pkg/client/sdk.go is excluded by !pkg/client/**
  • pkg/client/v1.go is excluded by !pkg/client/**
  • pkg/client/v2.go is excluded by !pkg/client/**
📒 Files selected for processing (97)
  • cmd/root.go
  • cmd/serve.go
  • cmd/worker.go
  • internal/api/backend.go
  • internal/api/backend_generated.go
  • internal/api/errors.go
  • internal/api/handler_info.go
  • internal/api/module.go
  • internal/api/module_test.go
  • internal/api/router.go
  • internal/api/v1/handler_abort_workflow_instance.go
  • internal/api/v1/handler_create_trigger.go
  • internal/api/v1/handler_create_workflow.go
  • internal/api/v1/handler_delete_trigger.go
  • internal/api/v1/handler_delete_workflow.go
  • internal/api/v1/handler_delete_workflow_test.go
  • internal/api/v1/handler_get_trigger.go
  • internal/api/v1/handler_list_instances.go
  • internal/api/v1/handler_list_instances_test.go
  • internal/api/v1/handler_list_triggers.go
  • internal/api/v1/handler_list_triggers_occurrences.go
  • internal/api/v1/handler_list_triggers_occurrences_test.go
  • internal/api/v1/handler_list_workflows.go
  • internal/api/v1/handler_post_event.go
  • internal/api/v1/handler_read_instance.go
  • internal/api/v1/handler_read_instance_history.go
  • internal/api/v1/handler_read_instance_test.go
  • internal/api/v1/handler_read_stage_history.go
  • internal/api/v1/handler_read_workflow.go
  • internal/api/v1/handler_run_workflow.go
  • internal/api/v1/handler_run_workflow_test.go
  • internal/api/v1/main_test.go
  • internal/api/v1/router.go
  • internal/api/v2/handler_abort_workflow_instance.go
  • internal/api/v2/handler_create_trigger.go
  • internal/api/v2/handler_create_workflow.go
  • internal/api/v2/handler_create_workflow_test.go
  • internal/api/v2/handler_delete_trigger.go
  • internal/api/v2/handler_delete_workflow.go
  • internal/api/v2/handler_delete_workflow_test.go
  • internal/api/v2/handler_get_trigger.go
  • internal/api/v2/handler_list_instances.go
  • internal/api/v2/handler_list_instances_test.go
  • internal/api/v2/handler_list_triggers.go
  • internal/api/v2/handler_list_triggers_occurrences.go
  • internal/api/v2/handler_list_workflows.go
  • internal/api/v2/handler_post_event.go
  • internal/api/v2/handler_read_instance.go
  • internal/api/v2/handler_read_instance_history.go
  • internal/api/v2/handler_read_instance_test.go
  • internal/api/v2/handler_read_stage_history.go
  • internal/api/v2/handler_read_workflow.go
  • internal/api/v2/handler_run_workflow.go
  • internal/api/v2/handler_run_workflow_test.go
  • internal/api/v2/handler_test_trigger.go
  • internal/api/v2/handler_test_trigger_test.go
  • internal/api/v2/main_test.go
  • internal/api/v2/router.go
  • internal/schema/map.go
  • internal/storage/main_test.go
  • internal/storage/migrations.go
  • internal/storage/migrations_test.go
  • internal/temporalworker/module.go
  • internal/triggers/activities.go
  • internal/triggers/expression.go
  • internal/triggers/listener.go
  • internal/triggers/listener_test.go
  • internal/triggers/main_test.go
  • internal/triggers/manager.go
  • internal/triggers/manager_test.go
  • internal/triggers/module.go
  • internal/triggers/trigger.go
  • internal/triggers/trigger_test.go
  • internal/triggers/workflow_trigger.go
  • internal/triggers/workflow_trigger_test.go
  • internal/workflow/activities.go
  • internal/workflow/activities/activity.go
  • internal/workflow/activities/activity_ledger_create_transaction.go
  • internal/workflow/activities/activity_wallet_credit.go
  • internal/workflow/activities/activity_wallet_debit.go
  • internal/workflow/activities/activity_wallet_list.go
  • internal/workflow/activities_test.go
  • internal/workflow/config.go
  • internal/workflow/main_test.go
  • internal/workflow/manager.go
  • internal/workflow/manager_test.go
  • internal/workflow/run.go
  • internal/workflow/stage.go
  • internal/workflow/stages/delay/delay.go
  • internal/workflow/stages/delay/run.go
  • internal/workflow/stages/delay/run_test.go
  • internal/workflow/stages/send/run.go
  • internal/workflow/stages/send/run_test.go
  • internal/workflow/stages/send/send.go
  • internal/workflow/stages/wait_event/run.go
  • internal/workflow/stages/wait_event/wait_event_test.go
  • pkg/events/events.go

Comment thread cmd/worker.go
Comment thread internal/triggers/expression.go
Comment thread internal/triggers/listener.go
Comment thread internal/workflow/manager_test.go

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 6 new inline findings.

Summary: #199 (comment)

Comment thread cmd/root.go
Comment thread internal/storage/migrations.go
Comment thread internal/api/v1/handler_list_instances.go
Comment thread internal/triggers/listener.go
Comment thread internal/triggers/expression.go
Comment thread internal/workflow/manager_test.go

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 5 new inline findings.

Summary: #199 (comment)

Comment thread internal/storage/migrations.go
Comment thread internal/api/v1/handler_list_instances.go
Comment thread internal/triggers/listener.go
Comment thread internal/triggers/expression.go
Comment thread internal/workflow/manager_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/worker.go`:
- Around line 46-49: Update the validation around temporalMaxParallelActivities
in the worker options path to reject values at or above the exclusive signed-int
limit, using strconv.IntSize to derive the bound before any int conversion;
retain the positive whole-number checks. Extend
TestWorkerOptionsValidatesMaxParallelActivities with the 64-bit overflow
boundary case.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5878317a-b3b5-4039-8016-8599e89caab8

📥 Commits

Reviewing files that changed from the base of the PR and between cd45ca6 and 9091214.

⛔ Files ignored due to path filters (67)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • openapi.yaml is excluded by !**/*.yaml
  • openapi/v1.yaml is excluded by !**/*.yaml
  • pkg/client/.speakeasy/gen.lock is excluded by !**/*.lock, !**/*.lock, !pkg/client/**
  • pkg/client/.speakeasy/gen.yaml is excluded by !**/*.yaml, !pkg/client/**
  • pkg/client/README.md is excluded by !pkg/client/**
  • pkg/client/USAGE.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/activitycreatetransferinitiation.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/activitycreatetransferinitiationmetadata.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/activitycreatetransferinitiationtype.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/listrunsresponse.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/listtriggersoccurrencesresponse.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/listtriggersresponse.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/listworkflowsresponse.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/payment.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/paymenttype.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/stagesenddestinationaccount.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/stagesenddestinationpayment.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/stagesendsourceaccount.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/stagesendsourcepayment.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/type.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2activitycreatetransferinitiation.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2activitycreatetransferinitiationmetadata.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2activitycreatetransferinitiationtype.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2stagesenddestinationaccount.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2stagesenddestinationpayment.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2stagesenddestinationpaymenttype.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2stagesendsourceaccount.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2stagesendsourcepayment.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/v2workflowinstancehistorystageinput.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/workflowinstancehistorystageinput.md is excluded by !pkg/client/**
  • pkg/client/docs/models/operations/listinstancesrequest.md is excluded by !pkg/client/**
  • pkg/client/docs/models/operations/listtriggersoccurrencesrequest.md is excluded by !pkg/client/**
  • pkg/client/docs/models/operations/listtriggersrequest.md is excluded by !pkg/client/**
  • pkg/client/docs/models/operations/listworkflowsrequest.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/v1/README.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/v2/README.md is excluded by !pkg/client/**
  • pkg/client/models/components/activitycreatetransferinitiation.go is excluded by !pkg/client/**
  • pkg/client/models/components/listrunsresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/listtriggersoccurrencesresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/listtriggersresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/listworkflowsresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/payment.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagesenddestinationaccount.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagesenddestinationpayment.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagesendsourceaccount.go is excluded by !pkg/client/**
  • pkg/client/models/components/stagesendsourcepayment.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2activitycreatetransferinitiation.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagesenddestinationaccount.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagesenddestinationpayment.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagesendsourceaccount.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2stagesendsourcepayment.go is excluded by !pkg/client/**
  • pkg/client/models/components/v2workflowinstancehistorystageinput.go is excluded by !pkg/client/**
  • pkg/client/models/components/workflowinstancehistorystageinput.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listinstances.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listtriggers.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listtriggersoccurrences.go is excluded by !pkg/client/**
  • pkg/client/models/operations/listworkflows.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listinstances.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listtriggers.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listtriggersoccurrences.go is excluded by !pkg/client/**
  • pkg/client/models/operations/v2listworkflows.go is excluded by !pkg/client/**
  • pkg/client/orchestration.go is excluded by !pkg/client/**
  • pkg/client/sdk.go is excluded by !pkg/client/**
  • pkg/client/v1.go is excluded by !pkg/client/**
  • pkg/client/v2.go is excluded by !pkg/client/**
📒 Files selected for processing (19)
  • cmd/root.go
  • cmd/root_test.go
  • cmd/serve.go
  • cmd/worker.go
  • cmd/worker_test.go
  • internal/api/v1/handler_list_instances.go
  • internal/api/v1/handler_list_instances_test.go
  • internal/api/v1/handler_list_triggers.go
  • internal/api/v1/handler_list_triggers_occurrences.go
  • internal/api/v1/handler_list_triggers_occurrences_test.go
  • internal/api/v1/handler_list_workflows.go
  • internal/api/v1/pagination.go
  • internal/triggers/expression.go
  • internal/triggers/listener.go
  • internal/triggers/listener_test.go
  • internal/triggers/module.go
  • internal/triggers/trigger_test.go
  • internal/workflow/activities_test.go
  • internal/workflow/manager_test.go
🚧 Files skipped from review as they are similar to previous changes (13)
  • internal/api/v1/handler_list_workflows.go
  • internal/triggers/listener_test.go
  • internal/triggers/expression.go
  • internal/triggers/listener.go
  • cmd/root.go
  • internal/api/v1/handler_list_instances.go
  • internal/api/v1/handler_list_instances_test.go
  • internal/workflow/manager_test.go
  • internal/api/v1/handler_list_triggers_occurrences_test.go
  • internal/workflow/activities_test.go
  • internal/api/v1/handler_list_triggers_occurrences.go
  • internal/triggers/trigger_test.go
  • cmd/serve.go

Comment thread cmd/worker.go

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 1 new inline finding.

Summary: #199 (comment)

Comment thread internal/workflow/stages/wait_event/run.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/api/v1/handler_list_instances_test.go (1)

129-140: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that the continuation cursor advances.

The current assertions only check the record count and hasMore. An implementation that returns five records from the first page can pass this test. Record the first-page IDs and assert that the second page has no overlap. Assert that both pages contain all 20 inserted IDs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/api/v1/handler_list_instances_test.go` around lines 129 - 140, The
continuation-cursor test must verify pagination advances rather than only
checking counts. In the test around firstPage and secondPage, collect IDs from
both responses, assert the two page ID sets are disjoint, and assert their
combined IDs equal all 20 inserted instance IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/api/v1/handler_list_instances_test.go`:
- Around line 129-140: The continuation-cursor test must verify pagination
advances rather than only checking counts. In the test around firstPage and
secondPage, collect IDs from both responses, assert the two page ID sets are
disjoint, and assert their combined IDs equal all 20 inserted instance IDs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 09b8ac6a-138c-4e66-8e86-413d309d0eba

📥 Commits

Reviewing files that changed from the base of the PR and between 9091214 and ff2e4aa.

⛔ Files ignored due to path filters (5)
  • openapi.yaml is excluded by !**/*.yaml
  • openapi/v2.yaml is excluded by !**/*.yaml
  • pkg/client/.speakeasy/gen.lock is excluded by !**/*.lock, !**/*.lock, !pkg/client/**
  • pkg/client/.speakeasy/gen.yaml is excluded by !**/*.yaml, !pkg/client/**
  • pkg/client/sdk.go is excluded by !pkg/client/**
📒 Files selected for processing (8)
  • cmd/worker.go
  • cmd/worker_test.go
  • internal/api/v1/handler_list_instances.go
  • internal/api/v1/handler_list_instances_test.go
  • internal/api/v1/handler_list_triggers.go
  • internal/api/v1/handler_list_triggers_occurrences.go
  • internal/api/v1/handler_list_workflows.go
  • internal/api/v1/pagination.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • internal/api/v1/handler_list_workflows.go
  • internal/api/v1/handler_list_instances.go
  • internal/api/v1/handler_list_triggers_occurrences.go
  • cmd/worker_test.go
  • cmd/worker.go
  • internal/api/v1/handler_list_triggers.go

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumaryBot posted 1 new inline finding.

Summary: #199 (comment)

Comment thread internal/workflow/stages/wait_event/run.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants