Skip to content

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

Open
sarthak688 wants to merge 1 commit into
mainfrom
feat/notifications-sdk
Open

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

Conversation

@sarthak688

Copy link
Copy Markdown

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
@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from 9594fac to f2758f7 Compare June 15, 2026 08:46
Comment thread src/services/notification/notifications.ts Outdated
Comment thread tests/utils/constants/notification.ts Outdated
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

New findings from this review run:

  1. Stale @returns in service class (notifications.ts line 53): The prior fix updated notifications.models.ts but left the service class with the old "Array of notifications" description. Both must be identical per convention.

  2. Unused speculative test constants (notification.ts lines 12–13): NOTIFICATION_ID_2, NOTIFICATION_ID_3, and ERROR_NOTIFICATION_NOT_FOUND are defined but never used in this PR — pre-staged for future PRs, which violates the "no hypothetical future requirements" convention.

@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from 55d58a6 to 7634b6c Compare June 15, 2026 11:13
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from 7634b6c to 311c875 Compare June 15, 2026 11:23
@claude

claude Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

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

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch 2 times, most recently from fdcc363 to c09e8e0 Compare June 16, 2026 06:04
Comment on lines +34 to +35
* @param options - Optional OData query and pagination options
* @returns Promise resolving to either a NonPaginatedResponse<NotificationGetResponse> or a PaginatedResponse<NotificationGetResponse> when pagination options are used.

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.

@returns missing {@link} refs + orphaned {@link} fragment on the next line.

Two issues here:

  1. The @returns text uses bare type names while the service class copy uses {@link} inline refs — violating "both the models file and the service implementation file must have identical JSDoc for each public method" (agent_docs/conventions.md). The ServiceModel is the source of truth, so it should set the format that the service class mirrors.

  2. The {@link NotificationGetResponse} on its own line (35) is an orphaned fragment — it's not part of any @param, @returns, or @example tag, so TypeDoc attaches it to the @returns block and renders it as a stray "NotificationGetResponse" hyperlink appended after the description. This looks like a copy-paste artifact from the prior fix.

Fix both lines (delete line 35, add {@link} refs inline on line 34):

Suggested change
* @param options - Optional OData query and pagination options
* @returns Promise resolving to either a NonPaginatedResponse<NotificationGetResponse> or a PaginatedResponse<NotificationGetResponse> when pagination options are used.
* @returns Promise resolving to either a {@link NonPaginatedResponse}<{@link NotificationGetResponse}> or a {@link PaginatedResponse}<{@link NotificationGetResponse}> when pagination options are used.

* @param tenantId - Tenant GUID (sent via `X-UIPATH-Internal-TenantId`)
* @param options - Optional OData query and pagination options
* @returns Promise resolving to either a {@link NonPaginatedResponse}<{@link NotificationGetResponse}> or a {@link PaginatedResponse}<{@link NotificationGetResponse}> when pagination options are used.
* {@link NotificationGetResponse}

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.

Same orphaned {@link NotificationGetResponse} fragment as in the ServiceModel (line 35 there). Once line 35 in notifications.models.ts is deleted and the {@link} refs are inlined on the @returns line, delete this line too so the two files stay in sync.

Suggested change
* {@link NotificationGetResponse}
*

@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

New findings from this review run:

  1. Orphaned {@link} fragment + missing inline {@link} refs in ServiceModel (notifications.models.ts lines 34–35): The @returns description uses bare type names while the service class uses {@link} inline refs — the two are not identical per convention. The {@link NotificationGetResponse} on line 35 is a dangling fragment (copy-paste artifact from the prior fix) that TypeDoc attaches as a stray trailing link.

  2. Same dangling fragment in the service class (notifications.ts line 54): Mirror of issue 1 — remove this line once the ServiceModel is fixed.

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from c09e8e0 to 730c61b Compare June 16, 2026 06:07
Comment thread src/models/notification/notifications.models.ts
@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

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

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from 730c61b to 4ac801d Compare June 16, 2026 06:22
@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Threads re-opened this run:

  1. PRRT_kwDOOpObr86JyrVVnotifications.models.ts line 35: The @returns still uses bare type names (no {@link} refs) and the orphaned * {@link NotificationGetResponse} fragment is still on the following line. The service class (notifications.ts) was correctly fixed to use inline {@link} refs, but NotificationServiceModel was not updated to match. Both issues need to be addressed together:

    * @returns Promise resolving to either a {@link NonPaginatedResponse}<{@link NotificationGetResponse}> or a {@link PaginatedResponse}<{@link NotificationGetResponse}> when pagination options are used.
    

    (delete the * {@link NotificationGetResponse} line that follows)

  2. PRRT_kwDOOpObr86JymoC — same root cause as above (file-level thread on the same two lines).

@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch 2 times, most recently from 14d05ea to 35d8ef4 Compare June 16, 2026 10:16
Comment thread tests/unit/services/notification/notifications.test.ts
@claude

claude Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

New finding from this review run:

Missing integration test (notifications.test.ts line 132): No file under tests/integration/shared/notification/ was added. Convention requires an integration test for every new method. If PAT auth is unsupported for this scope, write the full test body under describe.skip (matching the insightsrtm_ precedent) rather than omitting the file entirely.

@sonarqubecloud

Copy link
Copy Markdown

…nternal]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sarthak688 sarthak688 force-pushed the feat/notifications-sdk branch from 35d8ef4 to 32c58a9 Compare June 16, 2026 10:40
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.

3 participants