Skip to content

Repository files navigation

Curio

링크·텍스트·사진을 한곳에 모아 AI로 정리하고 다시 찾을 수 있게 만드는 개인 아카이브.

운영 상태

Railway 무료 이용 기간 종료로 백엔드 운영을 일시 중단했습니다.

Vercel 프론트엔드는 남아 있지만, 현재 저장·검색·로그인 등 백엔드 기능은 사용할 수 없습니다.

기획 의도

인터넷과 여러 앱에서 발견한 자료는 메신저, 브라우저 북마크, 사진첩처럼 서로 다른 곳에 흩어지기 쉽습니다. Curio는 이 자료들을 하나의 아카이브에서 종합적으로 관리하고, 나중에 필요한 순간에 다시 찾을 수 있게 만드는 것을 목표로 시작했습니다.

MVP에서는 별도의 입력 화면을 매번 열지 않아도 되도록 카카오톡을 첫 번째 수집 채널로 선택했습니다. 이후 웹에서도 링크·텍스트·사진을 직접 저장할 수 있도록 확장해 핵심 흐름인 수집 → AI 정리 → 검색 → 수정을 구현했습니다.

첫 번째 사용자군은 개발·취업 자료와 레퍼런스를 자주 모으는 IT 취업 준비생과 주니어 개발자입니다.

현재 구현된 기능

자료 수집

  • 카카오톡 저장 — 오픈빌더 챗봇에 링크·텍스트·사진을 보내면 즉시 접수 응답을 반환하고 비동기로 저장합니다.
  • 웹 직접 추가 — 웹 아카이브에서 링크·텍스트·이미지를 선택해 바로 저장할 수 있습니다.
  • 링크 메타데이터 수집 — OG 태그에서 제목·설명·썸네일을 수집하고, 유튜브 링크는 oEmbed를 사용합니다.
  • 이미지 보관 — 카카오톡 또는 웹에서 받은 이미지를 검증한 뒤 AWS S3에 저장합니다.
  • 중복 링크 방지 — 추적 파라미터만 제거하는 URL 정규화로 같은 링크의 중복 저장을 막습니다.

AI 정리

  • 링크·텍스트 분류 — Google Gemini가 개발, 커리어·취업, 기타 카테고리와 키워드 태그를 생성합니다.
  • 이미지 비전 분류 — 이미지 내용을 분석해 한 줄 캡션, 카테고리, 태그를 함께 생성합니다.
  • 안전한 실패 처리 — AI 호출이 실패하면 임의의 카테고리로 오염시키지 않고 미분류 상태로 남깁니다.
  • 사용자 수정 보호 — 사용자가 직접 고친 제목과 카테고리는 재크롤링이나 재분류가 덮어쓰지 않습니다.

열람과 편집

  • 카드형 아카이브 — 저장한 자료를 카드 피드로 확인하고 카테고리별로 필터링할 수 있습니다.
  • 통합 검색 — 제목, 본문, 태그를 기준으로 검색할 수 있습니다.
  • 상세 편집 — 제목과 메모를 수정하고 카테고리를 정정하거나 태그를 추가·삭제할 수 있습니다.
  • 텍스트 편집 — 저장한 텍스트의 전체 본문을 상세 화면에서 확인하고 수정할 수 있습니다.
  • 원문 연결 — 링크 아이템의 썸네일을 통해 원문을 열 수 있습니다.

계정과 운영

  • 카카오 로그인 — 카카오 OAuth2와 JWT를 사용하며 Refresh Token은 httpOnly 쿠키로 관리합니다.
  • 공지와 팝업 — 사용자는 공지를 확인할 수 있고, 관리자는 공지와 진입 팝업을 관리할 수 있습니다.
  • 관리자 권한 분리 — 허용된 카카오 계정만 관리자 API와 화면에 접근할 수 있습니다.

다음 단계

아래 항목은 Curio의 제품 방향이며 아직 구현되지 않았습니다.

  • 모바일 공유 — 다른 앱의 공유 메뉴에서 링크·텍스트·사진을 Curio로 바로 보내기
  • 빠른 캡션 — 저장 전후에 짧은 설명을 더 적은 동작으로 입력하기
  • 안전한 카드 동작 — 카드를 잘못 눌러 원문으로 이동하지 않도록 상세 보기와 원문 열기를 명확히 분리하기
  • 사진 다시 저장 — Curio에 보관된 이미지를 기기의 사진첩이나 파일로 내보내기
  • 북마크와 재발견 — 중요한 자료를 별도로 표시하고, 잊고 있던 자료를 다시 꺼내보기

