Skip to content

maxkim77/RecipeSpark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

151 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

RecipeSpark

title

1. ๋ถ„์„

1.1 ์‚ฌ์šฉ์ž ์š”๊ตฌ์‚ฌํ•ญ ์ •์˜์„œ (User Requirements Specification)

ํ”„๋กœ์ ํŠธ ์ด๋ฆ„: RecipeSpark

1.1.1 ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

  1. ์š”๋ฆฌ ๋ ˆ์‹œํ”ผ ๊ณต์œ  ๋ฐ ์š”๋ฆฌ ๊ด€๋ จ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ์„ฑํ™”.
  2. ์ธ๊ณต์ง€๋Šฅ์„ ํ™œ์šฉํ•œ ๋งž์ถคํ˜• ๋ ˆ์‹œํ”ผ ์ถ”์ฒœ ๋ฐ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ ์ œ๊ณต.
  3. ์‚ฌ์šฉ์ž์˜ ์žฌ๋ฃŒ ๋ฐ ์„ ํ˜ธ๋„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ฐœ์ธํ™”๋œ ์š”๋ฆฌ ๊ฒฝํ—˜ ์ง€์›.

1.1.2 ์ฃผ์š” ๊ธฐ๋Šฅ

๊ธฐ๋ณธ ๊ธฐ๋Šฅ

  • ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ํ”„๋กœํ•„ ๊ธฐ๋Šฅ
  • ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ ๊ธฐ๋Šฅ(๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ, Q&A ๊ฒŒ์‹œํŒ)
  • AI ๋งž์ถค ๋ ˆ์‹œํ”ผ ๋ฐ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ

๋ถ€๊ฐ€ ๊ธฐ๋Šฅ

  • ์Šคํฌ๋žฉ ๊ธฐ๋Šฅ
  • ํˆฌํ‘œ ๊ธฐ๋Šฅ (ex. ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š”)
  • ๋Œ“๊ธ€ ๊ธฐ๋Šฅ

1.1.3 ์‚ฌ์šฉ์ž ์š”๊ตฌ์‚ฌํ•ญ

ID ์š”๊ตฌ์‚ฌํ•ญ ์šฐ์„ ์ˆœ์œ„ ์„ค๋ช…
UR-001 ์‚ฌ์šฉ์ž๋Š” ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ ๋น„ํšŒ์› ์‚ฌ์šฉ์ž๋Š” ์ผ๋ถ€ ๊ธฐ๋Šฅ(์—ด๋žŒ)์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, AI ์ถ”์ฒœ ๋ฐ ๋ณ€ํ™˜, ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ์€ ํšŒ์›๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
UR-002 ์‚ฌ์šฉ์ž๋Š” ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ์—์„œ ๋ ˆ์‹œํ”ผ๋ฅผ ๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ ๋ณธ์ธ์ด ์ž‘์„ฑํ•œ ๋ ˆ์‹œํ”ผ๋งŒ ์ˆ˜์ • ๋ฐ ์‚ญ์ œ ๊ฐ€๋Šฅ.
UR-003 ์‚ฌ์šฉ์ž๋Š” Q&A ๊ฒŒ์‹œํŒ์—์„œ ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ ์š”๋ฆฌ ๊ด€๋ จ ๊ถ๊ธˆ์ฆ ํ•ด๊ฒฐ ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ˜•์„ฑ์„ ๋ชฉ์ ์œผ๋กœ ํ•œ๋‹ค.
UR-004 ์‚ฌ์šฉ์ž๋Š” AI ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ์—์„œ ์ž์‹ ์˜ ๋งž์ถคํ˜• ๋ ˆ์‹œํ”ผ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์—ด๋žŒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ AI๊ฐ€ ์ถ”์ฒœํ•œ ๋ ˆ์‹œํ”ผ์™€ ๋ณ€ํ™˜๋œ ๋ ˆ์‹œํ”ผ๋ฅผ ๊ฐœ์ธ ๊ฒŒ์‹œํŒ์—์„œ ํ™•์ธ.
UR-005 ์‚ฌ์šฉ์ž๋Š” ๊ฒŒ์‹œ๊ธ€์— ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅด๊ฑฐ๋‚˜ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์„ ํƒ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ ๋ฐ ์†Œํ†ต ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-006 ์‚ฌ์šฉ์ž๋Š” ๋ ˆ์‹œํ”ผ๋ฅผ ์Šคํฌ๋žฉํ•˜์—ฌ ๊ฐœ์ธ ์ €์žฅ์†Œ์— ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์„ ํƒ ๊ด€์‹ฌ ์žˆ๋Š” ๋ ˆ์‹œํ”ผ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ.
UR-007 ์‹œ์Šคํ…œ์€ ๋ชจ๋“  ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๊ธ€(Q&A, ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ)์˜ ์—ด๋žŒ์€ ํšŒ์›/๋น„ํšŒ์› ๋ชจ๋‘ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ ์ ‘๊ทผ์„ฑ์„ ๋†’์ด๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ์„ฑํ™”๋ฅผ ์ง€์›.
UR-008 ์‹œ์Šคํ…œ์€ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์™€ ๊ฒŒ์‹œ๊ธ€ ์ •๋ณด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅ ๋ฐ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. ํ•„์ˆ˜ MySQL DB์™€ Spring Security๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋ณด์•ˆ ๊ฐ•ํ™”.

1.2 ์œ ์Šค์ผ€์ด์Šค ๋ช…์„ธ์„œ

1.2.1 ํšŒ์›๊ฐ€์ž…

์œ ์Šค์ผ€์ด์Šค ์ด๋ฆ„ ํšŒ์›๊ฐ€์ž…
ํ–‰์œ„์ž ๋น„ํšŒ์›
๋ชฉํ‘œ ์‚ฌ์šฉ์ž๊ฐ€ RecipeSpark ์„œ๋น„์Šค์— ๊ฐ€์ž…
์‚ฌ์ „์กฐ๊ฑด ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ.
์‚ฌํ›„์กฐ๊ฑด ๊ฐ€์ž…๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋จ.
์‹œ๋‚˜๋ฆฌ์˜ค 1. ๋น„ํšŒ์›์ด ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ์—ฐ๋‹ค.
2. ์ด๋ฉ”์ผ, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๋‹‰๋„ค์ž„์„ ์ž…๋ ฅํ•œ๋‹ค.
3. ๊ฐ€์ž… ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค.
4. ์‹œ์Šคํ…œ์ด ์ž…๋ ฅ ์ •๋ณด๋ฅผ ๊ฒ€์ฆํ•˜๊ณ  ๊ฐ€์ž… ์ฒ˜๋ฆฌํ•œ๋‹ค.
5. ์„ฑ๊ณต ์‹œ ํ™˜์˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ  ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋œ๋‹ค.
์˜ˆ์™ธ 1. ์ด๋ฉ”์ผ์ด ์ค‘๋ณต๋  ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.
2. ํ•„์ˆ˜ ์ž…๋ ฅ ํ•ญ๋ชฉ์ด ๋น„์–ด ์žˆ์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.

1.2.2 ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ CRUD

์œ ์Šค์ผ€์ด์Šค ์ด๋ฆ„ ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ CRUD
ํ–‰์œ„์ž ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž
๋ชฉํ‘œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์‹œํ”ผ๋ฅผ ๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Œ.
์‚ฌ์ „์กฐ๊ฑด ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์ƒํƒœ์—ฌ์•ผ ํ•จ.
์‚ฌํ›„์กฐ๊ฑด ๊ฒŒ์‹œํŒ์— ๋“ฑ๋ก๋œ ๋ ˆ์‹œํ”ผ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋จ.
์‹œ๋‚˜๋ฆฌ์˜ค 1. ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€๋ฅผ ์—ฐ๋‹ค.
2. ๋ ˆ์‹œํ”ผ๋ฅผ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๋ ˆ์‹œํ”ผ๋ฅผ ์ˆ˜์ • ๋˜๋Š” ์‚ญ์ œํ•œ๋‹ค.
3. ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์ด ์‹œ์Šคํ…œ์— ์ €์žฅ๋˜๊ณ  ํ™”๋ฉด์— ๋ฐ˜์˜๋œ๋‹ค.
์˜ˆ์™ธ 1. ๋น„ํšŒ์›์ด ์ ‘๊ทผํ•  ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.
2. ํ•„์ˆ˜ ์ž…๋ ฅ ํ•ญ๋ชฉ์ด ๋น„์–ด ์žˆ์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.

1.2.3 Q&A ๊ฒŒ์‹œํŒ ๊ด€๋ฆฌ

์œ ์Šค์ผ€์ด์Šค ์ด๋ฆ„ Q&A ๊ฒŒ์‹œํŒ ๊ด€๋ฆฌ
ํ–‰์œ„์ž ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋ฐ ๋น„ํšŒ์›
๋ชฉํ‘œ ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์„ ๋“ฑ๋กํ•˜๊ณ  ๋‹ต๋ณ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ.
์‚ฌ์ „์กฐ๊ฑด ์งˆ๋ฌธ/๋‹ต๋ณ€ ๋“ฑ๋ก์€ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๋งŒ ๊ฐ€๋Šฅ.
์‚ฌํ›„์กฐ๊ฑด ๊ฒŒ์‹œํŒ์— ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์ด ์ €์žฅ๋˜๊ณ  ์—ด๋žŒ ๊ฐ€๋Šฅ.
์‹œ๋‚˜๋ฆฌ์˜ค 1. ์‚ฌ์šฉ์ž๊ฐ€ Q&A ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€๋ฅผ ์—ฐ๋‹ค.
2. ์งˆ๋ฌธ์„ ์—ด๋žŒํ•˜๊ฑฐ๋‚˜ ์ƒˆ ์งˆ๋ฌธ์„ ์ž‘์„ฑํ•œ๋‹ค.
3. ๊ธฐ์กด ์งˆ๋ฌธ์— ๋Œ€ํ•ด ๋‹ต๋ณ€์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
4. ์‹œ์Šคํ…œ์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐ˜์˜๋œ๋‹ค.
์˜ˆ์™ธ 1. ์งˆ๋ฌธ ๋˜๋Š” ๋‹ต๋ณ€ ๋‚ด์šฉ์ด ๋น„์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.
2. ๋น„ํšŒ์›์ด ์งˆ๋ฌธ/๋‹ต๋ณ€์„ ๋“ฑ๋กํ•˜๋ ค๊ณ  ํ•  ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ์š”์ฒญ.

