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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
@RequiredArgsConstructor
public enum CherryLevel {

LEVEL_1(1, "๋ชฝ๋กฑ์ฒด๋ฆฌ"), // 0-24%
LEVEL_0(0, "๋ชฝ๋กฑ์ฒด๋ฆฌ"), // completedCount == 0
LEVEL_1(1, "๋ชฝ๋กฑ์ฒด๋ฆฌ"), // 1๊ฐœ ์ด์ƒ, 0-24%
LEVEL_2(2, "๋ฝ€๋“์ฒด๋ฆฌ"), // 25-49%
LEVEL_3(3, "ํŒกํŒก์ฒด๋ฆฌ"), // 50-74%
LEVEL_4(4, "๊พธ๊พธ์ฒด๋ฆฌ"); // 75-100%
Expand All @@ -34,6 +35,7 @@ public enum CherryLevel {
* ๋ ˆ๋ฒจ ์ˆซ์ž๋กœ CherryLevel ์ฐพ๊ธฐ
*
* @param level ์ฒด๋ฆฌ ๋ ˆ๋ฒจ (1-4)
* ๋ฐ๋ชจ์šฉ์œผ๋กœ ํ˜„์žฌ (0-4)
* @return ํ•ด๋‹นํ•˜๋Š” CherryLevel enum
* @throws ChallengeException ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ ˆ๋ฒจ์ธ ๊ฒฝ์šฐ
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum ChallengeErrorCode implements ErrorType {
DUPLICATE_ROUTINE_IDS("CH009", "์ค‘๋ณต๋œ ๋ฃจํ‹ด ID๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค", 400),
CHALLENGE_NOT_ACTIVE("CH010", "๋น„ํ™œ์„ฑ ์ฑŒ๋ฆฐ์ง€์—๋Š” ๋ฃจํ‹ด์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค", 400),
CUSTOM_ROUTINE_LIMIT_EXCEEDED("CH011", "์ตœ๋Œ€๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฃจํ‹ด์€ 20๊ฐœ์ž…๋‹ˆ๋‹ค", 400),
INVALID_CHERRY_LEVEL("CH012", "์œ ํšจํ•˜์ง€ ์•Š์€ ์ฒด๋ฆฌ ๋ ˆ๋ฒจ์ž…๋‹ˆ๋‹ค (1-4)", 400);
INVALID_CHERRY_LEVEL("CH012", "์œ ํšจํ•˜์ง€ ์•Š์€ ์ฒด๋ฆฌ ๋ ˆ๋ฒจ์ž…๋‹ˆ๋‹ค (0-4)", 400);

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ public class DemoChallengeStatistics extends BaseTimeEntity {
private Integer totalRoutineCount;

@Column(nullable = false, name = "cherry_level")
private Integer cherryLevel = 1;
private Integer cherryLevel = 0;

@Builder
private DemoChallengeStatistics(DemoChallenge demoChallenge, Integer totalRoutineCount) {
this.demoChallenge = demoChallenge;
this.completedCount = 0;
this.totalRoutineCount = totalRoutineCount;
this.cherryLevel = 1;
this.cherryLevel = 0;
}

/**
Expand Down Expand Up @@ -86,10 +86,15 @@ public int getProgressPercentage() {

/**
* ์™„๋ฃŒ ์ง„ํ–‰๋ฅ  ๊ธฐ๋ฐ˜ ์ฒด๋ฆฌ ๋ ˆ๋ฒจ ๊ณ„์‚ฐ
* - ๋ ˆ๋ฒจ 0: completedCount == 0 (๋ชฝ๋กฑ์ฒด๋ฆฌ)
* - ๋ ˆ๋ฒจ 1: 1๊ฐœ ์ด์ƒ, 0% ~ 24.99%
* - ๋ ˆ๋ฒจ 2: 25% ~ 49.99%
* - ๋ ˆ๋ฒจ 3: 50% ~ 74.99%
* - ๋ ˆ๋ฒจ 4: 75% ~ 100%
*/
public int calculateCherryLevel() {
if (totalRoutineCount == 0) {
return 1;
if (completedCount == 0) {
return 0;
}

double progressPercentage = getProgressPercentage();
Expand All @@ -110,7 +115,7 @@ public int calculateCherryLevel() {
* ํ˜„์žฌ ๋ ˆ๋ฒจ ๊ตฌ๊ฐ„ ๋‚ด์—์„œ์˜ ์ง„์ฒ™๋„ ๊ณ„์‚ฐ (0-100%)
*/
public double getProgressToNextLevel() {
if (totalRoutineCount == 0) {
if (totalRoutineCount == 0 || completedCount == 0) {
return 0.0;
}

Expand All @@ -130,11 +135,12 @@ public double getProgressToNextLevel() {

/**
* ๋‹ค์Œ ๋ ˆ๋ฒจ๊นŒ์ง€ ๋‚จ์€ ๋ฃจํ‹ด ๊ฐœ์ˆ˜ ๊ณ„์‚ฐ
* ๋ ˆ๋ฒจ 0, 1์ผ ๋•Œ๋Š” ๋ ˆ๋ฒจ 2(25%)๊นŒ์ง€ ๋‚จ์€ ๊ฐœ์ˆ˜ ๋ฐ˜ํ™˜
* ๋ ˆ๋ฒจ 4์ผ ๋•Œ๋Š” 100%๊นŒ์ง€ ๋‚จ์€ ๋ฃจํ‹ด ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
*/
public int getRemainingRoutinesToNextLevel() {
double nextThreshold = switch (cherryLevel) {
case 1 -> LEVEL_2_THRESHOLD;
case 0, 1 -> LEVEL_2_THRESHOLD;
case 2 -> LEVEL_3_THRESHOLD;
case 3 -> LEVEL_4_THRESHOLD;
default -> 100.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,48 @@
public class ChallengePromptTemplate {

private static final String CHALLENGE_RECOMMENDATION_TEMPLATE = """
๋‹น์‹ ์€ ํ”ผ๋ถ€ ํ™ˆ์ผ€์–ด ๋ฐ ์…€ํ”„์ผ€์–ด ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ํ™ˆ์ผ€์–ด ๋ฃจํ‹ด ์นดํ…Œ๊ณ ๋ฆฌ: "{homecareContent}"
๋‹น์‹ ์€ ํ”ผ๋ถ€ ํ™ˆ์ผ€์–ด ๋ฐ ์…€ํ”„์ผ€์–ด โ€˜์ฒด๋ฆฌ์‰ฌโ€™ ์•ฑ์˜ 7์ผ ์ฑŒ๋ฆฐ์ง€ ๋ฃจํ‹ด์„ ๋งŒ๋“œ๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ์นดํ…Œ๊ณ ๋ฆฌ: "{homecareContent}"

๋ชฉํ‘œ: ์‚ฌ์šฉ์ž๊ฐ€ ํ•˜๋ฃจ 1๋ฒˆ โ€˜ํ–ˆ์Œ/์•ˆํ–ˆ์Œโ€™์œผ๋กœ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฃจํ‹ด 6๊ฐœ๋ฅผ ๋งŒ๋“œ์„ธ์š”.
๊ฒฐ๊ณผ ๋ฌธ๊ตฌ์—๋Š” ๋นˆ๋„(๋งค์ผ/์ผ์ผ/์ผ์ฃผ์ผ/NํšŒ/N๋ฒˆ/ํ•ญ์ƒ/๋งค๋ฒˆ)๋ฅผ ์ ˆ๋Œ€ ์“ฐ์ง€ ๋งˆ์„ธ์š”.

[์ ˆ๋Œ€ ๊ธˆ์ง€(ํ•˜๋‚˜๋ผ๋„ ๋‚˜์˜ค๋ฉด ์‹คํŒจ)]
- ์ ๊ฒ€/ํ™•์ธ/์ฒดํฌ/์ •๋ฆฌ/์„ธํƒ/๋ฒ„๋ฆฌ๊ธฐ ๋“ฑ โ€˜๊ด€๋ฆฌ/์‚ฌํ›„์ฒ˜๋ฆฌโ€™ ๋ชฉ์  ํ–‰๋™
- ๊ณต์ค‘์œ„์ƒยท๊ธฐ๋ณธ ์ƒํ™œ ์˜๋ฌด ์ˆ˜์ค€์˜ ํ–‰๋™(์ƒค์›Œ/์–‘์น˜/์†์”ป๊ธฐ ๋“ฑ) ์ ˆ๋Œ€ ๊ธˆ์ง€
- ๋ฏผ๊ฐ„์š”๋ฒ•, ์ž์—ฐ์š”๋ฒ•, ์ธํ„ฐ๋„ท ์นด๋”๋ผ ๋ฐ DIY ๋ ˆ์‹œํ”ผ ํ˜•ํƒœ์˜ ๋ฃจํ‹ด ์ œ์™ธ
- ์ „๋ฌธ ์‹œ์ˆ /์˜ํ•™์  ๊ด€๋ฆฌ์ฒ˜๋Ÿผ ๋ณด์ด๊ฑฐ๋‚˜ ์ž๊ทน์ ยท๊ณผ๋„ํ•œ ์ผ€์–ด
- ์˜คํƒ€, ๋น„ํ‘œ์ค€์–ด, ์–ด์ƒ‰ํ•œ ํ•ฉ์„ฑ์–ด, ์‹ค์ œ ํ•œ๊ตญ์–ด์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํ‘œํ˜„ ๊ธˆ์ง€
- ์™ธ๋ž˜์–ดยท์˜์–ดยท์ „๋ฌธ์šฉ์–ด๋Š” ์ผ๋ฐ˜์ ์ธ ํ•œ๊ตญ์–ด ํ‘œํ˜„์œผ๋กœ ์น˜ํ™˜ํ•˜์—ฌ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ:
- ์—‘์Šคํด๋ฆฌ์—์ด์…˜ โ†’ ๊ฐ์งˆ ์ œ๊ฑฐ ์ œํ’ˆ
- ๋ดํƒˆ ํ”Œ๋กœ์Šค โ†’ ์น˜์‹ค
- ์„ ์Šคํฌ๋ฆฐ โ†’ ์„ ํฌ๋ฆผ
[์ž‘์„ฑ ๊ทœ์น™]
- ๊ฐ ๋ฃจํ‹ด: ๊ณต๋ฐฑ ํฌํ•จ 20์ž ์ด๋‚ด
- ๋ฃจํ‹ด์€ โ€œ๋ทฐํ‹ฐ/์ž๊ธฐ๊ด€๋ฆฌ ํšจ์šฉโ€์ด ๋ถ„๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- ๋งค์ผ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๋ฃจํ‹ด๋งŒ ์ž‘์„ฑ ("์ฃผ NํšŒ" ๊ฐ™์€ ์ฃผ๊ฐ„ ๋ฃจํ‹ด ์ œ์™ธ)
- ์ƒ์‹์ ์ด๊ณ  ์•ˆ์ „ํ•˜๋ฉฐ, ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ ํ•ด๋„ ๋ฌด๋ฆฌ๊ฐ€ ์—†๋Š” ์ˆ˜์ค€์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- ์ฝ์ž๋งˆ์ž ์–ด๋–ค ํ–‰๋™์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ช…ํ™•ํ•œ ํ–‰๋™ํ˜• ๋ฌธ์žฅ์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

[์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์˜ˆ์‹œ]
- ํ”ผ๋ถ€ ์ปจ๋””์…˜: "์„ธ์•ˆ ํ›„ ํŒฉ ํ•˜๊ธฐ", "๋งค์ผ ๋ฐค ๋ชจ๋ธ๋งํŒฉ ํ•˜๊ธฐ", "์†์œผ๋กœ ์–ผ๊ตด ๋งŒ์ง€์ง€ ์•Š๊ธฐ", "์ƒค์›Œ ํ›„ PDRN ๋งˆ์ŠคํฌํŒฉํ•˜๊ธฐ", "์ž๊ธฐ ์ „ ํŽ˜์ด์Šค ๊ด„์‚ฌ ๋งˆ์‚ฌ์ง€ํ•˜๊ธฐ", "์ฝœ๋ผ๊ฒ ์ฑ™๊ฒจ๋จน๊ธฐ"
- ์ƒํ™œ์Šต๊ด€: "์ผ์–ด๋‚˜์ž๋งˆ์ž ๋ฌผ ํ•œ ์ž”", "6์‹œ๊ฐ„ ์ด์ƒ ์ž๊ธฐ", "์˜คํ›„ 3์‹œ ์ดํ›„ ์นดํŽ˜์ธ ์Œ๋ฃŒ ํ”ผํ•˜๊ธฐ", "์ž ๋“ค๊ธฐ 30๋ถ„ ์ „ ์Šค๋งˆํŠธํฐ ๋‚ด๋ ค๋†“๊ธฐ", "12์‹œ ์ „์— ๋ˆ•๊ธฐ"
- ์ฒดํ˜•๊ด€๋ฆฌ: "๊ธฐ์ƒ ์งํ›„ ์ŠคํŠธ๋ ˆ์นญ 10๋ถ„", "์œ ์‚ฐ์†Œ ์šด๋™ํ•˜๊ธฐ", "์ €๋… ์‹์‚ฌ ํ›„ ์•ผ์‹ ์•ˆ ๋จน๊ธฐ", "๊ณ„๋‹จ์œผ๋กœ ์ด๋™ํ•˜๊ธฐ"
- ์›ฐ๋‹ˆ์Šค โ€ข ๋งˆ์Œ์ฑ™๊น€: "๊ธฐ์ƒ ์งํ›„ ์•„์นจ ๋ช…์ƒ", "์ผ์–ด๋‚˜์ž๋งˆ์ž ์Šค๋งˆํŠธํฐ ๋ณด์ง€ ์•Š๊ธฐ", "์ž๊ธฐ ์ „ ์ŠคํŠธ๋ ˆ์นญ", "์ž๊ธฐ ์ „ ๊ฐ์‚ฌ์ผ๊ธฐ 3๊ฐ€์ง€", "๋‚ด์ผ ๊ธฐ๋Œ€๋˜๋Š” ๊ฒƒ 1๊ฐ€์ง€ ์ ๊ธฐ"

[์ถœ๋ ฅ ์ „ ์ž์ฒด ๊ฒ€์ˆ˜(ํ•„์ˆ˜)]
- 6๊ฐœ๋ฅผ ๋งŒ๋“  ๋’ค, ์•„๋ž˜ ๊ธˆ์ง€ ๋‹จ์–ด/ํŒจํ„ด์ด ํฌํ•จ๋˜๋ฉด ๋ฌธ์žฅ์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ๊ต์ฒดํ•˜์„ธ์š”:
1) ๋นˆ๋„: ๋งค์ผ, ์ผ์ผ, ์ผ์ฃผ์ผ, NํšŒ, N๋ฒˆ, ํ•ญ์ƒ, ๋งค๋ฒˆ
2) ๊ด€๋ฆฌ/์‚ฌํ›„์ฒ˜๋ฆฌ: ์ ๊ฒ€, ํ™•์ธ, ์ฒดํฌ, ์ •๋ฆฌ, ์„ธํƒ, ๋ฒ„๋ฆฌ๊ธฐ
- ๊ฒ€์ˆ˜ ๊ณผ์ •์€ ์ถœ๋ ฅํ•˜์ง€ ๋ง๊ณ , ์ตœ์ข… JSON๋งŒ ์ถœ๋ ฅํ•˜์„ธ์š”.

์‘๋‹ต ํ˜•์‹(JSON๋งŒ):
{{
"routines": ["๋ฃจํ‹ด1","๋ฃจํ‹ด2","๋ฃจํ‹ด3","๋ฃจํ‹ด4","๋ฃจํ‹ด5","๋ฃจํ‹ด6"]
}}
""";

์œ„ ์นดํ…Œ๊ณ ๋ฆฌ์— ๋งž๋Š” ๋งค์ผ ์‹ค์ฒœ ๊ฐ€๋Šฅํ•œ ๋ฃจํ‹ด 6๊ฐœ๋ฅผ ์ถ”์ฒœํ•ด์ฃผ์„ธ์š”.

[์ž‘์„ฑ ๊ทœ์น™]
- ๊ฐ ๋ฃจํ‹ด์€ ๊ณต๋ฐฑ ํฌํ•จ 20์ž ์ด๋‚ด
- ์งง๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘์„ฑ
- ๋งค์ผ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๋ฃจํ‹ด๋งŒ ์ž‘์„ฑ ("์ฃผ NํšŒ" ๊ฐ™์€ ์ฃผ๊ฐ„ ๋ฃจํ‹ด ์ œ์™ธ)

[์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์˜ˆ์‹œ]
- ํ”ผ๋ถ€ ์ปจ๋””์…˜: "์•„์นจ ๋‹ฆํ† ํ•˜๊ธฐ", "์„ธ์•ˆ ํ›„ ํŒฉํ† ํ•˜๊ธฐ", "๋งค์ผ ๋ฐค ๋ชจ๋ธ๋งํŒฉ ํ•˜๊ธฐ", "์†์œผ๋กœ ์–ผ๊ตด ๋งŒ์ง€์ง€ ์•Š๊ธฐ", "์ƒค์›Œ ํ›„ PDRN ๋งˆ์ŠคํฌํŒฉํ•˜๊ธฐ", "์ž๊ธฐ ์ „ ํŽ˜์ด์Šค ๊ด„์‚ฌ ๋งˆ์‚ฌ์ง€ํ•˜๊ธฐ"
- ์ƒํ™œ์Šต๊ด€: "์ผ์–ด๋‚˜์ž๋งˆ์ž ๋ฌผ ํ•œ ์ž”", "6์‹œ๊ฐ„ ์ด์ƒ ์ž๊ธฐ", "์˜คํ›„ 3์‹œ ์ดํ›„ ์นดํŽ˜์ธ ๊ธˆ์ง€", "์ž ๋“ค๊ธฐ 30๋ถ„ ์ „ ํฐ ๋‚ด๋ ค๋†“๊ธฐ", "12์‹œ ์ „์— ๋ˆ•๊ธฐ"
- ์ฒดํ˜•๊ด€๋ฆฌ: "๊ธฐ์ƒ ์งํ›„ ์ŠคํŠธ๋ ˆ์นญ 10๋ถ„", "์œ ์‚ฐ์†Œ ์šด๋™ํ•˜๊ธฐ", "์ €๋… ์‹์‚ฌ ํ›„ ์•ผ์‹ ์•ˆ ๋จน๊ธฐ", "๊ณ„๋‹จ์œผ๋กœ ์ด๋™ํ•˜๊ธฐ"
- ์›ฐ๋‹ˆ์Šค โ€ข ๋งˆ์Œ์ฑ™๊น€: "๊ธฐ์ƒ ์งํ›„ ์•„์นจ ๋ช…์ƒ", "์ผ์–ด๋‚˜์ž๋งˆ์ž ํฐ ๋ณด์ง€ ์•Š๊ธฐ", "์ž๊ธฐ ์ „ ์ŠคํŠธ๋ ˆ์นญ", "์ž๊ธฐ ์ „ ๊ฐ์‚ฌ์ผ๊ธฐ 3๊ฐ€์ง€", "๋‚ด์ผ ๊ธฐ๋Œ€๋˜๋Š” ๊ฒƒ 1๊ฐ€์ง€ ์ ๊ธฐ"

[๊ณตํ†ต ์˜ˆ์‹œ (๋ชจ๋“  ์นดํ…Œ๊ณ ๋ฆฌ์— ํ™œ์šฉ ๊ฐ€๋Šฅ)]
- "๋ฌผ 2L ๋งˆ์‹œ๊ธฐ", "๋ฒ ๊ฐœ ์œ„ ์ˆ˜๊ฑด ๊น”๊ธฐ"

์œ„ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜๋˜, ์˜ˆ์‹œ์™€ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ƒˆ๋กœ์šด ๋ฃจํ‹ด์„ ์ถ”์ฒœํ•ด์ฃผ์„ธ์š”.

์‘๋‹ต์€ ๋ฐ˜๋“œ์‹œ ๋‹ค์Œ JSON ํ˜•์‹์œผ๋กœ๋งŒ ๋‹ต๋ณ€ํ•˜์„ธ์š”:
{{
"routines": ["๋ฃจํ‹ด1", "๋ฃจํ‹ด2", "๋ฃจํ‹ด3", "๋ฃจํ‹ด4", "๋ฃจํ‹ด5", "๋ฃจํ‹ด6"]
}}
""";

/**
* ์ฑŒ๋ฆฐ์ง€ ์ถ”์ฒœ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ ๋ฐ˜ํ™˜
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-openai.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ spring:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: ${OPENAI_MODEL:gpt-3.5-turbo}
model: ${OPENAI_MODEL:gpt-4.1-mini}
temperature: ${OPENAI_TEMPERATURE:0.7}
max-tokens: ${OPENAI_MAX_TOKENS:500}