fix: fetch newest workflow runs in ui query#1140
Conversation
📝 WalkthroughWalkthroughThe ChangesWorkflow Runs Listing
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes the workflows UI showing only the first 100 runs by changing the runs.list tRPC query to first pick the newest run IDs (ordered by the earliest job creation time) and then fetch their job details, instead of joining first and applying LIMIT against the row-multiplied join. The default page size is also bumped from 100 to 500.
Changes:
- Add a subquery that selects the newest
workflowRun.ids for a workflow, ordered bymin(job.createdAt) DESC NULLS LAST, withLIMIT/OFFSETapplied there. - Drive the main job query off that subquery via an
innerJoin, removing the previouswhere/limit/offsetfrom the row-multiplied join. - Increase the default
limitfrom 100 to 500.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
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 `@packages/trpc/src/routes/workflows.ts`:
- Around line 165-178: The ordering uses min(schema.job.createdAt) so workflow
runs without jobs sort last; add a createdAt timestamp to the workflowRun schema
and migration, then update the newestRunIds query to order using COALESCE
between job.createdAt and workflowRun.createdAt (e.g.
orderBy(sql`coalesce(min(${schema.job.createdAt}),
${schema.workflowRun.createdAt}) desc nulls last`)) or simply order by
schema.workflowRun.createdAt desc; update the workflowRun schema (createdAt),
migration, and replace the orderBy in the newestRunIds query accordingly.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5f4a66fb-0fba-4075-a3bc-159cb8a4077a
📒 Files selected for processing (1)
packages/trpc/src/routes/workflows.ts
| const newestRunIds = ctx.db | ||
| .select({ id: schema.workflowRun.id }) | ||
| .from(schema.workflowRun) | ||
| .leftJoin( | ||
| schema.workflowJob, | ||
| eq(schema.workflowJob.workflowRunId, schema.workflowRun.id), | ||
| ) | ||
| .leftJoin(schema.job, eq(schema.job.id, schema.workflowJob.jobId)) | ||
| .where(eq(schema.workflowRun.workflowId, input.workflowId)) | ||
| .groupBy(schema.workflowRun.id) | ||
| .orderBy(sql`min(${schema.job.createdAt}) desc nulls last`) | ||
| .limit(input.limit) | ||
| .offset(input.offset) | ||
| .as("newest_runs"); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check schema.workflowRun for timestamp fields
# Search for workflowRun schema definition and look for timestamp fields
ast-grep --pattern $'workflowRun = $$$({
$$$
})'Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
#!/bin/bash
# Description: Check if workflow runs can be created without jobs
# Look for workflowRun creation logic to see if jobs are always created
rg -nP --type=ts -C5 'workflowRun.*insert|insert.*workflowRun'Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Find schema-related files
fd -e ts -e js -e sql | grep -i schema | head -20Repository: ctrlplanedev/ctrlplane
Length of output: 955
🏁 Script executed:
# Look for drizzle or database schema definitions
find . -type f \( -name "*schema*" -o -name "*migration*" \) | grep -E "\.(ts|js|sql)$" | head -20Repository: ctrlplanedev/ctrlplane
Length of output: 248
🏁 Script executed:
# Search for workflowRun definition in the codebase
rg -l "workflowRun" --type=ts | head -10Repository: ctrlplanedev/ctrlplane
Length of output: 325
🏁 Script executed:
# Check the workflow schema definition
cat -n packages/db/src/schema/workflow.tsRepository: ctrlplanedev/ctrlplane
Length of output: 1761
🏁 Script executed:
# Look at the context around lines 165-178 in workflows.ts
sed -n '150,190p' packages/trpc/src/routes/workflows.tsRepository: ctrlplanedev/ctrlplane
Length of output: 1453
🏁 Script executed:
# Check where workflowRun records are created
rg -n "workflowRun" packages/trpc/src/routes/workflows.ts -B5 -A5Repository: ctrlplanedev/ctrlplane
Length of output: 3345
🏁 Script executed:
# Look for where workflowRun is inserted/created
rg -n "insert.*workflowRun|workflowRun.*insert" packages/trpc/src -B3 -A3Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Check if there's any creation logic that always creates jobs
rg -n "create.*workflow|workflow.*create" packages/trpc/src/routes/workflows.ts -B5 -A5Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Search for where workflowRun is created - look for .insert calls
rg -n "\.insert\(" packages/trpc/src/routes/workflows.ts -B3 -A3Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Look at the job schema to confirm it has createdAt
sed -n '1,100p' packages/db/src/schema/job.ts | head -50Repository: ctrlplanedev/ctrlplane
Length of output: 1180
🏁 Script executed:
# Get more of the job schema to see the createdAt field
sed -n '45,150p' packages/db/src/schema/job.tsRepository: ctrlplanedev/ctrlplane
Length of output: 3115
🏁 Script executed:
# Search for where workflowRun is created - broader search
rg -n "workflowRun" packages/trpc/src -B2 -A2 | grep -E "\.insert|\.values|create|add"Repository: ctrlplanedev/ctrlplane
Length of output: 178
🏁 Script executed:
# Look for create run mutations
rg -n "createRun|create.*run|run.*create" packages/trpc/src/routes/workflows.ts -B3 -A10Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Check if there's any logic that always creates jobs when creating a run
rg -n "workflowRun.*insert|insert.*workflowRun" packages/trpc -B5 -A5Repository: ctrlplanedev/ctrlplane
Length of output: 48
🏁 Script executed:
# Look at all procedures in workflows.ts to find run creation
sed -n '1,300p' packages/trpc/src/routes/workflows.ts | grep -E "\.mutation|\.insert|workflowRun" -B2 -A2Repository: ctrlplanedev/ctrlplane
Length of output: 2329
Add createdAt field to workflowRun schema or reconsider ordering strategy.
The query orders by min(schema.job.createdAt) desc nulls last, which means workflow runs without any jobs will appear at the end of the list (because their min job creation time is NULL). Since the workflowRun table has no timestamp field (confirmed from schema), and runs can exist without jobs (indicated by the LEFT JOIN strategy), this ordering produces incorrect results for newly created runs that haven't spawned jobs yet.
Either add a createdAt timestamp to the workflowRun schema and order by that, or implement an alternative ordering strategy that correctly handles runs without jobs.
🤖 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 `@packages/trpc/src/routes/workflows.ts` around lines 165 - 178, The ordering
uses min(schema.job.createdAt) so workflow runs without jobs sort last; add a
createdAt timestamp to the workflowRun schema and migration, then update the
newestRunIds query to order using COALESCE between job.createdAt and
workflowRun.createdAt (e.g. orderBy(sql`coalesce(min(${schema.job.createdAt}),
${schema.workflowRun.createdAt}) desc nulls last`)) or simply order by
schema.workflowRun.createdAt desc; update the workflowRun schema (createdAt),
migration, and replace the orderBy in the newestRunIds query accordingly.
fixes #1128
Summary by CodeRabbit