Reve AI
데이터 분석

Supabase + Claude Code로 사용자 행동 분석 파이프라인 만들기

레브AI 보조3분 읽기

GA4·Amplitude 같은 도구는 좋지만 커스텀 이벤트·조인 분석에는 한계가 있다. Supabase의 Postgres를 이벤트 스토어로 쓰면 "내가 원하는 그대로의 분석"이 가능해진다.

왜 Supabase인가

  • 데이터 소유: 이벤트 원본이 내 DB에 있다 (GA는 Google 서버)
  • SQL 분석: BI 도구 없이 쿼리로 모든 분석 가능
  • 비용: Free 티어로도 월 100만 이벤트 여유
  • 연동 편함: 프론트·백엔드 이미 Supabase라면 별도 설정 거의 없음

이벤트 테이블 스키마

create table events (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users on delete set null,
  session_id text not null,
  event_name text not null,
  properties jsonb default '{}'::jsonb,
  created_at timestamptz default now()
);

create index idx_events_user_time on events(user_id, created_at desc);
create index idx_events_name_time on events(event_name, created_at desc);
create index idx_events_props on events using gin (properties);

핵심은 properties jsonb — 유연한 속성 저장.

프론트엔드 트래킹 헬퍼

// lib/track.ts
import { createClient } from "@/lib/supabase/client";

export async function track(name: string, props: Record<string, unknown> = {}) {
  const supabase = createClient();
  const { data: { session } } = await supabase.auth.getSession();
  const sessionId = getSessionId(); // localStorage 기반

  await supabase.from("events").insert({
    user_id: session?.user.id ?? null,
    session_id: sessionId,
    event_name: name,
    properties: props,
  });
}

사용:

track("cta_click", { location: "home_hero", destination: "/contact" });

Claude Code로 분석 쿼리 뽑기

여기가 핵심이다. 쿼리를 Claude에게 위임한다.

프롬프트:

"events 테이블에서 지난 7일간 cta_click 이벤트의 location 별 집계를 뽑아줘. 유니크 사용자 수와 클릭 수를 함께."

Claude 응답:

select
  properties->>'location' as location,
  count(*) as clicks,
  count(distinct coalesce(user_id::text, session_id)) as unique_users,
  round(count(*)::numeric / count(distinct coalesce(user_id::text, session_id)), 2) as clicks_per_user
from events
where event_name = 'cta_click'
  and created_at >= now() - interval '7 days'
group by properties->>'location'
order by clicks desc;

퍼널 분석

프롬프트:

"홈 방문 → 서비스 페이지 → 문의 제출 퍼널의 각 단계 전환율을 뽑아줘"

Claude 응답 (CTE로):

with funnel as (
  select
    session_id,
    max(case when event_name = 'page_view' and properties->>'path' = '/' then 1 else 0 end) as step1,
    max(case when event_name = 'page_view' and properties->>'path' like '/services%' then 1 else 0 end) as step2,
    max(case when event_name = 'contact_submit' then 1 else 0 end) as step3
  from events
  where created_at >= now() - interval '7 days'
  group by session_id
)
select
  sum(step1) as visited_home,
  sum(step2) as visited_services,
  sum(step3) as submitted_contact,
  round(sum(step2)::numeric / nullif(sum(step1), 0) * 100, 1) as home_to_services_pct,
  round(sum(step3)::numeric / nullif(sum(step2), 0) * 100, 1) as services_to_contact_pct
from funnel;

실시간 대시보드 구축

Supabase Realtime으로 라이브 모니터링:

const channel = supabase
  .channel("events")
  .on("postgres_changes",
    { event: "INSERT", schema: "public", table: "events" },
    (payload) => updateDashboard(payload.new)
  )
  .subscribe();

어드민 페이지에서 방금 일어난 이벤트를 실시간으로 볼 수 있다.

GA4와의 역할 분담

도구담당
GA4전체 트래픽·획득 채널·기본 전환
Supabase events커스텀 플로우·유저별 journey·서버 이벤트
Clarity세션 리플레이·히트맵 (UI 이슈 발견)

세 개가 겹치지 않고 보완 관계. 각자 가장 잘하는 영역만 맡긴다.

주의할 점

  1. 개인정보 수집 금지 필드: 입력 값·내부 DB ID는 properties에 넣지 말 것
  2. 이벤트 수 폭증 방지: 스크롤·마우스 무브는 샘플링 또는 제외
  3. 보존 기간: 90일 이상 데이터는 월별 집계 테이블로 요약 후 삭제

결론: "GA로는 부족한데 BI는 과한" 중간 지점이 있다. Supabase + Claude Code가 정확히 그 자리를 채운다.

#Supabase#Claude Code#데이터 분석#이벤트 트래킹#퍼널

새 글을 이메일로 받아보세요

AI·데이터·서비스 기획 실전 글을 주 1-2회 발행합니다.

이런 문제로 고민 중이신가요?

30분 상담으로 해결 방향을 잡아드립니다.