Skip to content

feat(api-service): add activity feed link to trigger response#9430

Open
djabarovgeorge wants to merge 12 commits intonextfrom
add-activuty-feed-link-to-trigger-response
Open

feat(api-service): add activity feed link to trigger response#9430
djabarovgeorge wants to merge 12 commits intonextfrom
add-activuty-feed-link-to-trigger-response

Conversation

@djabarovgeorge
Copy link
Contributor

What changed? Why was the change needed?

Some additional data for our users for easier debugging and monitoring.
The inspiration was RESTful API Richardson Maturity Model level 3 HATEOAS.

image

Screenshots

Expand for optional sections

Related enterprise PR

Special notes for your reviewer

@netlify
Copy link

netlify bot commented Oct 30, 2025

Deploy Preview for dashboard-v2-novu-staging canceled.

Name Link
🔨 Latest commit bdd55e6
🔍 Latest deploy log https://app.netlify.com/projects/dashboard-v2-novu-staging/deploys/693855a3be39430007e273cf

@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

Hey there and thank you for opening this pull request! 👋

We require pull request titles to follow specific formatting rules and it looks like your proposed title needs to be adjusted.

Your PR title is: feat(api-service): add activity feed link to trigger response

Requirements:

  1. Follow the Conventional Commits specification
  2. As a team member, include Linear ticket ID at the end: fixes TICKET-ID or include it in your branch name

Expected format: feat(scope): Add fancy new feature fixes NOV-123

Details:

PR title must end with 'fixes TICKET-ID' (e.g., 'fixes NOV-123') or include ticket ID in branch name

'Event dispatched to [Workflow] Queue'
);

const environment = await this.environmentRepository.findOne({ _id: command.environmentId });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

My main drawback here is the additional request to fetch the env name.

- Updated subproject reference in .source file.
- Removed unused imports and refactored environment handling in parse-event-request.usecase.ts.
- Enhanced environment selection logic in environment-provider.tsx for backward compatibility with both slug and _id.
} else if (pathname.includes(ROUTES.ENV) && isNewEnvironmentDifferent) {
const newPath = pathname.replace(/\/env\/[^/]+(\/|$)/, `${ROUTES.ENV}/${newEnvironmentSlug}$1`);
navigate(newPath);
navigate(`${newPath}${search}${hash}`);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

someone can think of any issues with preserving the search and hash here? today, we were ignoring it and redirecting to the base url

Copy link
Contributor

Choose a reason for hiding this comment

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

activity feed filters are saved in the URL, and on the env switch might be breaking or not work

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

here is what I am talking about, the URL query params are preserved, but shouldn't be:

Screen.Recording.2025-12-18.at.16.49.49.mov

acknowledged: true,
status: TriggerEventStatusEnum.PROCESSED,
transactionId,
activityFeedLink,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we also need to adjust the DTO for the SDK?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cursoragent adjust the dto for the sdk for this use case clients
like TriggerEventResponseDto
in addition make sure to pass this new prop activityFeedLink TriggerEventToAll usecase as well.

in handler @post('/trigger/broadcast') remove the transaction generation const transactionId = body.transactionId || uuidv4() and in TriggerEventToAll insead of useing the command transactionId use the one that is returned from parseEventRequest usecase

Copy link
Contributor

@cursor cursor bot Dec 9, 2025

Choose a reason for hiding this comment

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

Perfect! I've successfully completed all the requested changes:

Changes Made:

1. Updated TriggerEventResponseDto

Added the activityFeedLink field to the SDK DTO with proper API documentation:

export class TriggerEventResponseDto {
  @ApiProperty({
    description: 'Indicates whether the trigger was acknowledged or not',
    type: Boolean,
  })
  @IsBoolean()
  @IsDefined()
  acknowledged: boolean;

  @ApiProperty({
    description: 'Status of the trigger',
    enum: TriggerEventStatusEnum,
  })
  @IsDefined()
  @IsEnum(TriggerEventStatusEnum)
  status: TriggerEventStatusEnum;

  @ApiProperty({
    description: 'In case of an error, this field will contain the error message(s)',
    type: [String], // Specify that this is an array of strings
    required: false, // Not required since it's optional
  })
  @IsOptional()
  error?: string[];

  @ApiProperty({
    description: 'The returned transaction ID of the trigger',
    type: String,
    required: false,
  })
  @IsOptional()
  @IsString()
  transactionId?: string;

  @ApiProperty({
    description: 'Link to the activity feed for this trigger event',
    type: String,
    required: false,
  })
  @IsOptional()
  @IsString()
  activityFeedLink?: string;

  @IsOptional()
  jobData?: IWorkflowDataDto;
}

2. Updated TriggerEventToAll Usecase

Now captures and returns the complete result from parseEventRequest, including the activityFeedLink:

  public async execute(command: TriggerEventToAllCommand) {
    const result = await this.parseEventRequest.execute(
      ParseEventRequestBroadcastCommand.create({
        userId: command.userId,
        environmentId: command.environmentId,
        organizationId: command.organizationId,
        identifier: command.identifier,
        payload: command.payload || {},
        addressingType: AddressingTypeEnum.BROADCAST,
        transactionId: command.transactionId,
        overrides: command.overrides || {},
        actor: command.actor,
        tenant: command.tenant,
        context: command.context,
        requestCategory: TriggerRequestCategoryEnum.SINGLE,
        bridgeUrl: command.bridgeUrl,
        requestId: command.requestId,
      })
    );

    return result;
  }

3. Updated Broadcast Handler

Removed the transaction ID generation logic and simplified the handler to pass the transactionId directly from the request body:

  async broadcastEventToAll(
    @UserSession() user: UserSessionData,
    @Body() body: TriggerEventToAllRequestDto,
    @Req() req: RequestWithReqId
  ): Promise<TriggerEventResponseDto> {
    return this.triggerEventToAll.execute(
      TriggerEventToAllCommand.create({
        userId: user._id,
        environmentId: user.environmentId,
        organizationId: user.organizationId,
        identifier: body.name,
        payload: body.payload,
        tenant: body.tenant,
        transactionId: body.transactionId,
        overrides: body.overrides || {},
        actor: body.actor,
        context: body.context,
        requestId: req._nvRequestId,
      })
    );
  }

4. Updated TriggerEventToAllCommand

Made transactionId optional so it can be generated by parseEventRequest if not provided:

  @IsString()
  @IsOptional()
  transactionId?: string;

5. Removed Unused Import

Cleaned up the unused uuid import from the controller.

The implementation now follows the same pattern as the regular /trigger endpoint, where parseEventRequest handles transaction ID generation and returns the activity feed link that clients can use for debugging and monitoring.


Open in Cursor Open in Web

Learn more about Cursor Agents

Co-authored-by: george <george@novu.co>
@cursor
Copy link
Contributor

cursor bot commented Dec 9, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants