feat: workspace user listing and per-user report filtering - #46
feat: workspace user listing and per-user report filtering#46vincentardern wants to merge 2 commits into
Conversation
Adds a new toggl_list_workspace_users tool and extends all four reporting tools (toggl_daily_report, toggl_weekly_report, toggl_project_summary, toggl_workspace_summary) with optional uid + workspace_id parameters that route through the Reports API v3 to fetch another workspace member's time entries. Also refactors the duplicated retry/rate-limit loop into a shared fetchWithRetry() private method used by both request() and the new reportsRequest() helper, removes the unused getDetailedReport() stub, and extracts resolveDateRange() to eliminate repeated date-range resolution logic in the report handlers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8b11a2c to
7ef6ca3
Compare
|
Hi – just a gentle ping on this one. The CI workflows are still awaiting maintainer approval to run. Would you be able to approve them so the test suite can execute? Happy to address any feedback once the checks are through. Thanks! |
|
Thanks for the ping @vincentardern , and glad to see CI is passing. I’m open to the capability here. I’m generally cautious about expanding the MCP tool surface, but Before merging, could you address two things?
One smaller privacy nit: I’d prefer the new user-listing tool not return emails/admin fields by default unless they’re needed. Once those are cleaned up, I think this is mergeable 🙏 |
- Use documented v9 GET /workspaces/{id}/users endpoint (was the
undocumented /workspace_users); map id->uid, fullname->name,
is_active->active.
- Drop misleading grouped:true from the reports query and make
time-entry flattening defensive: use nested time_entries when
present, else treat the row as a single entry (v3 search response
body schema is undocumented).
- Extract TogglAPI.toWorkspaceMemberSummary returning only
{uid,name,active}; regression test asserts email/admin/role/rate
never leak.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — all three addressed in c2f411c:
Build clean, 40/40 tests, lint 0 errors. |
|
I opened a maintainer refresh branch as #57: #57 This keeps the original contribution moving without force-pushing to the fork, and stacks the work on the refreshed self-host HTTP foundation from #36. The refresh preserves the workspace-user/report-filtering intent from this PR, adds MCP handler coverage, uses the documented /workspaces/{id}/users response shape, and keeps the member listing privacy-safe as uid/name/active only. I credited the original work in the commit and PR body. Local verification on #57:
|
* feat(toggl): add workspace user reporting Refreshes PR #46 on top of feat/self-host-streamable-http. Adds privacy-safe workspace user lookup and optional uid report filtering through Toggl Reports API v3. Co-authored-by: Vincent Ardern <vincent@charityaccounts.co.nz> * fix: address review feedback for workspace users and header casing --------- Co-authored-by: Vincent Ardern <vincent@charityaccounts.co.nz> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Summary
toggl_list_workspace_users— lists all members of a workspace with theiruidvaluestoggl_daily_report,toggl_weekly_report,toggl_project_summary,toggl_workspace_summary) with optionaluid+workspace_idparameters that route through the Reports API v3 to fetch a specific team member's entries instead of the authenticated user'sfetchWithRetry()private method used by bothrequest()and the newreportsRequest()helper, and removes the unusedgetDetailedReport()stubresolveDateRange()to eliminate repeated date-range logic across the four report handlersHow it works
When
uidis omitted the existing code path is unchanged — no extra API calls, no performance impact. Whenuidis provided, the Reports API v3 (/search/time_entries) is used withuser_idsfiltering and automatic cursor-based pagination via theX-Next-Row-Numberresponse header.The Reports API returns grouped rows with nested
time_entriesarrays; these are flattened into the sameTimeEntryshape the rest of the codebase uses, so hydration and report generation work without modification. The Reports API uses inclusive end dates — conversion from the codebase's exclusive-end convention happens insidegetTimeEntriesForUserAndDateRange().Test plan
npm test— all 37 tests passtoggl_list_workspace_usersreturns workspace members withuidvaluestoggl_daily_report/toggl_weekly_reportwithuidreturns correct entries for that memberuidbehave identically to before🤖 Generated with Claude Code