Skip to content

feat(subscriptions): publisher/group-level updates (PR 6/7)#518

Open
sarthak688 wants to merge 7 commits into
feat/subscriptions-topic-updatesfrom
feat/subscriptions-publisher-updates
Open

feat(subscriptions): publisher/group-level updates (PR 6/7)#518
sarthak688 wants to merge 7 commits into
feat/subscriptions-topic-updatesfrom
feat/subscriptions-publisher-updates

Conversation

@sarthak688

Copy link
Copy Markdown
Contributor

PR 6/7 in the Notification SDK stack. Stacked on top of #517.

Adds the two broader-scope subscription writes — publisher-level opt-in/out and topic-group entity scoping.

Methods Added

Layer Method Signature
Service subscriptions.updatePublisher() updatePublisher(tenantId: string, subscriptions: PublisherSubscriptionUpdate[]): Promise<SubscriptionUpdatePublisherResponse>
Service subscriptions.updateTopicGroup() updateTopicGroup(tenantId: string, subscriptions: TopicGroupSubscriptionUpdate[]): Promise<SubscriptionUpdateTopicGroupResponse>

Endpoints Called

Method HTTP Endpoint OAuth Scope
updatePublisher() POST notificationservice_/usersubscriptionservice/api/v1/UserSubscription/PublisherSubscription NotificationService
updateTopicGroup() POST notificationservice_/usersubscriptionservice/api/v1/UserSubscription/TopicGroupSubscription NotificationService
  • API spec misspelling preserved: the publisher request body field is publisherID (sic), not publisherId. The SDK's public surface uses the clean spelling; the rename happens at send time inside updatePublisher.
  • Both methods accept arrays of entries — callers can batch many publisher/group updates per request.
  • updatePublisher supports optional entity scoping (e.g. opt in for two specific folders only); updateTopicGroup always scopes a named topic group to a list of entities.

Example Usage

// Opt out of a publisher entirely
await subscriptions.updatePublisher(tenantId, [
  { publisherId: '<publisherId>', isUserOptIn: false },
]);

// Subscribe a topic group to two folders
await subscriptions.updateTopicGroup(tenantId, [
  {
    publisherId: '<publisherId>',
    topicGroupName: 'JobNotifications',
    entities: [
      { id: '<folderId1>', type: 'Folder', isSubscribed: true },
      { id: '<folderId2>', type: 'Folder', isSubscribed: true },
    ],
  },
]);

Verification

Check Status
npm run typecheck ✅ clean
npm run lint ✅ 0 warnings, 0 errors
npm run test:unit ✅ 31 tests in notification suite (5 new)

Integration: updatePublisher round-trip — flip the user's opt-in for the first visible publisher, then restore. updateTopicGroup is unit-only because it needs a configured topic group on the test tenant.

Files

Area Files
Endpoint constants src/utils/constants/endpoints/notification.ts (UPDATE_PUBLISHER, UPDATE_TOPIC_GROUP)
Types src/models/notification/subscriptions.types.ts (PublisherSubscriptionUpdate, TopicGroupSubscriptionUpdate)
Models src/models/notification/subscriptions.models.ts (response types + ServiceModel methods)
Service src/services/notification/subscriptions.ts
Unit tests tests/unit/services/notification/subscriptions.test.ts (+5 tests)
Integration tests tests/integration/shared/notification/subscriptions.integration.test.ts (+1 round-trip test)
Docs docs/oauth-scopes.md

PR Stack

# Branch Status
1 feat/notifications-sdk #512
2 feat/notifications-mark-read #513
3 feat/notifications-delete #514
4 feat/subscriptions-sdk #516
5 feat/subscriptions-topic-updates #517
6 feat/subscriptions-publisher-updates (this PR)
7 feat/subscriptions-mode-reset upcoming

🤖 Generated with Claude Code

sarthak688 and others added 6 commits June 12, 2026 11:52
Establishes the notification service module with the inbox listing
endpoint. Routes at the organization level via NOTIFICATION_BASE
(URL-traversal trick to bypass the tenant segment). tenantId is taken
as a positional argument and forwarded via X-UIPATH-Internal-TenantId.

Foundation included for follow-up PRs that add the remaining inbox and
subscription methods on top of this branch:
  - @uipath/uipath-typescript/notifications subpath in package.json + rollup
  - NOTIFICATION_BASE, NOTIFICATION_ENDPOINTS scaffold
  - test infra (NOTIFICATION_TEST_TENANT_ID env var, test-config,
    unified-setup registration, notification mock factories, constants)
  - oauth-scopes + pagination + mkdocs nav entries

Methods: getAll (paginated OData listing with $top/$skip/$count,
filter, orderby; transformFn drops 8 internal/transport fields).

Tests: 4 unit + 4 integration (skipped when NOTIFICATION_TEST_TENANT_ID
is not set).

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

Adds the three read-state mutation methods on top of the foundation
established in feat/notifications-sdk. All three POST to the
NotificationEntry.UpdateRead OData action; markAllRead uses the
server-side forceAllRead flag.

Adds UPDATE_READ endpoint constant and per-method telemetry decorators.

Tests: 6 additional unit tests + 2 integration tests (mark/unmark
round-trip + markAllRead).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the two delete methods. Both POST to the NotificationEntry.DeleteBulk
OData action; deleteAll uses the server-side deleteAll flag.

Preserves the API spec's misspelling `notifcationIds` in the request body —
the server expects that exact (mistyped) key.

Tests: 4 additional unit tests. No integration tests — these destructively
mutate the inbox with no SDK-level undo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the SubscriptionService class alongside the existing
NotificationService. Both services live under
@uipath/uipath-typescript/notifications as discrete classes (no shared
state). Subscription endpoints route through the same notificationservice_
base via the URL-traversal trick.

Methods: getAll, getPublishers, getSupportedChannels — the three read-side
methods that return user subscription state and tenant channel availability.
Mutation methods land in follow-up PRs.

Adds SUBSCRIPTION_ENDPOINTS scaffold (3 read URLs), subscription model
types (SubscriptionPublisher, SubscriptionTopic, SubscriptionMode,
SupportedChannel, AllowedMode, options types), subscription test
infrastructure (mock factories), Subscriptions section in oauth-scopes
and mkdocs nav, and Subscriptions registration in unified-setup.

Tests: 8 unit + 4 integration.

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

Adds the two topic/category-scoped subscription writes. Each entry in
the payload sets the subscription state for a single (topic, mode) or
(category, mode) pair.

UPDATE_TOPIC reuses the same URL as GET_ALL — POST vs GET differentiates.

Adds TopicSubscriptionUpdate and CategorySubscriptionUpdate types,
response types, oauth-scopes entries, and unit + integration tests
(updateTopic round-trip; updateCategory unit-only because it needs
richer tenant fixtures).

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

Adds the two broader-scope subscription writes:
- updatePublisher: opt-in/out at the publisher level, optionally scoped
  to specific entities (folders, etc.)
- updateTopicGroup: scope a named topic group to a set of entities

API spec misspells the publisher key as `publisherID`; the SDK preserves
the typo at send time and keeps the public surface clean (`publisherId`).

Adds PublisherSubscriptionUpdate + TopicGroupSubscriptionUpdate types,
response types, oauth-scopes entries, 5 new unit tests, and an
updatePublisher round-trip integration test.

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.

…uth-scopes entries

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.

* { publisherId: '<publisherId>', isUserOptIn: false },
* ]);
* ```
* @internal

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.

if these methods are public dont mark them as internal. Check for other similar methods as well

@deepeshrai-tech

Copy link
Copy Markdown
Contributor

in PR description u mentioned docs/oauth scopes have also changed but i dont see it , is that part of another dependent PR?

// Intentional duplicate URL of GET_ALL: same path, POST vs GET differentiates the operation.
UPDATE_TOPIC: `${SUBSCRIPTION_API_BASE}/api/v1/UserSubscription`,
UPDATE_CATEGORY: `${SUBSCRIPTION_API_BASE}/api/v1/UserSubscription/CategorySubscription`,
UPDATE_PUBLISHER: `${SUBSCRIPTION_API_BASE}/api/v1/UserSubscription/PublisherSubscription`,

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.

add js doc for remaining constants as well like u have done for UPDATE_TOPIC

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.

2 participants