Skip to content

Latest commit

ย 

History

128 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ  ์ด๋ฒˆ์ง‘ (Second-Zip)

์ „์„ธ์‚ฌ๊ธฐ ์œ ํ˜•๋ณ„ ์œ„ํ—˜ ๋ถ„์„ยท์˜ˆ๋ฐฉ ์„œ๋น„์Šค

Java Spring Spring Security MyBatis MySQL Redis Vue

KB IT's Your Life 7๊ธฐ ยท 24๋ฐ˜ 3ํŒ€ (5์ธ)

๋ณธ ์ €์žฅ์†Œ ์ž‘์„ฑ์ž๋Š” ๋ฐฑ์—”๋“œ ๋ฆฌํฌํŠธ(RE) ๋„๋ฉ”์ธ์„ ๋‹ด๋‹นํ–ˆ์Šต๋‹ˆ๋‹ค


์„œ๋น„์Šค ๊ฐœ์š”

์ „์„ธ ๋งค๋ฌผ์˜ ์ฃผ์†Œ์™€ ๋ณด์ฆ๊ธˆ์„ ์ž…๋ ฅํ•˜๋ฉด, ์—ฌ๋Ÿฌ ๊ณต๊ณตยท๋ฏผ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฐํ•ฉํ•ด ์œ„ํ—˜์„ ํŒ์ •ํ•˜๊ณ  ๊ณ„์•ฝ ์ฒดํฌ๋ฆฌ์ŠคํŠธ์™€ ๋…น์ทจ ๊ธฐ๋ฐ˜ AI ํ™•์ธ๊นŒ์ง€ ์ด์–ด์ฃผ๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

ํŒ์ • ๋ฒ”์œ„๋Š” ํ•„์ˆ˜ ์ ๊ฒ€ 5๊ฐœ ยท ์ „์„ธ์‚ฌ๊ธฐ ์œ ํ˜• 3๊ฐœ ยท ์œ ํ˜•๋ณ„ ์ƒ์„ธ ํŒ์ • 3๊ฐœ, ์ด 9๊ฐœ์ž…๋‹ˆ๋‹ค. ์ฃผ์š” ๊ธฐ์ค€์€ ์ „์„ธ๊ฐ€์œจ 70/80%, ์„ ์ˆœ์œ„์ฑ„๊ถŒ 54%, HUG ๊ธฐ์ค€๊ฐ€ 90%, ์ˆ˜๋„๊ถŒ 7์–ตยท๋น„์ˆ˜๋„๊ถŒ 5์–ต ํ•œ๋„ ๋“ฑ์ž…๋‹ˆ๋‹ค.

์„ค๊ณ„ ์›์น™ โ€” "ํ™•๋‹ต์ด ์•„๋‹Œ ๋„์›€"

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


ํŒ€ ๊ตฌ์„ฑ๊ณผ ๋‹ด๋‹น

5์ธ ํŒ€(ํ”„๋ก ํŠธ์—”๋“œ 2 ยท ๋ฐฑ์—”๋“œ 3)์ด๋ฉฐ, ์ €๋Š” ๋ฐฑ์—”๋“œ ๋ฆฌํฌํŠธ(RE) ๋„๋ฉ”์ธ์„ ๋งก์•˜์Šต๋‹ˆ๋‹ค.

์˜์—ญ ๋‚ด์šฉ
๋ถ„์„ ์›Œํฌํ”Œ๋กœ CODEF ์–‘๋ฐฉํ–ฅ ์ธ์ฆ ์ƒํƒœ ๋จธ์‹ , ๋ถ„์‚ฐ ๋ฝ, ๋ฉฑ๋“ฑ ์ฒ˜๋ฆฌ
์™ธ๋ถ€ API ๊ณ„์ธต ๋“ฑ๊ธฐยท๊ฑด์ถ•๋ฌผ๋Œ€์žฅยท์‹ค๊ฑฐ๋ž˜๊ฐ€ยท์ฃผ์†Œ ํด๋ผ์ด์–ธํŠธ์™€ ํŒŒ์„œ, ์บ์‹œยทํƒ€์ž„์•„์›ƒ ์ •์ฑ…
์œ„ํ—˜ ํŒ์ • ์—”์ง„ ์œ„ํ—˜๋„์™€ ๋ฐ์ดํ„ฐ ํ™•๋ณด ์ƒํƒœ๋ฅผ ๋ถ„๋ฆฌํ•œ ํŒ์ • ๋ชจ๋ธ
๋ฆฌํฌํŠธ ์ €์žฅยท์กฐํšŒยท๊ณต์œ ยท์ฆ๊ฒจ์ฐพ๊ธฐยท์ฒดํฌ๋ฆฌ์ŠคํŠธ ์ž๋™ ์ฒดํฌ
ํ’ˆ์งˆ report ๋„๋ฉ”์ธ ํ…Œ์ŠคํŠธ ๋ณด๊ฐ•

