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"
๊ณ์ ์ฐ๊ฒฐ ํ๋ฆ:
- ํ
๋ ๊ทธ๋จ์์
/link๋ช ๋ น ์ ๋ ฅ - 10๋ถ ์ ํจ ์ฐ๊ฒฐ ์ฝ๋
NION-XXXXXX๋ฐ๊ธ - ์น์์
POST /auth/link { "code": "NION-XXXXXX" }ํธ์ถ - ๋ ํ๋ซํผ์ด ๊ฐ์
user_id๋ก ํตํฉ๋จ