feat(identity): onboard Users service with getById#616
Conversation
First slice of the Identity user management onboarding: introduces the
modular Users service (@uipath/uipath-typescript/users) with
- getById(userId) GET /api/User/{userId}
Identity routes at the organization level, so endpoints use a `../identity_`
base (IDENTITY_ORG_BASE) to collapse the tenant segment ApiClient inserts —
same pattern as the notification service.
Live-API findings encoded (Swagger spec is wrong on these): `type`/`category`
come back as numeric codes, not string enums — mapped to UserType/UserCategory
via value maps; internal `legacyId` is dropped.
Follow-up PRs add updateById/deleteById/create (with bound entity methods)
and invite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Review findingsTwo issues flagged as inline comments:
|
This comment was marked as resolved.
This comment was marked as resolved.
The branch was assembled from a draft based on an older main; oauth-scopes.md, mkdocs.yml, package.json and unified-setup.ts had newer main content (downloadCitationSource row, Sample Apps Gallery nav, 1.5.5 version bump, Subscriptions service registration) reverted. Reset those files to main and re-applied only the Users additions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review summaryOne new finding posted as an inline comment this run: users.models.ts:37-38 — The core implementation (model/types/constants, transform pipeline, endpoint wiring, unit + integration tests) looks correct. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
✅ No issues found. Checked for bugs and CLAUDE.md compliance. |
e1aa810 to
b17f2fb
Compare
…ecret Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
✅ No issues found. Checked for bugs and CLAUDE.md compliance. |
| * Field selection: `legacyId` (an internal platform synchronization field) is returned | ||
| * by the API but dropped from the SDK because it has no use for an application developer. | ||
| */ | ||
| export interface RawUserGetResponse { |
There was a problem hiding this comment.
The JSDoc says "User as returned by the Identity user management API" but RawUserGetResponse is the SDK-facing shape (after field renames and numeric→enum mapping), not the raw API wire format. The actual API response shape is RawUserEntry in users.internal-types.ts — which has creationTime, groupIDs, and numeric type/category codes.
Per CLAUDE.md: Raw{Entity}GetResponse types describe the shape before method attachment, not the literal API wire format. A contributor implementing a future method (e.g. getAll) who reads this comment could incorrectly assume the API returns createdTime / UserType values and skip the transform step.
| export interface RawUserGetResponse { | |
| /** | |
| * SDK-facing user shape returned by {@link UserServiceModel.getById}. | |
| * | |
| * Field selection: `legacyId` (an internal platform synchronization field) is returned | |
| * by the API but dropped from the SDK because it has no use for an application developer. | |
| */ | |
| export interface RawUserGetResponse { |
Review summaryOne new finding posted as an inline comment this run: users.types.ts:41 — The JSDoc on The rest of the implementation looks correct — transform pipeline, enum mappings, internal field stripping, subpath export wiring, and tests all follow the SDK conventions. |
| return applyDataTransforms(renamed, { | ||
| field: 'type', | ||
| valueMap: UserTypeMap, | ||
| transform: (data) => | ||
| applyDataTransforms(data, { field: 'category', valueMap: UserCategoryMap }), | ||
| }); |
There was a problem hiding this comment.
Non-standard use of the transform callback to chain a second applyDataTransforms call. The transform option is designed for arbitrary post-processing, not for chaining field-value maps; using it this way is unusual and makes extending the pipeline (e.g., a third enum field) require further nesting.
The conventional pattern throughout the SDK is two sequential calls:
| return applyDataTransforms(renamed, { | |
| field: 'type', | |
| valueMap: UserTypeMap, | |
| transform: (data) => | |
| applyDataTransforms(data, { field: 'category', valueMap: UserCategoryMap }), | |
| }); | |
| const withType = applyDataTransforms(renamed, { field: 'type', valueMap: UserTypeMap }); | |
| return applyDataTransforms(withType, { field: 'category', valueMap: UserCategoryMap }); |
Review summaryOne new finding posted as an inline comment this run: users.ts:42–47 — All previously-raised threads were confirmed fixed (version downgrade reverted, |
Verified empirically: a scope-less PAT from an admin account succeeds on all /api/User endpoints (200/204) while the same token is rejected by Orchestrator (401). Identity user management is authorized by org-admin role, not OAuth scopes — the previously listed PM.Users scopes are not enforced. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|



Summary
PR 1 of 3 splitting the Identity user management onboarding (#609 is the final slice). Introduces the modular Users service (
@uipath/uipath-typescript/users) with the first method:getById(userId)GET /api/User/{userId}Design notes
../identity_base (IDENTITY_ORG_BASE) to collapse the tenant segmentApiClientinserts — same pattern as the notification service.type/categoryare returned as numeric codes, not string enums → mapped toUserType/UserCategoryenums; internallegacyIdis dropped from the SDK response.creationTime→createdTime,lastModificationTime→lastModifiedTime,groupIDs→groupIds.package.json,rollup.config.js), TypeDoc export, mkdocs nav, oauth-scopes entry.Testing
IDENTITY_TEST_USER_IDfixture (self-provisioning arrives in PR 2 withcreate())Stack
getByIdfeat/identity-users-crud—updateById,deleteById,create+ bound entity methodsfeat/identity-users(feat(identity): add invite to Users service #609) —invite🤖 Generated with Claude Code