카카오톡은 Curio 자체가 아니라 여러 수집 채널 중 먼저 구현한 하나의 채널입니다. 웹은 아카이브를 관리하는 중심 화면으로 유지하고, 모바일 환경에서는 수집과 재방문을 더 빠르게 만드는 방향으로 확장할 예정입니다.

동작 구조

카카오 오픈빌더 스킬 서버는 5초 이내에 응답해야 합니다. Curio는 요청을 받으면 먼저 접수 응답을 반환하고, 크롤링·AI 분류·이미지 업로드·저장은 비동기로 처리합니다.

카카오톡
   │
   ▼
KakaoController ── 즉시 접수 응답
   │
   ▼
QueueService
   │
   ▼
ItemProcessor ── 크롤링 · AI 분류 · S3 업로드 · 저장

웹에서 직접 추가한 자료는 같은 크롤링·분류·저장 로직을 공유합니다. 큐는 인터페이스로 분리해 현재의 @Async 구현을 이후 Redis Stream 등으로 교체할 수 있게 구성했습니다.

상세한 판단 근거와 트레이드오프는 아키텍처 결정 기록에 정리했습니다.

기술 스택

구분 기술
백엔드 Java 21, Spring Boot 3.5, Gradle
데이터 MySQL 8, Redis, Hibernate JPA
인증 Kakao OAuth2, JWT, httpOnly Cookie
AI Google Gemini gemini-2.5-flash
파일 AWS S3
프론트엔드 React, Vite, Tailwind CSS, Zustand
API 문서 SpringDoc OpenAPI
배포 이력 Railway(Docker), Vercel, GitHub Actions

저장소 구조

curio/
├── backend/                    # Spring Boot API와 비동기 처리 파이프라인
├── frontend/                   # React 웹 아카이브
├── docs/
│   ├── architecture-decisions.md
│   └── testing.md
├── docker-compose.yml          # 로컬 MySQL과 Redis
├── DEPLOY.md                   # 배포 구성과 체크리스트
└── curio-implementation-plan.md

로컬 실행

Java 21, Node.js, Docker가 필요합니다. 환경 변수의 이름과 설명은 루트의 .env.example을 참고합니다.

# 1. MySQL + Redis
docker-compose up -d

# 2. 백엔드
cd backend
./gradlew bootRun

# 3. 프론트엔드
cd frontend
npm install
npm run dev

백엔드는 기본적으로 http://localhost:8080, 프론트엔드는 http://localhost:5173에서 실행됩니다.

테스트와 품질 관리

  • URL 판별·정규화·문자열 처리 등 순수 함수 단위 테스트
  • 서비스와 비동기 처리 파이프라인의 Mockito 테스트
  • Spring MVC·JPA 슬라이스 테스트
  • JWT 발급·검증과 인증 필터 테스트
  • 실제 카카오톡 링크·텍스트·사진 페이로드 라우팅 테스트
  • 사용자 편집 보호, 이미지 비전 분류, 태그 동시 생성 테스트

테스트를 도입하며 유튜브 URL 중복 판정, AI 태그 중복, 카카오 발화 URL 추출, 미인증 응답 코드 등의 실제 버그를 발견하고 수정했습니다. 테스트 전략과 범위는 테스트 문서에 기록했습니다.

cd backend
./gradlew test

AI와 협업한 방식

Curio는 Claude Code와 Codex를 개발 보조 도구로 사용하면서, 결과물뿐 아니라 사람이 판단한 맥락과 결정 과정도 저장소에 남기는 방식으로 진행했습니다.

  • 프로젝트 규칙과 현재 구조를 컨텍스트 문서로 관리
  • 반복되는 로컬 실행·문서 동기화 작업을 재사용 가능한 스킬로 구성
  • 중요한 선택은 아키텍처 결정 기록에 이유와 대안을 함께 기록
  • AI가 작성한 변경을 테스트와 코드 리뷰로 검증
  • 새 세션에서도 이전 결정과 남은 작업을 이어갈 수 있도록 진행 기록 유지

목표는 AI에 구현을 맡기는 것이 아니라, 반복 작업을 줄이고 사람이 제품 범위와 기술적 트레이드오프를 더 명확하게 판단하는 것입니다.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages