refactor: streamline Redis caching logic across services

- Implemented a unified `getAndSet` method in RedisService to handle caching for single, list, and paginated responses.
- Removed redundant cache checks and writes in various services, simplifying the code and improving readability.
- Updated GoodsService, StockKeepingUnitsService, PartnerActivatedLicensesService, and others to utilize the new caching mechanism.
- Adjusted Prisma connection limit for better resource management.
This commit is contained in:
2026-05-21 17:27:37 +03:30
parent 1d47fb1a1d
commit 9aa12184a1
16 changed files with 689 additions and 1896 deletions
+33 -36
View File
@@ -52,47 +52,44 @@ export class GoodsService {
guild_id: string,
consumer_account_id: string,
) {
const cacheKey = RedisKeyMaker.posGoodsList(guild_id, business_activity_id)
try {
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
if (cached) {
return ResponseMapper.list(cached)
}
throw new Error('Cache miss')
} catch (error) {
const goods = await this.prisma.good.findMany({
where: {
OR: [
{
is_default_guild_good: true,
category: {
guild_id,
const cacheKey = RedisKeyMaker.posGoodsList(business_activity_id, guild_id)
return this.redisService.getAndSet(
cacheKey,
'list',
async () => {
const goods = await this.prisma.good.findMany({
where: {
OR: [
{
is_default_guild_good: true,
category: {
guild_id,
},
},
{
business_activity_id,
},
],
},
select: {
...this.defaultSelect,
consumer_account_good_favorites: {
where: {
consumer_account_id,
},
},
{
business_activity_id,
},
],
},
select: {
...this.defaultSelect,
consumer_account_good_favorites: {
where: {
consumer_account_id,
},
},
},
})
})
const mappedGoods = goods.map(good => ({
...good,
is_favorite: good.consumer_account_good_favorites.length > 0,
}))
const mappedGoods = goods.map(good => ({
...good,
is_favorite: good.consumer_account_good_favorites.length > 0,
}))
await this.redisService.setJson(cacheKey, mappedGoods, this.listCacheTtlSeconds)
return ResponseMapper.list(mappedGoods)
}
return mappedGoods
},
this.listCacheTtlSeconds,
)
}
async findOne(good_id: string, business_activity_id: string, guild_id: string) {
+109 -105
View File
@@ -19,93 +19,95 @@ export class PosService {
async getInfo(pos_id: string) {
const cacheKey = RedisKeyMaker.posInfo(pos_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const pos = await this.prisma.pos.findUniqueOrThrow({
where: {
id: pos_id,
},
select: {
name: true,
complex: {
return await this.redisService.getAndSet(
cacheKey,
'single',
async () => {
const pos = await this.prisma.pos.findUniqueOrThrow({
where: {
id: pos_id,
},
select: {
id: true,
name: true,
branch_code: true,
business_activity: {
complex: {
select: {
id: true,
name: true,
economic_code: true,
license_activation: {
branch_code: true,
business_activity: {
select: {
expires_at: true,
license: {
id: true,
name: true,
economic_code: true,
license_activation: {
select: {
id: true,
charge_transaction: {
expires_at: true,
license: {
select: {
partner: {
id: true,
charge_transaction: {
select: {
id: true,
name: true,
code: true,
logo_url: true,
partner: {
select: {
id: true,
name: true,
code: true,
logo_url: true,
},
},
},
},
},
},
},
},
},
},
guild: {
select: {
id: true,
name: true,
code: true,
guild: {
select: {
id: true,
name: true,
code: true,
},
},
},
},
},
},
},
},
},
})
const { name, complex } = pos
const { name: complexName, id: complexId, business_activity } = complex
const {
name: businessName,
id: businessId,
guild,
economic_code,
license_activation,
} = business_activity
})
const { name, complex } = pos
const { name: complexName, id: complexId, business_activity } = complex
const {
name: businessName,
id: businessId,
guild,
economic_code,
license_activation,
} = business_activity
const payload = {
name,
complex: {
id: complexId,
name: complexName,
branch_code: complex.branch_code,
const payload = {
name,
complex: {
id: complexId,
name: complexName,
branch_code: complex.branch_code,
},
businessActivity: {
id: businessId,
name: businessName,
economic_code,
},
guild,
license_info: {
expires_at: license_activation?.expires_at,
license_id: license_activation?.license.id,
},
partner: license_activation?.license.charge_transaction.partner,
}
return payload
},
businessActivity: {
id: businessId,
name: businessName,
economic_code,
},
guild,
license_info: {
expires_at: license_activation?.expires_at,
license_id: license_activation?.license.id,
},
partner: license_activation?.license.charge_transaction.partner,
}
await this.redisService.setJson(cacheKey, payload, this.infoCacheTtlSeconds)
return ResponseMapper.single(payload)
this.infoCacheTtlSeconds,
)
}
async getAccessible(account_id: string) {
@@ -153,57 +155,59 @@ export class PosService {
async getMe(account_id: string, pos_id: string) {
const cacheKey = RedisKeyMaker.posMe(account_id, pos_id)
const cached = await this.redisService.getJson<unknown>(cacheKey)
if (cached) {
return ResponseMapper.single(cached)
}
const pos = await this.prisma.consumerAccount.findUniqueOrThrow({
where: {
id: account_id,
consumer: {
status: ConsumerStatus.ACTIVE,
business_activities: {
some: {
complexes: {
return await this.redisService.getAndSet(
cacheKey,
'single',
async () => {
const pos = await this.prisma.consumerAccount.findUniqueOrThrow({
where: {
id: account_id,
consumer: {
status: ConsumerStatus.ACTIVE,
business_activities: {
some: {
pos_list: {
complexes: {
some: {
id: pos_id,
pos_list: {
some: {
id: pos_id,
},
},
},
},
},
},
},
},
},
},
select: {
id: true,
role: true,
consumer: {
select: {
id: true,
type: true,
status: true,
...QUERY_CONSTANTS.CONSUMER.infoSelect,
role: true,
consumer: {
select: {
id: true,
type: true,
status: true,
...QUERY_CONSTANTS.CONSUMER.infoSelect,
},
},
account: {
select: {
username: true,
},
},
},
},
account: {
select: {
username: true,
},
},
})
const { consumer, ...rest } = pos
const payload = {
...rest,
consumer: consumer_mappersUtil(consumer),
}
return payload
},
})
const { consumer, ...rest } = pos
const payload = {
...rest,
consumer: consumer_mappersUtil(consumer),
}
await this.redisService.setJson(cacheKey, payload, this.meCacheTtlSeconds)
return ResponseMapper.single(payload)
this.meCacheTtlSeconds,
)
}
}