Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>AI Collaboration TrackerNew to Visual Studio Code? Get it now.
AI Collaboration Tracker

AI Collaboration Tracker

saeparan

|
2 installs
| (0) | Free
AI 활용 코딩 과정을 추적하고 분석하는 플러그인
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Supabase Edge Function 설정 가이드

1️⃣ Supabase CLI 설치

# macOS/Linux
brew install supabase/tap/supabase

# Windows (Scoop 사용)
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase

# 또는 npm으로 설치
npm install -g supabase

2️⃣ Supabase 프로젝트 초기화

# 프로젝트 루트에서 실행
supabase init

# 이 명령어가 supabase/ 디렉토리를 생성합니다

3️⃣ Edge Function 생성

# evaluate-session 함수 생성
supabase functions new evaluate-session

# 이 명령어가 다음 파일을 생성합니다:
# supabase/functions/evaluate-session/index.ts

4️⃣ Edge Function 코드 작성

supabase/functions/evaluate-session/index.ts 파일에 앞서 제공한 코드를 복사합니다.

5️⃣ 환경 변수 설정

# .env 파일 생성 (프로젝트 루트)
cat > .env << EOF
GROQ_API_KEY=your_groq_api_key_here
SUPABASE_URL=your_supabase_url
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
EOF

# Supabase 프로젝트에 환경 변수 설정
supabase secrets set GROQ_API_KEY=your_groq_api_key_here

6️⃣ 로컬에서 테스트

# Supabase 로컬 개발 환경 시작
supabase start

# Edge Function 로컬 실행
supabase functions serve evaluate-session

# 다른 터미널에서 테스트
curl -i --location --request POST 'http://localhost:54321/functions/v1/evaluate-session' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"sessionId":"session_123"}'

7️⃣ 프로덕션 배포

# Supabase 프로젝트에 로그인
supabase login

# 프로젝트 연결 (처음 한 번만)
supabase link --project-ref your-project-ref

# Edge Function 배포
supabase functions deploy evaluate-session

# 배포 확인
supabase functions list

8️⃣ CORS 설정 (웹앱에서 호출할 경우)

supabase/functions/evaluate-session/index.ts에 CORS 헤더 추가:

import { serve } from "https://deno.land/std@0.168.0/http/server.ts";

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type",
};