1.2.4 AI ๋งž์ถค ๋ ˆ์‹œํ”ผ ๊ด€๋ฆฌ

์œ ์Šค์ผ€์ด์Šค ์ด๋ฆ„ AI ๋งž์ถค ๋ ˆ์‹œํ”ผ ๊ด€๋ฆฌ
ํ–‰์œ„์ž ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž
๋ชฉํ‘œ AI๊ฐ€ ์ถ”์ฒœํ•œ ๋ ˆ์‹œํ”ผ๋ฅผ ์ €์žฅ ๋ฐ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ฐœ์ธ ๊ฒŒ์‹œํŒ์— ๊ด€๋ฆฌ
์‚ฌ์ „์กฐ๊ฑด ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์ƒํƒœ์—ฌ์•ผ ํ•จ.
์‚ฌํ›„์กฐ๊ฑด AI๊ฐ€ ์ƒ์„ฑํ•œ ๋ ˆ์‹œํ”ผ๊ฐ€ ๊ฐœ์ธ AI ๊ฒŒ์‹œํŒ์— ์ €์žฅ๋จ.
์‹œ๋‚˜๋ฆฌ์˜ค 1. ์‚ฌ์šฉ์ž๊ฐ€ AI ์ถ”์ฒœ ํŽ˜์ด์ง€๋ฅผ ์—ฐ๋‹ค.
2. ํ•„์š”ํ•œ ์žฌ๋ฃŒ๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ ์š”์ฒญ์„ ์ง„ํ–‰ํ•œ๋‹ค.
3. ์ƒ์„ฑ๋œ ๋งž์ถคํ˜• ๋ ˆ์‹œํ”ผ๊ฐ€ ๊ฐœ์ธ ๊ฒŒ์‹œํŒ์— ์ €์žฅ๋œ๋‹ค.
4. ์ €์žฅ๋œ ๋ ˆ์‹œํ”ผ๋Š” ์ดํ›„ ์—ด๋žŒ ๋ฐ ์ˆ˜์ • ๊ฐ€๋Šฅ.
์˜ˆ์™ธ 1. ์ž…๋ ฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.
2. AI API ํ˜ธ์ถœ ์‹คํŒจ ์‹œ '์ผ์‹œ์ ์ธ ๋ฌธ์ œ ๋ฐœ์ƒ' ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ.

1.3 ์š”๊ตฌ์‚ฌํ•ญ ์ถ”์ ํ‘œ

์š”๊ตฌ์‚ฌํ•ญ ID ์œ ์Šค์ผ€์ด์Šค ID ๊ธฐ๋Šฅ ID ์„ค๋ช…
UR-001 UC-001 F-001 ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-002 UC-002 F-002 ๋ ˆ์‹œํ”ผ ๊ฒŒ์‹œํŒ CRUD ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-003 UC-003 F-003 Q&A ๊ฒŒ์‹œํŒ ์งˆ๋ฌธ ๋ฐ ๋‹ต๋ณ€ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-004 UC-004 F-004 AI ๊ธฐ๋ฐ˜ ๋งž์ถค ๋ ˆ์‹œํ”ผ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-005 UC-005 F-005 ์ข‹์•„์š” ๋ฐ ๋Œ“๊ธ€ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-006 UC-006 F-006 ๋ ˆ์‹œํ”ผ ์Šคํฌ๋žฉ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-007 UC-007 F-007 ๋ชจ๋“  ๊ฒŒ์‹œํŒ์˜ ์—ด๋žŒ ๊ธฐ๋Šฅ ์ œ๊ณต.
UR-008 UC-008 F-008 ๋ฐ์ดํ„ฐ ๋ณด์•ˆ ๋ฐ ์ €์žฅ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์ œ๊ณต.

1.4 ๊ฐœ๋ฐœ ์ผ์ • (WBS)

image


2. ์„ค๊ณ„

2.1 ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„

SystemArchitecture


2.2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„(ERD)

DBERD


2.3 ํด๋ž˜์Šค ์„ค๊ณ„

ClassDiagram

  • ํด๋ž˜์Šค ๊ฐ„์˜ ์—ฐ๊ด€ ๊ด€๊ณ„, ์ƒ์† ๊ตฌ์กฐ ๋“ฑ์„ ์„ค๊ณ„.
  • ๋„๋ฉ”์ธ ๋กœ์ง๊ณผ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฝ”๋“œ ๊ตฌํ˜„ ์ค€๋น„.

2.4 ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„

ComponentDiagram

  • ๊ฐ ๋ ˆ์ด์–ด์˜ ์—ญํ• ๊ณผ ์ฑ…์ž„ ์ •์˜.
  • ๋ ˆ์ด์–ด ๊ฐ„ ํ˜ธ์ถœ ๊ด€๊ณ„ ์„ค๊ณ„.
  • ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ์ฃผ์š” ์„œ๋น„์Šค ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ ์ •์˜.

