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
96 changes: 48 additions & 48 deletions sentry.client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,55 @@
// The config you add here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from "@sentry/nextjs";
import * as Sentry from '@sentry/nextjs'

const dsn = process.env.NEXT_PUBLIC_SENTRY_DSN || process.env.SENTRY_DSN;
const vercelEnv = process.env.NEXT_PUBLIC_VERCEL_ENV;
const isProd = process.env.NEXT_PUBLIC_VERCEL_ENV === "production";
const dsn = process.env.NEXT_PUBLIC_SENTRY_DSN || process.env.SENTRY_DSN
const vercelEnv = process.env.NEXT_PUBLIC_VERCEL_ENV
const isProd = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'

if (dsn) {
Sentry.init({
dsn,

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: isProd ? 0.2 : 1,
profilesSampleRate: 0.1,
// NOTE: reducing sample only 10% of transactions in prod to get general trends instead of detailed and overfitted data

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,

// You can remove this option if you're not planning to use the Sentry Session Replay feature:
// NOTE: Since session replay barely helps us anyways, getting rid of it to reduce some bundle size at least
// replaysOnErrorSampleRate: 1.0,
// replaysSessionSampleRate: 0,
integrations: [
Sentry.browserTracingIntegration({
beforeStartSpan: (e) => {
console.info('SentryBrowserTracingSpan', e.name)
return e
},
}),
// Sentry.replayIntegration({
// Additional Replay configuration goes in here, for example:
// maskAllText: true,
// blockAllMedia: true,
// }),
],

// ignoreErrors: [/fetch failed/i],
ignoreErrors: [/fetch failed/i],

beforeSend(event) {
if (!isProd && event.type === undefined) {
return null
}
event.tags = {
...event.tags,
// Adding additional app_env tag for cross-checking
app_env: isProd ? 'production' : vercelEnv || 'development',
}
return event
},
})
Sentry.init({
dsn,

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: isProd ? 0.2 : 1,
profilesSampleRate: 0.1,
// NOTE: reducing sample only 10% of transactions in prod to get general trends instead of detailed and overfitted data

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,

// You can remove this option if you're not planning to use the Sentry Session Replay feature:
// NOTE: Since session replay barely helps us anyways, getting rid of it to reduce some bundle size at least
// replaysOnErrorSampleRate: 1.0,
// replaysSessionSampleRate: 0,
integrations: [
Sentry.browserTracingIntegration({
beforeStartSpan: (e) => {
console.info('SentryBrowserTracingSpan', e.name)
return e
},
}),
// Sentry.replayIntegration({
// Additional Replay configuration goes in here, for example:
// maskAllText: true,
// blockAllMedia: true,
// }),
],

// ignoreErrors: [/fetch failed/i],
ignoreErrors: [/fetch failed/i],

beforeSend(event) {
if (!isProd && event.type === undefined) {
return null
}
event.tags = {
...event.tags,
// Adding additional app_env tag for cross-checking
app_env: isProd ? 'production' : vercelEnv || 'development',
}
return event
},
})
}
34 changes: 17 additions & 17 deletions sentry.server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
// The config you add here will be used whenever the server handles a request.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from "@sentry/nextjs";
import * as Sentry from '@sentry/nextjs'

const dsn = process.env.NEXT_PUBLIC_SENTRY_DSN || process.env.SENTRY_DSN
const vercelEnv = process.env.NEXT_PUBLIC_VERCEL_ENV
const isProd = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'

if (dsn) {
Sentry.init({
dsn,
Sentry.init({
dsn,

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,
// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,

// Uncomment the line below to enable Spotlight (https://spotlightjs.com)
// spotlight: process.env.NODE_ENV === 'development',
ignoreErrors: [/fetch failed/i],
// Uncomment the line below to enable Spotlight (https://spotlightjs.com)
// spotlight: process.env.NODE_ENV === 'development',
ignoreErrors: [/fetch failed/i],

beforeSend(event) {
if (!isProd && event.type === undefined) {
return null
}
return event
},
})
beforeSend(event) {
if (!isProd && event.type === undefined) {
return null
}
return event
},
})
}
25 changes: 19 additions & 6 deletions src/app/api/tasks/tasks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,22 @@ export class TasksService extends TasksSharedService {
}
}

private validateTaskShare(prevTask: Task, isTaskShared?: boolean) {
if (prevTask.associations.length) {
return !!isTaskShared
private validateTaskShare(prevTask: Task, data: UpdateTaskRequest): boolean | undefined {
const isTaskShared = data.isShared

if (isTaskShared === undefined) return undefined

if (isTaskShared) {
const isEligibleForShare = !!(
(prevTask.associations.length && prevTask.internalUserId) ||
(data.associations?.length && data.internalUserId)
)
if (!isEligibleForShare) {
throw new APIError(httpStatus.BAD_REQUEST, 'Cannot share task with assocations')
}
return true
}
throw new APIError(httpStatus.BAD_REQUEST, 'Cannot share task when it has no association')
return false
}

async updateOneTask(id: string, data: UpdateTaskRequest) {
Expand Down Expand Up @@ -355,7 +366,9 @@ export class TasksService extends TasksSharedService {
})

let associations: Associations = AssociationsSchema.parse(prevTask.associations)
const viewersResetCondition = shouldUpdateUserIds ? !!clientId || !!companyId : !prevTask.internalUserId

// check if current or previous assignee is a client or company
const viewersResetCondition = shouldUpdateUserIds ? !!clientId || !!companyId : prevTask.clientId || prevTask.companyId
if (data.associations) {
// only update of associations attribute is available. No associations in payload attribute means the data remains as it is in DB.
if (viewersResetCondition || !data.associations?.length) {
Expand Down Expand Up @@ -412,7 +425,7 @@ export class TasksService extends TasksSharedService {
completedBy,
completedByUserType,
associations,
isShared: data.isShared !== undefined ? this.validateTaskShare(prevTask, data.isShared) : false,
isShared: this.validateTaskShare(prevTask, data),
...userAssignmentFields,
...(await getTaskTimestamps('update', this.user, data, prevTask)),
},
Expand Down
4 changes: 2 additions & 2 deletions src/app/detail/[task_id]/[user_type]/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export const updateAssignee = async (
internalUserId,
clientId,
companyId,
...(associations && { associations: !internalUserId ? [] : associations }), // if assignee is not internal user, remove associations. Only include associations if viewer are changed. Not including viewer means not chaning the current state of associations in DB.
...(isShared && { isShared }),
...(associations && { associations: clientId || companyId ? [] : associations }), // if assignee is not internal user, remove associations. Only include associations if viewer are changed. Not including viewer means not chaning the current state of associations in DB.
isShared: isShared ?? undefined,
}),
})
}
Expand Down
Loading
Loading