Gateway (Go)

์—ญํ• 

Gateway๋Š” Starnion์˜ ํŠธ๋ž˜ํ”ฝ ์ค‘์‹ฌ๋ถ€์ž…๋‹ˆ๋‹ค. Go ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ๋‹ค์Œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • REST API ์„œ๋ฒ„: UI์™€ ์™ธ๋ถ€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์œ„ํ•œ API ์—”๋“œํฌ์ธํŠธ ์ œ๊ณต
  • WebSocket ์„œ๋ฒ„: ์‹ค์‹œ๊ฐ„ ์›น ์ฑ„ํŒ… ํ—ˆ๋ธŒ(Hub) ์šด์˜
  • Telegram ๋ด‡ ๊ด€๋ฆฌ์ž: ์‚ฌ์šฉ์ž๋ณ„ ๋‹ค์ค‘ Telegram ๋ด‡ ์ธ์Šคํ„ด์Šค ๊ด€๋ฆฌ
  • Cron ์Šค์ผ€์ค„๋Ÿฌ: ์ฃผ๊ธฐ์  ์•Œ๋ฆผ, ๋ฆฌํฌํŠธ, ์˜ˆ์‚ฐ ๊ฒฝ๊ณ  ์ž๋™ ์‹คํ–‰
  • gRPC ํด๋ผ์ด์–ธํŠธ: Python Agent์™€ ํ†ต์‹ ํ•˜์—ฌ AI ์‘๋‹ต ์š”์ฒญ

์‹œ์Šคํ…œ ๋‹ค์ด์–ด๊ทธ๋žจ

ํด๋ผ์ด์–ธํŠธ (๋ธŒ๋ผ์šฐ์ €/์•ฑ)
        โ”‚
        โ”œโ”€โ”€ HTTP REST โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”œโ”€โ”€ WebSocket (wss://) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚
        โ””โ”€โ”€ Telegram Bot API โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
                                                        โ–ผ
                                            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                            โ”‚   Gateway (Go)      โ”‚
                                            โ”‚                     โ”‚
                                            โ”‚  Echo Router        โ”‚
                                            โ”‚  BotManager         โ”‚
                                            โ”‚  Scheduler (Cron)   โ”‚
                                            โ”‚  WebSocket Hub      โ”‚
                                            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                   โ”‚ gRPC
                                                   โ–ผ
                                            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                            โ”‚   Agent (Python)    โ”‚
                                            โ”‚   gRPC :50051       โ”‚
                                            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                   โ”‚
                                            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
                                            โ”‚  PostgreSQL  โ”‚
                                            โ”‚   pgvector   โ”‚
                                            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

์ฃผ์š” ์ปดํฌ๋„ŒํŠธ

Echo ๋ผ์šฐํ„ฐ

labstack/echo v4๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  HTTP ์š”์ฒญ์€ main.go์—์„œ ๋ผ์šฐํŠธ๊ฐ€ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

BotManager

์‚ฌ์šฉ์ž๋ณ„ Telegram ๋ด‡์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ Telegram Bot Token์„ ๋“ฑ๋กํ•˜๋ฉด BotManager๊ฐ€ ํ•ด๋‹น ๋ด‡ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—…๋ฐ์ดํŠธ ํด๋ง์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ DB์— ์ €์žฅ๋œ ๋ชจ๋“  ๋ด‡ ํ† ํฐ์„ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค (ReloadAll()).

WebSocket Hub

์›น ์ฑ„ํŒ…์„ ์œ„ํ•œ ์‹ค์‹œ๊ฐ„ ์—ฐ๊ฒฐ ํ—ˆ๋ธŒ์ž…๋‹ˆ๋‹ค. JWT ์ธ์ฆ์„ ํ†ตํ•ด ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฝํ•˜๊ณ , Agent์˜ gRPC ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

Cron ์Šค์ผ€์ค„๋Ÿฌ

robfig/cron v3๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, KST(UTC+9) ๊ธฐ์ค€์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ Cron ์Šค์ผ€์ค„ ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

gRPC ํด๋ผ์ด์–ธํŠธ

protobuf๋กœ ์ •์˜๋œ AgentService๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋‹จ๋ฐฉํ–ฅ ์š”์ฒญ(Chat), ์„œ๋ฒ„ ์ŠคํŠธ๋ฆฌ๋ฐ(ChatStream) ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.


์ธ์ฆ ๋ฐฉ์‹

๋ชจ๋“  API ์š”์ฒญ์€ JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Authorization: Bearer <jwt_token>

ํ† ํฐ์€ /auth/token ์—”๋“œํฌ์ธํŠธ์—์„œ ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์›น ์‚ฌ์šฉ์ž๋Š” NextAuth ์„ธ์…˜์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ํ† ํฐ์„ ํš๋“ํ•ฉ๋‹ˆ๋‹ค. Telegram ์‚ฌ์šฉ์ž๋Š” ํ”Œ๋žซํผ ID ๊ธฐ๋ฐ˜์œผ๋กœ ํ† ํฐ์ด ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.


๋ฏธ๋“ค์›จ์–ด

์š”์ฒญ์ด ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ
RequestID ๋ชจ๋“  ์š”์ฒญ์— ๊ณ ์œ  ID ๋ถ€์—ฌ (X-Request-ID)
Recover ํ•ธ๋“ค๋Ÿฌ ํŒจ๋‹‰์„ 500 ์‘๋‹ต์œผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณต๊ตฌ
CORS ํ—ˆ์šฉ๋œ Origin, Method, Header ํ•„ํ„ฐ๋ง
RequestLogger zerolog ๊ธฐ๋ฐ˜ ์š”์ฒญ/์‘๋‹ต ๋กœ๊น…

API ์—”๋“œํฌ์ธํŠธ ์ „์ฒด ๋ชฉ๋ก

์ธ์ฆ (Auth)

Method Path ์„ค๋ช…
POST /auth/register ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ํšŒ์›๊ฐ€์ž…
POST /auth/login ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ๋กœ๊ทธ์ธ
POST /auth/token ์ต๋ช… JWT ํ† ํฐ ๋ฐœ๊ธ‰
POST /auth/link ์›น ๊ณ„์ •๊ณผ Telegram ๊ณ„์ • ์—ฐ๊ฒฐ
GET /auth/google/callback Google OAuth2 ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ
GET /auth/google/telegram Telegram ๋ด‡์—์„œ Google OAuth ์‹œ์ž‘

์ฑ„ํŒ… (Chat)

Method Path ์„ค๋ช…
POST /api/v1/chat ๋‹จ๋ฐฉํ–ฅ ์ฑ„ํŒ… ์š”์ฒญ
POST /api/v1/chat/stream SSE ์ŠคํŠธ๋ฆฌ๋ฐ ์ฑ„ํŒ… (AI SDK ํ˜ธํ™˜)
GET /ws WebSocket ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์—ฐ๊ฒฐ

๋Œ€ํ™” ๊ด€๋ฆฌ (Conversations)

Method Path ์„ค๋ช…
GET /api/v1/conversations ๋Œ€ํ™” ๋ชฉ๋ก ์กฐํšŒ
POST /api/v1/conversations ์ƒˆ ๋Œ€ํ™” ์ƒ์„ฑ
PATCH /api/v1/conversations/:id ๋Œ€ํ™” ์ œ๋ชฉ ์ˆ˜์ •
GET /api/v1/conversations/:id/messages ๋Œ€ํ™” ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก ์กฐํšŒ

๊ฐ€๊ณ„๋ถ€ (Finance)

Method Path ์„ค๋ช…
GET /api/v1/finance/summary ์ˆ˜์ž…/์ง€์ถœ ์š”์•ฝ
GET /api/v1/finance/transactions ๊ฑฐ๋ž˜ ๋‚ด์—ญ ๋ชฉ๋ก ์กฐํšŒ
POST /api/v1/finance/transactions ์ƒˆ ๊ฑฐ๋ž˜ ๋‚ด์—ญ ์ถ”๊ฐ€
PUT /api/v1/finance/transactions/:id ๊ฑฐ๋ž˜ ๋‚ด์—ญ ์ˆ˜์ •
DELETE /api/v1/finance/transactions/:id ๊ฑฐ๋ž˜ ๋‚ด์—ญ ์‚ญ์ œ
GET /api/v1/budget ์˜ˆ์‚ฐ ์กฐํšŒ
PUT /api/v1/budget ์˜ˆ์‚ฐ ์„ค์ •
GET /api/v1/statistics ์ง€์ถœ ํ†ต๊ณ„
GET /api/v1/statistics/insights ์ง€์ถœ ์ธ์‚ฌ์ดํŠธ

๊ฐœ์ธ ๋ฐ์ดํ„ฐ

Method Path ์„ค๋ช…
GET/POST /api/v1/diary/entries ์ผ๊ธฐ ๋ชฉ๋ก/์ƒ์„ฑ
GET/PUT/DELETE /api/v1/diary/entries/:id ์ผ๊ธฐ ์ƒ์„ธ/์ˆ˜์ •/์‚ญ์ œ
GET/POST /api/v1/goals ๋ชฉํ‘œ ๋ชฉ๋ก/์ƒ์„ฑ
POST /api/v1/goals/:id/checkin ๋ชฉํ‘œ ์ฒดํฌ์ธ
GET/POST /api/v1/memos ๋ฉ”๋ชจ ๋ชฉ๋ก/์ƒ์„ฑ
PUT/DELETE /api/v1/memos/:id ๋ฉ”๋ชจ ์ˆ˜์ •/์‚ญ์ œ
GET/POST /api/v1/ddays D-Day ๋ชฉ๋ก/์ƒ์„ฑ

์„ค์ • ๋ฐ ๋ชจ๋ธ

Method Path ์„ค๋ช…
GET/PATCH /api/v1/profile ํ”„๋กœํ•„ ์กฐํšŒ/์ˆ˜์ •
GET/POST /api/v1/providers LLM ํ”„๋กœ๋ฐ”์ด๋” ๋ชฉ๋ก/๋“ฑ๋ก
POST /api/v1/providers/validate API ํ‚ค ์œ ํšจ์„ฑ ๊ฒ€์ฆ
DELETE /api/v1/providers/:provider ํ”„๋กœ๋ฐ”์ด๋” ์‚ญ์ œ
GET/POST /api/v1/personas ํŽ˜๋ฅด์†Œ๋‚˜ ๋ชฉ๋ก/์ƒ์„ฑ
PUT/DELETE /api/v1/personas/:id ํŽ˜๋ฅด์†Œ๋‚˜ ์ˆ˜์ •/์‚ญ์ œ

ํ†ตํ•ฉ (Integrations)

Method Path ์„ค๋ช…
GET /api/v1/integrations/status ์—ฐ๋™ ์ƒํƒœ ์กฐํšŒ
GET /api/v1/integrations/google/auth-url Google OAuth URL ์ƒ์„ฑ
DELETE /api/v1/integrations/google Google ์—ฐ๋™ ํ•ด์ œ
PUT /api/v1/integrations/notion Notion ์—ฐ๊ฒฐ
PUT /api/v1/integrations/tavily Tavily ์›น๊ฒ€์ƒ‰ ์—ฐ๊ฒฐ
PUT /api/v1/integrations/naver_search ๋„ค์ด๋ฒ„ ๊ฒ€์ƒ‰ ์—ฐ๊ฒฐ

ํŒŒ์ผ ๋ฐ ๋ฏธ๋””์–ด

Method Path ์„ค๋ช…
POST /api/v1/upload ํŒŒ์ผ ์—…๋กœ๋“œ (MinIO)
GET/POST/DELETE /api/v1/documents ๋ฌธ์„œ ๊ด€๋ฆฌ
GET/DELETE /api/v1/images ์ด๋ฏธ์ง€ ๊ฐค๋Ÿฌ๋ฆฌ
GET/POST/DELETE /api/v1/audios ์˜ค๋””์˜ค ๊ฐค๋Ÿฌ๋ฆฌ

๋ถ„์„ ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

Method Path ์„ค๋ช…
GET /api/v1/analytics ๋Œ€ํ™” ๋ถ„์„ ํ†ต๊ณ„
GET /api/v1/usage LLM ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰
GET /api/v1/logs ๊ฒŒ์ดํŠธ์›จ์ด ๋กœ๊ทธ ๋ชฉ๋ก
GET /api/v1/logs/stream ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ์ŠคํŠธ๋ฆฌ๋ฐ (SSE)
GET /api/v1/logs/agent Python Agent ๋กœ๊ทธ ํ”„๋ก์‹œ

Cron ์Šค์ผ€์ค„

์Šค์ผ€์ค„๋Ÿฌ๋Š” KST(UTC+9) ๊ธฐ์ค€์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์Šค์ผ€์ค„ ์ž‘์—… ์„ค๋ช…
๋งค์ฃผ ์›”์š”์ผ 09:00 weekly_report ์ฃผ๊ฐ„ ๊ฐ€๊ณ„๋ถ€ ๋ฆฌํฌํŠธ ๋ฐœ์†ก
๋งค์‹œ๊ฐ„ budget_warning ์˜ˆ์‚ฐ ์ดˆ๊ณผ ๊ฒฝ๊ณ  ํ™•์ธ
๋งค์ผ 21:00 daily_summary ์˜ค๋Š˜ ํ•˜๋ฃจ ์š”์•ฝ ๋ฐœ์†ก
๋งค์ผ 20:00 inactive_reminder ๋น„ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์•Œ๋ฆผ
๋งค์›” 28~31์ผ 21:00 monthly_closing ์›”๋ง ๊ฒฐ์‚ฐ ์•Œ๋ฆผ
๋งค์ผ 06:00 pattern_analysis ์ง€์ถœ ํŒจํ„ด ๋ถ„์„
3์‹œ๊ฐ„๋งˆ๋‹ค spending_anomaly ๋น„์ •์ƒ ์ง€์ถœ ๊ฐ์ง€
๋งค์ผ 14:00 pattern_insight ํŒจํ„ด ๊ธฐ๋ฐ˜ ์ธ์‚ฌ์ดํŠธ ๋ฐœ์†ก
10๋ถ„๋งˆ๋‹ค conversation_analysis ๋Œ€ํ™” ๋ถ„์„ (์œ ํœด ๊ฐ์ง€)
๋งค์ผ 07:00 goal_evaluation ๋ชฉํ‘œ ๋‹ฌ์„ฑ๋„ ํ‰๊ฐ€
๋งค์ฃผ ์ˆ˜์š”์ผ 12:00 goal_status ๋ชฉํ‘œ ํ˜„ํ™ฉ ์•Œ๋ฆผ
๋งค์ผ 08:00 dday_notification D-Day ์•Œ๋ฆผ
15๋ถ„๋งˆ๋‹ค user_schedules ์‚ฌ์šฉ์ž ์ •์˜ ์Šค์ผ€์ค„ ์‹คํ–‰
๋งค์ฃผ ์›”์š”์ผ 05:00 memory_compaction ๋ฉ”๋ชจ๋ฆฌ ์••์ถ• (AI ๋กœ๊ทธ ์ •๋ฆฌ)

๋กœ๊ทธ ํ™•์ธ

Gateway์˜ ๋กœ๊ทธ๋Š” zerolog ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ์  JSON ๋กœ๊ทธ๋กœ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

์›น UI์—์„œ ํ™•์ธ

Settings > Logs ๋ฉ”๋‰ด์—์„œ ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ์ŠคํŠธ๋ฆผ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. GET /api/v1/logs/stream SSE ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•ด ์ƒˆ ๋กœ๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์‹ค์‹œ๊ฐ„์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

Docker ๋กœ๊ทธ

docker compose logs -f gateway
docker compose logs -f agent

๋กœ๊ทธ ๋ ˆ๋ฒจ

LOG_LEVEL ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์กฐ์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค: debug, info, warn, error.


๊ธฐ์ˆ  ์Šคํƒ ์š”์•ฝ

ํ•ญ๋ชฉ ์„ ํƒ ๋ฒ„์ „
์–ธ์–ด Go 1.25
์›น ํ”„๋ ˆ์ž„์›Œํฌ labstack/echo v4.15
gRPC google.golang.org/grpc v1.79
WebSocket gorilla/websocket v1.5
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„ lib/pq v1.11
์Šค์ผ€์ค„๋Ÿฌ robfig/cron v3
์˜ค๋ธŒ์ ํŠธ ์Šคํ† ๋ฆฌ์ง€ minio/minio-go v7
JWT golang-jwt/jwt v5
๋กœ๊ฑฐ rs/zerolog v1.34
CLI spf13/cobra v1.10

Identity Service: ๋ฉ€ํ‹ฐํ”Œ๋žซํผ ์‚ฌ์šฉ์ž ํ†ตํ•ฉ

๊ฐ™์€ ์‚ฌ์šฉ์ž๊ฐ€ ์›น๊ณผ ํ…”๋ ˆ๊ทธ๋žจ์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ๋•Œ ๋™์ผํ•œ user_id๋กœ ๋ฌถ์–ด์ค๋‹ˆ๋‹ค.

ํ…”๋ ˆ๊ทธ๋žจ chat_id: 12345  โ”€โ”€โ–ถ platform_identities โ”€โ”€โ–ถ user_id: "abc-uuid"
์›น session_id: "xxx"    โ”€โ”€โ–ถ platform_identities โ”€โ”€โ–ถ user_id: "abc-uuid"

๊ณ„์ • ์—ฐ๊ฒฐ ํ๋ฆ„:

  1. ํ…”๋ ˆ๊ทธ๋žจ์—์„œ /link ๋ช…๋ น ์ž…๋ ฅ
  2. 10๋ถ„ ์œ ํšจ ์—ฐ๊ฒฐ ์ฝ”๋“œ NION-XXXXXX ๋ฐœ๊ธ‰
  3. ์›น์—์„œ POST /auth/link { "code": "NION-XXXXXX" } ํ˜ธ์ถœ
  4. ๋‘ ํ”Œ๋žซํผ์ด ๊ฐ™์€ user_id๋กœ ํ†ตํ•ฉ๋จ

Copyright © 2025 StarNion. All rights reserved.  |  v0.1.1