2.6 ์ธํ„ฐํŽ˜์ด์Šค ์„ค๊ณ„ (D4)

  • ์ฃผ์š” API ์—”๋“œํฌ์ธํŠธ ์„ค๊ณ„ (URL, HTTP ๋ฉ”์„œ๋“œ)

2.6.1 AIReviewController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
POST /submit-recipe AI ๋ฆฌ๋ทฐ ์š”์ฒญ ๋ฐ ์ €์žฅ recipeInput(String), language(String) ๋ฆฌ๋ทฐ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ ๋ฐ ์ €์žฅ ์™„๋ฃŒ ๋ฉ”์‹œ์ง€
GET /submit-recipe ๋ ˆ์‹œํ”ผ ์ž…๋ ฅ ํผ ํŽ˜์ด์ง€ ์—†์Œ ๋ ˆ์‹œํ”ผ ์ž…๋ ฅ ํผ ๋ทฐ
GET /my-reviews ๋‚ด ๋ฆฌ๋ทฐ ๋ชฉ๋ก ์กฐํšŒ page(int), keyword(String) ๋ฆฌ๋ทฐ ๋ชฉ๋ก ๋ทฐ ๋ฐ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ
POST /delete-review/{id} ํŠน์ • ๋ฆฌ๋ทฐ ์‚ญ์ œ reviewId(Long) ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ๋ฆฌ๋ทฐ ๋ชฉ๋ก ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

2.6.2 AnswerController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
POST /answer/create ๋‹ต๋ณ€ ์ƒ์„ฑ questionId(Integer), content(String) ๋‹ต๋ณ€ ์ƒ์„ฑ ํ›„ ์งˆ๋ฌธ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
GET /answer/editForm/{answerId} ๋‹ต๋ณ€ ์ˆ˜์ • ํผ ์กฐํšŒ answerId(Integer) ๋‹ต๋ณ€ ์ˆ˜์ • ํผ ๋ทฐ
POST /answer/modify/{answerId} ๋‹ต๋ณ€ ์ˆ˜์ • answerId(Integer), content(String) ์ˆ˜์ • ์™„๋ฃŒ ํ›„ ์งˆ๋ฌธ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
POST /answer/delete/{answerId} ๋‹ต๋ณ€ ์‚ญ์ œ answerId(Integer) ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ์งˆ๋ฌธ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

2.6.3 CommentController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
POST /recipe/{recipeId}/comment ๋Œ“๊ธ€ ์ƒ์„ฑ recipeId(Long), content(String) ๋Œ“๊ธ€ ์ƒ์„ฑ ํ›„ ๋ ˆ์‹œํ”ผ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
GET /recipe/{recipeId}/comment/{id}/edit ๋Œ“๊ธ€ ์ˆ˜์ • ํผ ์กฐํšŒ recipeId(Long), commentId(Long) ๋Œ“๊ธ€ ์ˆ˜์ • ํผ ๋ทฐ
POST /recipe/{recipeId}/comment/{id}/edit ๋Œ“๊ธ€ ์ˆ˜์ • recipeId(Long), commentId(Long), content(String) ์ˆ˜์ • ์™„๋ฃŒ ํ›„ ๋ ˆ์‹œํ”ผ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
POST /recipe/{recipeId}/comment/{id}/delete ๋Œ“๊ธ€ ์‚ญ์ œ recipeId(Long), commentId(Long) ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ๋ ˆ์‹œํ”ผ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

2.6.4 MainController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
GET / ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์—†์Œ ๋ฉ”์ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
GET /main ๋ฉ”์ธ ํŽ˜์ด์ง€ ์กฐํšŒ ์—†์Œ ๋ฉ”์ธ ํŽ˜์ด์ง€ ๋ทฐ
GET /about ์†Œ๊ฐœ ํŽ˜์ด์ง€ ์กฐํšŒ ์—†์Œ ์†Œ๊ฐœ ํŽ˜์ด์ง€ ๋ทฐ

2.6.5 QuestionController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
GET /question/list ์งˆ๋ฌธ ๋ชฉ๋ก ์กฐํšŒ page(int), kw(String) ์งˆ๋ฌธ ๋ชฉ๋ก ๋ทฐ ๋ฐ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ
GET /question/detail/{id} ์งˆ๋ฌธ ์ƒ์„ธ ์กฐํšŒ id(Integer) ์งˆ๋ฌธ ์ƒ์„ธ ๋ทฐ
GET /question/create ์งˆ๋ฌธ ์ƒ์„ฑ ํผ ์กฐํšŒ ์—†์Œ ์งˆ๋ฌธ ์ƒ์„ฑ ํผ ๋ทฐ
POST /question/create ์งˆ๋ฌธ ์ƒ์„ฑ title(String), content(String) ์ƒ์„ฑ ์™„๋ฃŒ ํ›„ ์งˆ๋ฌธ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
GET /question/modify/{id} ์งˆ๋ฌธ ์ˆ˜์ • ํผ ์กฐํšŒ id(Integer) ์งˆ๋ฌธ ์ˆ˜์ • ํผ ๋ทฐ
POST /question/modify/{id} ์งˆ๋ฌธ ์ˆ˜์ • id(Integer), title(String), content(String) ์ˆ˜์ • ์™„๋ฃŒ ํ›„ ์งˆ๋ฌธ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
POST /question/delete/{id} ์งˆ๋ฌธ ์‚ญ์ œ id(Integer) ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ์งˆ๋ฌธ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

