Refactor Category and Center schemas to improve field descriptions and code clarity; update email templates for consistency in messaging. Add Redis service to CenterSchema for session management. Bump epess-database subproject commit reference to indicate changes. Clean up logging in ClerkService and ServiceSchema.

This commit is contained in:
2024-11-27 01:09:13 +07:00
parent c9435a6e04
commit 2581ca396f
11 changed files with 56 additions and 59 deletions

View File

@@ -1,10 +1,5 @@
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos'
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@@ -28,6 +23,9 @@ export class CategorySchema extends PothosSchema {
name: t.exposeString('name', {
description: 'The name of the category.',
}),
description: t.exposeString('description', {
description: 'The description of the category.',
}),
subCategory: t.relation('subCategory', {
description: 'The subcategory of the category.',
}),
@@ -46,16 +44,17 @@ export class CategorySchema extends PothosSchema {
name: t.exposeString('name', {
description: 'The name of the subcategory.',
}),
description: t.exposeString('description', {
description: 'The description of the subcategory.',
}),
categoryId: t.exposeID('categoryId', {
description:
'The ID of the category that the subcategory belongs to.',
description: 'The ID of the category that the subcategory belongs to.',
}),
category: t.relation('category', {
description: 'The category that the subcategory belongs to.',
}),
serviceAndCategory: t.relation('serviceAndCategory', {
description:
'The service and category that the subcategory belongs to.',
description: 'The service and category that the subcategory belongs to.',
}),
}),
})
@@ -65,8 +64,7 @@ export class CategorySchema extends PothosSchema {
init(): void {
this.builder.queryFields((t) => ({
categories: t.prismaField({
description:
'Retrieve a list of categories with optional filtering, ordering, and pagination.',
description: 'Retrieve a list of categories with optional filtering, ordering, and pagination.',
type: [this.category()],
args: this.builder.generator.findManyArgs('Category'),
resolve: async (query, _root, args) => {
@@ -91,8 +89,7 @@ export class CategorySchema extends PothosSchema {
},
}),
subCategories: t.prismaField({
description:
'Retrieve a list of subcategories with optional filtering, ordering, and pagination.',
description: 'Retrieve a list of subcategories with optional filtering, ordering, and pagination.',
type: [this.subCategory()],
args: this.builder.generator.findManyArgs('SubCategory'),
resolve: async (query, _root, args) => {

View File

@@ -1,15 +1,12 @@
import { Inject, Injectable, Logger } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos'
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from '../Minio/minio.service'
import { CenterStatus, Role } from '@prisma/client'
import { MailService } from '../Mail/mail.service'
import { clerkClient } from '@clerk/express'
import { RedisService } from 'src/Redis/redis.service'
@Injectable()
export class CenterSchema extends PothosSchema {
@@ -18,6 +15,7 @@ export class CenterSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly minioService: MinioService,
private readonly mailService: MailService,
private readonly redisService: RedisService,
) {
super()
}
@@ -54,11 +52,7 @@ export class CenterSchema extends PothosSchema {
resolve: async (center) => {
// get file id from logoUrl
const logoFileId = center.logoUrl?.split('/').pop()?.split('?')[0]
return await this.minioService.updatePresignUrl(
logoFileId ?? '',
'files',
center.logoUrl ?? undefined,
)
return await this.minioService.updatePresignUrl(logoFileId ?? '', 'files', center.logoUrl ?? undefined)
},
}),
logoFile: t.relation('logoFile', {
@@ -103,8 +97,7 @@ export class CenterSchema extends PothosSchema {
init(): void {
this.builder.queryFields((t) => ({
centers: t.prismaField({
description:
'Retrieve a list of centers with optional filtering, ordering, and pagination.',
description: 'Retrieve a list of centers with optional filtering, ordering, and pagination.',
type: [this.center()],
args: this.builder.generator.findManyArgs('Center'),
resolve: async (query, _root, args) => {
@@ -221,8 +214,14 @@ export class CenterSchema extends PothosSchema {
required: false,
}),
},
resolve: async (query, _root, args) => {
resolve: async (query, _root, args, ctx) => {
return await this.prisma.$transaction(async (prisma) => {
if (ctx.isSubscription) {
throw new Error('Not allowed in subscription')
}
if (ctx.http.me?.role !== Role.ADMIN && ctx.http.me?.role !== Role.MODERATOR) {
throw new Error('Not allowed')
}
const center = await prisma.center.findUnique({
...query,
where: {
@@ -249,6 +248,14 @@ export class CenterSchema extends PothosSchema {
if (!centerOwner) {
throw new Error('User not found')
}
// get active clerk session and invalidate cache
const sessionList = await clerkClient.sessions.getSessionList({
userId: centerOwnerId,
})
// clear all session cache in redis
sessionList.data.forEach(async (session) => {
await this.redisService.del(session.id)
})
await prisma.user.update({
where: {
id: centerOwnerId,
@@ -257,6 +264,7 @@ export class CenterSchema extends PothosSchema {
role: Role.CENTER_OWNER,
},
})
// update center status
const updatedCenter = await prisma.center.update({
...query,
@@ -264,9 +272,7 @@ export class CenterSchema extends PothosSchema {
id: args.centerId,
},
data: {
centerStatus: args.approve
? CenterStatus.APPROVED
: CenterStatus.REJECTED,
centerStatus: args.approve ? CenterStatus.APPROVED : CenterStatus.REJECTED,
},
})
// mail to center owner if approved

View File

@@ -24,11 +24,10 @@ export class ClerkService {
// session.removed
// session.ended
// email.created
console.log(eventType, data)
Logger.log(eventType, data, 'ClerkService')
if (eventType === 'user.created') {
this.eventUserCreated(data)
}
if (eventType === 'user.updated') {
this.eventUserUpdated(data)
}
@@ -57,7 +56,6 @@ export class ClerkService {
const primary_email_address_id = data.primary_email_address_id
// get primary email address on email_addresses by querying email_addresses with primary_email_address_id
let primary_email_address = data.email_addresses.find((email: any) => email.id === primary_email_address_id)
console.log(primary_email_address)
if (!primary_email_address) {
primary_email_address = ''
}
@@ -87,7 +85,6 @@ export class ClerkService {
}
async eventUserUpdated(data: any) {
console.log(data)
const user_id = data.id
const name = `${data.first_name} ${data.last_name}`
await this.prisma.user.update({
@@ -97,7 +94,6 @@ export class ClerkService {
}
async eventSessionCreated(data: any) {
console.log(data)
// check if user exists in database or create user
const user = await this.prisma.user.findUnique({
where: { id: data.user_id },
@@ -105,7 +101,6 @@ export class ClerkService {
if (!user) {
// get user info from clerk
const userInfo = await clerkClient.users.getUser(data.user_id)
console.log(userInfo)
try {
await this.prisma.user.create({
data: {
@@ -123,18 +118,18 @@ export class ClerkService {
}
eventSessionRevoked(data: any) {
console.log(data)
Logger.log(data, 'ClerkService')
}
eventSessionRemoved(data: any) {
console.log(data)
Logger.log(data, 'ClerkService')
}
eventSessionEnded(data: any) {
console.log(data)
Logger.log(data, 'ClerkService')
}
eventEmailCreated(data: any) {
console.log(data)
Logger.log(data, 'ClerkService')
}
}

View File

@@ -59,7 +59,7 @@ html
body
.container
.header
h1 Chúc mừng Trung tâm #{CENTER_NAME} đã được phê duyệt
h1 Chúc mừng #{CENTER_NAME} đã được phê duyệt
.content
p Kính gửi Quý Trung tâm,
p Chúng tôi vui mừng thông báo rằng trung tâm #{CENTER_NAME} của bạn đã được phê duyệt trên nền tảng của chúng tôi.

View File

@@ -67,7 +67,7 @@ html
body
.container
.header
h1 Thông báo từ chối Trung tâm #{CENTER_NAME}
h1 Thông báo từ chối #{CENTER_NAME}
.content
p Kính gửi Quý Trung tâm,
p Chúng tôi rất tiếc thông báo rằng trung tâm #{CENTER_NAME} của bạn chưa được phê duyệt trên nền tảng của chúng tôi.

View File

@@ -59,10 +59,10 @@ html
body
.container
.header
h1 Thư mời làm việc từ Trung tâm #{center_name}
h1 Thư mời làm việc từ #{center_name}
.content
p Chào bạn,
p Chúng tôi rất vui mừng thông báo rằng bạn đã được mời làm người hướng dẫn tại trung tâm #{center_name}.
p Chúng tôi rất vui mừng thông báo rằng bạn đã được mời làm người hướng dẫn tại #{center_name}.
p Để tiếp tục quá trình ứng tuyển, vui lòng nhấn vào nút dưới đây để truy cập vào trang nộp resume của bạn.
a.button(href=invite_url) Nộp Resume
p Nếu bạn có bất kỳ thắc mắc nào, đừng ngần ngại liên hệ với chúng tôi.

View File

@@ -62,7 +62,7 @@ html
h1 Thông báo kết quả ứng tuyển của #{USER_NAME} tại #{CENTER_NAME}
.content
p Chào #{USER_NAME},
p Chúng tôi rất tiếc thông báo rằng bạn chưa được phê duyệt trở thành Mentor tại trung tâm #{CENTER_NAME} lần này.
p Chúng tôi rất tiếc thông báo rằng bạn chưa được phê duyệt trở thành Mentor tại #{CENTER_NAME} lần này.
p Chúng tôi khuyến khích bạn tiếp tục nâng cao kỹ năng và kinh nghiệm, và mong đợi đơn ứng tuyển của bạn trong tương lai.
p Bạn có thể truy cập trang web của chúng tôi để biết thêm thông tin:
a.button(href="https://center.epess.org") Truy cập Trung tâm

View File

@@ -61,7 +61,7 @@ html
.header
h1 Chúc mừng Dịch vụ #{SERVICE_NAME} đã được phê duyệt
.content
p Kính gửi Quý Trung tâm #{CENTER_NAME},
p Kính gửi #{CENTER_NAME},
p Chúng tôi vui mừng thông báo rằng dịch vụ #{SERVICE_NAME} của bạn đã được phê duyệt trên nền tảng của chúng tôi.
p Vui lòng nhấn vào nút dưới đây để truy cập vào dịch vụ của bạn:
a.button(href="https://center.epess.org") Truy cập Dịch vụ

View File

@@ -69,7 +69,7 @@ html
.header
h1 Thông báo từ chối Dịch vụ #{SERVICE_NAME}
.content
p Kính gửi Quý Trung tâm #{CENTER_NAME},
p Kính gửi #{CENTER_NAME},
p Chúng tôi rất tiếc thông báo rằng dịch vụ #{SERVICE_NAME} của bạn chưa được phê duyệt trên nền tảng của chúng tôi.
.note
p Lý do từ chối:

View File

@@ -364,7 +364,6 @@ export class ServiceSchema extends PothosSchema {
const mentorEmails = await prisma.user.findMany({
where: { id: { in: mentorIds } },
})
Logger.log(mentorEmails, 'ServiceSchema')
const emails = [centerOwner.email, ...mentorEmails.map((mentor) => mentor.email)]
if (args.approve) {
await this.mailService.sendTemplateEmail(emails, 'Thông báo về trạng thái dịch vụ', 'ServiceApproved', {

File diff suppressed because one or more lines are too long