Skip to content

ahnbu/my_bookstations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

282 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📚 마이북스테이션 (My BookStation)

서비스 정보

최종 확인: 2026-07-22

항목
서비스 URL https://my-bookstations.vercel.app/
상태 ✅ 정상
호스팅 Vercel (프론트 + /api/search) + Cloudflare Workers (library-checker)
DB Supabase (Postgres) — Auth · RPC · Edge Function 포함
⚠️ 유지 조건 CF Cron이 3일마다 Supabase keep_alive RPC 호출. 이 Worker가 멈추면 7일 후 무료티어 DB가 정지되어 서비스 전체가 중단된다
인증 Supabase Auth (이메일/비밀번호 + OAuth)
외부 API 알라딘 TTB, 도서관 4종(광주시립·경기교육청 등), Gemini
부속 Worker https://library-checker.byungwook-an.workers.dev
배포 방식 library-checker/** 변경 시 GitHub Actions → CF 자동 배포 (프론트는 Vercel 자동)
필요 환경변수 VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY, ALADIN_TTB_KEY(서버 전용), VITE_ALADIN_TTB_KEY(로컬 개발 전용)

알라딘 TTB 키는 프로덕션에서 서버(api/search.ts) 경유로만 사용되며 클라이언트 번들에 포함되지 않는다. VITE_ALADIN_TTB_KEY는 로컬 Vite 프록시 전용이다.


도서 검색 및 도서관 재고 확인 서비스

알라딘 API와 연동하여 도서를 검색하고, 여러 도서관의 재고 현황을 실시간으로 확인할 수 있는 웹 애플리케이션입니다. 개인 서재 관리 기능을 통해 관심 도서를 체계적으로 관리할 수 있습니다.

React TypeScript Vite Supabase Zustand Vercel Cloudflare Workers

🎯 서비스 목표

  • 원스톱 도서 서비스: 검색부터 재고 확인, 개인 관리까지 한 곳에서
  • 실시간 재고 확인: 여러 도서관의 재고 상태를 동시에 확인
  • 개인화된 서재 관리: 독서 상태, 별점, 태그, 즐겨찾기 등 체계적인 도서 관리
  • 편리한 접근성: 직관적인 UI/UX로 누구나 쉽게 사용

✨ 주요 기능

📖 도서 검색

  • 알라딘 API 연동: 제목, 저자, 출판사, 전자책별 검색 및 페이지네이션 지원
  • 검색 결과 필터링: '[세트]'로 시작하는 도서를 자동으로 제외하여 검색 결과의 정확성 향상
  • 상세 정보 제공: 도서 정보, 가격, ISBN, 전자책 유무, 알라딘 구매 링크 등 상세 정보 표시
  • 키워드 통합 검색: 단일 키워드로 여러 도서관의 소장 자료를 한 번에 검색하는 기능

📍 통합 도서 재고 확인

  • 실시간 통합 조회: 종이책(광주 시립도서관), 전자책(경기도 교육청 통합 도서관), 전자책(광주 시립도서관 구독형), 전자책(경기도 전자도서관 API) 재고를 한 번의 요청으로 동시에 확인
  • 커스텀 검색어: 기본 검색어로 조회가 어려운 도서의 경우, 사용자가 직접 검색어를 지정하여 조회 정확도 향상
  • 정확도 높은 재고: "정보없음" 데이터 제외(광주 시립) 등 정확한 정보 제공
  • 도서관 바로가기: 재고 확인 셀 클릭 시, 해당 도서관의 도서 검색 결과 페이지로 바로 이동
  • 재고 새로고침: 클릭 한 번으로 최신 재고 상태 업데이트

연동 도서관 목록

  • 종이책: 광주 중앙, 송정, 오포, 퇴촌 도서관 및 기타 시립도서관
  • 전자책: 경기도 교육청 통합전자도서관, 성남교육도서관
  • 전자책: 광주 시립도서관 구독형(교보문고) 및 소장형
  • 전자책: 경기도 전자도서관 (소장형+구독형 통합)

👤 개인 서재 관리

  • 내 서재: 관심 도서를 개인 서재에 저장 및 관리
  • 독서 기록: 읽음 상태(읽지 않음/읽는 중/완독) 및 별점(1-5점) 기록
  • 🏷️ 커스텀 태그: 사용자 정의 태그 생성/편집/삭제 및 태그 기반 필터링
  • ❤️ 좋아하는 책: 하트 아이콘으로 즐겨찾기 표시 및 필터링
  • 📝 한 줄 메모: 책별로 최대 50자의 간단한 메모 기록 및 수정
  • 🔍 서버 기반 검색: 페이지네이션과 무관하게 DB 전체를 대상으로 제목, 저자별 실시간 검색
  • 다양한 정렬: 추가순, 제목순, 저자순, 출간일순, 별점순, 읽음순 정렬
  • ⚡ 페이지네이션: 사용자 설정(25/50/100/200권)에 따라 초기 데이터를 부분 로딩하여 렌더링 성능 95% 개선
  • 대량 작업: 여러 책을 선택하여 태그 일괄 변경, 삭제 등 대량 작업 지원
  • 일괄 재고 갱신: 내 서재의 모든 책 재고 정보를 한 번에 업데이트 (최신순/오래된순/범위지정, 일시정지/재개/취소 가능)
  • 데이터 내보내기: 서재 데이터를 CSV 파일로 내보내기 (파일명에 날짜 자동 포함)

⚙️ 맞춤 설정 시스템

  • 표시 옵션: 독서 상태, 별점, 태그, 메모, 도서관 재고, 좋아요 아이콘 표시 여부 설정
  • 🌙 테마 시스템: 다크/라이트/시스템 테마 선택
  • 📱 모바일 최적화: 반응형 디자인으로 모든 기기에서 최적화된 경험 제공
  • 기본값 설정: 관리자를 통한 신규 사용자 기본 설정값 관리

🔐 사용자 인증 및 계정 관리

  • Google 소셜 로그인: 간편한 Google 계정 연동
  • 이메일 회원가입/로그인: 이메일과 비밀번호를 통한 인증
  • 계정 관리: 비밀번호 변경, 프로필 관리
  • 안전한 회원탈퇴: 2단계 확인 절차를 통한 계정 삭제 (Supabase Admin API 연동)

💬 사용자 피드백 시스템

  • 의견 보내기: 프로필 메뉴에서 간편한 피드백 전송
  • 보안 강화: Supabase Edge Function을 통해 안전하게 피드백 처리

👨‍💼 관리자 기능

  • 관리자 전용 페이지: 이메일 기반 권한 관리 시스템
  • 주요 기능: 대량 도서 조회, API 테스트 도구, 개발 노트, 신규 사용자 기본값 설정 등

🏗️ 기술 스택

Frontend

  • React 19 & TypeScript
  • Vite: 빠른 개발 서버 및 빌드
  • Tailwind CSS Play CDN + 커스텀 CSS: index.html의 Tailwind CDN과 index.css의 디자인 토큰·공통 클래스를 함께 사용
  • Lucide React: 일관성 있는 아이콘 시스템

State Management

  • Zustand: 경량 상태 관리 (인증, 도서, UI, 설정별 분리)

Backend & Database

  • Supabase: PostgreSQL 데이터베이스, 인증, 실시간 동기화
  • Supabase Edge Functions: 서버리스 로직 (피드백 처리)
  • Cloudflare Workers: 도서관 재고 크롤링 및 키워드 검색 API
  • Vercel Serverless Functions: Aladin API 프록시 처리

Data Validation

  • Zod: 런타임 타입 검증으로 외부 API 응답 안정성 확보

🚀 빠른 시작

필수 조건

  • Node.js 18 이상
  • pnpm
  • Git

설치 및 실행

  1. 저장소 클론
    git clone <repository-url>
    cd my_bookstation
  2. 의존성 설치
    pnpm install
  3. 환경 변수 설정 (.env.local 파일 생성)
    VITE_SUPABASE_URL=your_supabase_url
    VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
    VITE_ALADIN_TTB_KEY=your_aladin_ttb_key
  4. 개발 서버 실행
    pnpm dev
  5. 브라우저에서 확인: http://localhost:5173

🚀 주요 기술적 개선사항

데이터 안정성 및 상태 관리 고도화 (2025-10-25)

  • 🐛 데이터 유실 방지: API가 비정상 응답을 반환할 때 기존 재고 정보가 undefined로 초기화되던 심각한 버그를 수정했습니다. 이제 API 실패 시 기존 데이터를 안전하게 유지합니다.
  • 🔄 상태 동기화: 검색이나 필터로 표시된 책에 대해 '좋아요', 태그 추가/삭제 등 상태 변경이 즉시 반영되지 않던 문제를 해결했습니다. 모든 데이터 소스를 포괄하는 조회 로직을 적용하여 UI 일관성을 확보했습니다.
  • 🎨 태그 시스템 UX 개선: 모든 뷰(책 목록, 상세 모달, 일괄 관리)에서 태그가 '색상 > 인기도 > 이름순'으로 일관되게 정렬되도록 수정했으며, 태그 추가/삭제 시 필터의 카운트가 실시간으로 업데이트되도록 개선했습니다.

성능 및 UX 개선 (2025-10-24)

  • ⚡️ API 응답 캐싱: Cloudflare Cache API를 도입하여 반복적인 재고 조회 요청에 대한 응답 속도를 수 초에서 수십 밀리초 단위로 비약적으로 단축했습니다.
  • 💡 직관적 에러 피드백: 재고 조회 실패 시 상세 모달에서 "조회중..."이 무한 반복되던 버그를 해결하고, 에러 상태를 명확히 표시하도록 UX를 개선했습니다.

커스텀 검색어 및 URL 중앙화 (2025-10-14)

  • 🎯 조회 정확도 향상: 사용자가 직접 도서관 검색어를 지정하는 '커스텀 검색어' 기능 추가.
  • 🛠️ 유지보수성 개선: 여러 컴포넌트에 흩어져 있던 도서관 바로가기 URL 생성 로직을 단일 함수로 중앙화하여 일관성을 확보하고 버그를 수정했습니다.

관리자 시스템 및 계정 관리 (2025-09-15)

  • 관리자 권한 시스템: 이메일 기반의 안전한 관리자 권한 부여.
  • 회원탈퇴 기능: Supabase Admin API를 연동한 2단계 확인 절차로 안전성 강화.
  • Race Condition 버그 수정: 사용자 설정 생성 시 발생하던 동시성 문제를 해결하여 안정성 확보.

DB 아키텍처 리팩토링 및 UX 개선 (2025-11-10)

  • ⚡️ 데이터 안정성 극대화: API의 일시적인 실패에도 기존의 유효한 재고 정보가 유실되지 않도록 데이터베이스 스키마를 리팩토링하고 "선택적 폴백(Fallback)" 데이터 업데이트 전략을 도입했습니다. 이제 한번이라도 조회에 성공한 재고 정보는 API 오류에도 안전하게 보존됩니다.
  • 🎨 UX 일관성 확보: 내 서재 목록에서는 항상 안정적인 마지막 재고 정보를 표시하고(실패 시 빨간색 X), 상세 모달에서만 현재의 갱신 실패 상태를 알려주도록 역할을 분담하여 사용자 경험을 크게 개선했습니다.

백엔드 고도화 및 성능 최적화 (2025-11-08)

  • ⚙️ TypeScript 전환: Cloudflare Worker(백엔드) 코드를 TypeScript로 전면 전환하여 타입 안정성을 확보하고 런타임 에러 발생 가능성을 크게 줄였습니다.
  • 🚀 API 응답 캐싱: Cloudflare Cache API를 도입하여 반복적인 재고 조회 요청에 대한 응답 속도를 수 초에서 수십 밀리초 단위로 99% 이상 단축했습니다.
  • 🛡️ 크롤링 안정성 강화: 도서관 서버의 봇 탐지 정책에 대응하기 위해, 실제 브라우저 헤더를 정교하게 모방하는 2단계 요청 방식을 도입하고 세션 만료 시 자동 복구 로직을 구현하여 크롤링 성공률을 대폭 향상시켰습니다.

데이터 안정성 및 상태 관리 고도화 (2025-10-28)

  • 🐛 데이터 무결성 보장: 책 정보 업데이트(개별/일괄) 시 id, note 등 중요 데이터가 누락되거나 손상되던 근본적인 버그를 해결하여 데이터 일관성을 확보했습니다.
  • 🔄 상태 동기화: 검색이나 필터로 표시된 책에 대해 '좋아요', 태그 추가/삭제 등 상태 변경이 즉시 반영되지 않던 문제를 해결하여 UI 일관성을 확보했습니다.

개발자 빠른 참조

광주시 도서관 조회 예산

  • Cloudflare Worker의 광주시 계열 조회는 종이책(KOLAS)과 시립 소장형 전자책을 병렬로 호출하지 않습니다.
  • 순서는 광주시 종이책 -> 시립 소장형 전자책이며, 두 조회의 합산 예산은 15초입니다.
  • 각 조회는 최대 10초까지만 기다립니다. 종이책 조회가 지연되어 남은 예산이 1초 미만이면 시립 소장형 전자책은 생략하고 기존 저장 재고를 유지합니다.
  • 시립 구독형 전자책, 경기도 교육청, 경기도 전자도서관 조회는 기존처럼 별도 흐름으로 진행됩니다.

태그 데이터 위치

  • 태그 정의(이름, 색상, 목록)는 계정별 user_settings.settings.tagSettings.tags[]에 저장됩니다.
  • 책별 수동·레거시 태그는 user_library.book_data.customTags[], 자동 규칙 결과는 user_library.book_data.autoTags[]에 저장됩니다.
  • 화면 표시와 Supabase RPC의 태그 집계·필터는 두 배열을 병합해 사용합니다.
  • 태그 사용 권수는 get_tag_counts_for_user, 태그 필터링은 get_books_by_tags RPC를 사용합니다.
  • 두 RPC의 병합 SQL 정본은 supabase/20260705_auto_tags_rpc.sql이며, 운영 적용은 별도 승인과 검증이 필요합니다.
  • 상세 구조와 관련 코드는 개발 가이드태그 데이터 모델 섹션을 확인합니다.

PWA(홈 화면 추가)

  • public/manifest.webmanifestpublic/icon-192.png·icon-512.png·icon-maskable-512.png로 홈 화면 추가 시 전용 아이콘과 standalone(전체화면) 실행을 지원합니다.
  • PWA 메타 태그(manifest, theme-color, apple-touch-icon 등)는 index.html <head>에 있습니다.
  • public/ 파일은 빌드 시 dist/ 루트로 복사되어 Vercel에서 절대경로(/manifest.webmanifest 등)로 서빙됩니다.
  • Service Worker·오프라인·푸시는 적용 범위가 아닙니다(온라인 검색 서비스 특성상 제외).

🔗 관련 문서

🤝 기여하기

프로젝트에 기여하고 싶으시다면 이슈를 통해 버그 리포트나 기능 제안을 해주시거나, Pull Request를 통해 코드 기여를 해주세요.

📄 라이선스

이 프로젝트는 MIT 라이선스 하에 배포됩니다.


made by planninghighway 2025

Releases

Packages

Contributors

Languages