Skip to content

Commit bf290dc

Browse files
committed
컨텐츠 보상 수정 시 모든 아이템 보상 설정 가능하도록 수정
- 이슈 해결을 위해 모든 컨텐츠 보상의 수량 정보에 default 값을 부여함(0개). - 또한 서버 설정을 거스르는 정보 수정이 가능하기 때문에 귀속 여부까지 설정 가능하도록 자유도를 부여함. - 기존에 이미 존재하던 유저 커스텀 보상은 서버의 귀속 여부 값을 상속받도록 함. - 이제 수정 모달에서는 모든 보상을 수정할 수 있도록 하고, 귀속 여부 설정이 가능함. - 귀속 여부가 유저 커스텀 테이블에도 추가되기 때문에, 시급 계산시에도 귀속 여부 체크를 유저 테이블을 함께 고려하도록 함. - 보상 테이블 및 상세 모달에서 0개인 경우는 편의 상 "-" 표시하도록 함(가시성 문제).
1 parent 49129db commit bf290dc

14 files changed

Lines changed: 237 additions & 55 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
-- AlterTable
2+
ALTER TABLE "content_reward" ALTER COLUMN "default_average_quantity" SET DEFAULT 0;
3+
4+
-- AlterTable
5+
ALTER TABLE "content_see_more_reward" ALTER COLUMN "quantity" SET DEFAULT 0;
6+
7+
-- AlterTable
8+
ALTER TABLE "user_content_reward" ADD COLUMN "is_sellable" BOOLEAN NOT NULL DEFAULT false,
9+
ALTER COLUMN "average_quantity" SET DEFAULT 0;
10+
11+
-- AlterTable
12+
ALTER TABLE "user_content_see_more_reward" ALTER COLUMN "quantity" SET DEFAULT 0;
13+
14+
INSERT INTO "content_reward" (
15+
"content_id",
16+
"content_reward_item_id",
17+
"created_at",
18+
"updated_at"
19+
)
20+
SELECT
21+
c.id,
22+
cri.id,
23+
NOW(),
24+
NOW()
25+
FROM "content" c
26+
CROSS JOIN "content_reward_item" cri
27+
ON CONFLICT ("content_id", "content_reward_item_id") DO NOTHING;
28+
29+
UPDATE "user_content_reward"
30+
SET "is_sellable" = cr."is_sellable",
31+
"updated_at" = NOW()
32+
FROM "content_reward" cr
33+
WHERE "user_content_reward"."content_reward_id" = cr.id;
34+
35+
INSERT INTO "user_content_reward" (
36+
"user_id",
37+
"content_reward_id",
38+
"created_at",
39+
"updated_at"
40+
)
41+
SELECT
42+
u.id,
43+
cr.id,
44+
NOW(),
45+
NOW()
46+
FROM "user" u
47+
CROSS JOIN "content_reward" cr
48+
ON CONFLICT ("user_id", "content_reward_id") DO NOTHING;
49+
50+
INSERT INTO "content_see_more_reward" (
51+
"content_id",
52+
"content_reward_item_id",
53+
"created_at",
54+
"updated_at"
55+
)
56+
SELECT
57+
c.id,
58+
cri.id,
59+
NOW(),
60+
NOW()
61+
FROM "content" c
62+
CROSS JOIN "content_reward_item" cri
63+
WHERE EXISTS (
64+
SELECT 1 FROM "content_see_more_reward" existing_csmr
65+
WHERE existing_csmr."content_id" = c.id
66+
)
67+
AND NOT EXISTS (
68+
SELECT 1 FROM "content_see_more_reward" csmr
69+
WHERE csmr."content_id" = c.id
70+
AND csmr."content_reward_item_id" = cri.id
71+
);
72+
73+
INSERT INTO "user_content_see_more_reward" (
74+
"user_id",
75+
"content_see_more_reward_id",
76+
"created_at",
77+
"updated_at"
78+
)
79+
SELECT
80+
u.id,
81+
csmr.id,
82+
NOW(),
83+
NOW()
84+
FROM "user" u
85+
CROSS JOIN "content_see_more_reward" csmr
86+
ON CONFLICT ("user_id", "content_see_more_reward_id") DO NOTHING;

