TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
이력서 PDF 하나 던지는 대신, 나와 대화할 수 있는 링크를 내보세요. 이력서를 입력하면 그 내용만 근거로 답하는 AI 클론 이 만들어지고, /@슬러그 주소 하나로 웹 이력서 + 실시간 채팅 을 공유합니다. 데모는 로그인 없이 볼 수 있습니다. @kimdev는 코드에 넣어 둔 가상의 프론트엔드 개발자 "김개발" 이고, 실제 사용자 데이터는 노출되지 않습니다. PDF 이력서는 끝까지 읽히기 어렵고, 웹 포트폴리오는 정적이라 "이 사람한테 직접 물어보고 싶은 것" 을 확인할 방법이 없습니다. CloneCV는 이력서에 있는 사실만 근거로 1인칭으로 답하는 AI를 붙여, 면접관의 경험을 읽기 → 대화로 바꾸는 실험입니다. 핵심 과제는 "그럴듯하게 말하는 챗봇"이 아니라 이력서에 없는 말을 지어내지 않는 챗봇을 만드는 것이었습니다. • 웹 이력서 열람(데스크톱 섹션 내비게이션, 모바일 대응) + 포트폴리오 이미지 · PDF · 영상 • AI 채팅 — 스트리밍 답변, 이력서에 근거가 있는 추천 질문 3개, 답하기 어려우면 직접 문의 폼 • 카카오톡 · X · 링크 공유README 전문 보기 ↗
데모는 로그인 없이 볼 수 있습니다.
@kimdev는 코드에 넣어 둔 가상의 프론트엔드 개발자 "김개발" 이고, 실제 사용자 데이터는 노출되지 않습니다.
| 기간 | 2026.07 ~ 2026.09 (진행 중) |
| 인원 | 1인 개발 — 기획 · 설계 · 프론트엔드 · 백엔드 · DB · 배포 |
| 개발 방식 | 요구사항 → 기능 명세 → 아키텍처 문서를 먼저 쓰고, AI 페어 프로그래밍(Cursor → Claude Code)으로 구현 |
| 주요 기술 | Next.js 16 · React 19 · TypeScript · Supabase(Postgres, RLS, pgvector) · Gemini · Upstash Redis |
| 규모 | 기능 명세 F-01 ~ F-33 · DB 마이그레이션 26개 · 단위 테스트 213개 · Playwright E2E 4종 |
| 운영 비용 | Gemini · Upstash · Supabase 무료 티어 안에서 운영 |
PDF 이력서는 끝까지 읽히기 어렵고, 웹 포트폴리오는 정적이라 "이 사람한테 직접 물어보고 싶은 것" 을 확인할 방법이 없습니다. CloneCV는 이력서에 있는 사실만 근거로 1인칭으로 답하는 AI를 붙여, 면접관의 경험을 읽기 → 대화로 바꾸는 실험입니다. 핵심 과제는 "그럴듯하게 말하는 챗봇"이 아니라 이력서에 없는 말을 지어내지 않는 챗봇을 만드는 것이었습니다.
면접관(방문자) — 로그인 없이 /@슬러그
지원자(소유자)
/@my-name 형태의 고유 주소/dashboard/edit) — 10개 섹션, 사이드바에서 순서 변경·섹션 on/off
published 상태로 전환/dashboard)
/dashboard 디자인 탭)
/@슬러그 접속 — 로그인 없음@kimdevflowchart LR
V["면접관<br/>/@slug"] --> PX
O["지원자<br/>/dashboard"] --> PX
subgraph VC["Vercel · Next.js 16 App Router"]
PX["proxy.ts<br/>/@slug → /[id] rewrite<br/>세션 갱신 · 관리자 확인"]
RSC["Server Components<br/>공개 프로필 · 대시보드"]
API["Route Handlers<br/>/api/chat · /api/prompt/generate<br/>/api/resume/import-pdf · export-pdf"]
end
PX --> RSC
PX --> API
subgraph SB["Supabase"]
AUTH["Auth<br/>이메일 · Google OAuth"]
DB[("Postgres + RLS<br/>pgvector")]
ST["Storage<br/>사진 · 포트폴리오"]
end
RSC --> DB
API --> AUTH
API --> DB
API --> ST
API --> GM["Google Gemini<br/>채팅 스트리밍 · PDF 추출 · 임베딩"]
API --> RD["Upstash Redis<br/>레이트리밋"]
발행 시점에 무거운 일을 끝내 둡니다. 소유자가 발행하면 /api/prompt/generate가 한 번에 처리합니다.
system_prompts.coverage(jsonb)에 저장합니다.gemini-embedding-001(768차원)로 pgvector 색인을 만듭니다.덕분에 채팅 요청 경로에서는 추가 계산이나 DB 조회 없이 저장된 결과만 읽습니다.
lib/chat/handle-chat-request.ts)sequenceDiagram
autonumber
participant B as 방문자 브라우저
participant C as /api/chat
participant R as Upstash
participant D as Supabase
participant G as Gemini
B->>C: 질문 (500자 이하)
C->>R: 레이트리밋 (분당 5 · 일 50)
C->>D: 시스템 프롬프트 + coverage, FAQ, RAG 청크 병렬 조회
Note over C: FAQ와 맞으면 준비된 답변 블록 주입<br/>아니면 관련 청크 focus 블록 (플래그 on일 때)
C->>G: 스트리밍 생성 (실패 시 다음 모델로 폴백)
G-->>B: SSE로 토큰 전달
Note over C: 민감정보 필터 → 거절 답변인지 판정
alt 답변 성공
C->>G: 꼬리질문 생성
Note over C: coverage로 검증하고<br/>부족하면 답변 가능한 질문으로 채움
else 거절
C-->>B: 직접 문의 폼 제안 (2차 호출 생략)
end
C->>D: chat_messages 기록 (answer_status · 모델 · 토큰)
C-->>B: 다음 추천 질문 3개
RAG_RETRIEVAL_ENABLED 플래그로 제어 (기본 off = 전체 컨텍스트 방식, 색인은 항상 수행)GEMINI_MODELS 체인의 다음 모델로 재시도인사말은 짧게 고정되어 있습니다.
안녕하세요, {이름}의 AI 챗봇입니다! 궁금하신 점이 있으시면 편하게 물어보세요.
| 선택 | 이유 | 대안 |
|---|---|---|
| Supabase | Auth · Postgres · Storage · RLS · pgvector를 한 서비스로 해결, 1인 개발에서 백엔드 서버 운영 부담 제거 | 별도 API 서버 + ORM |
| 전체 컨텍스트 프롬프트 (기본값) | 한 사람의 이력서는 분량이 작아 통째로 넣는 쪽이 더 단순하고 정확함. 벡터 색인은 미리 쌓고 주입만 플래그로 | 처음부터 벡터 검색 RAG |
| 템플릿 조합 시스템 프롬프트 | 발행 시 한 번만 조립, LLM이 이력서를 재작성하지 않아 환각 여지와 비용이 줄어듦 | LLM으로 페르소나 요약 생성 |
| 규칙 기반 coverage 엔진 | 결정론적이라 단위 테스트가 가능하고 API 쿼터를 쓰지 않음 | 임베딩 유사도로 답변 가능성 판정 |
| Upstash Redis | 서버리스 인스턴스 사이에 공유되는 카운터가 필요 | 인메모리 카운터 (인스턴스마다 초기화) |
| Gemini | 채팅 · PDF 추출 · 임베딩을 SDK 하나로, 무료 티어 안에서 운영 가능 | — |
lib/chat/question-coverage.ts — 근거 필드가 채워진 질문만 만드는 결정론적 coverage 엔진. 발행 시 계산해 저장하므로 채팅 경로의 추가 DB 조회는 0회입니다.lib/chat/follow-up.ts — LLM이 만든 꼬리질문을 같은 기준으로 걸러내고, 부족한 수는 답변 가능한 질문으로 채웁니다. 직전 답변이 거절이면 Gemini 2차 호출 자체를 건너뜁니다.chat_messages에 answer_status 등을 기록해 대시보드에 답변하지 못한 질문 카드를 만들었습니다.lib/public-profile/sanitize-public-profile.ts에서 서버 단계에서 필드를 지웁니다. 생년은 아예 빼고 나이대 라벨만 내보내며, 전화번호는 공개 설정일 때만 포함합니다.lib/ 아래 테스트 4개를 실행하지 않던 문제lib/auth/safe-redirect.ts) 등 보안 점검을 이어서 진행했습니다.lib/chat/token-budget.ts
countTokens를 부르면 왕복 시간과 무료 쿼터를 쓰므로, 문자 수 기반으로 보수적으로 추정합니다(한국어 기준 ÷1.5, 과대 추정 쪽으로).lib/theme/css-vars.ts가 globals.css와 같은 토큰 이름을 덮어씁니다. 주입 지점은 public-profile-body.tsx 한 곳이라 공개 페이지 · 빌더 미리보기 · 디자인 편집기가 함께 적용됩니다.--font-sans: var(--font-sans) 자기 참조 때문에 지정한 글꼴이 처음부터 적용된 적이 없었습니다. 한글 글리프가 있는 Pretendard로 교체했습니다.lg:는 실제 뷰포트 기준으로 걸려 레이아웃이 깨졌습니다. narrow prop으로 해결했습니다.tests/ 도메인별 + lib/ 인접 테스트)docs/)CLAUDE.md에 작업 원칙을, .claude/skills에 문서 · 품질 점검 · PR 작성 역할을 분리해 두고 사용합니다데스크톱은 상단 히어로 + 이력서 본문 구조에 우측 섹션 내비게이션이 붙고, 채팅은 우하단 플로팅 버튼으로 엽니다.
데스크톱 (/@kimdev)
모바일
10개 섹션 순서 변경 · on/off, 자동 저장, 완성도 카드, PDF 가져오기, 공개 화면 미리보기.
공개 주소 · 링크 복사 · 공개 토글은 상단에 고정되고, 한눈에 보기 위젯이 완성도 · AI 답변 준비율 · 최근 대화 · 답변하지 못한 질문을 보여 줍니다.
프리셋 · 색 · 글꼴 · 사진 모양 · 카드 스타일을 고르면 실제 공개 화면으로 된 미리보기에 즉시 반영됩니다.
대화 로그
통계
받은 질문
회원가입 (이메일 · Google OAuth)
로그인
온보딩 (슬러그 설정)
로그인 없이 보는 예시 경로: /demo/onboarding · /demo/dashboard · /demo/dashboard/edit
배운 점
아직 손볼 부분
test:e2e:rag)로 임계값을 검증한 뒤 기본 on 검토전체 backlog: docs/07_현황감사.md
npm install
cp .env.local.example .env.local # 키 입력
npm run db:push # 마이그레이션 적용
npm run dev
환경변수는 .env.local.example 참고.
프로덕션 출시 전: docs/10_프로덕션_체크리스트.md
| 명령 | 설명 |
|---|---|
npm run dev | 개발 서버 |
npm run build | 프로덕션 빌드 |
npm run test | Vitest |
npm run test:e2e | Playwright smoke |
npm run test:e2e:integration | Playwright 통합 (발행→채팅) |
npm run test:e2e:screenshots | README 스크린샷 갱신 |
npm run test:e2e:rag | RAG 골든 질문 회귀 |
npm run db:push | Supabase 마이그레이션 |
npm run db:types | types/database.ts 재생성 |
| # | 파일 | 요약 |
|---|---|---|
| 1 | 20260705150000_initial_schema.sql | 초기 스키마, RLS, auth 트리거 |
| 2 | 20260705160000_avatars_storage.sql | 프로필 사진 Storage |
| 3 | 20260705170000_profile_daily_stats.sql | 일별 조회 통계 |
| 4 | 20260705180000_admin_moderation.sql | 관리자·모더레이션 |
| 5 | 20260705190000_reports_resolution.sql | 신고 처리 상태 |
| 6 | 20260705200000_resume_data_expansion.sql | 경력·학력·연락처 등 |
| 7 | 20260705210000_profile_enabled_sections.sql | 섹션 on/off |
| 8 | 20260706000000_owner_faqs.sql | 예상 질문 답변 |
| 9 | 20260706120000_resume_sections_expansion.sql | 학력·자격·활동 분리 |
| 10 | 20260706130000_skills_sort_order.sql | 기술 스택 정렬 |
| 11 | 20260706140000_profile_section_order.sql | 섹션 표시 순서 |
| 12 | 20260707000000_korean_market_improvements.sql | PII 토글, 문의, 채팅 세션 타입 |
| 13 | 20260708000000_profile_links_replace_external_sources.sql | 외부 링크 테이블, RSS 연동 제거 |
| 14 | 20260714100000_multi_profiles.sql | 다중 프로필(3개), owner_id RLS |
| 15 | 20260714110000_profile_label.sql | 프로필 라벨 |
| 16 | 20260715100000_mvp_security_hardening.sql | RLS·RPC 보안 강화 |
| 17 | 20260911100000_drop_legacy_portfolios.sql | 미사용 portfolios 잔재 제거 |
| 18 | 20260911110000_portfolio_items.sql | 포트폴리오 항목 |
| 19 | 20260911120000_portfolio_media_storage.sql | 포트폴리오 미디어 Storage |
| 20 | 20260914100000_system_prompt_token_estimate.sql | 프롬프트 토큰 추정치 기록 |
| 문서 | 내용 |
|---|---|
docs/01_요구사항명세서.md | 문제 정의, 사용자, 요구사항 |
docs/02_기능명세서.md | F-01~F-33 기능 상세 |
docs/04_아키텍처명세서.md | DB·API·프롬프트 구조 |
docs/07_현황감사.md | 코드 vs 명세, backlog |
docs/08_개발일지.md | 세션별 작업 로그 |
docs/09_학습가이드.md | A–Z 학습 (TS/Next 초보용) |
AGENTS.md · CLAUDE.md | 에이전트 역할 · 작업 가이드라인 |
개인 프로젝트. 상업 이용 시 별도 문의.
| 21 | 20260914110000_rag_pgvector.sql | pgvector 임베딩 색인·검색 RPC |
| 22 | 20260914120000_drop_legacy_editor_documents.sql | 미사용 editor_documents 제거 |
| 23 | 20260914130000_projects_tech_stack_jsonb.sql | 프로젝트 기술 스택 jsonb 전환 |
| 24 | 20260918100000_chat_quality_metrics.sql | 답변 성공 여부 계측, 답변 가능 질문 목록 |
| 25 | 20260919100000_chat_token_usage.sql | Gemini 실측 토큰 기록 |
| 26 | 20260920100000_profile_theme_config.sql | 공개 프로필 디자인 설정 |