serve(async (req) => {
  // CORS preflight 처리
  if (req.method === "OPTIONS") {
    return new Response("ok", { headers: corsHeaders });
  }

  try {
    // ... 기존 코드 ...

    return new Response(JSON.stringify({ success: true, evaluation }), {
      status: 200,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  } catch (error) {
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});

9️⃣ Groq API 키 발급

  1. Groq Console 접속
  2. 회원가입/로그인
  3. API Keys 메뉴에서 새 키 생성
  4. 무료 티어 자동 적용됨

🔟 데이터베이스 마이그레이션

# SQL 파일 생성
supabase migration new create_tables

# supabase/migrations/에 생성된 파일에 테이블 스키마 작성
# (coding_sessions, session_evaluations 테이블)

# 로컬 DB에 적용
supabase db push

# 프로덕션에 적용
supabase db push --linked

📝 프로젝트 구조 예시

ai-collaboration-platform/
├── .env                           # 로컬 환경 변수
├── .gitignore                     # .env 반드시 포함!
├── supabase/
│   ├── functions/
│   │   └── evaluate-session/
│   │       └── index.ts           # Edge Function
│   ├── migrations/
│   │   ├── 20240115000001_create_coding_sessions.sql
│   │   └── 20240115000002_create_session_evaluations.sql
│   └── config.toml
├── vscode-extension/
│   ├── src/
│   │   └── extension.ts
│   ├── package.json
│   └── tsconfig.json
└── README.md

⚠️ 주의사항

  1. 환경 변수 보안: .env 파일은 절대 Git에 커밋하지 마세요
  2. API 키 관리: Groq API 키는 Supabase Secrets로 관리
  3. 로컬 테스트: 배포 전 반드시 로컬에서 테스트
  4. 에러 처리: Edge Function에 적절한 에러 핸들링 추가

🔍 유용한 명령어

# Edge Function 로그 확인
supabase functions inspect evaluate-session

# Edge Function 삭제
supabase functions delete evaluate-session

# 모든 시크릿 보기
supabase secrets list

# 특정 시크릿 삭제
supabase secrets unset GROQ_API_KEY

🎯 문제 생성 API 사용법 (generate-problem)

개요

generate-problem Edge Function은 Groq AI를 사용하여 실무 중심의 코딩 문제 또는 비즈니스 시나리오 기반 엑셀 문제를 자동으로 생성하고, Supabase의 challenges 테이블에 저장합니다.

🎯 주요 특징

코딩 문제:

  • 실제 개발 현장에서 마주칠 법한 시나리오 (API 통합, 데이터 처리, 에러 핸들링 등)
  • 상세한 starter_code (30-100줄) 제공:
    • 타입 정의/인터페이스
    • 헬퍼 함수 스켈레톤
    • 한국어 상세 주석
    • TODO 주석으로 구현 영역 표시
    • 예제 테스트 케이스

엑셀 문제:

  • 실제 비즈니스 상황 (매출 분석, 재고 관리, 재무 보고 등)
  • 현실적인 샘플 데이터 (최소 10-20행)
  • 실무에서 사용되는 Excel 기능 활용

API 엔드포인트

POST https://your-project-ref.supabase.co/functions/v1/generate-problem

요청 형식

헤더

Authorization: Bearer YOUR_ANON_KEY
Content-Type: application/json

요청 본문 (코딩 문제)

{
  "topic": "이진 탐색",
  "type": "coding",
  "difficulty": "medium",
  "language": "Python"
}

요청 본문 (엑셀 문제)

{
  "topic": "VLOOKUP 함수",
  "type": "excel",
  "difficulty": "easy"
}

필수 파라미터

파라미터 타입 필수 여부 설명 예시
type string ✅ 필수 문제 유형 (coding 또는 excel) "coding"
difficulty string ✅ 필수 난이도 (easy, medium, hard) "medium"
category string ⭕ 선택 개발 분야 (아래 참조) "frontend", "backend"
topic string ⭕ 선택 문제 주제 (생략 시 LLM이 자동 선정) "배열", "피벗 테이블"
language string ⭕ 선택 프로그래밍 언어 (coding 타입만 해당, 기본값: Python) "Python", "JavaScript"

카테고리 (category) 옵션

카테고리 설명 예시 주제
frontend 프론트엔드 개발 React 상태 관리, CSS 반응형, 폼 검증, 무한 스크롤
backend 백엔드 개발 REST API, DB 쿼리 최적화, 인증/인가, 캐싱, 레이트 리미팅
fullstack 풀스택 개발 실시간 알림, OAuth 인증, 파일 업로드, 검색 기능
devops DevOps CI/CD 파이프라인, 컨테이너, 모니터링, 로그 분석
data 데이터 엔지니어링 ETL, 데이터 파이프라인, 분석 쿼리, 대용량 처리
mobile 모바일 개발 오프라인 동기화, 푸시 알림, 네이티브 연동, 상태 관리

응답 형식

성공 응답 (200 OK)

{
  "success": true,
  "challenge": {
    "id": "uuid-here",
    "title": "API 응답 캐싱 시스템 구현",
    "track": "coding",
    "difficulty": "medium",
    "description": "주제: API 성능 최적화",
    "problem_statement": "외부 API 호출 비용을 절감하기 위해 LRU 캐시를 활용한 응답 캐싱 시스템을 구현하세요...",
    "test_cases": {
      "examples": [
        {
          "input": "{ url: 'https://api.example.com/users', params: { id: 1 } }",
          "output": "{ data: {...}, cached: false }",
          "explanation": "첫 요청은 실제 API를 호출하고 결과를 캐시에 저장합니다"
        }
      ],
      "constraints": [
        "캐시 크기는 최대 100개 항목으로 제한",
        "동일한 요청은 5분간 캐시된 결과 반환",
        "..."
      ]
    },
    "starter_code": {
      "TypeScript": "/**\n * API 응답 캐싱 시스템\n * LRU (Least Recently Used) 캐시 알고리즘 구현\n */\n\ninterface CacheEntry<T> {\n  data: T;\n  timestamp: number;\n  hitCount: number;\n}\n\ninterface ApiRequestConfig {\n  url: string;\n  params?: Record<string, any>;\n  headers?: Record<string, string>;\n}\n\nclass ApiCache {\n  private cache: Map<string, CacheEntry<any>>;\n  private maxSize: number;\n  private ttl: number; // Time to live in milliseconds\n\n  constructor(maxSize: number = 100, ttl: number = 300000) {\n    this.cache = new Map();\n    this.maxSize = maxSize;\n    this.ttl = ttl;\n  }\n\n  // TODO: 캐시 키 생성 로직 구현\n  private generateCacheKey(config: ApiRequestConfig): string {\n    // 구현 필요\n  }\n\n  // TODO: 캐시에서 데이터 조회\n  async get<T>(config: ApiRequestConfig): Promise<T | null> {\n    // 구현 필요\n  }\n\n  // TODO: 캐시에 데이터 저장\n  set<T>(config: ApiRequestConfig, data: T): void {\n    // LRU 정책에 따라 오래된 항목 제거\n    // 구현 필요\n  }\n\n  // TODO: 만료된 항목 정리\n  private evictExpired(): void {\n    // 구현 필요\n  }\n}\n\n// 사용 예시:\n// const cache = new ApiCache(100, 300000);\n// const result = await cache.get({ url: 'https://api.example.com/users' });\n"
    },
    "tech_stack": ["TypeScript"],
    "is_published": true,
    "created_at": "2026-01-15T09:07:00.000Z"
  },
  "generatedContent": {
    "title": "API 응답 캐싱 시스템 구현",
    "topic": "API 성능 최적화",
    "description": "외부 API 호출 비용을 절감하기 위해...",
    "examples": [...],
    "constraints": [...],
    "starterCode": "..."
  }
}

에러 응답

{
  "error": "Missing required fields: topic, type, difficulty"
}

사용 예시

1. cURL 사용

# 코딩 문제 생성 (주제 지정)
curl -i --location --request POST \
  'https://your-project-ref.supabase.co/functions/v1/generate-problem' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "topic": "동적 프로그래밍",
    "type": "coding",
    "difficulty": "hard",
    "language": "Python"
  }'

# 코딩 문제 생성 (LLM이 주제 자동 선정)
curl -i --location --request POST \
  'https://your-project-ref.supabase.co/functions/v1/generate-problem' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "coding",
    "difficulty": "medium",
    "language": "TypeScript"
  }'

# 프론트엔드 문제 생성
curl -i --location --request POST \
  'https://your-project-ref.supabase.co/functions/v1/generate-problem' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "coding",
    "category": "frontend",
    "difficulty": "medium",
    "language": "TypeScript"
  }'

# 백엔드 문제 생성
curl -i --location --request POST \
  'https://your-project-ref.supabase.co/functions/v1/generate-problem' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "coding",
    "category": "backend",
    "difficulty": "hard",
    "language": "Python"
  }'

# 엑셀 문제 생성
curl -i --location --request POST \
  'https://your-project-ref.supabase.co/functions/v1/generate-problem' \
  --header 'Authorization: Bearer YOUR_ANON_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "topic": "조건부 서식",
    "type": "excel",
    "difficulty": "easy"
  }'

2. JavaScript/TypeScript 사용

const { data, error } = await fetch(
  "https://your-project-ref.supabase.co/functions/v1/generate-problem",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${SUPABASE_ANON_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      topic: "재귀 함수",
      type: "coding",
      difficulty: "medium",
      language: "JavaScript",
    }),
  }
).then((res) => res.json());

if (data.success) {
  console.log("생성된 문제 ID:", data.challenge.id);
  console.log("문제 제목:", data.challenge.title);
}

3. Python 사용

import requests

url = "https://your-project-ref.supabase.co/functions/v1/generate-problem"
headers = {
    "Authorization": f"Bearer {SUPABASE_ANON_KEY}",
    "Content-Type": "application/json"
}
payload = {
    "topic": "그래프 탐색",
    "type": "coding",
    "difficulty": "hard",
    "language": "Python"
}

response = requests.post(url, json=payload, headers=headers)
result = response.json()

if result.get("success"):
    print(f"문제 생성 완료: {result['challenge']['title']}")
    print(f"문제 ID: {result['challenge']['id']}")

로컬 테스트

# 로컬 Supabase 시작
supabase start

# generate-problem 함수 실행
supabase functions serve generate-problem

# 다른 터미널에서 테스트
curl -i --location --request POST \
  'http://localhost:54321/functions/v1/generate-problem' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  --header 'Content-Type: application/json' \
  --data '{
    "topic": "배열 정렬",
    "type": "coding",
    "difficulty": "easy",
    "language": "Python"
  }'

데이터베이스 스키마 (challenges 테이블)

CREATE TABLE challenges (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  title TEXT NOT NULL,
  type TEXT NOT NULL CHECK (type IN ('coding', 'excel')),
  difficulty TEXT NOT NULL CHECK (difficulty IN ('easy', 'medium', 'hard')),
  topic TEXT NOT NULL,

  -- Coding 문제 필드
  description TEXT,
  examples JSONB,
  constraints JSONB,
  starter_code TEXT,
  language TEXT,

  -- Excel 문제 필드
  scenario TEXT,
  data JSONB,
  question TEXT,
  solution TEXT,
  explanation TEXT,

  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

환경 변수 설정

# Groq API 키 설정 (필수)
supabase secrets set GROQ_API_KEY=your_groq_api_key_here

# Supabase URL과 ANON KEY는 자동으로 설정됨

에러 처리

에러 메시지 원인 해결 방법
GROQ_API_KEY is not set Groq API 키 미설정 supabase secrets set GROQ_API_KEY=... 실행
Missing required fields: type, difficulty 필수 파라미터 누락 type, difficulty 전달 (topic은 선택)
Invalid type. Must be "coding" or "excel" 잘못된 type 값 type을 "coding" 또는 "excel"로 설정
Failed to save challenge to database DB 저장 실패 challenges 테이블 존재 여부 확인
Generated content was not valid JSON AI 응답 오류 다시 시도하거나 max_tokens 증가

Examples

curl -i --location --request POST 'https://soqscjpglqbbzxkdtien.supabase.co/functions/v1/generate-problem' --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNvcXNjanBnbHFiYnp4a2R0aWVuIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Njc3Njg5NTQsImV4cCI6MjA4MzM0NDk1NH0.q_zBFkJWaCE1UTc-UwFGLduxUWrpOG-veVaZCR_kCFc' --header 'Content-Type: application/json' --data '{"type":"coding", "topic":"", "difficulty":"medium", "language":"typescript"}'


📦 챌린지 다운로드 기능 (VS Code Extension)

웹 사이트에서 문제를 선택하면 VS Code 플러그인이 자동으로 챌린지를 다운로드하고, 압축을 풀어 바로 코딩을 시작할 수 있습니다.

아키텍처

┌─────────────────────────────────────────────────────────────────────┐
│                              웹 사이트                                │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  📋 문제 목록                                                   │  │
│  │  ├── [Frontend] React 상태 관리 (medium)                       │  │
│  │  ├── [Backend] API 레이트 리미팅 (hard)                        │  │
│  │  └── [Fullstack] 실시간 채팅 (hard)                           │  │
│  │                                                                │  │
│  │  [VS Code에서 열기] 버튼 클릭                                   │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                              │                                       │
│                              ▼                                       │
│            vscode://ai-collaboration-tracker/challenge?id=xxx       │
└─────────────────────────────────────────────────────────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         VS Code Extension                            │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  1. URI Handler가 challenge ID 수신                            │  │
│  │  2. Supabase Storage에서 ZIP 파일 다운로드                     │  │
│  │  3. ~/AIPang-Challenges/{문제명}/ 폴더에 압축 해제             │  │
│  │  4. 새 워크스페이스로 열기                                      │  │
│  │  5. 세션 시작 (코딩 추적 시작)                                  │  │
│  └───────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

사용 방법

1. 웹에서 "VS Code에서 열기" 버튼 클릭

웹 사이트에 다음과 같은 버튼을 추가합니다:

<a href="vscode://ai-collaboration-tracker/challenge?id=챌린지-UUID">
  VS Code에서 열기
</a>

2. VS Code에서 직접 다운로드

  1. Cmd/Ctrl + Shift + P 로 명령 팔레트 열기
  2. "AI Tracker: 챌린지 다운로드" 선택
  3. 챌린지 ID 입력
  4. 자동으로 다운로드 및 워크스페이스 열기

Supabase Storage 설정

챌린지 ZIP 파일은 Supabase Storage에 저장합니다.

1. Storage 버킷 생성

-- Supabase SQL Editor에서 실행
INSERT INTO storage.buckets (id, name, public)
VALUES ('challenges', 'challenges', true);

2. 폴더 구조

challenges/
├── {challenge-id-1}/
│   └── challenge.zip
├── {challenge-id-2}/
│   └── challenge.zip
└── ...

3. ZIP 파일 구조

challenge.zip
├── README.md           # 문제 설명
├── src/
│   └── solution.ts     # 시작 코드
├── tests/
│   └── test.ts         # 테스트 케이스
├── package.json        # 종속성
└── .challenge.json     # 메타데이터 (자동 생성)

웹 사이트에 버튼 추가 예시

// React 예시
function ChallengeCard({ challenge }) {
  const openInVSCode = () => {
    window.location.href = `vscode://ai-collaboration-tracker/challenge?id=${challenge.id}`;
  };

  return (
    <div className="challenge-card">
      <h3>{challenge.title}</h3>
      <p>{challenge.description}</p>
      <span className="badge">{challenge.difficulty}</span>
      <span className="badge">{challenge.track}</span>
      
      <button onClick={openInVSCode}>
        🚀 VS Code에서 열기
      </button>
    </div>
  );
}

프로세스 상세

  1. URI 수신: vscode://ai-collaboration-tracker/challenge?id=xxx
  2. 챌린지 정보 조회: challenges 테이블에서 메타데이터 조회
  3. ZIP 다운로드: Supabase Storage에서 {id}/challenge.zip 다운로드
  4. 압축 해제: ~/AIPang-Challenges/{문제명}/ 폴더에 압축 해제
  5. 메타데이터 생성: .challenge.json 파일 생성 (챌린지 ID, 다운로드 시간)
  6. 워크스페이스 열기: VS Code에서 해당 폴더 열기
  7. 세션 시작 안내: "세션 시작" 버튼으로 코딩 추적 시작

관련 명령어

명령어 설명
AI Tracker: 챌린지 다운로드 ID 입력하여 챌린지 다운로드
AI Tracker: 챌린지 시작 다운로드된 챌린지로 세션 시작
AI Tracker: 세션 종료 코딩 세션 종료 및 평가
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft