리옵트 데이터 문서
플랫폼과 개발

서비스 Plane과 엔드포인트

Next.js control plane과 분리 가능한 data plane 서비스, 주요 API endpoint의 역할을 정리합니다.

리옵트 데이터는 apps/web을 중심으로 동작하지만, 수집과 조회, 실시간, export는 별도 서비스로 분리할 수 있어요. 로컬 개발에서는 fallback으로 단순하게 시작하고, 운영 환경에서는 필요에 따라 plane을 분리합니다.

서비스 plane

서비스역할
apps/webNext.js control plane, 인증 세션, gateway route, docs, UI
apps/ingest-worker로컬 또는 비-Vercel 환경용 background ingest worker
apps/control-api조직, 프로젝트, 대시보드, 빌링 등 control plane API
apps/query-apifunnel, retention, event analysis 등 query plane API
apps/realtime-serviceSSE 전용 스트림 서비스
apps/export-serviceexport 전용 서비스

주요 엔드포인트

엔드포인트역할
POST /api/track이벤트 수집
OPTIONS /api/trackCORS preflight
/api/trpc/*compatibility tRPC gateway
/api/control-trpc/*control plane tRPC gateway
/api/query-trpc/*query plane tRPC gateway
/api/v1/organizations*버전 있는 provisioning/control REST
/api/v1/projects*버전 있는 project provisioning REST
/api/v1/query/*서버 자격증명 기반 analytics REST
GET /api/realtime/[projectId]SSE 실시간 이벤트 스트림
GET /api/export/events이벤트 CSV export
GET /api/healthPostgreSQL, Redis, analytics backend, ingest 상태 확인
GET /api/docs/searchdocs search index
POST /api/webhooks/stripeStripe billing webhook
GET /api/reopt-auth/completeReopt OAuth 완료 후 로컬 세션 생성
GET /api/reopt-auth/e2e/completelocal/test 전용 OAuth completion
POST /api/queues/process-ingestVercel Queue ingest consumer

health endpoint가 보여주는 것

  • PostgreSQL 상태
  • Redis 상태
  • 선택된 analytics backend 상태와 backend 종류 (motherduck 또는 clickhouse)
  • ingest queue provider
  • queue backlog
  • worker heartbeat

health는 단순 프로세스 up/down만 보여주지 않습니다. 수집 파이프라인이 실제로 처리 가능한 상태인지 함께 보여줍니다.

export endpoint 동작

  • EXPORT_SERVICE_URL이 있으면 upstream 서비스로 proxy
  • 없으면 앱 내부 핸들러로 직접 처리

tRPC gateway 분리

/api/trpc/*는 compatibility gateway입니다. 새 호출은 plane에 맞춰 다음 경로를 우선 사용하세요.

  • control plane: /api/control-trpc/*
  • query plane: /api/query-trpc/*

CONTROL_API_URL 또는 QUERY_API_URL이 설정되어 있으면 apps/web은 canonical tRPC 경로뿐 아니라 각 plane의 /api/v1/* REST 경로도 해당 upstream으로 proxy합니다. standalone 서비스도 같은 공유 핸들러를 서빙하므로 fallback과 분리 배포의 응답 계약이 같습니다. 비어 있으면 web process 안의 같은 핸들러가 처리합니다.

Cron과 replay endpoint

운영 작업은 cron route로 노출됩니다.

엔드포인트메서드역할
/api/cron/evaluate-alertsGET알림 조건 평가
/api/cron/sync-usageGETRedis 사용량을 PostgreSQL로 동기화
/api/cron/process-ingestGET로컬/수동 ingest batch 처리
/api/cron/process-ingest/replayGET, POST특정 프로젝트/request/date 범위 raw event replay enqueue
/api/cron/process-ingest/replay-unmaterializedGETmaterialization 누락 raw event replay enqueue
/api/cron/process-ingest/statusGETingest queue 상태와 preview 조회

production에서는 Authorization: Bearer $CRON_SECRET이 필요합니다. 각 cron은 Redis lock을 사용합니다. 이미 같은 scope가 실행 중이면 skipped: true, reason: "locked"로 응답합니다.

Vercel Queue consumer

Vercel 배포에서는 app/api/queues/process-ingest/route.ts가 queue consumer 역할을 합니다.

  • topic: ingest-events
  • max delivery count: 8
  • visibility timeout: 600초
  • retry delay: 지수 backoff, 최대 300초
  • poisoned message는 최대 delivery 이후 acknowledge합니다.

로컬/비-Vercel 환경에서는 apps/ingest-worker가 Redis queue를 처리합니다.

주의할 점

  • CONTROL_API_URL, QUERY_API_URL, REALTIME_SERVICE_URL, EXPORT_SERVICE_URL을 설정하면 apps/web이 해당 서비스로 proxy합니다.
  • pnpm devdev:core는 로컬 fallback을 우선 사용하도록 서비스 URL을 비워 두는 구성이 안전합니다.
  • 분리 배포할 때는 각 plane의 health와 인증 헤더 전달을 함께 확인하세요.
  • cron/replay/status route는 운영 데이터 재처리와 삭제성 작업의 입구가 될 수 있으므로 CRON_SECRET을 반드시 강하게 설정하세요.

다음 단계