์ธ์ฆ/๋งˆ์ดํŽ˜์ด์ง€/์•ฝ๊ด€ ๋„๋ฉ”์ธ๊ณผ ๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ์€ ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ ํŒ€์›์ด ๋‹ด๋‹นํ–ˆ์Šต๋‹ˆ๋‹ค.


๋ฐฑ์—”๋“œ์—์„œ ์‹ค์ œ๋กœ ํ‘ผ ๋ฌธ์ œ

1. ํ•œ ๋ฒˆ์˜ ์š”์ฒญ์œผ๋กœ ๋๋‚˜์ง€ ์•Š๋Š” ์™ธ๋ถ€ ์ธ์ฆ

CODEF ๊ฑด์ถ•๋ฌผ๋Œ€์žฅ ๋ฐœ๊ธ‰์€ ๋™๊ธฐ ์š”์ฒญ ํ•œ ๋ฒˆ์œผ๋กœ ๋๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ„ํŽธ์ธ์ฆ, ์ฃผ์†Œยท๋™ยทํ˜ธ ์„ ํƒ, CAPTCHA ๊ฐ™์€ ์ถ”๊ฐ€ ์ž…๋ ฅ์ด ์š”์ฒญ ์‚ฌ์ด์— ๋ผ์–ด๋“ญ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์žฌ์‹œ์ž‘, ์ค‘๋ณต ํด๋ฆญ, HTTP ์žฌ์‹œ๋„๊นŒ์ง€ ๊ณ ๋ คํ•˜๋ฉด ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋‚˜ ์„ธ์…˜ ๋ฉ”๋ชจ๋ฆฌ๋กœ๋Š” ๊ฐ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ถ„์„ ์š”์ฒญ ์ž์ฒด๋ฅผ ์ƒํƒœ ๋จธ์‹ ์œผ๋กœ ๋ชจ๋ธ๋งํ–ˆ์Šต๋‹ˆ๋‹ค.

AUTH_REQUIRED โ†’ AUTH_PENDING / SELECTION_REQUIRED โ†’ PROCESSING โ†’ COMPLETED / FAILED
  • ์ฃผ์†Œ ๊ฒ€์ƒ‰์—์„œ ์–ป์€ ๋ฒ•์ •๋™์ฝ”๋“œยท๋ณธ๋ฒˆยท๋ถ€๋ฒˆ์„ UUID addressId๋กœ Redis์— ๋ณด๊ด€ํ•ด, ์ดํ›„ ๋‹จ๊ณ„๊ฐ€ ์ฃผ์†Œ๋ฅผ ๋‹ค์‹œ ์กฐํšŒํ•˜์ง€ ์•Š๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค
  • CODEF์˜ jobIndexยทthreadIndexยทjtiยทtwoWayTimestamp์™€ ์‚ฌ์šฉ์ž ์„ ํƒ์„ AnalysisWorkflowState์— ์ €์žฅ (TTL 15๋ถ„)
  • ์กฐํšŒํ•  ๋•Œ accountId ์†Œ์œ ๊ถŒ์„ ํ•จ๊ป˜ ํ™•์ธํ•˜๊ณ , ๋งŒ๋ฃŒยท๋ฏธ์กด์žฌยทํƒ€์ธ ์†Œ์œ ๋ฅผ ์ „๋ถ€ ๊ฐ™์€ 404๋กœ ์‘๋‹ตํ•ด ์š”์ฒญ ์กด์žฌ ์—ฌ๋ถ€๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค

2. ์œ ๋ฃŒ API ์ค‘๋ณต ๊ณผ๊ธˆ ๋ง‰๊ธฐ

๋“ฑ๊ธฐ๋ถ€๋“ฑ๋ณธ ์กฐํšŒ๋Š” ๊ฑด๋‹น ๊ณผ๊ธˆ๋ฉ๋‹ˆ๋‹ค. ๋”๋ธ”ํด๋ฆญ, ๋„คํŠธ์›Œํฌ ์žฌ์‹œ๋„, DB ์ €์žฅ ์งํ›„ ์‘๋‹ต ๋‹จ์ ˆ โ€” ๋ชจ๋‘ ์ค‘๋ณต ๊ณผ๊ธˆ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.

์ธต ๋ฐฉ๋ฒ• ๋ง‰๋Š” ๊ฒƒ
์ง„์ž… Redis SET NX + TTL ์š”์ฒญ ๋ฝ ๋™์‹œ์— ๋“ค์–ด์˜จ ์ค‘๋ณต ์š”์ฒญ
ํ•ด์ œ UUID ํ† ํฐ + Lua compare-and-delete ๋งŒ๋ฃŒ๋œ ๋’ค ๋‚จ์˜ ๋ฝ์„ ์ž˜๋ชป ์ง€์šฐ๋Š” ๊ฒƒ
์ˆœ์„œ ๋ฌด๋ฃŒ ๋ฐ์ดํ„ฐ ์„ ๊ฒ€์ฆ ํ›„ ์œ ๋ฃŒ ํ˜ธ์ถœ ์• ์ดˆ์— ๋ถ„์„ ๋ถˆ๊ฐ€ํ•œ ๊ฑด์˜ ๊ณผ๊ธˆ
์ €์žฅ analysis_reports.request_id UNIQUE ๋ฝ์„ ๋น ์ ธ๋‚˜๊ฐ„ ์ค‘๋ณต์˜ ์ตœ์ข… ์ €์ง€

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

๋‹ค๋งŒ ์ด๊ฑด ์™„์ „ํ•œ ๋‹จ์ผ ์‹คํ–‰ ๋ณด์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ฝ TTL์ด 300์ดˆ์ธ๋ฐ CODEF read timeout๋„ 300์ดˆ์ด๊ณ  ๋ฝ ๊ฐฑ์‹  ๊ธฐ๋Šฅ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ๊ฐ€ TTL์„ ๋„˜๊ธฐ๋ฉด ์‹คํ–‰์ด ๊ฒน์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ตฌํ˜„์€ ์ •์ƒ ์ฒ˜๋ฆฌ ๊ตฌ๊ฐ„์˜ ์ค‘๋ณต์„ ์ค„์ด๋Š” ์žฅ์น˜์ด๋ฉฐ, ์šด์˜ ์ˆ˜์ค€์—์„œ๋Š” lock renewal/watchdog๊ณผ UNIQUE ์ถฉ๋Œ ํ›„ ๊ธฐ์กด ๊ฒฐ๊ณผ ์žฌ์กฐํšŒ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

3. "ํ™•์ธ ๋ถˆ๊ฐ€"๊ฐ€ "์•ˆ์ „"์œผ๋กœ ์ฝํžˆ์ง€ ์•Š๊ฒŒ

๊ฐ€์žฅ ์œ„ํ—˜ํ•œ ์‹คํŒจ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ชป ๊ฐ€์ ธ์™”๋Š”๋ฐ ์œ„ํ—˜ ์—†์Œ์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ทธ๊ฑธ "์•ˆ์ „ํ•˜๋‹ค"๋กœ ์ฝ์Šต๋‹ˆ๋‹ค. ์™ธ๋ถ€ API ์‹คํŒจ๋‚˜ ๊ธˆ์•ก ํŒŒ์‹ฑ ์‹คํŒจ๊ฐ€ 0์ด๋‚˜ false๋กœ ๋Œ€์ฒด๋˜๋ฉด ์œ„ํ—˜ ๋งค๋ฌผ์ด SAFE๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ํŒ์ • ๊ฒฐ๊ณผ Judgement๋ฅผ ๋‘ ์ถ•์œผ๋กœ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

DataStatus ์˜๋ฏธ ์ง‘๊ณ„
VERIFIED ๋ฐ์ดํ„ฐ๋ฅผ ํ™•๋ณดํ•ด ์‹ค์ œ ํŒ์ • ์œ„ํ—˜๋„์— ๋ฐ˜์˜
UNVERIFIED ๋ฐ์ดํ„ฐ ๋ถ€์กฑยทํŒŒ์‹ฑ ์‹คํŒจ๋กœ ํ™•์ธ ๋ถˆ๊ฐ€ CAUTION์œผ๋กœ ์ง‘๊ณ„์— ์ฐธ์—ฌ
NOT_APPLICABLE ํ•ด๋‹น ์ฃผํƒ์— ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๊ทœ์น™ ์ง‘๊ณ„์—์„œ ์ œ์™ธ

์ ๊ฒ€ ๊ทผ๊ฑฐ๋Š” JSON evidence๋กœ ํ•จ๊ป˜ ์ €์žฅํ•ด ํŒ์ • ๊ฒฐ๊ณผ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

4. ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฏฟ์ง€ ์•Š๊ธฐ

์™ธ๋ถ€ ์‘๋‹ต์„ ์œ„ํ—˜ ์—”์ง„์— ๋ฐ”๋กœ ๋„˜๊ธฐ์ง€ ์•Š๊ณ  ๋‚ด๋ถ€ ๋„๋ฉ”์ธ์œผ๋กœ ์ •๊ทœํ™”ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ํŒ์ •์„ ๋’ค์ง‘๋Š” ๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ ์ด ๋‹จ๊ณ„์˜ ๋””ํ…Œ์ผ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋“ฑ๊ธฐ๋ถ€๋“ฑ๋ณธ

  • ๋ง์†Œ๋œ ๊ถŒ๋ฆฌ ํ‘œ์‹œ๋ฅผ ์ œ์™ธ
  • ๊ทผ์ €๋‹น ํ‘œํ˜„์€ ์žˆ๋Š”๋ฐ ๊ธˆ์•ก ํŒŒ์‹ฑ์— ์‹คํŒจํ•˜๋ฉด 0์›์ด ์•„๋‹ˆ๋ผ null๋กœ ์œ ์ง€ โ€” 0์›์œผ๋กœ ๋‘๋ฉด ์•ˆ์ „์œผ๋กœ ํŒ์ •๋ฉ๋‹ˆ๋‹ค
  • ์‹ ํƒ ์ดํ›„ ๋ฐœ์ƒํ•œ ๊ถŒ๋ฆฌ์นจํ•ด์™€ ์‹ ํƒ ์ด์ „ ๊ถŒ๋ฆฌ๋ฅผ ๊ตฌ๋ถ„
  • ์†Œ์œ ์ž๊ฐ€ ์‹ ํƒํšŒ์‚ฌ์ธ ๊ฒฝ์šฐ ์‹ ํƒ ๋ฌธ๊ตฌ ๋ˆ„๋ฝ์„ ๋ณด์™„

๊ณต์‹œ๊ฐ€๊ฒฉ

๊ณผ๊ฑฐ ์ตœ๋Œ€ ๊ธˆ์•ก์ด ์•„๋‹ˆ๋ผ ๊ธฐ์ค€์ผ์ด ๊ฐ€์žฅ ์ตœ๊ทผ์ธ ๊ฐ€๊ฒฉ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋‚ ์งœ๊ฐ€ ์ „ํ˜€ ์—†์„ ๋•Œ๋งŒ ์ตœ๋Œ€๊ฐ’์œผ๋กœ ํด๋ฐฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๊ฒฉ ํ•˜๋ฝ๊ธฐ์— ๊ณผ๊ฑฐ ์ตœ๊ณ ๊ฐ€๋ฅผ ์“ฐ๋ฉด ์ „์„ธ๊ฐ€์œจ์ด ๋‚ฎ๊ฒŒ ๊ณ„์‚ฐ๋˜์–ด ์œ„ํ—˜์„ ๊ณผ์†Œํ‰๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ตœ์‹  4.2์–ตยท๊ณผ๊ฑฐ 5์–ต์ผ ๋•Œ 4.2์–ต์œผ๋กœ ํŒ์ •ํ•˜๋Š” ๊ฒƒ์„ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋กœ ๊ณ ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์†Œ

์นด์นด์˜ค ์ฃผ์†Œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด ์žฅ์†Œ ๊ฒ€์ƒ‰์œผ๋กœ ํด๋ฐฑํ•˜๊ณ , ํ”„๋ก ํŠธ์—๋Š” Redis์— ์ €์žฅํ•œ ํ›„๋ณด ID๋งŒ ๋…ธ์ถœํ•ด ๋ถ„์„ ๋Œ€์ƒ ์‹๋ณ„๊ฐ’ ๋ณ€์กฐ๋ฅผ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

5. LLM ์‘๋‹ต์„ ์—…๋ฌด ๋ฐ์ดํ„ฐ์— ๋ฐ˜์˜ํ•˜๊ธฐ ์ „ 3๋‹จ๊ณ„ ๋ฐฉ์–ด

LLM ์ถœ๋ ฅ์€ ๋น„๊ฒฐ์ •์ ์ด๋ผ DB์— ๋ฐ”๋กœ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  1. strict JSON Schema โ€” ์‘๋‹ต ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ธ ๋‹จ์—์„œ ์ œํ•œ
  2. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถˆ๋ณ€์‹ โ€” ํŠน์•ฝ์€ 35๊ฐœยท์ œ๋ชฉ 50์žยท๋ณธ๋ฌธ 200์žยท์ค‘๋ณต ๊ฑฐ๋ถ€, ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋Š” ์š”์ฒญํ•œ item ID๊ฐ€ ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ์”ฉ ์กด์žฌํ•˜๋Š”์ง€์™€ 01 ์‹ ๋ขฐ๋„ ๊ฒ€์ฆ
  3. ํŠธ๋žœ์žญ์…˜ ๋ฐ˜์˜ โ€” ํŠน์•ฝ ๊ต์ฒด๋Š” ๋ฆฌํฌํŠธ ํ–‰์„ SELECT ... FOR UPDATE๋กœ ์ž ๊ทผ ๋’ค delete/insert

์‹ค์‹œ๊ฐ„ ๋…น์ทจ๋Š” provisional / final์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ค‘๊ฐ„ ๋ถ„์„์ด CHECKED๋ฅผ ๋ฐ˜ํ™˜ํ•ด๋„ ์‹ค์ œ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  JVM ๋ฉ”๋ชจ๋ฆฌ์— ํ›„๋ณด๋กœ๋งŒ ๋‘์—ˆ๋‹ค๊ฐ€, ๋…น์Œ ์ข…๋ฃŒ ํ›„ ์ „์ฒด ๋…น์ทจ๋ฅผ ๋‹ค์‹œ ๋ถ„์„ํ•œ ์ตœ์ข… ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.

6. ์™ธ๋ถ€ API ํŠน์„ฑ๋ณ„ ํƒ€์ž„์•„์›ƒ ๋ถ„๋ฆฌ

๋Œ€์ƒ connect / read
์ผ๋ฐ˜ API 3์ดˆ / 10์ดˆ
ํŠน์•ฝ GPT 3์ดˆ / 30์ดˆ
CODEF ์žฅ์‹œ๊ฐ„ ์ž‘์—… 5์ดˆ / 300์ดˆ

๋ชจ๋“  ํ˜ธ์ถœ์— ๊ฐ™์€ ํƒ€์ž„์•„์›ƒ์„ ์“ฐ๋ฉด ๋А๋ฆฐ ๋ฌธ์„œ ๋ฐœ๊ธ‰์ด ์ •์ƒ์ธ๋ฐ๋„ ์‹คํŒจํ•˜๊ณ , ๋ฐ˜๋Œ€๋กœ ์ผ๋ฐ˜ API ์žฅ์• ๊ฐ€ ์š”์ฒญ ์Šค๋ ˆ๋“œ๋ฅผ ์˜ค๋ž˜ ์ ์œ ํ•ฉ๋‹ˆ๋‹ค. CODEF ํ† ํฐ์€ ๋งŒ๋ฃŒ 60์ดˆ ์ „ ์„ ์ œ ๊ฐฑ์‹ ํ•˜๊ณ , 401์ผ ๋•Œ๋งŒ ์บ์‹œ๋ฅผ ํ๊ธฐํ•˜๊ณ  ํ•œ ๋ฒˆ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๋ฌด์กฐ๊ฑด ์žฌ์‹œ๋„ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ์œ ๋ฃŒยท๋น„๋ฉฑ๋“ฑ ํ˜ธ์ถœ์ด ์ค‘๋ณต ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

7. ์œ ๋ฃŒ API ์—†์ด๋„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ

RegistryDataProvider ยท PriceDataProvider ยท BuildingRegisterGateway ์ธํ„ฐํŽ˜์ด์Šค์™€ Spring Condition(RealApiCondition / MockApiCondition)์œผ๋กœ ์‹ค์ œ API์™€ Mock์„ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ฑด์ถ•๋ฌผ๋Œ€์žฅ Mock์€ ์‹ค์ œ CODEF ํ•„๋“œ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด ํŒŒ์„œ๊นŒ์ง€ ๊ฒ€์ฆํ•˜๊ณ , ๋“ฑ๊ธฐยท๊ฐ€๊ฒฉ Mock์€ ์ •๊ทœํ™”๋œ ๋‚ด๋ถ€ ๋„๋ฉ”์ธ์„ ๋ฐ˜ํ™˜ํ•ด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ์œ ๋ฃŒ ํ˜ธ์ถœ ์—†์ด ์ „์ฒด ํ๋ฆ„์„ ๋Œ๋ฆด ์ˆ˜ ์žˆ์–ด, ๊ฐœ๋ฐœ ์ค‘ ๊ณผ๊ธˆ๊ณผ ํŒ€์› ๊ฐ„ ํ‚ค ๊ณต์œ  ๋ฌธ์ œ๋ฅผ ํ•จ๊ป˜ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.


์Šคํ‚ค๋งˆ๊ฐ€ ๋‚จ๊ธด ๊ธฐ๋ก

Flyway ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ 9๊ฐœ ์ค‘ ๋‘ ๊ฐœ๊ฐ€ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ๋’ค๋Šฆ๊ฒŒ ๊ณ ์นœ ํ”์ ์ž…๋‹ˆ๋‹ค.

๋ฒ„์ „ ๋‚ด์šฉ ์™œ ๋‚˜์ค‘์— ์ถ”๊ฐ€๋๋‚˜
V2__add_analysis_report_request_id.sql request_id UNIQUE ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฝ๋งŒ์œผ๋กœ๋Š” DB ์ €์žฅ ์งํ›„ ์‘๋‹ต ๋‹จ์ ˆ์„ ๋ชป ๋ง‰๋Š”๋‹ค๋Š” ๊ฑธ ๋’ค๋Šฆ๊ฒŒ ์ธ์‹
V3__add_data_status_to_report_results.sql data_status ์ปฌ๋Ÿผ ์ฒ˜์Œ์—” ์œ„ํ—˜๋„๋งŒ ์ €์žฅํ–ˆ๊ณ , "ํ™•์ธ ๋ถˆ๊ฐ€"์™€ "์•ˆ์ „"์ด ๊ตฌ๋ถ„๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ๋‚˜์ค‘์— ๋ฐœ๊ฒฌ

์ฒ˜์Œ๋ถ€ํ„ฐ ์™„๋ฒฝํ•˜๊ฒŒ ์„ค๊ณ„ํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ, ๋Œ๋ ค๋ณด๊ณ  ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•ด ์Šคํ‚ค๋งˆ๋ฅผ ๊ณ ์ณค์Šต๋‹ˆ๋‹ค.


ํ…Œ์ŠคํŠธ

์‹คํŒจ๊ฐ€ ์‚ฌ์šฉ์ž ํ”ผํ•ด๋‚˜ ์™ธ๋ถ€ API ๋น„์šฉ์œผ๋กœ ์ง๊ฒฐ๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์šฐ์„  ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. (2026-08-17 ์ธก์ •, report ๋„๋ฉ”์ธ ๊ธฐ์ค€)

์ง€ํ‘œ ๋ณด๊ฐ• ์ „ ๋ณด๊ฐ• ํ›„
ํ…Œ์ŠคํŠธ ์ˆ˜ 93 252 (+159)
์‹คํŒจ / ์˜ค๋ฅ˜ 0 / 0 0 / 0
Instruction 61.31% 82.12%
Line 58.53% 80.84%
Branch 49.35% 66.31%

branch coverage๋ฅผ ํ•จ๊ป˜ ๋ณธ ์ด์œ ๋Š”, ์œ„ํ—˜ ํŒ์ • ๋กœ์ง์ด ์กฐ๊ฑด ๋ถ„๊ธฐ ๋ฉ์–ด๋ฆฌ๋ผ line coverage๋งŒ์œผ๋กœ๋Š” ๊ฒ€์ฆ๋๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ๊ฒ€์ฆ ํ•ญ๋ชฉ:

  • @ParameterizedTest๋กœ ์ „์„ธ๊ฐ€์œจยท์„ ์ˆœ์œ„์ฑ„๊ถŒ ๊ฒฝ๊ณ„๊ฐ’์˜ ๋ฐ”๋กœ ์•„๋ž˜ยท๊ฐ™์Œยท๋ฐ”๋กœ ์œ„ โ€” ์œ„ํ—˜๋„๋งŒ์ด ์•„๋‹ˆ๋ผ DataStatus๋„ ํ•จ๊ป˜ ๋‹จ์–ธํ•ด "ํ™•์ธ ๋ถˆ๊ฐ€๋ฅผ ์•ˆ์ „์œผ๋กœ ์ฒ˜๋ฆฌ"ํ•˜๋Š” ํšŒ๊ท€๋ฅผ ์ฐจ๋‹จ
  • SET NX ๋ฝ ํš๋“ ์‹คํŒจ ์‹œ ์‹คํ–‰ ์ค‘๋‹จ, Lua ํ•ด์ œ, ์˜ˆ์™ธ ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•œ finally ํ•ด์ œ
  • ์™„๋ฃŒ๋œ requestId ์žฌ์š”์ฒญ ์‹œ ์œ ๋ฃŒ ํ˜ธ์ถœ ์—†์ด ๊ธฐ์กด ๋ฆฌํฌํŠธ ๋ฐ˜ํ™˜
  • MockRestServiceServer๋กœ URLยท์ฟผ๋ฆฌยทํ—ค๋”ยทform body ๊ณ„์•ฝ ๊ฒ€์ฆ, ํ•„์ˆ˜๊ฐ’ ๋ˆ„๋ฝยท์˜ค๋ฅ˜ ์‘๋‹ตยทํ†ต์‹  ์˜ˆ์™ธยท๊นจ์ง„ JSON
  • RSA ์•”ํ˜ธํ™”๋Š” ์ž„์‹œ ํ‚ค ์Œ์œผ๋กœ ์‹ค์ œ ๋ณตํ˜ธํ™”๊นŒ์ง€ ํ™•์ธํ•˜๊ณ , ์ž˜๋ชป๋œ ๊ณต๊ฐœํ‚ค๊ฐ€ ๋ฏผ๊ฐ์ •๋ณด๋ฅผ ํ‰๋ฌธ์œผ๋กœ ๋„˜๊ธฐ์ง€ ์•Š๋Š” ์‹คํŒจ ๊ฒฝ๋กœ๋„ ๊ฒ€์ฆ

AI ํŠน์•ฝ ์ „์šฉ ํ…Œ์ŠคํŠธ 4๊ฐœ๋Š” ํŒ€์› ๋‹ด๋‹น ๋ฒ”์œ„์™€ ์ค‘๋ณต๋˜์–ด ์ œ๊ฑฐํ–ˆ์œผ๋ฉฐ ์œ„ ์ˆ˜์น˜์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™์ผ ์ œ์™ธ ๊ธฐ์ค€์˜ ์ „์ฒด ๋ฐฑ์—”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋Š” line 49.74%, branch 48.75%์ž…๋‹ˆ๋‹ค.


๊ธฐ์ˆ  ์Šคํƒ

๊ตฌ๋ถ„ ๊ธฐ์ˆ  ์‚ฌ์šฉ ์ด์œ 
Runtime Java 17 ยท Tomcat 9 ยท WAR javax ๊ธฐ๋ฐ˜ Spring MVC ๊ตฌ์„ฑ๊ณผ ๋ฐฐํฌ ํ™˜๊ฒฝ
Web Spring MVC 5.3 ยท Spring Security 5.8 REST API, ํ•„ํ„ฐ ๊ธฐ๋ฐ˜ JWT ์ฒ˜๋ฆฌ
Persistence MyBatis ยท MySQL 8 ยท Flyway ๋ณต์žกํ•œ ์กฐํšŒ/UPSERT/ํ–‰ ์ž ๊ธˆ SQL ์ œ์–ด์™€ ์Šคํ‚ค๋งˆ ๋ฒ„์ „ ๊ด€๋ฆฌ
Ephemeral state Redis ยท Spring Data Redis ์ธ์ฆ ์›Œํฌํ”Œ๋กœ, TTL ์ƒํƒœ, ์š”์ฒญ ๋ฝ, ์บ์‹œ, ํ† ํฐ
Async / streaming @Async ยท WebSocket ยท gRPC ๋…น์Œ ์ˆ˜์‹ ๊ณผ STT/AI ์ฒ˜๋ฆฌ ๋ถ„๋ฆฌ
Storage Ncloud Object Storage ์—…๋กœ๋“œ ๋…น์Œ ์›๋ณธ
Frontend Vue 3 ยท Pinia ยท Axios ๋ชจ๋ฐ”์ผ ํผ์ŠคํŠธ ๋ฐ˜์‘ํ˜•
API ๋ฌธ์„œ Swagger (springfox) ํ”„๋ก ํŠธ์™€์˜ ๊ณ„์•ฝ ๊ณต์œ 
CI/CD GitHub Actions ยท Docker Compose backend/frontend ๊ฐ๊ฐ CI์™€ ๋ฐฐํฌ ์›Œํฌํ”Œ๋กœ
Test JUnit 5 ยท Mockito ยท AssertJ ยท JaCoCo ํŒ์ •ยท์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋ถ„๊ธฐ์™€ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •

์™ธ๋ถ€ ๋ฐ์ดํ„ฐ โ€” CODEF(๋“ฑ๊ธฐยท๊ฑด์ถ•๋ฌผ๋Œ€์žฅ), ๊ตญํ† ๊ตํ†ต๋ถ€ ์‹ค๊ฑฐ๋ž˜๊ฐ€, ํ•œ๊ตญ๋ถ€๋™์‚ฐ์›, ๊ฑด์ถ•HUB, ์นด์นด์˜ค ์ฃผ์†Œ, CLOVA STT, OpenAI

์ธ์ฆยท๊ณตํ†ต

  • BCrypt ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‹œ, HMAC ์„œ๋ช… JWT (Access / Refresh ํƒ€์ž… ๋ถ„๋ฆฌ), stateless session
  • ๋กœ๊ทธ์•„์›ƒ ์‹œ Access Token์„ ๋‚จ์€ ๋งŒ๋ฃŒ ์‹œ๊ฐ„๋งŒํผ Redis blacklist์— ๋“ฑ๋ก
  • anyRequest().authenticated() ๊ธฐ๋ณธ๊ฐ’์— ๊ณต๊ฐœ ์—”๋“œํฌ์ธํŠธ๋งŒ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ
  • BusinessException + ErrorCode ๊ณตํ†ต ์˜ˆ์™ธ ๋ชจ๋ธ, status / code / message / path / timestamp ํ†ต์ผ ์‘๋‹ต

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

second-zip-app/
โ”œโ”€โ”€ backend/     Spring MVC WAR ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”œโ”€โ”€ frontend/    Vue 3 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
โ”œโ”€โ”€ docker/      ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ (MySQL ยท Redis healthcheck ํ›„ ๋ฐฑ์—”๋“œ ๊ธฐ๋™)
โ”œโ”€โ”€ docs/        ERD ยท ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ ยท ์„ค๊ณ„ ๋ฌธ์„œ
โ””โ”€โ”€ .github/     CI ยท ๋ฐฐํฌ ์›Œํฌํ”Œ๋กœ

๋ฐฑ์—”๋“œ ํŒจํ‚ค์ง€

ํŒจํ‚ค์ง€ ์—ญํ• 
report ๋ถ„์„ ์›Œํฌํ”Œ๋กœ ยท ์™ธ๋ถ€ API ยท ์œ„ํ—˜ ํŒ์ • ยท ๋ฆฌํฌํŠธ โ† ๋‹ด๋‹น
checklist ๊ณ„์•ฝ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
record ๋…น์ทจ (WebSocket ยท gRPC ยท STT ยท AI ๋ถ„์„)
map ์ „์„ธ๊ฐ€๊ฒฉ ์ง€์ˆ˜ ยท ์‚ฌ๊ธฐ ํ”ผํ•ด ์ง€๋„
account / terms ๊ณ„์ • ยท ์•ฝ๊ด€
security JWT ๋ฐœ๊ธ‰ยท๊ฒ€์ฆยทblacklist
common ๊ณตํ†ต ์˜ˆ์™ธ ยท ์‘๋‹ต ๋ชจ๋ธ

์•Œ๋ ค์ง„ ํ•œ๊ณ„

์ž˜๋œ ๋ถ€๋ถ„๋งŒ ์ ์œผ๋ฉด ๊ฒ€์ฆ ์งˆ๋ฌธ์—์„œ ๋ฌด๋„ˆ์ง‘๋‹ˆ๋‹ค. ์‹ค์ œ ์ƒํƒœ๋Š” ์ด๋ ‡์Šต๋‹ˆ๋‹ค.

๋ณด์•ˆ

  • WebSocket์ด setAllowedOrigins("*")์ด๊ณ , URL์˜ ์„ธ์…˜ ID ์†Œ์œ ๊ถŒ ๊ฒ€์ฆ์ด ์—†์Šต๋‹ˆ๋‹ค
  • ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์˜ ๊ธฐ์กด Access Token์„ ์ผ๊ด„ ๋ฌดํšจํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์—†์Šต๋‹ˆ๋‹ค
  • ์ „์„ธ๊ฐ€๊ฒฉ ์ˆ˜๋™ ๋™๊ธฐํ™” API์— ๋ณ„๋„ ๊ด€๋ฆฌ์ž ์ธ๊ฐ€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค

๋™์‹œ์„ฑยท์ •ํ•ฉ์„ฑ

  • ๋“ฑ๊ธฐ ์บ์‹œ TTL ๊ธฐ๋ณธ๊ฐ’์ด 300์ดˆ๋กœ ์›Œํฌํ”Œ๋กœ TTL(15๋ถ„)๋ณด๋‹ค ์งง์•„, ์œ ๋ฃŒ ์กฐํšŒ ํ›„ DB ์ €์žฅ ์ „ ์‹คํŒจํ•˜๊ณ  5๋ถ„์ด ์ง€๋‚˜๋ฉด ์žฌ๊ณผ๊ธˆ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›Œํฌํ”Œ๋กœ๋ณด๋‹ค ๊ธด ๊ฐ’์œผ๋กœ ์ •๋ ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  • RegistryClient์˜ ์œ ๋ฃŒ ํ˜ธ์ถœ์ด synchronized๋ผ ๋‹จ์ผ JVM์—์„œ๋Š” ์ง๋ ฌํ™”๋˜์ง€๋งŒ, ์ฒ˜๋ฆฌ๋Ÿ‰ ๋ณ‘๋ชฉ์ด๋ฉฐ ๋‹ค์ค‘ ์ธ์Šคํ„ด์Šค์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค
  • ์‹ค์‹œ๊ฐ„ ๋…น์ทจ์˜ Context์™€ gRPC ์„ธ์…˜์ด JVM ๋ฉ”๋ชจ๋ฆฌ๋ผ scale-out ์‹œ sticky session์ด๋‚˜ ์™ธ๋ถ€ ์ƒํƒœ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค
  • ์ผ๋ถ€ ์„œ๋น„์Šค๊ฐ€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•ด DB ์ž์›์„ ์˜ค๋ž˜ ์ ์œ ํ•ฉ๋‹ˆ๋‹ค

๊ด€์ธก์„ฑ

  • Actuator, metrics, tracing, request correlation ID, ๊ตฌ์กฐํ™” ๋กœ๊ทธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค
  • ์™ธ๋ถ€ API 429/5xx backoff์™€ circuit breaker๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค

์„ฑ๊ณผ ์ง€ํ‘œ

์œ ๋ฃŒ ํ˜ธ์ถœ ๊ฐ์†Œ์œจยท์บ์‹œ ์ ์ค‘๋ฅ ยทP95 ์ฒ˜๋ฆฌ์‹œ๊ฐ„์€ ์ธก์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๊ตฌ์กฐ์ƒ ๊ธฐ๋Œ€๋˜๋Š” ํšจ๊ณผ๋Š” ์žˆ์œผ๋‚˜ ์ˆ˜์น˜๋กœ ๊ฒ€์ฆํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์ ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.


KB IT's Your Life 7๊ธฐ ยท 24๋ฐ˜ 3ํŒ€

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages