Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Support cursor pagination on the dead letter jobs API, so callers can fetch jobs beyond the first 200 results. [PR #713](https://github.com/riverqueue/riverui/pull/713).

- Add a Pro-only dead letter queue panel that lists discarded jobs newest first, with ID, kind, queue, priority, and tag filters, dead letter autocomplete, and More/Fewer controls to inspect jobs and retry them as new jobs. [PR #711](https://github.com/riverqueue/riverui/pull/711).

### Changed

- Require Node.js 24.15+ or 26+ for frontend development and use Node.js 24.21.0 in CI and container builds to support the updated test dependencies. [PR #690](https://github.com/riverqueue/riverui/pull/690).

### Fixed

- Show a "Page not found" page with a link back to Jobs for unknown URLs, instead of a blank page. [PR #711](https://github.com/riverqueue/riverui/pull/711).
- Keep a long job kind on one line in the job detail heading, with a tooltip and a copy button for the full kind. [PR #711](https://github.com/riverqueue/riverui/pull/711).
- Cancel job search suggestion requests that a newer keystroke has replaced. [PR #711](https://github.com/riverqueue/riverui/pull/711).
- Clear filters and pagination when switching between Jobs and Dead Letters, while preserving them when switching job states within Jobs. [PR #711](https://github.com/riverqueue/riverui/pull/711).
- Show queues whose concurrency metadata is missing, `null`, or `{}` as having no concurrency override, matching how River Pro interprets them, and stop showing a zero concurrency config for producers that report none. [PR #704](https://github.com/riverqueue/riverui/pull/704).
- Reject negative queue concurrency `global_limit` and `local_limit` values with a 400 error instead of storing them. [PR #704](https://github.com/riverqueue/riverui/pull/704).
- Keep workflow diagram layouts compatible with Dagre's package exports after dependency upgrades. [PR #687](https://github.com/riverqueue/riverui/pull/687).
Expand Down
11 changes: 11 additions & 0 deletions riverproui/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func (e *endpoints[TTx]) Extensions(ctx context.Context) (map[string]bool, error
}
defer execTx.Rollback(ctx)

hasDeadLetterTable, err := prohandler.HasDeadLetterTable(ctx, execTx, schema)
if err != nil {
return nil, err
}

hasPeriodicJobTable, err := execTx.TableExists(ctx, &riverdriver.TableExistsParams{
Schema: schema,
Table: "river_periodic_job",
Expand Down Expand Up @@ -120,6 +125,7 @@ func (e *endpoints[TTx]) Extensions(ctx context.Context) (map[string]bool, error
}

return map[string]bool{
"dead_letter_jobs": hasDeadLetterTable,
"durable_periodic_jobs": hasPeriodicJobTable,
"producer_queries": true,
"workflow_queries": hasWorkflowV2Tables,
Expand Down Expand Up @@ -153,10 +159,15 @@ func (e *endpoints[TTx]) MountEndpoints(archetype *baseservice.Archetype, logger
},
Client: e.client,
DB: executor,
Tx: e.proOpts.Tx,
}

endpoints := e.ossEndpoints.MountEndpoints(archetype, logger, mux, mountOpts)
endpoints = append(endpoints,
apiendpoint.Mount(mux, prohandler.NewDeadLetterJobListEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewDeadLetterAutocompleteEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewDeadLetterJobGetEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewDeadLetterJobRetryEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewPeriodicJobListEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewProducerListEndpoint(bundle), mountOpts),
apiendpoint.Mount(mux, prohandler.NewWorkflowCancelEndpoint(bundle), mountOpts),
Expand Down
14 changes: 14 additions & 0 deletions riverproui/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ func TestProEndpointsExtensions(t *testing.T) {
}
}

t.Run("DeadLetterJobs", func(t *testing.T) {
t.Parallel()
bundle := setup(ctx, t)
ext, err := bundle.endpoint.Extensions(ctx)
require.NoError(t, err)
require.True(t, ext["dead_letter_jobs"])

_, err = bundle.tx.Exec(ctx, `DROP TABLE river_job_dead_letter`)
require.NoError(t, err)
ext, err = bundle.endpoint.Extensions(ctx)
require.NoError(t, err)
require.False(t, ext["dead_letter_jobs"])
})

t.Run("DurablePeriodicJobs", func(t *testing.T) { //nolint:dupl
t.Parallel()

Expand Down
22 changes: 12 additions & 10 deletions riverproui/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ require (
github.com/google/uuid v1.6.0
github.com/jackc/pgx/v5 v5.11.0
github.com/riverqueue/apiframe v0.0.0-20260908014005-b546730aa405
github.com/riverqueue/river v0.49.0
github.com/riverqueue/river/riverdriver v0.49.0
github.com/riverqueue/river/rivershared v0.49.0
github.com/riverqueue/river/rivertype v0.49.0
github.com/riverqueue/river v0.49.1-0.20261013022952-3e6c2d5eb0af
github.com/riverqueue/river/riverdriver v0.49.1-0.20261013022952-3e6c2d5eb0af
github.com/riverqueue/river/rivershared v0.49.1-0.20261013022952-3e6c2d5eb0af
github.com/riverqueue/river/rivertype v0.49.1-0.20261013022952-3e6c2d5eb0af
github.com/stretchr/testify v1.12.1
modernc.org/sqlite v1.60.1
riverqueue.com/riverpro v0.32.0
Expand Down Expand Up @@ -66,10 +66,12 @@ retract (
v0.12.0 // Improper release process, not fully usable
)

// replace riverqueue.com/riverpro => ../../riverpro

// replace riverqueue.com/riverpro/driver => ../../riverpro/driver

// replace riverqueue.com/riverpro/driver/riverpropgxv5 => ../../riverpro/driver/riverpropgxv5
// These local replacements are temporary until the required APIs are released.
replace (
riverqueue.com/riverpro => ../../riverpro
riverqueue.com/riverpro/driver => ../../riverpro/driver
riverqueue.com/riverpro/driver/riverpropgxv5 => ../../riverpro/driver/riverpropgxv5
riverqueue.com/riverpro/driver/riverprosqlite => ../../riverpro/driver/riverprosqlite
)

// replace riverqueue.com/riverui => ../
replace riverqueue.com/riverui => ../
26 changes: 8 additions & 18 deletions riverproui/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/riverqueue/apiframe v0.0.0-20260908014005-b546730aa405 h1:81wtaFw2lJmuptnXgrzco8k1R46b2sonqsYVt/mALlY=
github.com/riverqueue/apiframe v0.0.0-20260908014005-b546730aa405/go.mod h1:vDMhByVzSCg13iaNuNPmWSn5BszIcmZqkhm+c9Wjhf4=
github.com/riverqueue/river v0.49.0 h1:JUCLFgregbX1Wu+bSTHCjF/WHGdrwGbtz/ddInHfeb0=
github.com/riverqueue/river v0.49.0/go.mod h1:USYb57gpMBXLQm2l7poskAalOPaf5uHjSZgp2AOoYDw=
github.com/riverqueue/river/riverdriver v0.49.0 h1:kSykNQJNB7AeG6kudjB0mThV29PvykoOBIFT8ipCHEc=
github.com/riverqueue/river/riverdriver v0.49.0/go.mod h1:rVUuX/fTF2kAiJjpPT+10Lft8n90kvLqjm6b+rFXaVE=
github.com/riverqueue/river v0.49.1-0.20261013022952-3e6c2d5eb0af h1:q0LRP6iyxhexmooHl9tFkx6Y3XsiJhCmGR/ZHwvZdvk=
github.com/riverqueue/river v0.49.1-0.20261013022952-3e6c2d5eb0af/go.mod h1:EERMc5G5ZTISFaGzYBfiNpT5hrKs28I8iy7l12eyCyQ=
github.com/riverqueue/river/riverdriver v0.49.1-0.20261013022952-3e6c2d5eb0af h1:AebzrE455tWt0+vwpm9SE1igft5Cd84+aAEW7xB47yg=
github.com/riverqueue/river/riverdriver v0.49.1-0.20261013022952-3e6c2d5eb0af/go.mod h1:rVUuX/fTF2kAiJjpPT+10Lft8n90kvLqjm6b+rFXaVE=
github.com/riverqueue/river/riverdriver/riverpgxv5 v0.49.0 h1:c7YA1plP/nrNS3SEHuKizf4wHx9OQ87Yxuhj3V0eQ50=
github.com/riverqueue/river/riverdriver/riverpgxv5 v0.49.0/go.mod h1:o7zkFstM+Fk+mnlOW2sx92mQW4JswSc6zvN191l8Isg=
github.com/riverqueue/river/riverdriver/riversqlite v0.49.0 h1:DfATYWIuQ4bKjhhqj/XYn3ZGpluXqG0VAZfk+voL558=
github.com/riverqueue/river/riverdriver/riversqlite v0.49.0/go.mod h1:sOSH7dNsGt2UWLFUk7Cy9qNRNkRTswFrTwYf+TJkpeg=
github.com/riverqueue/river/rivershared v0.49.0 h1:wnCYVwftMiu85kT1JrUPKEgujKkBIWoRtSNZJTUtotY=
github.com/riverqueue/river/rivershared v0.49.0/go.mod h1:E8UzQAdDutFT8rVL1wZeNbuphmIS81TgngU7/1F4U5E=
github.com/riverqueue/river/rivertype v0.49.0 h1:3up3P2DtOqnM2yEYSC1xeK9AjrljOtIfl10yZlaF4aM=
github.com/riverqueue/river/rivertype v0.49.0/go.mod h1:XKkcRQR6zm8RR/JQa1Q2ywpj8uXQu21quPa4Lpw1Xhw=
github.com/riverqueue/river/rivershared v0.49.1-0.20261013022952-3e6c2d5eb0af h1:mywEI2ybhH41LOt3CGazFSHpT09p0HNmQafSPVk9O9I=
github.com/riverqueue/river/rivershared v0.49.1-0.20261013022952-3e6c2d5eb0af/go.mod h1:MnjbPPoDuUd+OkoeAjUdLSKo3JvZpvU69j/T7W8oaI0=
github.com/riverqueue/river/rivertype v0.49.1-0.20261013022952-3e6c2d5eb0af h1:kezLfQw2EWDq1RrA3CrPhg+gK8wrjOE7YliWy6U+QSc=
github.com/riverqueue/river/rivertype v0.49.1-0.20261013022952-3e6c2d5eb0af/go.mod h1:XKkcRQR6zm8RR/JQa1Q2ywpj8uXQu21quPa4Lpw1Xhw=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
Expand Down Expand Up @@ -138,13 +138,3 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
riverqueue.com/riverpro v0.32.0 h1:2ydPgcxWhkCs2IiHQnkMaMnyXEtrhyfow3t+EleRKgo=
riverqueue.com/riverpro v0.32.0/go.mod h1:4GkB+CMUGu2Ut+VepOmoV3QwHH91wcCxARJwu/B3Ll0=
riverqueue.com/riverpro/driver v0.32.0 h1:M1V2Aqh9sBNFBuujvopT7nbzaA6TUjF7lQM66jHCkTA=
riverqueue.com/riverpro/driver v0.32.0/go.mod h1:Pif8aXQIgYWGbPrRHa3cfi7/RQZKY/xZ1p7ZomqIz1E=
riverqueue.com/riverpro/driver/riverpropgxv5 v0.32.0 h1:/zqKDEOiheb/cfV6hrPDv1lAVO0lymfsqXMqxP36RyY=
riverqueue.com/riverpro/driver/riverpropgxv5 v0.32.0/go.mod h1:RVz3DBxBcpfa+pPXed87H70hwQb3dDOdeS37x/vmOXo=
riverqueue.com/riverpro/driver/riverprosqlite v0.32.0 h1:jlE2zmlZM6zVltvRTrucCTPKK+4SMBOhF62rHqYCeU4=
riverqueue.com/riverpro/driver/riverprosqlite v0.32.0/go.mod h1:sQPQwrCaEgCp/4QhLBWX5vQQfAu067E6/vjlNd4ctlk=
riverqueue.com/riverui v0.21.0 h1:ERvscQm7Ohw6qmJ24nbgbBIibMME/zcL6DTYfZHZvdQ=
riverqueue.com/riverui v0.21.0/go.mod h1:4Ak1OzaMolEjH/7PLSP/zu0wB/MvrVtadQ/K2e1/6Uc=
Loading
Loading