Skip to content

fix(api/purchases): add scheduled_execution_at to GetPlannedExecutions SELECT - #1255

Merged
cristim merged 3 commits into
mainfrom
fix/qa579-planned-executions-scan
Jul 11, 2026
Merged

fix(api/purchases): add scheduled_execution_at to GetPlannedExecutions SELECT#1255
cristim merged 3 commits into
mainfrom
fix/qa579-planned-executions-scan

Conversation

@cristim

@cristim cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member

Closes #1247

Symptom

On the Plans page, the "Planned Purchases" section fails to load with "Failed to load planned purchases: Internal server error" (HTTP 500). Reproducible by the Admin user, so this is not a permissions issue.

Root Cause

GetPlannedExecutions in internal/config/store_postgres.go projected only 26 columns in its SELECT, omitting scheduled_execution_at. The shared scanExecutionRows helper scans 27 columns, with &scheduledExecutionAt as the final (27th) scan target. Against a real PostgreSQL instance the row Scan fails with "expected 27 destination arguments in Scan, not 26", returning "failed to scan execution" which the handler surfaces as a 500.

This drifted in via PR #804 (revocation-delay feature, commit 8e5f139) which added scheduled_execution_at to scanExecutionRows and every other SELECT feeding it (ListStuckExecutions, GetPendingExecutions, GetStaleApprovedExecutions), but skipped GetPlannedExecutions.

Fix

  1. Add scheduled_execution_at to the GetPlannedExecutions SELECT in the correct position (after idempotency_key, matching the scanExecutionRows scan order and consistent with every sibling query).
  2. Tighten the regression test TestPGXMock_GetPlannedExecutions_ProjectsAllScanColumns: the mock ExpectQuery regexp now requires both idempotency_key AND scheduled_execution_at to appear in the issued SQL, so a future column-count drift is caught at test time instead of in production.

Why the old test was a false positive

The previous matcher (mock.ExpectQuery("idempotency_key")) matched any SQL containing idempotency_key and returned a 27-column mock result regardless of the actual projection, so it passed even with the bug present. The tightened alternation regexp (idempotency_key.*scheduled_execution_at|scheduled_execution_at.*idempotency_key) fails to match a projection missing either column, the mock then returns no rows, and the test fails.

Testing

  • go build ./...: pass
  • go test ./internal/config/...: 585 passed
  • Regression test, pre-fix (SELECT change reverted, tightened test active): FAILS with "could not match actual sql" because the issued SELECT does not contain scheduled_execution_at.
  • Regression test, post-fix (both files in place): PASSES.

Stacking

Stacked on #1254 (pre-commit repair); retarget to main when #1254 merges.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed planned-execution database querying so the scheduled execution timestamp is correctly selected and returned, including proper handling when the timestamp is absent.
  • Tests
    • Strengthened coverage for planned-execution queries to verify the SQL projection includes the idempotency key and scheduled timestamp, and that null vs. populated timestamp values round-trip as expected.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 180607e7-725f-4e77-8ce5-3634c6c2c072

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

GetPlannedExecutions now selects scheduled_execution_at in the order expected by scanExecutionRows. Its pgxmock regression test verifies the projection and confirms NULL and populated timestamps scan correctly.

Changes

Fix GetPlannedExecutions SQL projection and regression guard

Layer / File(s) Summary
Add scheduled_execution_at to SELECT and validate scanning
internal/config/store_postgres.go, internal/config/store_postgres_pgxmock_test.go
The SELECT includes scheduled_execution_at after idempotency_key. The test requires both columns and verifies nil handling for NULL values and timestamp round-tripping for populated values.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main fix in GetPlannedExecutions and matches the change set.
Linked Issues check ✅ Passed The PR implements the column mismatch fix and strengthens the regression test as required by #1247.
Out of Scope Changes check ✅ Passed The changes stay focused on the planned purchases scan-column fix and its regression test.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/qa579-planned-executions-scan

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

