Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions .github/workflows/deployment-summary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,57 @@ jobs:
- name: Generate AI deployment summary
id: ai-summary
if: ${{ steps.fetch-prs.outputs.pr_count > 0 }}
run: |
echo "🤖 Starting AI deployment summary generation..."
echo "System prompt length: ${#SYSTEM_PROMPT}"
echo "User prompt length: ${#USER_PROMPT}"
echo "PR count: ${{ steps.fetch-prs.outputs.pr_count }}"
echo ""
echo "First 500 chars of user prompt:"
echo "${USER_PROMPT:0:500}..."
echo ""
echo "Calling AI inference action..."

- name: Call AI inference
id: ai-inference-call
if: ${{ steps.fetch-prs.outputs.pr_count > 0 }}
continue-on-error: true
uses: actions/ai-inference@v1
with:
system-prompt: ${{ env.SYSTEM_PROMPT }}
prompt: ${{ env.USER_PROMPT }}

- name: Log AI summary errors
if: ${{ steps.fetch-prs.outputs.pr_count > 0 && steps.ai-inference-call.outcome == 'failure' }}
run: |
echo "❌ AI deployment summary generation failed"
echo "Step outcome: ${{ steps.ai-inference-call.outcome }}"
echo "Step conclusion: ${{ steps.ai-inference-call.conclusion }}"
echo ""
echo "=== VERBOSE ERROR DETAILS ==="
echo "AI Inference outputs:"
echo "Response: '${{ steps.ai-inference-call.outputs.response }}'"
echo "Error: '${{ steps.ai-inference-call.outputs.error }}'"
echo "Status: '${{ steps.ai-inference-call.outputs.status }}'"
echo ""
echo "All step outputs:"
echo "${{ toJson(steps.ai-inference-call.outputs) }}"
echo ""
echo "Step context:"
echo "${{ toJson(steps.ai-inference-call) }}"
echo ""
echo "Environment variables used:"
echo "SYSTEM_PROMPT length: ${#SYSTEM_PROMPT}"
echo "USER_PROMPT length: ${#USER_PROMPT}"
echo ""
echo "GitHub context:"
echo "Repository: ${{ github.repository }}"
echo "Run ID: ${{ github.run_id }}"
echo "Actor: ${{ github.actor }}"
echo ""
echo "=== END ERROR DETAILS ==="
echo "Continuing with fallback summary generation..."

- name: Handle no recent PRs
id: no-prs-message
if: ${{ steps.fetch-prs.outputs.pr_count == 0 }}
Expand All @@ -245,9 +291,19 @@ jobs:
if: ${{ always() }}
run: |
# Write the summary to a temporary file to avoid shell interpretation issues
cat > /tmp/summary.txt << 'SUMMARY_EOF'
${{ steps.ai-summary.outputs.response || steps.no-prs-message.outputs.summary || 'Summary generation failed. Please check the workflow logs.' }}
if [[ "${{ steps.ai-inference-call.outcome }}" == "failure" ]]; then
cat > /tmp/summary.txt << 'SUMMARY_EOF'
⚠️ AI deployment summary generation failed. Please check the workflow logs for details.

Found ${{ steps.fetch-prs.outputs.pr_count || 0 }} PRs merged to production in the last ${{ steps.output-variables.outputs.days_back }} days.

Manual review of recent PRs is recommended. View them at: https://github.com/${{ github.repository }}/pulls?q=is%3Apr+is%3Amerged+base%3Aprod
SUMMARY_EOF
else
cat > /tmp/summary.txt << 'SUMMARY_EOF'
${{ steps.ai-inference-call.outputs.response || steps.no-prs-message.outputs.summary || 'Summary generation failed. Please check the workflow logs.' }}
SUMMARY_EOF
fi

# Read and clean the content for Slack
summary_text=$(cat /tmp/summary.txt)
Expand Down
2 changes: 1 addition & 1 deletion .source
8 changes: 4 additions & 4 deletions apps/api/src/app/bridge/bridge.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import {
CreateChange,
CreateMessageTemplate,
CreateWorkflow,
DeleteMessageTemplate,
DeletePreferencesUseCase,
DeleteWorkflowUseCase,
GetPreferences,
GetWorkflowByIdsUseCase,
GetWorkflowWithPreferencesUseCase,
ResourceValidatorService,
TierRestrictionsValidateUsecase,
UpdateChange,
UpdateMessageTemplate,
UpdateWorkflow,
UpsertControlValuesUseCase,
UpsertPreferences,
} from '@novu/application-generic';
Expand All @@ -25,6 +21,10 @@ import { BuildVariableSchemaUsecase } from '../workflows-v2/usecases';
import { CreateVariablesObject } from '../shared/usecases/create-variables-object/create-variables-object.usecase';
import { BuildStepIssuesUsecase } from '../workflows-v2/usecases/build-step-issues/build-step-issues.usecase';
import { WebhooksModule } from '../webhooks/webhooks.module';
import { CreateWorkflow } from '../workflows-v1/usecases/create-workflow/create-workflow.usecase';
import { UpdateWorkflow } from '../workflows-v1/usecases/update-workflow/update-workflow.usecase';
import { DeleteWorkflowUseCase } from '../workflows-v1/usecases/delete-workflow/delete-workflow.usecase';
import { GetWorkflowWithPreferencesUseCase } from '../workflows-v1/usecases/get-workflow-with-preferences/get-workflow-with-preferences.usecase';

const PROVIDERS = [
CreateWorkflow,
Expand Down
19 changes: 7 additions & 12 deletions apps/api/src/app/bridge/usecases/sync/sync.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,7 @@ import {
NotificationTemplateEntity,
NotificationTemplateRepository,
} from '@novu/dal';
import {
AnalyticsService,
CreateWorkflow,
CreateWorkflowCommand,
DeleteWorkflowCommand,
DeleteWorkflowUseCase,
ExecuteBridgeRequest,
JSONSchema,
NotificationStep,
UpdateWorkflow,
UpdateWorkflowCommand,
} from '@novu/application-generic';
import { AnalyticsService, ExecuteBridgeRequest, JSONSchema, NotificationStep } from '@novu/application-generic';
import {
buildWorkflowPreferences,
StepTypeEnum,
Expand All @@ -36,6 +25,12 @@ import { BuildStepIssuesUsecase } from '../../../workflows-v2/usecases/build-ste
import { computeWorkflowStatus } from '../../../workflows-v2/shared/compute-workflow-status';
import { StepIssuesDto } from '../../../workflows-v2/dtos';
import { JSONSchemaDto } from '../../../shared/dtos/json-schema.dto';
import { CreateWorkflow } from '../../../workflows-v1/usecases/create-workflow/create-workflow.usecase';
import { CreateWorkflowCommand } from '../../../workflows-v1/usecases/create-workflow/create-workflow.command';
import { UpdateWorkflow } from '../../../workflows-v1/usecases/update-workflow/update-workflow.usecase';
import { UpdateWorkflowCommand } from '../../../workflows-v1/usecases/update-workflow/update-workflow.command';
import { DeleteWorkflowCommand } from '../../../workflows-v1/usecases/delete-workflow/delete-workflow.command';
import { DeleteWorkflowUseCase } from '../../../workflows-v1/usecases/delete-workflow/delete-workflow.usecase';

@Injectable()
export class Sync {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ describe('EmailOutputRendererUsecase', () => {
getOrganizationSettingsMock.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});
pinoLoggerMock = sinon.createStubInstance(PinoLogger);
controlValuesRepositoryMock = sinon.createStubInstance(ControlValuesRepository);
Expand Down Expand Up @@ -1570,7 +1569,6 @@ describe('EmailOutputRendererUsecase', () => {
getOrganizationSettingsMock.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});

const renderCommand: EmailOutputRendererCommand = {
Expand All @@ -1595,7 +1593,6 @@ describe('EmailOutputRendererUsecase', () => {
getOrganizationSettingsMock.execute.resolves({
removeNovuBranding: true,
defaultLocale: 'en_US',
translationsEnabled: false,
});

const renderCommand: EmailOutputRendererCommand = {
Expand All @@ -1618,7 +1615,6 @@ describe('EmailOutputRendererUsecase', () => {
getOrganizationSettingsMock.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});

const htmlWithBodyTag = '<html><body><p>Content</p></body></html>';
Expand Down Expand Up @@ -1652,7 +1648,6 @@ describe('EmailOutputRendererUsecase', () => {
getOrganizationSettingsMock.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});
});

Expand Down
5 changes: 0 additions & 5 deletions apps/api/src/app/inbox/usecases/session/session.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ describe('Session', () => {
getOrganizationSettingsUsecase.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});

const validateHmacEncryptionStub = sinon.stub(encryption, 'validateHmacEncryption');
Expand Down Expand Up @@ -221,15 +220,13 @@ describe('Session', () => {
getOrganizationSettingsUsecase.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});
const response: SubscriberSessionResponseDto = await session.execute(command);
expect(response.removeNovuBranding).to.equal(false);

getOrganizationSettingsUsecase.execute.resolves({
removeNovuBranding: true,
defaultLocale: 'en_US',
translationsEnabled: false,
});
const responseWithRemoveNovuBranding: SubscriberSessionResponseDto = await session.execute(command);
expect(responseWithRemoveNovuBranding.removeNovuBranding).to.equal(true);
Expand Down Expand Up @@ -261,7 +258,6 @@ describe('Session', () => {
getOrganizationSettingsUsecase.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});

const response: SubscriberSessionResponseDto = await session.execute(command);
Expand Down Expand Up @@ -301,7 +297,6 @@ describe('Session', () => {
getOrganizationSettingsUsecase.execute.resolves({
removeNovuBranding: false,
defaultLocale: 'en_US',
translationsEnabled: false,
});

// FREE plan should have 24 hours max snooze duration
Expand Down
6 changes: 5 additions & 1 deletion apps/api/src/app/layouts-v2/dtos/layout-response.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
import { IsEnum, IsOptional, IsString, IsBoolean } from 'class-validator';
import { Type } from 'class-transformer';
import { ResourceOriginEnum, ResourceTypeEnum } from '@novu/shared';
import { ResourceOriginEnum, ResourceTypeEnum, Slug } from '@novu/shared';

import { RuntimeIssueDto } from '../../workflows-v2/dtos/runtime-issue.dto';
import { CreateLayoutDto } from './create-layout.dto';
Expand All @@ -27,6 +27,10 @@ export class LayoutResponseDto {
@IsString()
layoutId: string;

@ApiProperty({ description: 'Slug of the layout' })
@IsString()
slug: Slug;

@ApiProperty({ description: 'Name of the layout' })
@IsString()
name: string;
Expand Down
4 changes: 3 additions & 1 deletion apps/api/src/app/layouts-v2/usecases/mapper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ChannelTypeEnum } from '@novu/shared';
import { ChannelTypeEnum, ShortIsPrefixEnum } from '@novu/shared';

import { LayoutResponseDto } from '../dtos';
import { LayoutDto } from '../../layouts-v1/dtos/layout.dto';
import { JSONSchemaDto } from '../../shared/dtos/json-schema.dto';
import { EmailControlsDto } from '../dtos/layout-controls.dto';
import { buildSlug } from '../../shared/helpers/build-slug';

export const mapToResponseDto = ({
layout,
Expand All @@ -20,6 +21,7 @@ export const mapToResponseDto = ({
_id: layout._id!,
layoutId: layout.identifier,
name: layout.name,
slug: buildSlug(layout.name, ShortIsPrefixEnum.LAYOUT, layout._id!),
isDefault: layout.isDefault,
updatedAt: layout.updatedAt!,
createdAt: layout.createdAt!,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IsOptional, IsString, ValidateNested, IsBoolean, IsEnum, IsNotEmpty, Length } from 'class-validator';
import { Type } from 'class-transformer';

import { EnvironmentWithUserObjectCommand, MAX_NAME_LENGTH } from '@novu/application-generic';
import { EnvironmentWithUserObjectCommand } from '@novu/application-generic';
import { MAX_NAME_LENGTH } from '@novu/shared';
import { LayoutCreationSourceEnum } from '../../types';
import { LayoutControlValuesDto } from '../../dtos/layout-controls.dto';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,4 @@ export class GetOrganizationSettingsDto {
})
@IsValidLocale()
defaultLocale: string;

@ApiProperty({
description: 'Whether translations are enabled for the organization',
example: false,
})
@IsBoolean()
translationsEnabled: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ export class UpdateOrganizationSettingsDto {
@IsBoolean()
removeNovuBranding?: boolean;

@ApiProperty({
description: 'Enable or disable translations',
example: true,
})
@IsOptional()
@IsBoolean()
translationsEnabled?: boolean;

@ApiProperty({
description: 'Default locale',
example: 'en-US',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export class EEOrganizationController {
userId: user._id,
organizationId: user.organizationId,
removeNovuBranding: body.removeNovuBranding,
translationsEnabled: body.translationsEnabled,
defaultLocale: body.defaultLocale,
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class GetOrganizationSettings {
return {
removeNovuBranding: organization.removeNovuBranding || false,
defaultLocale: organization.defaultLocale || DEFAULT_LOCALE,
translationsEnabled: organization.translationsEnabled || false,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ export class UpdateOrganizationSettingsCommand extends AuthenticatedCommand {
@IsBoolean()
removeNovuBranding?: boolean;

@IsOptional()
@IsBoolean()
translationsEnabled?: boolean;

@IsOptional()
@IsValidLocale()
defaultLocale?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ export class UpdateOrganizationSettings {
updateFields.removeNovuBranding = command.removeNovuBranding;
}

if (command.translationsEnabled !== undefined) {
updateFields.translationsEnabled = command.translationsEnabled;
}

if (command.defaultLocale !== undefined) {
updateFields.defaultLocale = command.defaultLocale;
}
Expand All @@ -84,7 +80,6 @@ export class UpdateOrganizationSettings {
private buildSettingsResponse(organization: OrganizationEntity): GetOrganizationSettingsDto {
return {
removeNovuBranding: organization.removeNovuBranding || false,
translationsEnabled: organization.translationsEnabled || false,
defaultLocale: organization.defaultLocale || DEFAULT_LOCALE,
};
}
Expand Down
Loading
Loading