[핵심 모듈 (lib/ebay-tools/)] - types.ts: 검색 요청/결과/크롤링/가격 공통 타입 정의 - crawler.ts: RockAuto HTTP 크롤러 + eBay 검색 (cheerio, UA 로테이션) - ai-analyzer.ts: Claude API Tool Use로 크롤링 결과 구조화 (lazy 클라이언트, 런타임 검증) - pricing.ts: 환율 API 연동 + HS Code 관세 + VAT + 소액면세 계산 [검색 API] - Mock 데이터 → 실제 크롤링+AI+가격 파이프라인으로 교체 - AI 실패 시 fallback 결과 생성 - 입력값 50자 제한 + 허용 문자 검증 [프론트엔드] - 중복 타입 제거 → lib/ebay-tools/types import - 가격 탭에 VAT, 총 수입비용, 면세 여부, 면책 문구 추가 [DB] - 004_ebay_search_history.sql: 검색 이력 테이블 + RLS (anon 전체 권한 제거) [Evaluator 반영] - anon RLS 보안 취약점 수정 - AI 응답 런타임 필드 검증 추가 - Anthropic 클라이언트 lazy 초기화 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
38 lines
1.4 KiB
SQL
38 lines
1.4 KiB
SQL
-- ============================================================
|
|
-- 이베이 부품 검색 이력 테이블
|
|
-- 목적: 검색 결과 캐싱 + 사용자별 검색 이력 관리
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS ebay_search_history (
|
|
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
|
|
part_number VARCHAR(100) NOT NULL,
|
|
part_name VARCHAR(500),
|
|
result JSONB NOT NULL,
|
|
sources_checked TEXT[] DEFAULT '{}',
|
|
processing_time VARCHAR(20),
|
|
ai_model VARCHAR(100),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- 인덱스
|
|
CREATE INDEX IF NOT EXISTS idx_ebay_search_part_number ON ebay_search_history(part_number);
|
|
CREATE INDEX IF NOT EXISTS idx_ebay_search_user ON ebay_search_history(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_ebay_search_created ON ebay_search_history(created_at DESC);
|
|
|
|
-- RLS (로그인 사용자는 본인 이력만 조회)
|
|
ALTER TABLE ebay_search_history ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY "Users view own search history"
|
|
ON ebay_search_history FOR SELECT
|
|
TO authenticated
|
|
USING (auth.uid() = user_id);
|
|
|
|
CREATE POLICY "Users insert own search history"
|
|
ON ebay_search_history FOR INSERT
|
|
TO authenticated
|
|
WITH CHECK (auth.uid() = user_id);
|
|
|
|
-- 서버 사이드 관리자 작업은 service_role 키를 사용하여 RLS를 우회합니다
|
|
-- anon 역할에 전체 권한을 부여하지 않습니다
|