@cristim cristim added triaged Item has been triaged type/bug Defect priority/p2 Backlog-worthy severity/high Significant harm urgency/this-sprint Within the current sprint impact/many Affects most users effort/s Hours labels Jun 19, 2026
@cristim

cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim changed the base branch from fix/1222-precommit-repair to main June 19, 2026 14:51
@cristim
cristim force-pushed the fix/qa579-planned-executions-scan branch from 1de7bb0 to 9ccf5ed Compare June 19, 2026 15:33
@cristim

cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim force-pushed the fix/qa579-planned-executions-scan branch from 9ccf5ed to 8de0d5d Compare July 10, 2026 14:17
@cristim

cristim commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added 3 commits July 11, 2026 23:12
…s SELECT

GetPlannedExecutions projected 26 columns, but scanExecutionRows scans 27
(the 27th being scheduled_execution_at). Against a real PostgreSQL instance
this caused rows.Scan to fail ("expected 27 destination arguments in Scan,
not 26"), returning "failed to scan execution" and surfacing as a 500 on
the Planned Purchases list endpoint.

The regression drifted in via PR #804 (commit 8e5f139) which added
scheduled_execution_at to scanExecutionRows and every other SELECT feeding
it, but skipped GetPlannedExecutions.

Also tighten TestPGXMock_GetPlannedExecutions_ProjectsAllScanColumns:
the mock ExpectQuery regexp now requires both idempotency_key AND
scheduled_execution_at in the SQL so future column-count drift is caught
at test time rather than in production.

Closes #1247
…GetPlannedExecutions test

The regression test already verified the scan column count (select+scan
both have 27 columns). This tightens it to also assert that a NULL
scheduled_execution_at comes back as a nil *time.Time pointer rather than
a zero-value time, confirming applyNullTimesToExecution's Valid-guard.
…GetPlannedExecutions

Extend TestPGXMock_GetPlannedExecutions_ProjectsAllScanColumns with a second
row carrying a non-NULL scheduled_execution_at and assert it deserialises into
the ScheduledExecutionAt pointer. The prior test only covered the NULL path
(nil pointer), which passes even if a real value is silently dropped. This adds
the direct regression guard for the fix: with the column absent from the SELECT
projection the value never reaches ScheduledExecutionAt and every delayed
execution reads back as unscheduled.
@cristim
cristim force-pushed the fix/qa579-planned-executions-scan branch from 8de0d5d to 5d954f2 Compare July 11, 2026 20:13
@cristim

cristim commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

Rebased onto latest main to clear the pre-existing errorlint findings the Lint Code job was flagging (err == pgx.ErrNoRows, err == io.EOF, err.(*clientError), etc.). Those were resolved on main by PR #1358 (fix/errorlint-purchase-handler); the branch was 9 commits behind.

Post-rebase CI:

  • Unit Tests, Integration Tests, E2E, Docker Build, Terraform validate, pre-commit, AWS/Azure sanity: all green
  • Lint Code: still red, but now on ci_cd_sanity_tests/** gocritic findings (exitAfterDefer, hugeParam, builtinShadow) that also fail on the latest main run (29166460118). Out of scope for this PR
  • Security Scanning: same story, red on main too

Scope of this PR remains a single production-code change: internal/config/store_postgres.go line 1195 adds scheduled_execution_at to the GetPlannedExecutions SELECT projection, plus a pgxmock regression test that asserts the column round-trips into ScheduledExecutionAt and stays nil when NULL.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@cristim Thanks for the update and for rebasing to clear the errorlint findings. Noted that the remaining Lint Code and Security Scanning failures stem from pre-existing ci_cd_sanity_tests/** gocritic findings that also fail on main, and are out of scope for this PR. Triggering a fresh review now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim merged commit 46f5827 into main Jul 11, 2026
13 of 16 checks passed
@cristim
cristim deleted the fix/qa579-planned-executions-scan branch July 27, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/many Affects most users priority/p2 Backlog-worthy severity/high Significant harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(api/purchases): GET planned purchases returns 500 (GetPlannedExecutions SELECT omits scheduled_execution_at) (QA row 579)

1 participant