TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
인스타그램 게시물과 유튜브 영상을 카테고리, 태그, 메모, 후기와 함께 저장하고 검색할 수 있는 개인 웹 서비스. 다시 보고 싶은 인스타그램 게시물과 유튜브 영상을 그때그때 찜해두고, 나중에 카테고리·태그·키워드로 한눈에 찾아보기 위해 만든 개인용 도구. • Frontend: Next.js 16 (App Router, Turbopack), TypeScript, Tailwind CSS v4 • Database: Supabase PostgreSQL + Prisma 7 (@prisma/adapter-pg) • Auth: Supabase Auth (@supabase/ssr) • Storage: Supabase Storage (썸네일 영구 보관) • External APIs: Microlink, iframely (썸네일 추출) • Deploy: Vercel (Seoul icn1 리전) • Icons: Lucide React • Charts: RechartsREADME 전문 보기 ↗
인스타그램 게시물과 유튜브 영상을 카테고리, 태그, 메모, 후기와 함께 저장하고 검색할 수 있는 개인 웹 서비스.
다시 보고 싶은 인스타그램 게시물과 유튜브 영상을 그때그때 찜해두고, 나중에 카테고리·태그·키워드로 한눈에 찾아보기 위해 만든 개인용 도구.
@prisma/adapter-pg)@supabase/ssr)인스타그램 CDN의 썸네일 URL은 만료 시간과 지역 정보가 서명에 박혀 있어, 며칠 지나거나 다른 지역에서 열면 깨집니다. 이를 막기 위해 추출한 이미지를 곧바로 Supabase Storage에 복사해서 영구 URL로 저장합니다. 그래도 만료·삭제 등으로 깨진 썸네일이 보이면 표시 시점에 자동으로 재추출·복구합니다(self-heal).
[콘텐츠 추가 / 저장]
↓
[추출] YouTube → oembed / Instagram·기타 → Microlink → iframely → OG 태그 스크래핑 (폴백 체인)
↓ 성공한 이미지 URL
[이미지 다운로드 → Supabase Storage(reel-thumbnails 버킷) 업로드] ← 실패 시 최대 3회 재시도
↓
[영구 URL을 DB에 저장]
[표시 중 썸네일이 깨지면 (만료·삭제 등)]
↓
[onError 감지 → 서버 재추출 → DB 갱신 → 그 자리서 교체] ← 자가복구(self-heal): 1회만 시도, 실패 시 대체 UI
핵심 코드: src/lib/og.ts, src/lib/thumbnail-cache.ts
src/
├── app/
│ ├── (main)/ # 메인 앱 (max-w-420px 모바일 레이아웃)
│ │ ├── page.tsx # 메인 페이지 (검색, 필터, 콘텐츠 그리드)
│ │ ├── login/ # 로그인
│ │ ├── signup/ # 회원가입
│ │ ├── forgot-password/ # 비밀번호 재설정
│ │ ├── reels/
│ │ │ ├── new/ # 콘텐츠 추가
│ │ │ └── [id]/ # 상세 / 수정
│ │ ├── archive/ # 아카이브
│ │ ├── tags/ # 태그 관리
│ │ ├── categories/ # 카테고리 관리
│ │ └── settings/ # 비밀번호 변경
│ ├── admin/ # 어드민 (풀스크린 레이아웃)
│ │ ├── page.tsx # 대시보드
│ │ └── members/ # 유저 관리 / 탈퇴 관리
│ └── layout.tsx # 루트 레이아웃
├── components/ # 클라이언트 컴포넌트
├── lib/
│ ├── actions.ts # Server Actions (CRUD, 검색)
│ ├── admin-actions.ts # 어드민 Server Actions
│ ├── auth.ts # requireAuth() 헬퍼
│ ├── db.ts # Prisma 클라이언트 (pg Pool + SSL)
│ ├── og.ts # 썸네일 추출 (Microlink/iframely/OG)
│ ├── thumbnail-cache.ts # Supabase Storage 캐싱
│ ├── reel-url.ts # 콘텐츠 URL 정규화 (인스타/유튜브)
│ └── supabase/ # 서버/클라이언트 Supabase 인스턴스
├── middleware.ts # 인증 미들웨어
└── types/ # 공용 TypeScript 타입
scripts/
└── recache-thumbnails.ts # 기존 콘텐츠 썸네일 일괄 재캐싱 스크립트
prisma/
└── schema.prisma # DB 스키마 정의
| 모델 | 설명 |
|---|---|
Reel | 콘텐츠 본체 (url, thumbnail, memo, review, visited, source[instagram/youtube], userId) |
Category | 카테고리 (사용자별 unique) |
Tag | 태그 (사용자별 unique) |
ReelCategory, ReelTag | N:M 매핑 테이블 |
AdminRole | 관리자 권한 |
Withdrawal | 회원탈퇴 이력 |
모든 사용자 데이터는 userId로 격리되어 있고, Reel.url은 사용자 단위로 unique입니다.
# Postgres (Supabase Transaction Pooler — 포트 6543)
DATABASE_URL="postgresql://postgres.xxxx:[email protected]:6543/postgres"
# Supabase 공개 키 (클라이언트/서버 모두)
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci...
# Supabase 서비스 롤 키 (서버 전용, Storage 업로드용)
SUPABASE_SERVICE_ROLE_KEY=eyJhbGci...
# iframely 폴백 API 키
IFRAMELY_API_KEY=your-iframely-api-key
SUPABASE_SERVICE_ROLE_KEY와IFRAMELY_API_KEY는 절대NEXT_PUBLIC_접두사를 붙이지 마세요. 클라이언트 번들에 노출되면 보안 사고로 이어집니다. 두 키 모두 서버 사이드(Server Actions, Route Handlers, Scripts)에서만 사용합니다.
git clone https://github.com/jjub0217/trovely.git
cd trovely
npm install
위 환경변수 섹션을 참고해 .env.local 파일을 만듭니다.
# 마이그레이션은 Session Pooler(포트 5432)로 실행해야 합니다
DATABASE_URL="postgresql://...:5432/postgres" npx prisma migrate deploy
Supabase 대시보드 → Storage → New bucket
reel-thumbnails아래 로컬 개발(Docker + Supabase) 방식으로 띄우면
supabase/seed.sql이 이 버킷을 자동 생성하므로 이 단계는 생략됩니다.
npm run dev
운영 Supabase에 연결하는 대신, 로컬에 Supabase 스택을 Docker로 띄워 개발할 수 있습니다 — 운영 DB를 건드리지 않고 동일한 환경에서 작업합니다.
사전 준비: Docker Desktop + Supabase CLI (brew install supabase/tap/supabase)
supabase start # 로컬 DB(54322)·Studio(54323)·API(54321)·Storage 기동
# supabase/seed.sql이 reel-thumbnails 버킷을 자동 생성
npx prisma migrate deploy # 로컬 DB에 스키마 적용 (.env의 DATABASE_URL이 로컬일 때)
npm run dev
.env를 로컬 값으로 채웁니다 (supabase status로 확인):
DATABASE_URL="postgresql://postgres:[email protected]:54322/postgres"
NEXT_PUBLIC_SUPABASE_URL="http://127.0.0.1:54321"
NEXT_PUBLIC_SUPABASE_ANON_KEY="<supabase status의 ANON_KEY>"
SUPABASE_SERVICE_ROLE_KEY="<supabase status의 SERVICE_ROLE_KEY>"
dev/prod 분리: 로컬 개발은 위 로컬 DB, 운영은 Vercel 환경변수의 클라우드 Supabase를 씁니다. 운영
DATABASE_URL·비밀 키는 Vercel에만 두고 로컬 디스크엔 두지 않습니다. (Prisma CLI는.env만 읽으므로, 로컬 주소를.env에 둬야prisma migrate가 운영을 건드리지 않습니다.) 작업이 끝나면supabase stop(데이터·이미지는 보존).
| 명령어 | 설명 |
|---|---|
npm run dev | 개발 서버 실행 (Turbopack) |
npm run build | 프로덕션 빌드 |
npm run start | 빌드 결과로 서버 실행 |
npm run lint | ESLint 검사 |
npm run recache-thumbnails | 기존 콘텐츠 썸네일을 Storage로 일괄 이전 (최신 50개씩, 매일 실행 권장) |
recache-thumbnails는 외부 라이브러리가 아니라 scripts/recache-thumbnails.ts를 실행하는 별명입니다. Microlink 무료 한도(50/일)에 맞춰 한 번에 50개씩만 처리하므로, 콘텐츠가 많다면 며칠에 걸쳐 매일 한 번씩 실행하면 됩니다.
DATABASE_URL="..." npx prisma migrate deployexport const dynamic = "force-dynamic" 추가 (Next.js 정적 빌드 캐시 회피)package.json에 "postinstall": "prisma generate"가 설정되어 있어야 Vercel 빌드 시 Prisma Client가 자동 생성됨.env.local의 5개 키를 모두 등록해야 함개인 프로젝트로 운영 중이며 별도의 오픈 라이선스는 적용하지 않습니다. 코드 참고는 자유롭게 하시되, 그대로 배포하는 것은 자제 부탁드립니다.