Skip to content

fix: paginate getProjects/getClients so all results resolve#56

Merged
jack-arturo merged 1 commit into
verygoodplugins:mainfrom
janis-ps:fix/paginate-projects-clients
Jun 8, 2026
Merged

fix: paginate getProjects/getClients so all results resolve#56
jack-arturo merged 1 commit into
verygoodplugins:mainfrom
janis-ps:fix/paginate-projects-clients

Conversation

@janis-ps

@janis-ps janis-ps commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Problem

getProjects and getClients issue a single un-paginated GET to the Toggl v9 list endpoints. Those endpoints paginate by page/per_page (sorted by name) and return only the first page by default, silently dropping the rest.

As a result, any project or client past the first page fails name resolution and surfaces as the Project <id> fallback in reports and summaries. Workspaces with more projects than a single page hit this for everything after the first page.

Fix

  • Add a private requestAllPages() helper that walks ?per_page=200&page=N until a short page is returned.
  • Two safety guards: a non-advancing-page detector (breaks if an endpoint ignores page and re-returns the same window, preventing an infinite loop) and a MAX_PAGES backstop.
  • Route both getProjects and getClients through it (clients had the identical bug).

This is offset pagination (page/per_page), verified against the v9 /workspaces/{id}/projects endpoint — page=2 returns a distinct, later, name-sorted window.

Tests

TDD: three tests written first and watched fail, then pass:

  • fetches every page until a short page (multi-page),
  • single request when the first page is short,
  • stops instead of looping when the endpoint ignores page.

Full suite green (30 passed, 3 pre-existing skips), tsc --noEmit clean, ESLint 0 errors.

Notes / out of scope

  • Pagination only. getProjects still uses Toggl's default active-only filter, so genuinely archived projects still won't name-resolve — left for a separate change (e.g. an active=both option).
  • PAGE_SIZE is hardcoded to 200 rather than wired to the documented TOGGL_BATCH_SIZE env var, since the TogglAPI constructor doesn't currently receive config. Happy to thread it through if preferred.

Toggl v9 list endpoints paginate by page/per_page (sorted by name).
getProjects and getClients issued a single un-paginated GET, so the API
returned only the first page and silently dropped the tail. Any project
or client past that page failed name resolution and surfaced as the
"Project <id>" fallback in reports and summaries.

Add a requestAllPages helper that walks pages until a short page, with a
guard against endpoints that ignore `page` (prevents an infinite loop)
and a MAX_PAGES backstop. Wire getProjects/getClients through it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@jack-arturo jack-arturo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I reviewed the diff and ran the verification set locally after checking out the branch:

  • npm run build
  • npm test (33/33 passing)
  • npm run lint (0 errors; existing warnings remain)
  • npm audit --audit-level=high (0 high/critical; existing moderate brace-expansion advisory only)

I also approved the pending fork CI/Security runs; GitHub checks are now passing. The pagination helper is scoped to projects/clients and has focused coverage for multi-page, short-page, and non-advancing-page behavior.

@jack-arturo jack-arturo merged commit 48b669a into verygoodplugins:main Jun 8, 2026
10 checks passed
@janis-ps janis-ps deleted the fix/paginate-projects-clients branch June 9, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants