🧑‍💻 바이브 코딩

[바이브 코딩 #7] 데이트 코스 추천 서비스 개발기

수구리 2025. 7. 3. 21:33
반응형

DAY7: 달력 컴포넌트, 관리자 유저 관리, 마케팅 동의 시스템 구축

📋 개요

DAY6에서 이미지 업로드 시스템과 장소 등록 기능이 완전히 완성된 후, DAY7에서는 여러 핵심 기능을 동시에 개발했습니다. 사용자 경험 개선을 위한 달력 컴포넌트 구현, 관리자 유저 관리 기능 강화, 마케팅 정보 수신 동의 시스템 구축, 그리고 전체적인 UI/UX 통일 작업까지 진행했습니다.

🎯 DAY7 목표

주요 개발 영역

  1. 달력 컴포넌트 시스템: 기존 HTML date input을 한국어 친화적 달력으로 교체
  2. 관리자 유저 관리 시스템: 유저별 장소 수 집계, 권한 관리 기능 완성
  3. 마케팅 동의 관리: 개인정보보호 강화를 위한 마케팅 정보 수신 동의 토글 시스템
  4. 프로필 시스템 확장: 내정보 페이지 추가 및 사용자 프로필 관리
  5. UI/UX 통일: 일관된 브랜드 경험을 위한 디자인 시스템 정비

🛠 주요 구현 내용

1. 달력 컴포넌트 개발 (app/components/ui/Calendar.tsx)

달력 컴포넌트

핵심 기능

  • 한국어 인터페이스: "2024년 1월", "월/화/수..." 요일 표시
  • 날짜 제한: 오늘 이후 날짜만 선택 가능
  • 시각적 피드백:
    • 오늘 날짜: 보라색 배경으로 강조
    • 선택된 날짜: 진한 보라색 하이라이트
    • 비활성화 날짜: 흐린 표시로 선택 불가 명시
  • 드롭다운 방식: 공간 효율적이고 모바일 친화적

기술적 특징

interface CalendarProps {
  name: string
  label?: string
  value?: string
  onChange?: (date: string) => void
  minDate?: Date
  required?: boolean
  helperText?: string
  className?: string
}
  • React Hooks 활용: useState, useEffect로 상태 관리
  • Form 연동: hidden input으로 기존 폼 시스템과 완벽 호환
  • 접근성 고려: 키보드 네비게이션 및 포커스 관리
  • 타입 안정성: TypeScript로 완전한 타입 정의

2. UI 시스템 개선

유틸리티 함수 추가

// app/utils/cn.ts
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
  • clsx + tailwind-merge: 조건부 클래스명 병합과 Tailwind 충돌 해결
  • 컴포넌트 스타일링: 동적 스타일 적용을 위한 기반 마련

 

2. 관리자 유저 관리 시스템 강화

유저별 장소 수 집계 기능 수정

기존 문제: user.user_metadata.user_places?.length를 참조하여 모든 유저의 장소 수가 0으로 표시

해결 방법:

// 각 유저별 등록한 장소 수 집계
const userPlaceCounts = new Map<string, number>()

for (const user of authUsers) {
  const { count, error: countError } = await supabaseAdmin
    .from('places')
    .select('*', { count: 'exact', head: true })
    .eq('user_id', user.id)
    .eq('source', 'user')

  if (!countError && count !== null) {
    userPlaceCounts.set(user.id, count)
  } else {
    userPlaceCounts.set(user.id, 0)
  }
}

유저 권한 업데이트 기능 개선

기존 문제: RLS 정책으로 인한 권한 업데이트 실패

해결 방법:

export async function updateUserRole(request: Request, userId: string, newRole: 'admin' | 'user') {
  await requireAdmin(request)

  // service role을 사용하여 RLS 우회
  const { data, error } = await supabaseAdmin
    .from('user_roles')
    .upsert({ 
      user_id: userId, 
      role: newRole 
    }, {
      onConflict: 'user_id'
    })
    .select()

  if (error) throw error
  return data?.[0] || { user_id: userId, role: newRole }
}

AdminUserSummary 타입 개선

type AdminUserSummary = {
  id: string
  email: string
  created_at: string | null
  last_sign_in_at: string | null
  user_metadata: Record<string, unknown>
  app_metadata: Record<string, unknown>
  role: 'admin' | 'user'
  placesCount: number  // 실제 등록한 장소 수
  nickname: string | null
}

 

3. 마케팅 정보 수신 동의 시스템 구축

백엔드 로직 구현

단계별 구현:

  1. 로더에서 동의 상태 조회: getUserAgreements로 현재 상태 확인
  2. 액션에서 토글 처리: toggleMarketingAgreement 함수 호출
  3. 기존 필수 동의 정보 보존: 중요한 버그 수정

핵심 버그 수정

문제: toggleMarketingAgreement가 기존 필수 동의 정보 모두를 false로 덮어씀

수정된 로직:

  • 기존 필수 동의 정보 보존 (terms_agreed, privacy_agreed)
  • 마케팅 동의 시점 관리 (marketing_agreed_at)
  • 마케팅 동의 철회 시 시점 정보 null 처리

UI 구현

iOS 스타일 토글 스위치:

  • 직관적인 on/off 인터페이스
  • 동의 시점 정보 표시
  • 접근성 지원 (aria-label, aria-describedby)

 

4. 내정보 페이지 및 프로필 시스템 확장

마이페이지

데이터베이스 마이그레이션

user_profiles 테이블 추가:

  • 사용자 프로필 정보 저장 (nickname, avatar_url, bio)
  • auth.users와 연동된 프로필 시스템

내정보 페이지 구현

  • 사용자 프로필 정보 표시 및 수정 기능
  • 닉네임 변경 기능
  • 프로필 이미지 관리

5. 마이페이지 UI/UX 개선

공통 헤더 적용

Before: 중앙 정렬된 단순 제목
After: 모바일 앱 스타일 헤더

{/* 헤더 */}
<div className="bg-white/10 backdrop-blur-sm">
  <div className="max-w-md mx-auto px-4 py-4 flex items-center">
    <Link
      to={ROUTES.HOME}
      className="mr-4 text-white/90 hover:text-white transition-colors"
      aria-label="뒤로가기"
    >
      ←
    </Link>
    <h1 className="text-lg font-semibold text-white">마이 페이지</h1>
  </div>
</div>

프로필 정보 개선

  • 프로필 테이블 데이터 우선 표시
  • 닉네임 시스템 통합
  • 동적 아바타 이미지 로딩

메뉴 시스템 확장

  • 내 정보 보기 메뉴 추가
  • 프로필 정보 확인 및 수정 기능 연결

6. 전체 서비스 디자인 통일

배경 스타일 표준화

통일된 그라데이션: bg-gradient-to-br from-purple-400 via-pink-500 to-red-500

  • 메인 페이지, 로그인/회원가입 페이지
  • 약관 동의 페이지, 마이페이지, 내정보 페이지

카드 디자인 표준화

  • 글래스모피즘: bg-white/95 backdrop-blur-sm
  • 그림자 효과: shadow-xl
  • 라운딩: rounded-2xl

컴포넌트 시스템 확장

  • app/components/ui/index.ts에 Calendar 컴포넌트 추가
  • 일관된 export 패턴으로 컴포넌트 관리 체계화

메인 페이지 날짜 선택 개선

Before & After
이전:

<Input
  type="date"
  name="date"
  label="데이트 날짜"
  required
  min={getTodayString()}
  helperText="오늘 이후 날짜를 선택해주세요"
/>

개선 후:

<Calendar
  name="date"
  label="데이트 날짜"
  required
  minDate={new Date()}
  helperText="오늘 이후 날짜를 선택해주세요"
/>

사용자 경험 개선

  • 직관적인 날짜 표시: "2024년 1월 15일 (월)" 형식
  • 월 네비게이션: 이전/다음 달로 쉽게 이동
  • 시각적 구분: 현재 달/이전 달/선택 불가 날짜 명확한 표시
  • 터치 친화적: 충분한 터치 영역과 호버 효과

🔧 기술적 도전과 해결

1. Supabase RLS 정책 관리

문제: 관리자 기능에서 RLS 정책으로 인한 접근 제한
해결: supabaseAdmin (service role) 사용으로 RLS 우회

2. 타입 안전성 확보

문제: user_metadata의 unknown 타입으로 인한 타입 에러
해결: IIFE(즉시 실행 함수 표현식)와 타입 가드 활용

3. 기존 데이터 보존

문제: 마케팅 동의 토글 시 필수 동의 정보 손실
해결: 기존 동의 정보 조회 후 선택적 업데이트

4. 컴포넌트 아키텍처

문제: 기존 폼 시스템과의 호환성 유지
해결: hidden input 패턴으로 기존 폼 로직과 완벽 호환

5. 의존성 관리

문제: clsxtailwind-merge 패키지 필요
해결: npm install을 통한 의존성 추가 및 유틸리티 함수 구현

📊 프로젝트 전체 진척도 (DAY1-DAY7)

✅ 완성된 핵심 기능

인증 & 사용자 관리 시스템 (DAY1-DAY7)

  • 카카오 OAuth: 로그인/회원가입 완성
  • 이메일 회원가입: 약관 동의 시스템 포함
  • 마케팅 동의 관리: 개인정보보호 강화
  • 프로필 시스템: 닉네임, 아바타, 내정보 페이지
  • 관리자 대시보드: 완전한 유저 관리 기능

장소 관리 시스템 (DAY4-DAY6)

  • 카카오 지도 연동: 위치 검색 및 선택
  • 장소 등록 기능: 자동 정보 추출, 카테고리 분류
  • 이미지 업로드: 자동 압축, 다중 업로드, RLS 보안 해결
  • 지역 자동 생성: 카카오 API 연동한 지역 매핑

UI/UX 시스템 (DAY5-DAY7)

  • 통합 디자인 시스템: 그라데이션 배경, 일관된 컴포넌트
  • 달력 컴포넌트: 한국어 인터페이스, 모바일 최적화
  • 카카오 지도 컴포넌트: 클라이언트 전용 지도 렌더링
  • 이미지 업로드 컴포넌트: 드래그앤드롭, 미리보기, 진행률
  • 마이페이지 시스템: 프로필 관리, 설정, 장소 관리

🚧 현재 진행 중

추천 시스템 기반

  • 지역별 장소 데이터베이스 구축 중
  • 시간대별 추천 로직 준비
  • 사용자 선호도 기반 개인화 시스템 설계

🎯 다음 단계 (DAY8 예정)

추천 알고리즘 완성

  1. 지역-시간-카테고리 매칭 로직 구현
  2. 사용자 히스토리 기반 개인화 추가
  3. 파트너십 장소 우선순위 시스템 구현

데이터 최적화

  1. 추천 성능 개선: 캐싱 및 인덱싱
  2. 이미지 최적화: CDN 연동 및 WebP 변환
  3. 데이터베이스 튜닝: 쿼리 최적화

고급 기능

  1. 장소 리뷰 시스템: 평점 및 후기
  2. 즐겨찾기 기능: 개인 장소 컬렉션
  3. 소셜 기능: 데이트 코스 공유

📈 성과 지표

기술적 성취

  • 완전한 관리자 시스템: 유저 관리, 권한 관리, 통계 기능
  • 개인정보보호 강화: 마케팅 동의 관리 시스템
  • 컴포넌트 재사용성: 8개 공통 UI 컴포넌트 구축
  • 타입 안전성: 100% TypeScript 커버리지
  • 성능 최적화: 이미지 60-80% 압축률 달성
  • 사용자 경험: 모바일 친화적 반응형 디자인

개발 효율성

  • 체계적 문서화: 7일간 상세한 개발 일지 작성
  • 점진적 개발: 기능별 단계적 구현 및 테스트
  • 재사용 가능한 아키텍처: 확장성 있는 컴포넌트 시스템
  • 보안 강화: RLS 정책과 서비스 역할 적절한 활용

🔮 프로젝트 전망

단기 목표 (1-2주)

  • 추천 시스템 완성 및 실제 장소 데이터 확충
  • 베타 테스트 환경 구축 및 초기 사용자 피드백 수집

중기 목표 (1개월)

  • 실제 데이트 장소 50-100개 등록
  • 사용자 행동 분석 및 추천 정확도 개선
  • 모바일 앱 버전 개발 검토

장기 목표 (3개월)

  • 지역 확장 (서울 → 수도권 → 전국)
  • 파트너십 업체 연동 및 예약 시스템
  • AI 기반 개인화 추천 고도화

🎉 DAY7 완료 요약

다면적 시스템 구축을 통해 코스모스 서비스를 완전한 웹 애플리케이션으로 발전시켰습니다. 단순한 기능 추가를 넘어서 관리 시스템, 개인정보보호, 사용자 경험 개선까지 모든 영역에서 품질을 향상시켰습니다.

핵심 성과

  • 달력 컴포넌트: 한국어 인터페이스 완성
  • 관리자 시스템: 완전한 유저 관리 기능
  • 개인정보보호: 마케팅 동의 관리 시스템
  • 프로필 시스템: 내정보 페이지 및 닉네임 관리
  • 디자인 통일: 일관된 브랜드 아이덴티티
  • UX 개선: 모바일 친화적 인터페이스

이제 코스모스는 사용자 관리부터 장소 등록, 개인정보보호까지 모든 측면에서 완성도 높은 서비스가 되었습니다. 다음 단계에서는 추천 알고리즘을 완성하여 사용자에게 완벽한 데이트 코스를 제공하는 것에 집중할 예정입니다. 🚀

반응형