src/backend/prisma/schema.prisma

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ model ContentReward {
115115
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
116116
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
117117
118-
defaultAverageQuantity Decimal @map("default_average_quantity")
118+
defaultAverageQuantity Decimal @default(0) @map("default_average_quantity")
119119
isSellable Boolean @default(false) @map("is_sellable")
120120
121121
// Relations
@@ -154,7 +154,7 @@ model ContentSeeMoreReward {
154154
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
155155
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
156156
157-
quantity Decimal
157+
quantity Decimal @default(0)
158158
159159
// Relations
160160
contentId Int @map("content_id")
@@ -304,8 +304,9 @@ model UserContentReward {
304304
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
305305
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
306306
307-
averageQuantity Decimal @map("average_quantity")
307+
averageQuantity Decimal @default(0) @map("average_quantity")
308308
isEdited Boolean @default(false) @map("is_edited")
309+
isSellable Boolean @default(false) @map("is_sellable")
309310
310311
// Relations
311312
contentRewardId Int @map("content_reward_id")
@@ -323,7 +324,7 @@ model UserContentSeeMoreReward {
323324
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
324325
325326
isEdited Boolean @default(false) @map("is_edited")
326-
quantity Decimal
327+
quantity Decimal @default(0)
327328
328329
// Relations
329330
contentSeeMoreRewardId Int @map("content_see_more_reward_id")

src/backend/schema.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,15 @@ type UserContentReward {
352352
contentRewardId: Int!
353353
createdAt: DateTime!
354354
id: Int!
355+
isSellable: Boolean!
355356
updatedAt: DateTime!
356357
userId: Int!
357358
}
358359

359360
input UserContentRewardEditInput {
360361
averageQuantity: Float!
361362
id: Int!
363+
isSellable: Boolean!
362364
}
363365

364366
type UserContentRewardItem {

src/backend/src/content/mutation/user-content-rewards-edit.mutation.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class UserContentRewardEditInput {
2222

2323
@Field(() => Float)
2424
averageQuantity: number;
25+
26+
@Field(() => Boolean)
27+
isSellable: boolean;
2528
}
2629

2730
@InputType()
@@ -62,10 +65,10 @@ export class UserContentRewardsEditMutation {
6265
}
6366

6467
await Promise.all(
65-
input.userContentRewards.map(({ id, averageQuantity }) =>
68+
input.userContentRewards.map(({ id, averageQuantity, isSellable }) =>
6669
tx.userContentReward.update({
6770
where: { id },
68-
data: { averageQuantity, isEdited: true },
71+
data: { averageQuantity, isEdited: true, isSellable },
6972
}),
7073
),
7174
);
@@ -98,7 +101,7 @@ export class UserContentRewardsEditMutation {
98101
tx: Prisma.TransactionClient,
99102
) {
100103
await Promise.all(
101-
userContentRewards.map(async ({ id, averageQuantity }) => {
104+
userContentRewards.map(async ({ id, averageQuantity, isSellable }) => {
102105
const userContentReward = await tx.userContentReward.findUniqueOrThrow({
103106
where: { id },
104107
include: {
@@ -113,6 +116,7 @@ export class UserContentRewardsEditMutation {
113116
},
114117
data: {
115118
averageQuantity,
119+
isSellable,
116120
},
117121
});
118122

@@ -122,6 +126,7 @@ export class UserContentRewardsEditMutation {
122126
},
123127
data: {
124128
defaultAverageQuantity: averageQuantity,
129+
isSellable,
125130
},
126131
});
127132
}),

src/backend/src/content/object/content-reward.object.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,4 @@ import { BaseObject } from 'src/common/object/base.object';
55
export class ContentReward extends BaseObject {
66
@Field()
77
contentRewardItemId: number;
8-
9-
@Field(() => Boolean)
10-
isSellable: boolean;
118
}

src/backend/src/content/object/content-reward.resolver.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ export class ContentRewardResolver {
3232
);
3333
}
3434

35+
@ResolveField(() => Boolean)
36+
async isSellable(@Parent() contentReward: ContentReward) {
37+
return await this.userContentService.getContentRewardIsSellable(
38+
contentReward.id,
39+
);
40+
}
41+
3542
@UseGuards(AuthGuard)
3643
@ResolveField(() => UserContentReward)
3744
async userContentReward(

src/backend/src/content/object/user-content-reward.object.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export class UserContentReward extends BaseObject {
99
@Field()
1010
contentRewardId: number;
1111

12+
@Field()
13+
isSellable: boolean;
14+
1215
@Field()
1316
userId: number;
1417
}

src/backend/src/user/service/user-content.service.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,13 @@ describe('UserContentService', () => {
504504
userId: user.id,
505505
contentRewardId: contentReward1.id,
506506
averageQuantity: userAverageQuantity1,
507+
isSellable: true,
507508
},
508509
{
509510
userId: user.id,
510511
contentRewardId: contentReward2.id,
511512
averageQuantity: userAverageQuantity2,
513+
isSellable: false,
512514
},
513515
],
514516
});

src/backend/src/user/service/user-content.service.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ export class UserContentService {
9999
: contentReward.defaultAverageQuantity;
100100
}
101101

102+
async getContentRewardIsSellable(contentRewardId: number) {
103+
const userId = this.getUserId();
104+
105+
const contentReward = await this.prisma.contentReward.findUniqueOrThrow({
106+
where: { id: contentRewardId },
107+
});
108+
109+
return userId
110+
? (
111+
await this.prisma.userContentReward.findUniqueOrThrow({
112+
where: { userId_contentRewardId: { userId, contentRewardId } },
113+
})
114+
).isSellable
115+
: contentReward.isSellable;
116+
}
117+
102118
async getContentSeeMoreRewardQuantity(contentSeeMoreRewardId: number) {
103119
const userId = this.getUserId();
104120

@@ -127,19 +143,17 @@ export class UserContentService {
127143
) {
128144
const userId = this.getUserId();
129145

130-
const where = {
131-
contentId,
132-
...(filter?.includeIsBound === false && { isSellable: true }),
133-
...(filter?.includeContentRewardItemIds && {
134-
contentRewardItemId: { in: filter.includeContentRewardItemIds },
135-
}),
136-
};
137-
138146
if (userId) {
139147
const userRewards = await this.prisma.userContentReward.findMany({
140148
where: {
141149
userId,
142-
contentReward: where,
150+
...(filter?.includeIsBound === false && { isSellable: true }),
151+
contentReward: {
152+
contentId,
153+
...(filter?.includeContentRewardItemIds && {
154+
contentRewardItemId: { in: filter.includeContentRewardItemIds },
155+
}),
156+
},
143157
},
144158
include: {
145159
contentReward: true,
@@ -152,6 +166,14 @@ export class UserContentService {
152166
}));
153167
}
154168

169+
const where = {
170+
contentId,
171+
...(filter?.includeIsBound === false && { isSellable: true }),
172+
...(filter?.includeContentRewardItemIds && {
173+
contentRewardItemId: { in: filter.includeContentRewardItemIds },
174+
}),
175+
};
176+
155177
const defaultRewards = await this.prisma.contentReward.findMany({
156178
where,
157179
});

src/backend/src/user/service/user-seed.service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ export class UserSeedService {
4545

4646
await tx.userContentReward.createMany({
4747
data: defaultRewards.map(
48-
({ id, defaultAverageQuantity: averageQuantity }) => ({
48+
({ id, defaultAverageQuantity: averageQuantity, isSellable }) => ({
4949
contentRewardId: id,
5050
averageQuantity,
51+
isSellable,
5152
userId,
5253
createdAt,
5354
}),

0 commit comments

Comments
 (0)