Fix Cosmos DB pagination for backwards compatibility#1594
Fix Cosmos DB pagination for backwards compatibility#1594MarcAstr0 merged 5 commits intoboostercloud:mainfrom
Conversation
PR Summary
|
There was a problem hiding this comment.
Pull request overview
Restores backward compatibility for Azure/CosmosDB pagination by ensuring GraphQL cursors always include a numeric id while still supporting continuation-token pagination.
Changes:
- Add a default page size and revise Cosmos feed options to better support continuation tokens.
- Always include a numeric
cursor.id(and optionallycursor.continuationToken) in paginated results. - Update the monorepo lockfile and add a Rush change file for a patch release.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/framework-provider-azure/src/helpers/query-helper.ts | Adjusts pagination logic to return a numeric cursor id for backward compatibility and refines continuation-token/legacy OFFSET behavior. |
| common/config/rush/pnpm-lock.yaml | Updates workspace specifiers and dependency resolutions in the pnpm lockfile. |
| common/changes/@boostercloud/framework-core/fix-cosmos-pagination_2026-02-27-21-10.json | Adds a Rush change file to drive release/versioning metadata for the change. |
Files not reviewed (1)
- common/config/rush/pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
common/changes/@boostercloud/framework-core/fix-cosmos-pagination_2026-02-27-21-10.json
Show resolved
Hide resolved
|
/integration sha=04d10e1 |
|
⌛ Integration tests are running... Check their status here 👈 |
|
❌ Oh no! Integration tests have failed |
|
⌛ Integration tests are running... Check their status here 👈 |
|
❌ Oh no! Integration tests have failed |
|
⌛ Integration tests are running... Check their status here 👈 |
|
❌ Oh no! Integration tests have failed |
|
⌛ Integration tests are running... Check their status here 👈 |
|
❌ Oh no! Integration tests have failed |
|
⌛ Integration tests are running... Check their status here 👈 |
|
❌ Oh no! Integration tests have failed |
|
/integration sha=589add3 |
|
⌛ Integration tests are running... Check their status here 👈 |
|
✅ Integration tests have finished successfully! |
alvaroloes
left a comment
There was a problem hiding this comment.
Codex: I found a backward-compatibility regression in the new numeric cursor semantics. When limit is omitted, the implementation now treats the default page size as the cursor position, so a one-item page can emit { id: "100" }. A legacy client that feeds that numeric cursor back into the next request will skip rows instead of continuing from the next consumed item.
...amework-integration-tests/integration/provider-unaware/end-to-end/read-models.integration.ts
Show resolved
Hide resolved
Claude: Code Review — Fix Cosmos DB pagination for backwards compatibilityHe revisado los 4 ficheros cambiados en este PR. Análisis completo: Contexto y lógica del cambioEl PR #1587 introdujo paginación basada en ✅ Lo que está bien
🔴 Problemas que bloquean el merge1. const previousOffset = afterCursor?.id ? parseInt(afterCursor.id) : 0Si un cliente envía un
El código ya tiene esta guardia en otro lugar ( const parsedId = afterCursor?.id ? parseInt(afterCursor.id, 10) : NaN
const previousOffset = Number.isFinite(parsedId) ? parsedId : 02. // path con continuationToken:
cursor = { continuationToken, id: (previousOffset + effectiveLimit).toString() }
// path sin continuationToken (no legacy):
cursor = { id: (previousOffset + effectiveLimit).toString() }Cosmos DB no garantiza que devuelva exactamente
Si un cliente que solo usa La rama legacy del código antiguo ( Recomendación: en el path de } else if (finalResources.length > 0) {
cursor = { id: (previousOffset + finalResources.length).toString() }
}3. if (limit || afterCursor?.continuationToken) {
feedOptions.maxItemCount = limit ?? DEFAULT_PAGE_SIZE
}En la primera llamada a una query paginada con continuationToken ( Esto hace que el // Siempre establecer maxItemCount en el path paginado
feedOptions.maxItemCount = limit ?? DEFAULT_PAGE_SIZE🟡 Observaciones importantes4. Rush change file declara { "packageName": "@boostercloud/framework-core", ... }El código que cambia está en Los usuarios que actualicen Recomendación: Generar el change file con 5. Tests de integración fallan 4 veces antes de pasar — señal de flakiness El historial muestra 4 rondas de "Integration tests failed" antes de que pasen con el commit
Si es flakiness, debería abrirse un issue separado porque tests flaky en CI reducen la confianza en todos los PRs. 6. No hay tests unitarios para los nuevos paths Las observaciones de Copilot ya señalan esto: no hay tests unitarios que cubran:
Los tests de integración son lentos y caros para iterar sobre lógica de paginación. Los tests unitarios de 7. parseInt(afterCursor.id) // sin radixAunque en la práctica los IDs son siempre decimales, es buena práctica usar VeredictoRequest Changes. Los puntos 1 (NaN sin guardia), 2 (avance por |
|
/integration sha=50d87eb |
|
⌛ Integration tests are running... Check their status here 👈 |
|
✅ Integration tests have finished successfully! |
|
@alvaroloes implemented some of the suggestions in commit 50d87eb. Regarding the second one: The original code (commit 44045a7, before PR #1587) was: cursor: { id: ((limit ? limit : 1) + (afterCursor?.id ? parseInt(afterCursor?.id) : 0)).toString() }This always advanced by |
Description
v3.4.2 (see #1587) introduced continuation-token-based pagination for the Azure provider. That change replaced the numeric
idin the response cursor with acontinuationToken. For backwards compatibility,OFFSET-based pagination could still be forced by sending a numericidin theafterCursorproperty of the GraphQL request (e.g.,'0'for the first page). However, this broke existing frontends that didn't forceOFFSET-based pagination and expected a numericidin the cursor. This PR restores backwards compatibility by always returning a numeric cursorid(indicating the cursor's position) alongside the optionalcontinuationToken.Changes
query-helper.tsto always return a numericidin the cursor for backwards compatibilityChecks