์ ์ธ์ฌ๊ธฐ ์ ํ๋ณ ์ํ ๋ถ์ยท์๋ฐฉ ์๋น์ค
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 ๋๋ฉ์ธ ํ ์คํธ ๋ณด๊ฐ |
์ธ์ฆ/๋ง์ดํ์ด์ง/์ฝ๊ด ๋๋ฉ์ธ๊ณผ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ ๋ค๋ฅธ ๋ฐฑ์๋ ํ์์ด ๋ด๋นํ์ต๋๋ค.
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๋ก ์๋ตํด ์์ฒญ ์กด์ฌ ์ฌ๋ถ๊ฐ ๋ ธ์ถ๋์ง ์๊ฒ ํ์ต๋๋ค
๋ฑ๊ธฐ๋ถ๋ฑ๋ณธ ์กฐํ๋ ๊ฑด๋น ๊ณผ๊ธ๋ฉ๋๋ค. ๋๋ธํด๋ฆญ, ๋คํธ์ํฌ ์ฌ์๋, 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 ์ถฉ๋ ํ ๊ธฐ์กด ๊ฒฐ๊ณผ ์ฌ์กฐํ๊ฐ ํ์ํฉ๋๋ค.
๊ฐ์ฅ ์ํํ ์คํจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ชป ๊ฐ์ ธ์๋๋ฐ ์ํ ์์์ผ๋ก ํ์๋๋ ๊ฒ์
๋๋ค. ์ฌ์ฉ์๋ ๊ทธ๊ฑธ "์์ ํ๋ค"๋ก ์ฝ์ต๋๋ค. ์ธ๋ถ API ์คํจ๋ ๊ธ์ก ํ์ฑ ์คํจ๊ฐ 0์ด๋ false๋ก ๋์ฒด๋๋ฉด ์ํ ๋งค๋ฌผ์ด SAFE๊ฐ ๋ฉ๋๋ค.
๊ทธ๋์ ํ์ ๊ฒฐ๊ณผ Judgement๋ฅผ ๋ ์ถ์ผ๋ก ๋ถ๋ฆฌํ์ต๋๋ค.
| DataStatus | ์๋ฏธ | ์ง๊ณ |
|---|---|---|
VERIFIED |
๋ฐ์ดํฐ๋ฅผ ํ๋ณดํด ์ค์ ํ์ | ์ํ๋์ ๋ฐ์ |
UNVERIFIED |
๋ฐ์ดํฐ ๋ถ์กฑยทํ์ฑ ์คํจ๋ก ํ์ธ ๋ถ๊ฐ | CAUTION์ผ๋ก ์ง๊ณ์ ์ฐธ์ฌ |
NOT_APPLICABLE |
ํด๋น ์ฃผํ์ ์ ์ฉ๋์ง ์๋ ๊ท์น | ์ง๊ณ์์ ์ ์ธ |
์ ๊ฒ ๊ทผ๊ฑฐ๋ JSON evidence๋ก ํจ๊ป ์ ์ฅํด ํ์ ๊ฒฐ๊ณผ๋ฅผ ์ถ์ ํ ์ ์๊ฒ ํ์ต๋๋ค.
์ธ๋ถ ์๋ต์ ์ํ ์์ง์ ๋ฐ๋ก ๋๊ธฐ์ง ์๊ณ ๋ด๋ถ ๋๋ฉ์ธ์ผ๋ก ์ ๊ทํํฉ๋๋ค. ์ค์ ๋ก ํ์ ์ ๋ค์ง๋ ๊ฒ์ ๋๋ถ๋ถ ์ด ๋จ๊ณ์ ๋ํ ์ผ์ด์์ต๋๋ค.
๋ฑ๊ธฐ๋ถ๋ฑ๋ณธ
- ๋ง์๋ ๊ถ๋ฆฌ ํ์๋ฅผ ์ ์ธ
- ๊ทผ์ ๋น ํํ์ ์๋๋ฐ ๊ธ์ก ํ์ฑ์ ์คํจํ๋ฉด 0์์ด ์๋๋ผ
null๋ก ์ ์ง โ 0์์ผ๋ก ๋๋ฉด ์์ ์ผ๋ก ํ์ ๋ฉ๋๋ค - ์ ํ ์ดํ ๋ฐ์ํ ๊ถ๋ฆฌ์นจํด์ ์ ํ ์ด์ ๊ถ๋ฆฌ๋ฅผ ๊ตฌ๋ถ
- ์์ ์๊ฐ ์ ํํ์ฌ์ธ ๊ฒฝ์ฐ ์ ํ ๋ฌธ๊ตฌ ๋๋ฝ์ ๋ณด์
๊ณต์๊ฐ๊ฒฉ
๊ณผ๊ฑฐ ์ต๋ ๊ธ์ก์ด ์๋๋ผ ๊ธฐ์ค์ผ์ด ๊ฐ์ฅ ์ต๊ทผ์ธ ๊ฐ๊ฒฉ์ ์ ํํฉ๋๋ค. ๋ ์ง๊ฐ ์ ํ ์์ ๋๋ง ์ต๋๊ฐ์ผ๋ก ํด๋ฐฑํฉ๋๋ค. ๊ฐ๊ฒฉ ํ๋ฝ๊ธฐ์ ๊ณผ๊ฑฐ ์ต๊ณ ๊ฐ๋ฅผ ์ฐ๋ฉด ์ ์ธ๊ฐ์จ์ด ๋ฎ๊ฒ ๊ณ์ฐ๋์ด ์ํ์ ๊ณผ์ํ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ต์ 4.2์ตยท๊ณผ๊ฑฐ 5์ต์ผ ๋ 4.2์ต์ผ๋ก ํ์ ํ๋ ๊ฒ์ ๋จ์ ํ ์คํธ๋ก ๊ณ ์ ํ์ต๋๋ค.
์ฃผ์
์นด์นด์ค ์ฃผ์ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ์ฅ์ ๊ฒ์์ผ๋ก ํด๋ฐฑํ๊ณ , ํ๋ก ํธ์๋ Redis์ ์ ์ฅํ ํ๋ณด ID๋ง ๋ ธ์ถํด ๋ถ์ ๋์ ์๋ณ๊ฐ ๋ณ์กฐ๋ฅผ ์ค์์ต๋๋ค.
LLM ์ถ๋ ฅ์ ๋น๊ฒฐ์ ์ ์ด๋ผ DB์ ๋ฐ๋ก ์ ์ฅํ์ง ์์ต๋๋ค.
- strict JSON Schema โ ์๋ต ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ธ ๋จ์์ ์ ํ
- ์ ํ๋ฆฌ์ผ์ด์
๋ถ๋ณ์ โ ํน์ฝ์ 3
5๊ฐยท์ ๋ชฉ 50์ยท๋ณธ๋ฌธ 200์ยท์ค๋ณต ๊ฑฐ๋ถ, ์ฒดํฌ๋ฆฌ์คํธ๋ ์์ฒญํ item ID๊ฐ ์ ํํ ํ ๋ฒ์ฉ ์กด์ฌํ๋์ง์ 01 ์ ๋ขฐ๋ ๊ฒ์ฆ - ํธ๋์ญ์
๋ฐ์ โ ํน์ฝ ๊ต์ฒด๋ ๋ฆฌํฌํธ ํ์
SELECT ... FOR UPDATE๋ก ์ ๊ทผ ๋ค delete/insert
์ค์๊ฐ ๋ น์ทจ๋ provisional / final์ ๋ถ๋ฆฌํฉ๋๋ค. ์ค๊ฐ ๋ถ์์ด CHECKED๋ฅผ ๋ฐํํด๋ ์ค์ ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ๋ฐ๊พธ์ง ์๊ณ JVM ๋ฉ๋ชจ๋ฆฌ์ ํ๋ณด๋ก๋ง ๋์๋ค๊ฐ, ๋ น์ ์ข ๋ฃ ํ ์ ์ฒด ๋ น์ทจ๋ฅผ ๋ค์ ๋ถ์ํ ์ต์ข ๊ฒฐ๊ณผ๋ง ๋ฐ์ํฉ๋๋ค.
| ๋์ | connect / read |
|---|---|
| ์ผ๋ฐ API | 3์ด / 10์ด |
| ํน์ฝ GPT | 3์ด / 30์ด |
| CODEF ์ฅ์๊ฐ ์์ | 5์ด / 300์ด |
๋ชจ๋ ํธ์ถ์ ๊ฐ์ ํ์์์์ ์ฐ๋ฉด ๋๋ฆฐ ๋ฌธ์ ๋ฐ๊ธ์ด ์ ์์ธ๋ฐ๋ ์คํจํ๊ณ , ๋ฐ๋๋ก ์ผ๋ฐ API ์ฅ์ ๊ฐ ์์ฒญ ์ค๋ ๋๋ฅผ ์ค๋ ์ ์ ํฉ๋๋ค. CODEF ํ ํฐ์ ๋ง๋ฃ 60์ด ์ ์ ์ ๊ฐฑ์ ํ๊ณ , 401์ผ ๋๋ง ์บ์๋ฅผ ํ๊ธฐํ๊ณ ํ ๋ฒ ์ฌ์๋ํฉ๋๋ค. ๋ฌด์กฐ๊ฑด ์ฌ์๋ํ์ง ์๋ ์ด์ ๋ ์ ๋ฃยท๋น๋ฉฑ๋ฑ ํธ์ถ์ด ์ค๋ณต ์คํ๋ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
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 ์ฒ๋ฆฌ์๊ฐ์ ์ธก์ ํ์ง ์์์ต๋๋ค. ์ฝ๋ ๊ตฌ์กฐ์ ๊ธฐ๋๋๋ ํจ๊ณผ๋ ์์ผ๋ ์์น๋ก ๊ฒ์ฆํ ๊ฒ์ด ์๋๋ฏ๋ก ์ ์ง ์์์ต๋๋ค.