Skip to content

feat(notifications): foundation + getAll (PR 1/7) - #512

Merged
sarthak688 merged 1 commit into
mainfrom
feat/notifications-sdk
Jun 30, 2026
Merged

feat(notifications): foundation + getAll (PR 1/7)#512
sarthak688 merged 1 commit into
mainfrom
feat/notifications-sdk

Conversation

@sarthak688

Copy link
Copy Markdown
Contributor

First in a stack of 7 PRs onboarding the user-facing Notification platform as a new modular subpath @uipath/uipath-typescript/notifications. This PR lays the foundation and ships one method (Notifications.getAll). Each subsequent PR (stacked on top of this branch) adds a small group of related methods.

Methods Added

Layer Method Signature
Service notifications.getAll() getAll<T extends NotificationGetAllOptions>(tenantId: string, options?: T): Promise<T extends HasPaginationOptions<T> ? PaginatedResponse<NotificationGetResponse> : NonPaginatedResponse<NotificationGetResponse>>

Endpoint Called

Method HTTP Endpoint OAuth Scope
notifications.getAll() GET notificationservice_/notificationserviceapi/odata/v1/NotificationEntry NotificationService
  • NotificationService extends BaseService — UserContext auth, no folder header.
  • getAll() supports OData pagination via PaginationHelpers.getAll ($top, $skip, $count) and OData query options (filter, orderby).
  • $select is not exposed (the API returns HTTP 500 when $select is supplied — verified live).
  • The method carries an @track('Notifications.GetAll') telemetry decorator.

Critical design point #1: tenantId as a per-call argument

The Notification API does not include the tenant in the URL path. Instead, it identifies the acting tenant via the X-UIPATH-Internal-TenantId header, which expects a tenant GUID (not the configured tenantName). The SDK takes tenantId as the first positional argument on every NS method and forwards it into the header via createHeaders() on each call. This mirrors how folder-scoped Orchestrator services already require folderId from the caller.

Critical design point #2: URL traversal for tenant-less routing

The notification service routes at the organization level — its URLs do NOT include a tenant segment, unlike most UiPath services. ApiClient always inserts ${orgName}/${tenantName}/${path}, so the endpoint constants use a ../ prefix to collapse the tenant segment:

// src/utils/constants/endpoints/base.ts
export const NOTIFICATION_BASE = '../notificationservice_';

${orgName}/${tenantName}/../notificationservice_/... resolves via new URL() normalization to ${orgName}/notificationservice_/.... The NOTIFICATION_BASE JSDoc documents this in detail. Verified live:

  • alpha.uipath.com/testmanagerdev/notificationservice_/... → HTTP 200
  • alpha.uipath.com/testmanagerdev/TestManagerDevTenant/notificationservice_/... → 302 /portal_/unregistered

Example Usage

import { UiPath } from '@uipath/uipath-typescript/core';
import { Notifications } from '@uipath/uipath-typescript/notifications';

const sdk = new UiPath(config);
await sdk.initialize();

const notifications = new Notifications(sdk);
const tenantId = '<tenant-guid>';

// List unread, most recent first
const unread = await notifications.getAll(tenantId, {
  filter: 'isRead eq false',
  orderby: 'publishedOn desc',
  pageSize: 20,
});

// First page with pagination
const page1 = await notifications.getAll(tenantId, { pageSize: 20 });
if (page1.hasNextPage) {
  const page2 = await notifications.getAll(tenantId, { cursor: page1.nextCursor });
}

API Response vs SDK Response

Transform pipeline

PaginationHelpers.getAlltransformFn: stripInternalNotificationFields → returned to consumer.

The API already returns camelCase, so pascalToCamelCaseKeys() is not applied. There are no semantic field renames. The only transform is dropping internal/transport-layer fields.

Field-strip (dropped from NotificationGetResponse)

Dropped field Reason
entityOrgName, entityTenantName Internal routing metadata
serviceRegistryName Internal infrastructure
messageTemplateKey, messageVersion Internal templating
publicationId Internal publish-event id
correlationId Internal tracing
partitionKey Storage detail (was readOnly: true in spec)

Sample SDK Response

notifications.getAll(tenantId, { pageSize: 1 })
{
  "items": [
    {
      "id": "9a3b0db5-9b8b-44a7-9b6a-08de0a17b4e2",
      "message": "A new model is now available for your product.",
      "isRead": false,
      "publisherName": "LlmGateway",
      "publisherId": "adc041d6-3098-4766-ae45-08dd3ac994aa",
      "topicName": "New model available for product",
      "topicKeyName": "New.Model.Available",
      "topicId": "66e76b72-5ef1-4567-6a00-08dd3ac994ba",
      "userId": "9ABFE2B8-F30F-4917-9F7F-A91D28F7B23C",
      "userEmail": null,
      "tenantId": null,
      "priority": "Low",
      "category": "Info",
      "messageParam": null,
      "redirectionUrl": "https://alpha.uipath.com/.../portal_/admin/ai-trust-layer/llm-configurations",
      "publishedOn": 1780413050
    }
  ],
  "totalCount": 500,
  "hasNextPage": true,
  "supportsPageJump": true,
  "currentPage": 1
}

Note: publishedOn is Unix epoch seconds (not milliseconds). Internal fields (entityOrgName, partitionKey, correlationId, etc.) are stripped before the SDK consumer sees the response.

Verification

Check Status
npm run typecheck ✅ clean
npm run lint ✅ 0 warnings, 0 errors
npm run test:unit ✅ 64 files / 1801 tests (4 in notification suite)
npm run build dist/notifications/index.{mjs,cjs,d.ts} produced

Live API curl confirmed the endpoint works against alpha/testmanagerdev.

Files

Area Files
Endpoint constants src/utils/constants/endpoints/notification.ts (new), src/utils/constants/endpoints/base.ts (NOTIFICATION_BASE), src/utils/constants/endpoints/index.ts
Types src/models/notification/notifications.types.ts
Internal types src/models/notification/notifications.internal-types.ts
Models src/models/notification/notifications.models.ts, index.ts
Services src/services/notification/notifications.ts, index.ts
Build package.json (subpath ./notifications), rollup.config.js (notifications entry)
Unit tests tests/unit/services/notification/notifications.test.ts (4 tests)
Integration tests tests/integration/shared/notification/notifications.integration.test.ts (4 tests, v1 mode only)
Integration wiring tests/integration/config/test-config.ts (notificationTenantId), tests/integration/config/unified-setup.ts, tests/.env.integration.example (NOTIFICATION_TEST_TENANT_ID)
Test utils tests/utils/constants/notification.ts, tests/utils/mocks/notification.ts (+ barrel updates)
Docs docs/oauth-scopes.md, docs/pagination.md, mkdocs.yml

PR Stack

This PR is part of a 7-PR stack that incrementally builds out the Notifications + Subscriptions services. Each subsequent PR targets the previous PR's branch.

# Branch Methods
1 feat/notifications-sdk (this PR) getAll
2 feat/notifications-mark-read markRead, markUnread, markAllRead
3 feat/notifications-delete deleteNotifications, deleteAll
4 feat/subscriptions-sdk Subscriptions foundation + getAll, getPublishers, getSupportedChannels
5 feat/subscriptions-topic-updates updateTopic, updateCategory
6 feat/subscriptions-publisher-updates updatePublisher, updateTopicGroup
7 feat/subscriptions-mode-reset updateMode, reset

Replaces #500.

🤖 Generated with Claude Code

Comment thread src/models/notification/notifications.types.ts Outdated
sarthak688 added a commit that referenced this pull request Jun 12, 2026
The NotificationMode enum describes notification delivery channels
(Email, Slack, Teams, InApp). It's a Subscriptions concept — the
notification inbox response doesn't reference it — and its JSDoc
cross-refs Subscriptions.getSupportedChannels() which doesn't exist
until PR 4. Removing the premature export here; PR 4 will (re-)define
it where it's first used.

Addresses review comment on PR #512.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

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

Comment thread docs/oauth-scopes.md Outdated
Comment thread src/models/notification/notifications.models.ts
sarthak688 added a commit that referenced this pull request Jun 12, 2026
NotificationService uses an internal OAuth scope. Per reviewer feedback
on #512:
- Tag the only method (getAll) @internal in both the ServiceModel
  interface and the service class so TypeDoc hides it from generated
  SDK API docs.
- Remove the Notifications section from docs/oauth-scopes.md (that file
  is for external scopes only).
- Remove the Notifications row from docs/pagination.md and the
  Notifications nav entry from mkdocs.yml — these surface methods that
  external SDK consumers can't call.

Addresses review comments on PR #512.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sarthak688 added a commit that referenced this pull request Jun 12, 2026
…opes entries

NotificationService uses an internal scope. Tag markRead, markUnread,
and markAllRead @internal in both the ServiceModel interface and the
service class so TypeDoc hides them from generated SDK API docs.
Remove their entries from docs/oauth-scopes.md (external-only).

Addresses reviewer feedback on PR #512 (same treatment applied here).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sarthak688 added a commit that referenced this pull request Jun 12, 2026
…s entries

Same treatment as PR #512 / #513 — tag deleteNotifications, deleteAll
@internal in models + service, drop their oauth-scopes entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sarthak688 added a commit that referenced this pull request Jun 12, 2026
… docs

NotificationService scope is internal. Tag getAll, getPublishers,
getSupportedChannels @internal in both the ServiceModel interface
and the service class. Remove the Subscriptions section from
docs/oauth-scopes.md and the Subscriptions entry from mkdocs.yml nav.

Same treatment as PR #512.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/models/notification/notifications.types.ts Outdated
Comment thread src/models/notification/notifications.types.ts
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

New finding from this review run:

Missing import — compile error (notifications.types.ts line 5): RequestOptions is referenced in Omit<RequestOptions, 'expand' | 'select'> at the bottom of the file but is never imported. The previous suggestion was applied via GitHub's Apply suggestion button, which only committed the type-alias body — the prerequisite import type { RequestOptions } from '../common/types'; line was not included. The typecheck claim in the PR description predates that last commit, so the branch currently fails npm run typecheck.

@sarthak688
sarthak688 requested a review from vnaren23 June 15, 2026 04:53
@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch from bf99365 to 27cbc39 Compare June 15, 2026 04:54
@sarthak688
sarthak688 requested a review from Copilot June 15, 2026 04:56
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds the initial Notifications SDK subpath (@uipath/uipath-typescript/notifications) and onboards the first user-facing method, Notifications.getAll, including endpoint constants, models/types, and unit + integration coverage. The implementation uses tenant GUID forwarding via X-UIPATH-Internal-TenantId and OData OFFSET pagination via PaginationHelpers.getAll.

Changes:

  • Introduces NotificationService (exported as Notifications) with getAll(tenantId, options?) and a transform that strips internal API fields.
  • Adds Notification models (public types + ServiceModel) and internal types/constants for field stripping.
  • Wires new notifications subpath into build/package exports and adds unit/integration tests + test fixtures/constants.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/utils/mocks/notification.ts Adds mock factory for raw notification entries (incl. internal fields).
tests/utils/mocks/index.ts Re-exports notification mocks via test mocks barrel.
tests/utils/constants/notification.ts Adds notification-specific test constants (tenant GUID, IDs, sample message, etc.).
tests/utils/constants/index.ts Re-exports notification test constants via constants barrel.
tests/unit/services/notification/notifications.test.ts Unit tests for getAll wiring + stripInternalNotificationFields.
tests/integration/shared/notification/notifications.integration.test.ts Integration tests for getAll + internal field stripping.
tests/integration/config/unified-setup.ts Registers Notifications service in v1 integration service setup.
tests/integration/config/test-config.ts Adds notificationTenantId to integration config loading/validation.
tests/.env.integration.example Documents NOTIFICATION_TEST_TENANT_ID env var for integration runs.
src/utils/constants/endpoints/notification.ts Adds notification service endpoint constants (GET_ALL).
src/utils/constants/endpoints/index.ts Re-exports notification endpoints from endpoints barrel.
src/utils/constants/endpoints/base.ts Adds NOTIFICATION_BASE (../notificationservice_) with routing JSDoc.
src/services/notification/notifications.ts Implements NotificationService.getAll + internal-field stripping transform.
src/services/notification/index.ts Creates notifications module entry and exports Notifications + models.
src/models/notification/notifications.types.ts Defines Notification enums, response shape, and getAll options.
src/models/notification/notifications.models.ts Adds NotificationServiceModel interface for API docs/reference.
src/models/notification/notifications.internal-types.ts Defines RawNotificationEntry + internal-field list.
src/models/notification/index.ts Adds notification models barrel export.
rollup.config.js Adds rollup entry for notifications build output.
package.json Adds ./notifications subpath export mapping to dist/notifications/*.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/services/notification/notifications.ts
Comment thread src/models/notification/notifications.models.ts
Comment thread src/models/notification/notifications.models.ts Outdated
Comment thread src/models/notification/notifications.internal-types.ts Outdated
@Sarath1018

Copy link
Copy Markdown
Collaborator

Please update PR description

@Sarath1018

Copy link
Copy Markdown
Collaborator

Can you add integration tests, test them locally using bearer token and once local testing is done skip them and push. So that in future if PAT token supports the required scopes we can just un-skip those tesrs

Comment thread src/models/notification/notifications.constants.ts
Comment thread src/models/notification/notifications.internal-types.ts Outdated
@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch from 019e3b3 to 9d136e9 Compare June 29, 2026 04:56
@sarthak688
sarthak688 requested a review from Sarath1018 June 29, 2026 04:57
@claude

claude Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

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

Comment thread src/models/notification/notifications.types.ts Outdated
Comment thread src/services/notification/notifications.ts Outdated
@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch from 9d136e9 to 0f2e425 Compare June 29, 2026 12:14
Comment thread src/models/notification/notifications.models.ts Outdated
@claude

claude Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

New finding from this review run:

Missing @param options in NotificationServiceModel (notifications.models.ts line 33): The service class (notifications.ts line 54) documents both @param tenantId and @param options, but NotificationServiceModel only has @param tenantId. Convention requires identical JSDoc on both files — add @param options - Optional OData query and pagination options after the @param tenantId line in the ServiceModel.

@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch from 52822ad to 7fc5058 Compare June 29, 2026 14:18
Comment thread tests/unit/services/notification/notifications.test.ts Outdated
@claude

claude Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

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

@claude

claude Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

New finding from this review run:

Missing ! definite assignment assertion (notifications.test.ts line 164): let RealApiClient: typeof ApiClient; in the routing test should be let RealApiClient!: typeof ApiClient;. Convention requires the ! for all variables initialized in beforeAll rather than at declaration.

@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch 2 times, most recently from b506498 to 8a4a2a0 Compare June 29, 2026 15:38
Comment thread src/models/notification/notifications.models.ts Outdated
Comment thread src/services/notification/notifications.ts Outdated
…nternal]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
@sarthak688
sarthak688 force-pushed the feat/notifications-sdk branch from 8a4a2a0 to 5b4d11c Compare June 30, 2026 10:49
@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

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

@sonarqubecloud

Copy link
Copy Markdown

@sarthak688
sarthak688 merged commit 4709de1 into main Jun 30, 2026
18 checks passed
@sarthak688
sarthak688 deleted the feat/notifications-sdk branch June 30, 2026 11:15
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.

4 participants