Add my assignments API operations (list, completed, due)#212
Add my assignments API operations (list, completed, due)#212robzolkos wants to merge 3 commits intobasecamp:mainfrom
Conversation
Three new endpoints for the current user's assignments:
- GET /my/assignments.json (priorities + non-priorities)
- GET /my/assignments/completed.json
- GET /my/assignments/due.json?scope={scope}
Includes Smithy spec, generated client, and Go service layer
with MyAssignmentsService (List, Completed, Due methods).
Spec Change ImpactChanges:
SDK Regeneration:
Breaking Changes:
SDK Update Checklist:
|
There was a problem hiding this comment.
Pull request overview
Adds Basecamp “My Assignments” support end-to-end (Smithy → OpenAPI/behavior model → generated Go client) and exposes it via a new Go service on AccountClient, aligning the SDK with the BC3 /my/assignments endpoints.
Changes:
- Extends the Smithy spec with
GetMyAssignments,GetMyAssignmentsCompleted, andGetMyAssignmentsDueoperations plusMyAssignmentshapes. - Regenerates
openapi.json,behavior-model.json, and the Go generated client to include the new endpoints/models. - Introduces
MyAssignmentsService(List,Completed,Due) and registers it viaAccountClient.MyAssignments().
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/basecamp.smithy | Adds the three /my/assignments operations and MyAssignment-related shapes to the source spec. |
| openapi.json | Regenerated OpenAPI containing the new paths, params, and schemas. |
| behavior-model.json | Regenerated behavior metadata for retries/readonly for the new operations. |
| go/pkg/generated/client.gen.go | Regenerated Go client interfaces, request builders, response parsers, and models for the new operations. |
| go/pkg/basecamp/my_assignments.go | New MyAssignmentsService wrapper and clean models, including conversion from generated types. |
| go/pkg/basecamp/client.go | Adds myAssignments field and MyAssignments() accessor on AccountClient. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Reuse the existing Person type for MyAssignment.Assignees instead of a separate MyAssignmentPerson struct, matching the pattern used by Todo.Assignees, Assignable.Assignees, and other types in the package.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 40 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jeremy
left a comment
There was a problem hiding this comment.
Blockers
1. Go service boundary diverges from spec and every other SDK
The Smithy spec tags all three operations as Reports (spec/overlays/tags.smithy:198-200). Every generated SDK places them in ReportsService (TypeScript, Ruby, Swift, Kotlin). But Go creates a brand new MyAssignmentsService (my_assignments.go:11) exposed via AccountClient.MyAssignments() (client.go:1283), with hook labels using Service: "MyAssignments" instead of Service: "Reports".
The existing Go ReportsService (reports.go) already has AssignedTodos, OverdueTodos, UpcomingSchedule — all under Service: "Reports". The new operations belong there too.
Impact: Cross-SDK API drift (Go: client.MyAssignments().List() vs everywhere else: client.reports.myAssignments()), and inconsistent observability labels for the same endpoints.
2. Smithy spec missing BadRequestError on GetMyAssignmentsDue
The upstream BC3 API docs state that an invalid scope value returns 400 Bad Request. The Smithy operation (basecamp.smithy:7496-7499) declares:
errors: [UnauthorizedError, ForbiddenError, RateLimitError, InternalServerError]
BadRequestError is absent. Since this spec is the source of truth, it should declare the documented error. No SDK has test coverage for the invalid-scope path — tests should assert SDK-specific error semantics (error codes, message content), not just 400 status presence.
Design decision needed before regeneration
3. MyAssignmentPerson vs Person — source model inconsistency
Commit dedb521e says "Replace MyAssignmentPerson with Person for consistency" but only changed Go's hand-authored SDK layer. The Smithy model still defines MyAssignmentPerson as a narrow three-field shape (basecamp.smithy:7560-7566: id, name, avatar_url). Every generated SDK still exposes this separate type.
The full Person shape (basecamp.smithy:1238) is much broader (~18 fields). Go now uses Person for Assignees but only populates 3 fields, leaving the rest zero-valued.
The decision: should assignees on my-assignments stay narrow (MyAssignmentPerson) or widen to the shared Person type? Either is valid, but all SDKs need to match. This must be decided before regeneration to avoid doing downstream churn twice.
Fix checklist
- Move the three methods from
MyAssignmentsServiceintoReportsService(reports.go) - Remove
MyAssignmentsServicestruct,NewMyAssignmentsService, andAccountClient.MyAssignments()fromclient.go - Change hook labels from
Service: "MyAssignments"toService: "Reports"on all three methods - Add
BadRequestErrortoGetMyAssignmentsDueerrors list inbasecamp.smithy:7499 - Regenerate OpenAPI and all downstream artifacts
- Add invalid-scope tests in Go, TypeScript, and Ruby (asserting error codes/messages, not just status)
- Decide
MyAssignmentPersonvsPersonat the Smithy level; make all SDKs match
Secondary observations
MyAssignmentRefdual-purpose struct: ExistingReportsServiceuses distinctBucketandParenttypes (inAssignable,reports.go:176-187). The new code introducesMyAssignmentRefwhich collapses both —Namefor buckets,Titlefor parents, the unused field silently empty. If methods move toReportsService, consider reusing the existing types.- Go test gaps:
Due(ctx, nil)untested;Completed/Duehave no error-path tests; zero-valueBucket/Parentguard logic untested. Coverage gaps, not bugs. - No Swift or Kotlin tests for the new report operations.
- Kotlin
myAssignments()returnsJsonElementfor the grouped{priorities, non_priorities}response rather than a typed wrapper. Consistent with Kotlin generator conventions but weaker than other SDKs.
|
Took another swing at this in #213 |
Summary
/my/assignmentsAPI operations to the Smithy spec, matching the BC3 endpoints from #9932GetMyAssignments—GET /my/assignments.jsonreturning priorities and non-prioritiesGetMyAssignmentsCompleted—GET /my/assignments/completed.jsonreturning completed assignmentsGetMyAssignmentsDue—GET /my/assignments/due.json?scope=with scope filtering (overdue, due_today, due_tomorrow, due_later_this_week, due_next_week, due_later)MyAssignmentsService) withList,Completed, andDuemethodsAccountClientviaMyAssignments()accessorNew
MyAssignmentshape is separate from the existingAssignablesince the response format differs (usescontentinstead oftitle, includescompleted,comments_count,has_description,priority_recording_id,children).Summary by cubic
Adds three
/my/assignmentsAPI operations (list, completed, due) and updates all SDKs (Go, TypeScript, Swift, Kotlin, Ruby) with service methods and models. Regenerates the spec, wires the GoMyAssignmentsServiceintoAccountClient, fixes codegen mappings, reusesPersonfor assignees, and adds tests.New Features
GetMyAssignments,GetMyAssignmentsCompleted,GetMyAssignmentsDuewithscopefilter (overdue,due_today,due_tomorrow,due_later_this_week,due_next_week,due_later) and retry (3x on 429/503).MyAssignmentshape (separate fromAssignable) withcontent,completed,comments_count,has_description,priority_recording_id,children, andassigneesusingPerson.MyAssignmentsServicewithList,Completed,Due(opts); available viaAccountClient.MyAssignments().Bug Fixes
MyAssignmentPersonwithPersonforMyAssignment.assigneesacross SDKs for consistency.Written for commit dedb521. Summary will update on new commits.