2.6.6 RecipeController

HTTP Method URL ๊ธฐ๋Šฅ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ
GET /recipe/list ๋ ˆ์‹œํ”ผ ๋ชฉ๋ก ์กฐํšŒ page(int), size(int), keyword(String) ๋ ˆ์‹œํ”ผ ๋ชฉ๋ก ๋ทฐ ๋ฐ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ
GET /recipe/detail/{id} ๋ ˆ์‹œํ”ผ ์ƒ์„ธ ์กฐํšŒ id(Long) ๋ ˆ์‹œํ”ผ ์ƒ์„ธ ๋ทฐ
GET /recipe/create ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ํผ ์กฐํšŒ ์—†์Œ ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ํผ ๋ทฐ
POST /recipe/create ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ title(String), content(String), image(MultipartFile) ์ƒ์„ฑ ์™„๋ฃŒ ํ›„ ๋ ˆ์‹œํ”ผ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
GET /recipe/edit/{id} ๋ ˆ์‹œํ”ผ ์ˆ˜์ • ํผ ์กฐํšŒ id(Long) ๋ ˆ์‹œํ”ผ ์ˆ˜์ • ํผ ๋ทฐ
POST /recipe/edit/{id} ๋ ˆ์‹œํ”ผ ์ˆ˜์ • id(Long), title(String), content(String), image(MultipartFile) ์ˆ˜์ • ์™„๋ฃŒ ํ›„ ๋ ˆ์‹œํ”ผ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
POST /recipe/delete/{id} ๋ ˆ์‹œํ”ผ ์‚ญ์ œ id(Long) ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ๋ ˆ์‹œํ”ผ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ

2.7 ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์„ค๊ณ„

UI/UX

  • ํ™”๋ฉด ๊ตฌ์„ฑ ์š”์†Œ(๋ฒ„ํŠผ, ์ž…๋ ฅ ํผ, ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ๋“ฑ) ์ •์˜.
  • ํŽ˜์ด์ง€ ๊ฐ„์˜ ์ด๋™ ํ๋ฆ„ ์„ค๊ณ„.
  • ํ™”๋ฉด ์š”์†Œ์˜ ์œ„์น˜ ๋ฐ ๋””์ž์ธ ๊ฐ€์ด๋“œ ์ž‘์„ฑ.

3.๊ตฌํ˜„

3.1 ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๋ฐ ๋ฐฐํฌ

  • Backend: Spring Boot, Java 17
  • Database: MySQL
  • Frontend: Thymeleaf
  • API Integration: OpenAI API (ChatGPT)
  • Deployment: AWS EC2, RDS (MySQL)

3.2 ๊ฐœ๋ฐœ์ผ์ •

wbs


4. ํ…Œ์ŠคํŠธ


4.1 ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ์„œ

1. ํ…Œ์ŠคํŠธ ๊ฐœ์š”

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ๊ฐ ์„œ๋น„์Šค ๊ณ„์ธต(AIReviewService, QuestionService, UserService, RecipeService)์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ๋Š” ์ฃผ์š” ๊ธฐ๋Šฅ๋ณ„๋กœ ๊ฒ€์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

2. ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค

ํ…Œ์ŠคํŠธ ID ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ์ž…๋ ฅ๊ฐ’ ์˜ˆ์ƒ ์ถœ๋ ฅ ๊ฒฐ๊ณผ
ATR001 generateAIReview recipeInput = "Test recipe input", user = testUser ์ƒ์„ฑ๋œ AIReview ๊ฐ์ฒด, ์‚ฌ์šฉ์ž ๋ฐ ๋ ˆ์‹œํ”ผ ์ž…๋ ฅ ํฌํ•จ Pass
ATR002 saveReview AIReview ๊ฐ์ฒด ์ €์žฅ๋œ AIReview ๊ฐ์ฒด Pass
ATR003 getUserReviews user = testUser ํ•ด๋‹น ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๋ชจ๋“  ๋ฆฌ๋ทฐ ๋ฐ˜ํ™˜ Pass
ATR004 deleteReview reviewId = 1L ํ•ด๋‹น ๋ฆฌ๋ทฐ ์‚ญ์ œ Pass
ATR005 getUserByUsername username = "testUser" ํ•ด๋‹น ์‚ฌ์šฉ์ž ๊ฐ์ฒด ๋ฐ˜ํ™˜ Pass
QSR001 getList keyword = "test", page = 0 ๊ฒ€์ƒ‰๋œ ์งˆ๋ฌธ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜ Pass
QSR002 getQuestion questionId = 1 ํ•ด๋‹น ID์˜ ์งˆ๋ฌธ ๋ฐ˜ํ™˜ Pass
QSR003 getQuestionNotFound questionId = 1 DataNotFoundException ๋ฐœ์ƒ Pass
QSR004 createQuestion title = "New Question", content = "This is a new question content." ์ƒˆ๋กœ์šด ์งˆ๋ฌธ ์ƒ์„ฑ Pass
QSR005 modifyQuestion question ๊ฐ์ฒด, newTitle = "Updated Title", newContent = "Updated Content" ์งˆ๋ฌธ ์ˆ˜์ • Pass
QSR006 deleteQuestion question ๊ฐ์ฒด ์งˆ๋ฌธ ์‚ญ์ œ Pass
USR001 createUser username = "testUser", email = "test@example.com", password = "password123" ์ƒˆ ์‚ฌ์šฉ์ž ์ƒ์„ฑ Pass
USR002 getUser (์„ฑ๊ณต) username = "testUser" ํ•ด๋‹น ์‚ฌ์šฉ์ž ๋ฐ˜ํ™˜ Pass
USR003 getUser (์‹คํŒจ) username = "nonExistingUser" DataNotFoundException ๋ฐœ์ƒ Pass
USR004 validatePassword (์„ฑ๊ณต) password1 = "password123", password2 = "password123" true ๋ฐ˜ํ™˜ Pass
USR005 validatePassword (์‹คํŒจ) password1 = "password123", password2 = "differentPassword" false ๋ฐ˜ํ™˜ Pass
RSR001 createRecipe title = "Test Recipe", content = "Test content", user = testUser ์ƒˆ ๋ ˆ์‹œํ”ผ ๊ฐ์ฒด ์ƒ์„ฑ Pass
RSR002 getRecipeById recipeId = 1L ํ•ด๋‹น ID์˜ ๋ ˆ์‹œํ”ผ ๋ฐ˜ํ™˜ Pass
RSR003 testSaveImage_InvalidFileType ์ž˜๋ชป๋œ MIME ํƒ€์ž… RuntimeException ๋ฐœ์ƒ Pass

3. ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฒฐ๊ณผ ์š”์•ฝ

๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์˜ˆ์ƒํ•œ ๋Œ€๋กœ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋ฐ˜ํ™˜ ๊ฐ’ ๋ฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ™•์ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

4. ๊ฒฐ๋ก 

ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์„œ๋น„์Šค ๋กœ์ง์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•˜๋ฉฐ, ๊ฐ ๋ฉ”์„œ๋“œ๋Š” ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•ด ์˜ฌ๋ฐ”๋ฅธ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์˜ˆ์™ธ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.


4.2 ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ์„œ

4.2.1 UserService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ํ•ญ๋ชฉ
ํ…Œ์ŠคํŠธ ํ•ญ๋ชฉ ๊ฒฐ๊ณผ ์ƒ์„ธ ์„ค๋ช…
์‚ฌ์šฉ์ž ์ƒ์„ฑ (createUser()) Pass ์‚ฌ์šฉ์ž ์ƒ์„ฑ ์‹œ, username, email, ์•”ํ˜ธํ™”๋œ password๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ €์žฅ๋จ.
์‚ฌ์šฉ์ž ์กฐํšŒ (getUser()) Pass ์ƒ์„ฑ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์กฐํšŒ๋จ.
๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ (validatePassword()) Pass ๋‘ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋ฉด true, ๋ถˆ์ผ์น˜ํ•˜๋ฉด false ๋ฐ˜ํ™˜๋จ.

4.2.2 AIReviewService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ํ•ญ๋ชฉ ๋ชฉํ‘œ ๊ฒฐ๊ณผ ๋น„๊ณ 
AIReviewService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ AIReviewService์˜ ์ „์ฒด ํ๋ฆ„ ๊ฒ€์ฆ generateAIReview์™€ saveReview๋กœ ์ƒ์„ฑ๋œ AIReview๊ฐ€ DB์— ์ €์žฅ๋จ ์„ฑ๊ณต: AIReview ๊ฐ์ฒด๊ฐ€ DB์— ์„ฑ๊ณต์ ์œผ๋กœ ์ €์žฅ๋จ
QuestionService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ QuestionService์˜ ์งˆ๋ฌธ ์ƒ์„ฑ ๋ฐ ์‚ญ์ œ ํ™•์ธ createQuestion์œผ๋กœ ์งˆ๋ฌธ ์ƒ์„ฑ ํ›„, deleteQuestion์œผ๋กœ ์‚ญ์ œ ํ™•์ธ๋จ ์„ฑ๊ณต: ์งˆ๋ฌธ์ด DB์— ์ €์žฅ๋˜๊ณ  ์‚ญ์ œ๋จ
RecipeService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ RecipeService์˜ ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ๋ฐ ์ €์žฅ ํ™•์ธ createRecipe๋กœ ์ƒ์„ฑ๋œ ๋ ˆ์‹œํ”ผ๊ฐ€ DB์— ์ €์žฅ๋จ ์„ฑ๊ณต: ๋ ˆ์‹œํ”ผ๊ฐ€ DB์— ์ €์žฅ๋จ
UserService ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ UserService์˜ ์‚ฌ์šฉ์ž ์ƒ์„ฑ, ์กฐํšŒ ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ createUser๋กœ ์ƒ์„ฑ๋œ ์‚ฌ์šฉ์ž์™€ validatePassword๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•จ ์„ฑ๊ณต: ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ ์ •์ƒ ์ž‘๋™

5. ๊ฒฐ๋ก 

  • ์ „์ฒด ๊ฒฐ๊ณผ: ๋ชจ๋“  ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ํ†ต๊ณผํ•˜์˜€์œผ๋ฉฐ, ๊ฐ ์„œ๋น„์Šค๊ฐ€ DB์™€ ์—ฐ๋™ํ•˜์—ฌ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•จ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ๋‹จ๊ณ„: ์ถ”๊ฐ€์ ์ธ ์„œ๋น„์Šค์™€ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ๋” ํ™•์žฅํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

4.3 ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ์„œ

4.3.1 ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ํ•ญ๋ชฉ ๋ชฉํ‘œ ๊ฒฐ๊ณผ ๋น„๊ณ 
๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ๋ฐ ์ €์žฅ ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์‹œํ”ผ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ createRecipe๋กœ ๋ ˆ์‹œํ”ผ๊ฐ€ DB์— ์„ฑ๊ณต์ ์œผ๋กœ ์ €์žฅ๋จ ์„ฑ๊ณต
์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฐ ์กฐํšŒ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ƒ์„ฑ๋˜๊ณ  ์กฐํšŒ๋˜๋Š”์ง€ ํ™•์ธ createUser๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์กฐํšŒ๋จ ์„ฑ๊ณต
AI ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ๋ฐ ์ €์žฅ AI๊ฐ€ ์ƒ์„ฑํ•œ ๋ ˆ์‹œํ”ผ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ generateAIReview ๋ฐ saveReview๋กœ AI ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ํ›„ ์ €์žฅ๋จ ์„ฑ๊ณต
์งˆ๋ฌธ ์ƒ์„ฑ ๋ฐ ์‚ญ์ œ ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์„ ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ createQuestion๋กœ ์งˆ๋ฌธ ์ƒ์„ฑ ํ›„, deleteQuestion์œผ๋กœ ์‚ญ์ œ๋จ ์„ฑ๊ณต

4.3.2 ๊ฒฐ๋ก 

  • ์ „์ฒด ๊ฒฐ๊ณผ: ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉฐ, ๋ชจ๋“  ์ฃผ์š” ๊ธฐ๋Šฅ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•จ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ๋‹จ๊ณ„: ์ถ”๊ฐ€์ ์ธ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋ฐ ๋” ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•ด ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ๋ฅผ ํ™•์žฅํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

4.4 ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ์„œ

4.4.1 ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ํ•ญ๋ชฉ ๋ชฉํ‘œ ๊ฒฐ๊ณผ ๋น„๊ณ 
ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์›๊ฐ€์ž… ํ›„ ๋กœ๊ทธ์ธ์ด ์ •์ƒ์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ๊ฒ€์ฆ createUser๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  login์œผ๋กœ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋จ ์„ฑ๊ณต
๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์‹œํ”ผ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ createRecipe๋กœ ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ํ›„, getRecipeById๋กœ ์กฐํšŒ ์„ฑ๊ณต ์„ฑ๊ณต
AI ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ AI๊ฐ€ ์ƒ์„ฑํ•œ ๋ ˆ์‹œํ”ผ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ generateAIReview ๋ฐ saveReview๋กœ AI ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ ํ›„ ์ €์žฅ๋จ ์„ฑ๊ณต
์งˆ๋ฌธ ๊ฒŒ์‹œํŒ ์ƒ์„ฑ ๋ฐ ์‚ญ์ œ ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์„ ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ ๊ฒ€์ฆ createQuestion๋กœ ์งˆ๋ฌธ ์ƒ์„ฑ ํ›„, deleteQuestion์œผ๋กœ ์‚ญ์ œ๋จ ์„ฑ๊ณต

4.4.2 ๊ฒฐ๋ก 

  • ์ „์ฒด ๊ฒฐ๊ณผ: ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ์ฃผ์š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋จ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ๋‹จ๊ณ„: ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ฒ€์ฆ์„ ๊ฐ•ํ™”ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

5. ์‹œ์—ฐ

  • Main & About Page
    • ๋ฉ”์ธํŽ˜์ด์ง€ ๋ฐ ์†Œ๊ฐœํŽ˜์ด์ง€
      MainAbout

  • Auth & Scrap Page
    • ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ํ”„๋กœํ•„ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ๊ฒŒ์‹œ๊ธ€ ์Šคํฌ๋žฉ ๊ธฐ๋Šฅ
      Auth

  • Recipe Board Page
    • ๊ฒŒ์‹œ๊ธ€ CRUD ๊ธฐ๋Šฅ
    • ๋Œ“๊ธ€ CRUD ๊ธฐ๋Šฅ
    • ๊ฒ€์ƒ‰๊ธฐ๋Šฅ
    • Pagination ๊ธฐ๋Šฅ
      RecipeBoard

  • QNA Board Page
    • ๊ฒŒ์‹œ๊ธ€ CRUD ๊ธฐ๋Šฅ
    • ๋Œ“๊ธ€ CRUD ๊ธฐ๋Šฅ
    • ๊ฒ€์ƒ‰๊ธฐ๋Šฅ
    • Pagination ๊ธฐ๋Šฅ
      QNA

  • AI Board Page
    • ๋ ˆ์‹œํ”ผ AI ์‘๋‹ต์ƒ์„ฑ ๊ธฐ๋Šฅ ๋ฐ ์‚ญ์ œ๊ธฐ๋Šฅ
    • ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ
    • Pagination
      AI

6. ์—๋Ÿฌ ํ•ด๊ฒฐ ๋ฐ ๋А๋‚€์ 

์—๋Ÿฌ 1: No qualifying bean of type 'PasswordEncoder'

์—๋Ÿฌ ์„ค๋ช…

Spring Security์—์„œ PasswordEncoder๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋Š” PasswordEncoder๊ฐ€ ์—†์œผ๋ฉด ์ธ์ฆ ๋ฐ ์ €์žฅ ๊ณผ์ •์—์„œ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—๋Ÿฌ ์‚ฌ์œ 

Spring Security๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ PasswordEncoder Bean์„ ์š”๊ตฌํ•˜์ง€๋งŒ, ํ”„๋กœ์ ํŠธ ์„ค์ •์—์„œ ์ด๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์—๋Ÿฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

@Configuration ํด๋ž˜์Šค์— PasswordEncoder๋ฅผ ์ •์˜ํ•˜์—ฌ Bean์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

์—๋Ÿฌ 2: Could not create query for method... No property 'id' found for type 'User'

์—๋Ÿฌ ์„ค๋ช…

Spring Data JPA์—์„œ ์ง€์ •๋œ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์—”ํ‹ฐํ‹ฐ ํ•„๋“œ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.

์—๋Ÿฌ ์‚ฌ์œ 

์—”ํ‹ฐํ‹ฐ User ํด๋ž˜์Šค์˜ ํ•„๋“œ๋ช…์ด id๊ฐ€ ์•„๋‹ˆ๋ผ userId๋กœ ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ, ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ์—์„œ ์ด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐ˜์˜ํ•˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

์—๋Ÿฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์—”ํ‹ฐํ‹ฐ ํ•„๋“œ๋ช…์„ ๊ธฐ์ค€์œผ๋กœ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

public interface AnswerVoterRepository extends JpaRepository<AnswerVoter, Long> {

    // ์ˆ˜์ • ์ „: findByUserId(Long id)
    // ์ˆ˜์ • ํ›„:
    List<AnswerVoter> findByUserUserId(Long userId);
}

์—๋Ÿฌ 3: OpenAI API ํ˜ธ์ถœ ์ค‘ ์ธ์ฆ ๋ฌธ์ œ

์—๋Ÿฌ ์„ค๋ช…

OpenAI API ํ˜ธ์ถœ ์‹œ API ํ‚ค๊ฐ€ ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ์ž˜๋ชป ์„ค์ •๋˜์–ด ์ธ์ฆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ

์—๋Ÿฌ ์‚ฌ์œ 

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •๋œ API ํ‚ค๊ฐ€ ์ œ๋Œ€๋กœ ๋กœ๋“œ๋˜์ง€ ์•Š๊ฑฐ๋‚˜, application.properties ๋˜๋Š” application.yml ํŒŒ์ผ์— ์„ค์ •์ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

์—๋Ÿฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  1. application.properties ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด API ํ‚ค๋ฅผ ์„ค์ •
spring.ai.openai.api-key=${OPENAI_API_KEY}

  1. dot env๋กœ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •

OPENAI_API_KEY=your_api_key

  1. Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ์‹œ์ž‘ํ•˜์—ฌ ํ‚ค๊ฐ€ ์ œ๋Œ€๋กœ ๋กœ๋“œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

6.2 ๋А๋‚€์ 

  • Spring Security์™€ JPA ์‚ฌ์šฉ ์‹œ ์„ธ๋ถ€ ์„ค์ •์ด ์ค‘์š”ํ•˜๋ฉฐ, ๊ธฐ๋ณธ ์„ค์ •์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ๋ช…ํ™•ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ์ด ํ•„์š”ํ•จ์„ ๊นจ๋‹ฌ์Œ
  • OpenAI API์™€ ๊ฐ™์€ ์™ธ๋ถ€ ์„œ๋น„์Šค๋ฅผ ์—ฐ๋™ํ•  ๋•Œ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋ฐ ์„ค์ • ํŒŒ์ผ ๊ด€๋ฆฌ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์•ˆ์ •์„ฑ๊ณผ ๋ณด์•ˆ์„ฑ์„ ํฌ๊ฒŒ ์ขŒ์šฐํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ์Œ
  • ์Šคํ”„๋ง ๋ถ€ํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋น„ํ•ด ์–ด๋ ต๋‹ค๊ณ  ๋А๊ผˆ๋Š”๋ฐ ๋ง‰์ƒํ•ด๋ณด๋‹ˆ ์‹œํ–‰์ฐฉ์˜ค๋Š” ๋งŽ์•˜์ง€๋งŒ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Œ

About

[Personal Project] SpringBoot Monolothic - Layered Architecture

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors