Skip to content

feat(identity): onboard Users service with getById#616

Open
Sarath1018 wants to merge 5 commits into
mainfrom
feat/identity-users-getbyid
Open

feat(identity): onboard Users service with getById#616
Sarath1018 wants to merge 5 commits into
mainfrom
feat/identity-users-getbyid

Conversation

@Sarath1018

Copy link
Copy Markdown
Collaborator

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:

SDK method Endpoint
getById(userId) GET /api/User/{userId}

Design notes

  • Org-level routing: Identity URLs have no tenant segment, 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 are returned as numeric codes, not string enums → mapped to UserType/UserCategory enums; internal legacyId is dropped from the SDK response.
  • Transforms: API is already camelCase; semantic renames creationTime→createdTime, lastModificationTime→lastModifiedTime, groupIDs→groupIds.
  • Full scaffold included: models/types/constants, subpath export wiring (package.json, rollup.config.js), TypeDoc export, mkdocs nav, oauth-scopes entry.

Testing

  • Unit: 3 tests (retrieval, transform completeness incl. absence of original API fields, error propagation)
  • Integration: 2 tests passing against live alpha — uses a configured IDENTITY_TEST_USER_ID fixture (self-provisioning arrives in PR 2 with create())
  • typecheck ✓, oxlint ✓, full unit suite passing

Stack

  1. This PR — service scaffold + getById
  2. feat/identity-users-crudupdateById, deleteById, create + bound entity methods
  3. feat/identity-users (feat(identity): add invite to Users service #609) — invite

🤖 Generated with Claude Code

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>
@Sarath1018
Sarath1018 marked this pull request as ready for review July 21, 2026 04:29
@Sarath1018
Sarath1018 requested a review from a team July 21, 2026 04:29
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://UiPath.github.io/uipath-typescript/pr-preview/pr-616/

Built to branch gh-pages at 2026-07-21 06:58 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Comment thread package.json Outdated
Comment thread tests/integration/config/unified-setup.ts
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review findings

Two issues flagged as inline comments:

  1. package.json:3 — Version downgraded from 1.5.5 to 1.5.4. Feature PRs must never touch the version; version bumps belong in a dedicated PR. Revert to 1.5.5.

  2. unified-setup.ts:69subscriptions is replaced by users in TestServices and createV1Services instead of being added alongside it. The existing subscriptions.integration.test.ts calls getServices().subscriptions, so this removal will cause a TypeScript error and silently break that test suite when re-enabled. Add users as a new field; keep subscriptions.

Comment thread package.json
Comment thread docs/oauth-scopes.md
Comment thread tests/integration/config/unified-setup.ts
@claude

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>
Comment thread src/models/identity/users.models.ts Outdated
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding posted as an inline comment this run:

users.models.ts:37-38{@link UserGetResponse} is orphaned on its own line after @returns instead of being inline. TypeDoc renders both lines concatenated without a separator, producing "Promise resolving to the user UserGetResponse". Inline placement + a brief content description fixes both the rendering and the missing "what the response includes" convention requirement.


The core implementation (model/types/constants, transform pipeline, endpoint wiring, unit + integration tests) looks correct.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

@Sarath1018
Sarath1018 force-pushed the feat/identity-users-getbyid branch from e1aa810 to b17f2fb Compare July 21, 2026 05:04
…ecret

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

✅ 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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Suggested change
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 {

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding posted as an inline comment this run:

users.types.ts:41 — The JSDoc on RawUserGetResponse says "User as returned by the Identity user management API" but the type uses SDK field names (createdTime, groupIds) and enum types (UserType, UserCategory) rather than the raw API wire format. The raw API shape lives in RawUserEntry (internal-types.ts). A future contributor implementing getAll could read this comment and incorrectly skip the transform step. Suggested fix: describe it as the "SDK-facing user shape" instead.


The rest of the implementation looks correct — transform pipeline, enum mappings, internal field stripping, subpath export wiring, and tests all follow the SDK conventions.

Comment on lines +42 to +47
return applyDataTransforms(renamed, {
field: 'type',
valueMap: UserTypeMap,
transform: (data) =>
applyDataTransforms(data, { field: 'category', valueMap: UserCategoryMap }),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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:

Suggested change
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 });

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review summary

One new finding posted as an inline comment this run:

users.ts:42–47applyDataTransforms is chained via the transform callback instead of two sequential calls. The transform option is for arbitrary post-processing, not for stringing together field-value maps; it reads less clearly and makes adding a third enum field require further nesting. Sequential calls are the SDK-wide convention.


All previously-raised threads were confirmed fixed (version downgrade reverted, subscriptions retained alongside users in TestServices, downloadCitationSource() not removed from oauth-scopes.md, {@link} inlined in @returns). The core implementation — transform pipeline, endpoint wiring, unit + integration tests, JSDoc — looks correct.

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>
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant