๊ณ ๊ฐ์ ๋น์ ํ ์์ฝ ๋ฉ์์ง๋ฅผ ๊ตฌ์กฐํํ์ฌ
์์ฝ ๋ฌธ์, ๋ณ๊ฒฝ, ์ทจ์, ๊ฒฐ์ ํ์ธ, ์ผ์ ๋ฑ๋ก๊น์ง ์๋ ์ฒ๋ฆฌํ๋
๋ค์ผ์ต ์ฌ์ฅ๋์ ์ํ AI ์์ฝ ์๋ ๋งค๋์
Team Nailgent
26-1 ๋ฐ์ดํฐ์ข ํฉ๋ถ์ ์บก์คํค ํ๋ก์ ํธ ย ยทย ๐ 2026 Low-Code AI Challenge Hackathon 3rd place
1์ธ ๋ค์ผ์ต ์ฌ์ฅ๋์ ์์ ์ค์๋ ์นด์นด์คํก์ผ๋ก ์์์ง๋ ์์ฝ ๋ฌธ์๋ฅผ ์ผ์ผ์ด ํ์ธํ๊ณ ๋ตํด์ผ ํฉ๋๋ค.
๊ณ ๊ฐ: ๋ด์ผ ์คํ 3์์ ์ ค ์ ๊ฑฐํ๊ณ ์ ค๋ค์ผ ๊ฐ๋ฅํด์? ์ฒซ๋ฐฉ๋ฌธ์ด๊ณ ์ด๋ฆ์ ๊น์ง์์์.
Reservia๋ ์ด๋ฐ ์์ ๋ก์ด ์์ฐ์ด ๋ฉ์์ง์์ ์์ฝ์ ํ์ํ ์ ๋ณด๋ฅผ ์ถ์ถํ๊ณ ,
์์ฝ ๊ฐ๋ฅ ์ฌ๋ถ ํ์ธ โ ๋๋ฝ ์ ๋ณด ์ฌ์ง๋ฌธ โ ์์ฝ๊ธ ๊ฒฐ์ โ Google Calendar ๋ฑ๋ก๊น์ง ์ฌ์ฅ๋ ๊ฐ์
์์ด ์๋์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
์ด ๋ ํฌ์งํ ๋ฆฌ๋ Reservia์ ๋ฐฑ์๋ ์๋ฒ์
๋๋ค.
AI ์์ด์ ํธ(n8n / LangGraph)์ ์ฌ์ฅ๋ ๊ด๋ฆฌ ๋์๋ณด๋(Frontend) ์ฌ์ด์์ ์์ฝยท๊ณ ๊ฐยท๊ฒฐ์ ยท์ต ์ค์ ๊ด๋ฆฌ๋ฅผ ์ํ REST API๋ฅผ ์ ๊ณตํฉ๋๋ค.
AWS ์์ 3-Tier Architecture ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
| Tier | ๊ตฌ์ฑ | ์ค๋ช |
|---|---|---|
| Presentation | Nginx (Public Subnet) | ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ์ ๋ด๋ถ ์๋ฒ๋ก ์ ๋ฌํ๋ ๋ฆฌ๋ฒ์ค ํ๋ก์ |
| Application | EC2 Backend + EC2 Agent (Private Subnet) | ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ โ Spring Boot ๋ฐฑ์๋ ๋ฐ AI ์์ด์ ํธ ์๋ฒ |
| Data | RDS MySQL + S3 (Private Subnet) | ๋ฐ์ดํฐ ์ ์ฅ โ ์์ฝยท๊ณ ๊ฐยท๊ฒฐ์ DB ๋ฐ ์ด๋ฏธ์ง ์คํ ๋ฆฌ์ง |
| ๊ตฌ์ฑ ์์ | ์ญํ |
|---|---|
| Nginx (Public Subnet) | ๋ฆฌ๋ฒ์ค ํ๋ก์, HTTPS ์ฒ๋ฆฌ |
| EC2 โ Backend (Private Subnet) | Spring Boot ๋ฐฑ์๋ ์๋ฒ |
| EC2 โ Agent (Private Subnet) | n8n / LangGraph ๊ธฐ๋ฐ AI ์์ด์ ํธ ์๋ฒ |
| RDS (Private Subnet) | MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค |
| S3 | ๊ณ ๊ฐ ๋์์ธ ๋ ํผ๋ฐ์ค ์ด๋ฏธ์ง ์ ์ฅ |
| NAT Gateway | Private Subnet โ ์ธ๋ถ API ์์๋ฐ์ด๋ ํต์ |
| GitHub Actions | main ๋ธ๋์น ํธ์ ์ ์๋ ๋ฐฐํฌ (CI/CD) |
๊ธฐ์กด์๋ S3 ์ ๊ทผ ํธ๋ํฝ์ด NAT Gateway โ ์ธํฐ๋ท์ ๊ฑฐ์ณ ๋๊ฐ์ง๋ง, ์ด ๊ฒฝ๋ก๋ฅผ VPC Endpoint๋ก ์ ํํ์ต๋๋ค.
AWS ๋ด๋ถ๋ง์ผ๋ก S3์ ์ง์ ์ฐ๊ฒฐ๋๋๋ก ํ์ฌ ๋ณด์ยท๋น์ฉยท์๋๋ฅผ ๋์์ ๊ฐ์ ํ์ต๋๋ค.
์ค๊ณ ๊ฒํ ๊ณผ์ ์์ ์ค๊ณ์ ์ค์ ์ค์ ์ ๋ถ์ผ์น๋ฅผ ๋ฐ๊ฒฌํ๊ณ , AWS ์ฝ์๋ก ์ง์ ๊ฒ์ฆํ์ต๋๋ค.
NAT Gateway๋ Public Subnet์ ์ํ ๋ฆฌ์์ค์ด๋ฏ๋ก, ์์ ์ด ์ํ ์๋ธ๋ท์ ๋ผ์ฐํ
ํ
์ด๋ธ(NailAgent-public-rt)์ ๋ฐ๋ผ๊ฐ๋๋ค.
์ฆ, ์์๋ฐ์ด๋ ํธ๋ํฝ์ ์ต์ข
์ถ๊ตฌ๋ NAT์ด ์๋ IGW(Internet Gateway) ์์ ์ฝ์ ๊ฒ์ฆ์ ํตํด ํ์ธํ์ต๋๋ค.
๋ฌธ์ ์ํฉ
๊ฒฐ์ ์ RESERVATION_NOT_FOUND๊ฐ ๋ฐ์ํ์ต๋๋ค. ๊ฒฐ์ ์ฐฝ ์ธ์ฆ์ ํต๊ณผํ์ง๋ง ์๋ฒ์์ ์์ฝ์ ์ฐพ์ง ๋ชปํด ๊ฒฐ์ ์น์ธ์ ์คํจํ์ต๋๋ค.
๊ทผ๋ณธ ์์ธ โ DB ์ด๊ธฐํ ํ ORDERID ์ค๋ณต
๊ฐ๋ฐ ์ค ํ
์คํธ ๋ชฉ์ ์ผ๋ก DB๋ฅผ ์ง์ ์ด๊ธฐํํ๋ฉด ์ฐ๋ฆฌ ์ชฝ AUTO_INCREMENT๋ 1๋ก ๋ฆฌ์
๋์ง๋ง, Toss๋ ์ด๋ฏธ ์ฒ๋ฆฌํ ORDERID๋ฅผ ๊ธฐ์ตํ๊ณ ์์ต๋๋ค.
๊ฐ์ ORDERID๋ก ์ฌ์์ฒญ ์ Toss๊ฐ ์ด๋ฅผ ๊ฑฐ์ ํ๊ฑฐ๋ ์ด์ ์์ฝ๊ณผ ๋งคํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ โ ORDERID์ ํ์์คํฌํ ์ถ๊ฐ
ORDERID๋ฅผ booking_{id}_{timestamp} ํ์์ผ๋ก ๋ณ๊ฒฝํ์ฌ, DB๊ฐ ์ด๊ธฐํ๋๋๋ผ๋ ํ์์คํฌํ๊ฐ ๋ฌ๋ผ ํญ์ ์ ์ผํ ORDERID๋ฅผ ๋ณด์ฅํ๋๋ก ํ์ต๋๋ค.
๋ฌธ์ ์ํฉ
์์ฝ ์งํ ์ ๋ฐฑ์๋๋ ์ด๋ฆ + ์ ํ๋ฒํธ๋ก ๊ธฐ์กด ๊ณ ๊ฐ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ , ์์ผ๋ฉด ์ ๊ท ๊ณ ๊ฐ์ ์๋ ๋ฑ๋กํ๋๋ก ์ค๊ณ๋์ด ์์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ๊ณ ๊ฐ์ด ์ด๋ฆ์ด๋ ์ ํ๋ฒํธ๋ฅผ ์๋ชป ์
๋ ฅํ ๋ค ์ด๋ฅผ ์ธ์งํ์ง ๋ชปํ ์ฑ ์ ์ ํ๋ฉด, ๊ฐ์ ์นด์นด์คํก ํ๋ฌ์ค์น๊ตฌ ID ํ๋์ ์๋ก ๋ค๋ฅธ ๊ณ ๊ฐ ๋ ์ฝ๋๊ฐ 2๊ฑด ์์ฑ๋์์ต๋๋ค.
์ด๋ ๊ฒ ์ค๋ณต ์์ฑ๋ ๊ณ ๊ฐ์ ์ดํ ๋ค๋ฅธ ์
๋ก๋ ๋ก์ง์์ ์ถฉ๋์ ์ผ์ผ์ผฐ์ต๋๋ค.
๊ทผ๋ณธ ์์ธ โ UNIQUE ์ ์ฝ์ ๊ณ ๊ฐ์ ์
๋ ฅ ์์จ์ฑ์ ๋งก๊น
์ด๋ฆยท์ ํ๋ฒํธ๋ ๊ณ ๊ฐ์ด ์์ ๋กญ๊ฒ ์
๋ ฅํ๋ ๊ฐ์ด๋ผ ์คํยท๋ณ๊ฒฝ์ด ์ธ์ ๋ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฐ ๊ฐ๋ณ์ ์ธ ๊ฐ์ ์๋ณ ๊ธฐ์ค(UNIQUE)์ผ๋ก ์ผ์ ๊ฒ์ด ์ค๋ณต์ ์ง์ ์์ธ์ด์์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ โ ์๋ณ ๊ธฐ์ค์ ๋ถ๋ณ๊ฐ์ธ ํ๋ฌ์ค์น๊ตฌ ID๋ก ์ ํ
UNIQUE ์ ์ฝ์ (์ด๋ฆ, ์ ํ๋ฒํธ)์์ ์์คํ
์ด ๋ณด์ฅํ๋ ๋ถ๋ณ๊ฐ์ธ ์นด์นด์คํก ํ๋ฌ์ค์น๊ตฌ ID๋ก ๋ณ๊ฒฝํ์ฌ ๊ณ ๊ฐ์ ์๋ณํ๋๋ก ํ์ต๋๋ค.
์ด๋ฅผ ํตํด UNIQUE ์ ์ฝ์ ์ฌ์ฉ์ ์
๋ ฅ ์์จ์ฑ์ ๋งก๊ธฐ๋ฉด ์ ๋๋ฉฐ, ์์คํ
์ด ํต์ ๊ฐ๋ฅํ ๋ถ๋ณ ์๋ณ์์ ๋ถ์ฌํด์ผ ํ๋ค๋ ์ ์ ์ฒด๊ฐํ์ต๋๋ค.
- AI ์์ด์ ํธ๊ฐ ๊ณ ๊ฐ๊ณผ ์นด์นด์คํก์ผ๋ก ๋ํ โ ์์ฝ ์๋ ์์ฑ
- ์์ฝ ์์ฑยท์์ ยท์ญ์ ์ Google Calendar ์ผ์ ์๋ ๋๊ธฐํ
- ์์ฝ ์ํ ํ๋ฆ:
PENDINGโCONFIRMEDโVISITED/NO_SHOW/CANCELLED - ๊ฒฐ์ ๋ฏธ์๋ฃ ์์ฝ 5๋ถ ํ ์๋ ์ทจ์ (์ค์ผ์ค๋ฌ)
- ๊ณ ๊ฐ์ด ์ ๋ก๋ํ ๋์์ธ ๋ ํผ๋ฐ์ค ์ด๋ฏธ์ง S3 ์ ์ฅ ๋ฐ ์กฐํ
- ๋ ์ง๋ณ ์์ฝ ์ฌ๋กฏ ์กฐํ (์์ด์ ํธ๊ฐ ๊ฐ๋ฅ ์๊ฐ๋ ํ๋จ์ ์ฌ์ฉ)
- ์นด์นด์ค
plusfriendUserKey๊ธฐ์ค ๊ณ ๊ฐ ์๋ ์๋ณ ๋ฐ ์ค๋ณต ์์ฑ ๋ฐฉ์ง - ์ฌ๋ฐฉ๋ฌธ ๊ณ ๊ฐ ์ ๋ณด(์ด๋ฆยท์ ํ๋ฒํธ) ์๋ ์ ๋ฐ์ดํธ
- ๋ ธ์ผ ํ์ ๋์ ๊ด๋ฆฌ
- Toss Payments ์ฐ๋ โ ์์ฝ๊ธ ๊ฒฐ์ ์ต์ข ์น์ธ
- ๊ฒฐ์ ์๋ฃ ์ ์์ฝ ์ํ
CONFIRMED์๋ ์ ํ - ํ๋ถ ์ฒ๋ฆฌ
- ์์ ์๊ฐ, ํด๋ฌด์ผ, ์์ฝ๊ธ ์ ์ฑ ๊ด๋ฆฌ
- ์๋น์ค ๋ฉ๋ด ๋ฐ ์์ ์๊ฐ (AI ์์ด์ ํธ๊ฐ ์ฐธ์กฐ)
- ์์ฝ ์๋ด ๋ฉ์์ง, ์ด์ฉ ์ฝ๊ด ํ ์คํธ
- AI๊ฐ ์๋ ์๋ต ๋ถ๊ฐํ ์ํฉ ๋ฐ์ ์ โ ์ฌ์ฅ๋ ๋์๋ณด๋์ ์ค์๊ฐ push
CopyOnWriteArrayList๊ธฐ๋ฐ ๋ค์ค ์ฐ๊ฒฐ ์ง์์ผ๋ก ์ฌ์ฐ๊ฒฐ ์ ๋๊น ๋ฐฉ์ง
๐ ์ ์ฒด API ๋ชฉ๋ก ๋ณด๊ธฐ
์์ฝ
| Method | Path | ์ค๋ช |
|---|---|---|
GET |
/api/v1/bookings/schedule |
๋ ์ง๋ณ ์์ฝ ๊ฐ๋ฅ ์ฌ๋กฏ ์กฐํ |
GET |
/api/v1/bookings |
์ ์ฒด ์์ฝ ๋ชฉ๋ก (ํ์ด์ง๋ค์ด์ ) |
POST |
/api/v1/bookings |
์์ฝ ์์ฑ |
PATCH |
/api/v1/bookings/{id} |
์์ฝ ์์ |
DELETE |
/api/v1/bookings/{id} |
์์ฝ ์ญ์ |
PATCH |
/api/v1/bookings/image |
๋์์ธ ๋ ํผ๋ฐ์ค ์ด๋ฏธ์ง ์ ๋ก๋ |
๊ณ ๊ฐ
| Method | Path | ์ค๋ช |
|---|---|---|
POST |
/api/v1/kakao-customers |
์นด์นด์ค ๊ณ ๊ฐ ์กฐํ (AI ์์ด์ ํธ ์ ์ฉ) |
GET |
/api/v1/customers |
๊ณ ๊ฐ ๋ชฉ๋ก ์กฐํ |
์ต ์ค์
| Method | Path | ์ค๋ช |
|---|---|---|
GET |
/api/v1/shopinfo |
์ต ์ค์ ์กฐํ |
PATCH |
/api/v1/shopinfo |
์ต ์ค์ ์์ |
๊ฒฐ์
| Method | Path | ์ค๋ช |
|---|---|---|
POST |
/api/v1/payments/confirm |
Toss Payments ๊ฒฐ์ ์ต์ข ์น์ธ |
PATCH |
/api/v1/payments/{id} |
๊ฒฐ์ ์ํ ์ ๋ฐ์ดํธ |
POST |
/api/v1/payments/{id}/refund |
๊ฒฐ์ ํ๋ถ |
์ค์๊ฐ ์๋ฆผ
| Method | Path | ์ค๋ช |
|---|---|---|
GET |
/api/v1/sse/connect |
SSE ์ฐ๊ฒฐ (๋์๋ณด๋ ์ ์ฉ) |
POST |
/api/v1/sse/notify |
์ค์๊ฐ ์๋ฆผ ์ ์ก (AI ์์ด์ ํธ ์ ์ฉ) |
API ๋ฌธ์:
/swagger-ui/index.html
| ๋ ํฌ | ์ค๋ช |
|---|---|
| NailAgent/agent | LangGraph ๊ธฐ๋ฐ AI ์์ด์ ํธ |
| NailAgent/n8n | n8n ๊ธฐ๋ฐ AI ์์ด์ ํธ |
| NailAgent/frontend | ์ฌ์ฅ๋ ๊ด๋ฆฌ ๋์๋ณด๋ (Vercel ๋ฐฐํฌ) |
| Role | Name | GitHub |
|---|---|---|
| AI / Agent | ๊น๋ฏธ์ง | @miji0 |
| AI / Agent | ๊น์ง์ | @sallysooo |
| Backend / Infra | ๋จ๋ฏผ์ | @minseo0313 |
| Frontend / Design | ์ ๊ต์ | @kyooonnnggg |



