Skip to content

feat(identity): onboard Identity user management endpoints as Users service#609

Draft
Sarath1018 wants to merge 1 commit into
mainfrom
feat/identity-users
Draft

feat(identity): onboard Identity user management endpoints as Users service#609
Sarath1018 wants to merge 1 commit into
mainfrom
feat/identity-users

Conversation

@Sarath1018

Copy link
Copy Markdown
Collaborator

Summary

Adds a new modular Users service (@uipath/uipath-typescript/users) onboarding the CORS-whitelisted Identity /api/User endpoints:

SDK method Endpoint
getById(userId) GET /api/User/{userId}
updateById(userId, options) PUT /api/User/{userId}
deleteById(userId) DELETE /api/User/{userId}
create(users, organizationId, options?) POST /api/User/BulkCreate
invite(users) POST /api/User/InviteUsers

getById() and create() return users with bound entity methods (user.update(), user.delete()).

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 via value maps
    • BulkCreate returns { result, users[] }, not a bare IdentityResult
    • invite redirectUrl is effectively required and must be a portal acceptInvite URL (validated per user)
    • userName is required for create (email alone is rejected)
  • Transforms: API is already camelCase (no case conversion); semantic renames creationTime→createdTime, lastModificationTime→lastModifiedTime, groupIDs→groupIds, errorMsg→errorMessage; internal legacyId dropped.

Testing

  • Unit: 20 new tests (service + bound-method model tests) — full suite 2079 passing
  • Integration: 8/8 passing against live alpha (procodeapps org) — full CRUD + invite lifecycle with cleanup; validates the org-level URL routing through the real ApiClient
  • Verification: typecheck ✓, oxlint ✓, rollup build ✓ (dist/users/* generated)

New integration env vars (optional, documented in tests/.env.integration.example): UIPATH_ORGANIZATION_ID (org GUID for create/invite), UIPATH_PORTAL_URL (portal host for invite redirect URLs when UIPATH_BASE_URL is the API gateway).

Remaining before marking ready

  • E2E browser validation (sdk-verify)
  • Convention review loop (sdk-review)
  • Cloudflare CORS worker: endpoints already whitelisted per cross-reference (api/User/{x} covers all five)

🤖 Generated with Claude Code

…ervice

Adds a new modular Users service (@uipath/uipath-typescript/users) covering
the whitelisted Identity /api/User endpoints:

- getById(userId)            GET    /api/User/{userId}
- updateById(userId, opts)   PUT    /api/User/{userId}
- deleteById(userId)         DELETE /api/User/{userId}
- create(users, orgId, opts) POST   /api/User/BulkCreate
- invite(users)              POST   /api/User/InviteUsers

Identity routes at the organization level, so endpoints use a `../identity_`
base to collapse the tenant segment ApiClient inserts (same pattern as the
notification service).

Live-API findings encoded in the SDK (spec is wrong on these):
- `type`/`category` come back as numeric codes, not string enums — mapped to
  UserType/UserCategory via value maps
- BulkCreate returns `{ result, users[] }`, not a bare IdentityResult
- invite `redirectUrl` is effectively required and must be a portal
  acceptInvite URL

Includes unit tests (service + bound-method model tests), live integration
tests (8/8 passing against alpha), JSDoc on UserServiceModel, and docs
updates (oauth-scopes, mkdocs nav).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
});

it('should throw when the user ID is undefined', async () => {
const user = createUserWithMethods(createBasicUser({ id: undefined as any }), mockService);

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 as any cast is unnecessary. createBasicUser accepts Partial<RawUserGetResponse>, which makes id type string | undefined, so { id: undefined } is valid TypeScript without a cast. Same issue on line 69.

Convention: "No any type — use unknown if truly unknown, then validate."

Suggested change
const user = createUserWithMethods(createBasicUser({ id: undefined as any }), mockService);
const user = createUserWithMethods(createBasicUser({ id: undefined }), mockService);

@claude

claude Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review summary

New finding posted this run:

  • tests/unit/models/identity/users.test.ts lines 51 & 69 — unnecessary as any casts. createBasicUser takes Partial<RawUserGetResponse>, which makes id type string | undefined, so { id: undefined } compiles without any cast. Suggestion posted on line 51 (same fix applies to line 69).

Everything else checked out — transform pipeline, endpoint routing, type naming, pagination absence, JSDoc on UserServiceModel, @track decorators, barrel exports, and integration test cleanup patterns all follow CLAUDE.md conventions.

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