feat: Add IT Contacts API - #1681
Conversation
Generate the ItContacts service from the OpenAPI spec and expose it as workos.itContacts, with list/create/delete/invite/revoke operations. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Original prompt from jonatas
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| export * from './it-contact.interface'; | ||
| export * from './list-it-contacts-options.interface'; | ||
| export * from './revoke-it-contact-options.interface'; |
There was a problem hiding this comment.
🟡 List response types for IT contacts are not publicly exported
The public type describing the IT contacts list result is left out of the module's export list (src/it-contacts/interfaces/index.ts:3-11), so anyone importing the SDK cannot reference the return type of the list operation even though every other list-returning module exposes it.
Impact: Consumers of the published package cannot import ItContactList/ItContactListListMetadata (and their response variants) to type their own code, unlike every other list-returning service.
Barrel omission vs. established generated pattern
The interfaces barrel src/it-contacts/interfaces/index.ts exports 9 interface files but omits it-contact-list.interface and it-contact-list-list-metadata.interface, both of which exist and are listed in .oagen-manifest.json:87,96,97. listItContacts returns Promise<ItContactList> (src/it-contacts/it-contacts.ts:38), and the top-level package re-exports this barrel via export * from './it-contacts/interfaces' (src/index.ts:27). By comparison, the analogous generated module exports its list-response interface in the barrel (e.g. src/pipes/interfaces/index.ts exports data-integrations-list-response.interface), and the it-contacts serializers barrel (src/it-contacts/serializers/index.ts:6-7) does export the corresponding list serializers, showing the interfaces barrel is inconsistent/incomplete.
| export * from './it-contact.interface'; | |
| export * from './list-it-contacts-options.interface'; | |
| export * from './revoke-it-contact-options.interface'; | |
| export * from './it-contact.interface'; | |
| export * from './it-contact-list.interface'; | |
| export * from './it-contact-list-list-metadata.interface'; | |
| export * from './list-it-contacts-options.interface'; | |
| export * from './revoke-it-contact-options.interface'; |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
This is deliberate emitter behaviour, not an omission in this PR: the node barrel generator skips list-wrapper and list-metadata models — if (isListMetadataModel(model) || isListWrapperModel(model)) continue; in generateServiceBarrels (@workos/oagen-emitters). Other services just don't have a *-list.interface.ts today (IT Contacts is the first generated non-paginated list endpoint), so there's no precedent being broken; the pipes example is a *-list-response model, which isn't a list wrapper.
Since these files are generated and must not be hand-edited, exporting ItContactList/ItContactListListMetadata would need a change in the emitter rather than here. Leaving as generated; happy to file that upstream if we want list wrappers in the public type surface.
| async listItContacts(options: ListItContactsOptions): Promise<ItContactList> { | ||
| const { organizationId } = options; | ||
| const { data } = await this.workos.get<ItContactListResponse>( | ||
| `/organizations/${encodeURIComponent(organizationId)}/it_contacts`, | ||
| ); | ||
| return deserializeItContactList(data); | ||
| } |
There was a problem hiding this comment.
🔍 listItContacts does not use AutoPaginatable unlike Groups
listItContacts (src/it-contacts/it-contacts.ts:38-44) performs a plain GET and returns a materialized ItContactList rather than wrapping in AutoPaginatable and accepting pagination options, unlike the analogous listGroups in src/groups/groups.ts. The response still carries list_metadata cursors, so callers cannot auto-paginate. This appears intentional as generated output for this endpoint, but worth confirming against the spec that IT contacts are not paginated.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Correct as generated: GET /organizations/{organization_id}/it_contacts takes no pagination parameters in the spec (only the organization_id path param), so there is nothing for AutoPaginatable to page with. The list_metadata cursors come from the shared list wrapper shape. If the API adds limit/before/after later, regenerating will pick up the paginated shape.
Greptile SummaryThe PR moves the IT Contacts API into the organization-scoped service and adds its public models, serializers, fixtures, and tests.
Confidence Score: 5/5The PR appears safe to merge with no blocking failure remaining from the applicable previous review thread. No blocking failure remains. Important Files Changed
|
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Description
Adds the org-scoped IT Contacts endpoints to the
Organizationsservice, per review feedback that IT contacts are an organization subresource rather than a top-level resource:Matching naming policy in openapi-spec: workos/openapi-spec#110 (
OrganizationsItContacts->Organizations, concise operation names).Notes on why this is hand-written rather than emitted by
oagen:src/organizations/organizations.tsin this repo is still the pre-oagenhand-written service. Runningsdk:generate --lang nodescoped toOrganizationsreplaces it wholesale, which changes existing public signatures (getOrganization(id)-> options object, same fordeleteOrganization/updateOrganization), pulls in unrelated Organization/OrganizationDomain model drift, adds unrelated endpoints (audit log configuration, authorized applications) and does not typecheck as-is — ~600 lines of breaking churn unrelated to IT contacts. So this PR follows the existing conventions of that directory (List<ItContact>fromcommon/interfaces,Serialized*Optionsrequest shapes, serializers insrc/organizations/serializers) and leaves the Organizations generation migration as separate work, which will subsume these methods.No SDK wiring changes needed:
src/index.tsandsrc/index.worker.tsalready re-export./organizations/interfaces, soItContact,ItContactIntentand the option types are exported from both barrels.Tests: five new cases in
src/organizations/organizations.spec.tscovering method, path and request body for each operation.npm run lint,npm run typecheckandnpm testpass locally.Documentation
Does this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates.
The IT Contacts reference docs already exist; they may want Node snippets once this ships.
Link to Devin session: https://app.devin.ai/sessions/2633e183d1b146d6a18a87e0e1b9c42b
Requested by: @jonatascastro12