Skip to content

Commit

Permalink
feat(core): proxy notification settings operations
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleSamtoshi committed Jan 16, 2024
1 parent ca5f796 commit 73546ba
Show file tree
Hide file tree
Showing 23 changed files with 3,840 additions and 348 deletions.
2 changes: 1 addition & 1 deletion core/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"eslint-check": "eslint src test --ext .ts",
"eslint-fix": "eslint src test --ext .ts --fix",
"circular-deps-check": "madge --circular --extensions ts src",
"build": "tsc -p tsconfig-build.json && cp -R src/services/price/protos dist/services/price/ && cp -R src/services/dealer-price/proto dist/services/dealer-price/ && cp -R src/services/loopd/protos dist/services/loopd/ && cp -R src/services/bria/proto dist/services/bria/ && tscpaths --silent -p tsconfig.json -s ./src -o ./dist",
"build": "tsc -p tsconfig-build.json && cp -R src/services/price/protos dist/services/price/ && cp -R src/services/dealer-price/proto dist/services/dealer-price/ && cp -R src/services/loopd/protos dist/services/loopd/ && cp -R src/services/bria/proto dist/services/bria/ && cp -R src/services/notifications/proto dist/services/notifications/ && tscpaths --silent -p tsconfig.json -s ./src -o ./dist",
"trigger": "pnpm run build && node dist/servers/trigger.js | pino-pretty -c -l",
"ws": "pnpm run build && node dist/servers/ws-server.js | pino-pretty -c -l",
"watch": "nodemon -V -e ts,graphql -w ./src -x pnpm run start",
Expand Down
15 changes: 9 additions & 6 deletions core/api/src/app/accounts/disable-notification-category.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {
NotificationChannel,
checkedToNotificationCategory,
disableNotificationCategory as domainDisableNotificationCategory,
} from "@/domain/notifications"
import { AccountsRepository } from "@/services/mongoose"
import { NotificationsService } from "@/services/notifications"

export const disableNotificationCategory = async ({
accountId,
Expand All @@ -19,13 +20,15 @@ export const disableNotificationCategory = async ({
const account = await AccountsRepository().findById(accountId)
if (account instanceof Error) return account

const newNotificationSettings = domainDisableNotificationCategory({
notificationSettings: account.notificationSettings,
notificationChannel,
const notificationsService = NotificationsService()

const newNotificationSettings = await notificationsService.disableNotificationCategory({
userId: account.kratosUserId,
notificationChannel: notificationChannel || NotificationChannel.Push,
notificationCategory: checkedNotificationCategory,
})

account.notificationSettings = newNotificationSettings
if (newNotificationSettings instanceof Error) return newNotificationSettings

return AccountsRepository().update(account)
return account
}
12 changes: 7 additions & 5 deletions core/api/src/app/accounts/disable-notification-channel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { disableNotificationChannel as domainDisableNotificationChannel } from "@/domain/notifications"
import { AccountsRepository } from "@/services/mongoose"
import { NotificationsService } from "@/services/notifications"

export const disableNotificationChannel = async ({
accountId,
Expand All @@ -11,12 +11,14 @@ export const disableNotificationChannel = async ({
const account = await AccountsRepository().findById(accountId)
if (account instanceof Error) return account

const newNotificationSettings = domainDisableNotificationChannel({
notificationSettings: account.notificationSettings,
const notificationsService = NotificationsService()

const newNotificationSettings = await notificationsService.disableNotificationChannel({
userId: account.kratosUserId,
notificationChannel,
})

account.notificationSettings = newNotificationSettings
if (newNotificationSettings instanceof Error) return newNotificationSettings

return AccountsRepository().update(account)
return account
}
15 changes: 9 additions & 6 deletions core/api/src/app/accounts/enable-notification-category.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {
NotificationChannel,
checkedToNotificationCategory,
enableNotificationCategory as domainEnableNotificationCategory,
} from "@/domain/notifications"
import { AccountsRepository } from "@/services/mongoose"
import { NotificationsService } from "@/services/notifications"

export const enableNotificationCategory = async ({
accountId,
Expand All @@ -19,13 +20,15 @@ export const enableNotificationCategory = async ({
const account = await AccountsRepository().findById(accountId)
if (account instanceof Error) return account

const newNotificationSettings = domainEnableNotificationCategory({
notificationSettings: account.notificationSettings,
notificationChannel,
const notificationsService = NotificationsService()

const newNotificationSettings = await notificationsService.enableNotificationCategory({
userId: account.kratosUserId,
notificationChannel: notificationChannel || NotificationChannel.Push,
notificationCategory: checkedNotificationCategory,
})

account.notificationSettings = newNotificationSettings
if (newNotificationSettings instanceof Error) return newNotificationSettings

return AccountsRepository().update(account)
return account
}
12 changes: 7 additions & 5 deletions core/api/src/app/accounts/enable-notification-channel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { enableNotificationChannel as domainEnableNotificationChannel } from "@/domain/notifications"
import { AccountsRepository } from "@/services/mongoose"
import { NotificationsService } from "@/services/notifications"

export const enableNotificationChannel = async ({
accountId,
Expand All @@ -11,12 +11,14 @@ export const enableNotificationChannel = async ({
const account = await AccountsRepository().findById(accountId)
if (account instanceof Error) return account

const newNotificationSettings = domainEnableNotificationChannel({
notificationSettings: account.notificationSettings,
const notificationsService = NotificationsService()

const newNotificationSettings = await notificationsService.enableNotificationChannel({
userId: account.kratosUserId,
notificationChannel,
})

account.notificationSettings = newNotificationSettings
if (newNotificationSettings instanceof Error) return newNotificationSettings

return AccountsRepository().update(account)
return account
}
11 changes: 11 additions & 0 deletions core/api/src/app/accounts/get-notification-settings-for-account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NotificationsService } from "@/services/notifications"

export const getNotificationSettingsForAccount = ({
account,
}: {
account: Account
}): Promise<NotificationSettings | ApplicationError> => {
const notificationsService = NotificationsService()

return notificationsService.getUserNotificationSettings(account.kratosUserId)
}
1 change: 1 addition & 0 deletions core/api/src/app/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export * from "./enable-notification-channel"
export * from "./disable-notification-channel"
export * from "./get-pending-incoming-on-chain-transactions-for-account"
export * from "./get-invoices-for-account"
export * from "./get-notification-settings-for-account"

const accounts = AccountsRepository()

Expand Down
11 changes: 11 additions & 0 deletions core/api/src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ export const env = createEnv({
BRIA_PORT: z.number().min(1).or(z.string()).pipe(z.coerce.number()).default(2742),
BRIA_API_KEY: z.string().min(1),

NOTIFICATIONS_HOST: z.string().min(1),
NOTIFICATIONS_PORT: z
.number()
.min(1)
.or(z.string())
.pipe(z.coerce.number())
.default(6685),

GEETEST_ID: z.string().min(1).optional(),
GEETEST_KEY: z.string().min(1).optional(),

Expand Down Expand Up @@ -168,6 +176,9 @@ export const env = createEnv({
BRIA_PORT: process.env.BRIA_PORT,
BRIA_API_KEY: process.env.BRIA_API_KEY,

NOTIFICATIONS_HOST: process.env.NOTIFICATIONS_HOST,
NOTIFICATIONS_PORT: process.env.NOTIFICATIONS_PORT,

GEETEST_ID: process.env.GEETEST_ID,
GEETEST_KEY: process.env.GEETEST_KEY,

Expand Down
2 changes: 2 additions & 0 deletions core/api/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ export const KRATOS_CALLBACK_API_KEY = env.KRATOS_CALLBACK_API_KEY
export const BRIA_HOST = env.BRIA_HOST
export const BRIA_PORT = env.BRIA_PORT
export const BRIA_API_KEY = env.BRIA_API_KEY
export const NOTIFICATIONS_HOST = env.NOTIFICATIONS_HOST
export const NOTIFICATIONS_PORT = env.NOTIFICATIONS_PORT
export const GEETEST_ID = env.GEETEST_ID
export const GEETEST_KEY = env.GEETEST_KEY
export const MONGODB_CON = env.MONGODB_CON
Expand Down
162 changes: 10 additions & 152 deletions core/api/src/domain/notifications/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { InvalidPushNotificationSettingError as InvalidNotificationSettingsError } from "./errors"

export * from "./errors"
import { InvalidPushNotificationSettingError } from "./errors"

export const NotificationType = {
IntraLedgerReceipt: "intra_ledger_receipt",
Expand All @@ -12,164 +11,23 @@ export const NotificationType = {
LigtningPayment: "lightning_payment",
} as const

export const NotificationChannel = {
Push: "push",
} as const

export const GaloyNotificationCategories = {
Payments: "Payments" as NotificationCategory,
Balance: "Balance" as NotificationCategory,
AdminPushNotification: "AdminPushNotification" as NotificationCategory,
} as const

export const checkedToNotificationCategory = (
notificationCategory: string,
): NotificationCategory | ValidationError => {
// TODO: add validation
if (!notificationCategory) {
return new InvalidNotificationSettingsError("Invalid notification category")
return new InvalidPushNotificationSettingError("Invalid notification category")
}

return notificationCategory as NotificationCategory
}

export const enableNotificationChannel = ({
notificationSettings,
notificationChannel,
}: {
notificationSettings: NotificationSettings
notificationChannel: NotificationChannel
}): NotificationSettings => {
return setNotificationChannelIsEnabled({
notificationSettings,
notificationChannel,
enabled: true,
})
}

export const disableNotificationChannel = ({
notificationSettings,
notificationChannel,
}: {
notificationSettings: NotificationSettings
notificationChannel: NotificationChannel
}): NotificationSettings => {
return setNotificationChannelIsEnabled({
notificationSettings,
notificationChannel,
enabled: false,
})
}

const setNotificationChannelIsEnabled = ({
notificationSettings,
notificationChannel,
enabled,
}: {
notificationSettings: NotificationSettings
notificationChannel: NotificationChannel
enabled: boolean
}): NotificationSettings => {
const notificationChannelSettings = notificationSettings[notificationChannel]
const enabledChanged = notificationChannelSettings.enabled !== enabled

const newNotificationSettings = {
enabled,
disabledCategories: enabledChanged
? []
: notificationChannelSettings.disabledCategories,
}

return {
...notificationSettings,
[notificationChannel]: newNotificationSettings,
}
}

export const enableNotificationCategory = ({
notificationSettings,
notificationChannel,
notificationCategory,
}: {
notificationSettings: NotificationSettings
notificationChannel?: NotificationChannel
notificationCategory: NotificationCategory
}): NotificationSettings => {
const notificationChannelsToUpdate: NotificationChannel[] = notificationChannel
? [notificationChannel]
: Object.values(NotificationChannel)

let newNotificationSettings = notificationSettings

for (const notificationChannel of notificationChannelsToUpdate) {
const notificationChannelSettings = notificationSettings[notificationChannel]
const disabledCategories = notificationChannelSettings.disabledCategories

const newNotificationChannelSettings = {
enabled: notificationChannelSettings.enabled,
disabledCategories: disabledCategories.filter(
(category) => category !== notificationCategory,
),
}

newNotificationSettings = {
...notificationSettings,
[notificationChannel]: newNotificationChannelSettings,
}
}

return newNotificationSettings
}

export const disableNotificationCategory = ({
notificationSettings,
notificationChannel,
notificationCategory,
}: {
notificationSettings: NotificationSettings
notificationChannel?: NotificationChannel
notificationCategory: NotificationCategory
}): NotificationSettings => {
const notificationChannelsToUpdate: NotificationChannel[] = notificationChannel
? [notificationChannel]
: Object.values(NotificationChannel)

let newNotificationSettings = notificationSettings

for (const notificationChannel of notificationChannelsToUpdate) {
const notificationChannelSettings = notificationSettings[notificationChannel]
const disabledCategories = notificationChannelSettings.disabledCategories
disabledCategories.push(notificationCategory)
const uniqueDisabledCategories = [...new Set(disabledCategories)]

const newNotificationChannelSettings = {
enabled: notificationChannelSettings.enabled,
disabledCategories: uniqueDisabledCategories,
}

newNotificationSettings = {
...notificationSettings,
[notificationChannel]: newNotificationChannelSettings,
}
}

return newNotificationSettings
}

export const shouldSendNotification = ({
notificationChannel,
notificationSettings,
notificationCategory,
}: {
notificationChannel: NotificationChannel
notificationSettings: NotificationSettings
notificationCategory: NotificationCategory
}): boolean => {
const channelNotificationSettings = notificationSettings[notificationChannel]

if (channelNotificationSettings.enabled) {
return !channelNotificationSettings.disabledCategories.includes(notificationCategory)
}
export const NotificationChannel = {
Push: "push",
} as const

return false
}
export const GaloyNotificationCategories = {
Payments: "Payments" as NotificationCategory,
Balance: "Balance" as NotificationCategory,
AdminPushNotification: "AdminPushNotification" as NotificationCategory,
} as const
26 changes: 26 additions & 0 deletions core/api/src/domain/notifications/index.types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,30 @@ interface INotificationsService {
adminPushNotificationFilteredSend(
args: SendFilteredPushNotificationArgs,
): Promise<true | NotificationsServiceError>

getUserNotificationSettings(
userId: UserId,
): Promise<NotificationSettings | NotificationsServiceError>

enableNotificationChannel(args: {
userId: UserId
notificationChannel: NotificationChannel
}): Promise<NotificationSettings | NotificationsServiceError>

disableNotificationChannel(args: {
userId: UserId
notificationChannel: NotificationChannel
}): Promise<NotificationSettings | NotificationsServiceError>

enableNotificationCategory(args: {
userId: UserId
notificationChannel: NotificationChannel
notificationCategory: NotificationCategory
}): Promise<NotificationSettings | NotificationsServiceError>

disableNotificationCategory(args: {
userId: UserId
notificationChannel: NotificationChannel
notificationCategory: NotificationCategory
}): Promise<NotificationSettings | NotificationsServiceError>
}
Loading

0 comments on commit 73546ba

Please sign in to comment.