Conversation
* docs: 프로젝트 README 및 CLAUDE.md를 작성한다 - README.md: 프로젝트 소개, 기술 스택, 시작 가이드, 문서 링크 - CLAUDE.md: Claude Code 프로젝트 설정, 코딩 컨벤션, 개발 커맨드 Co-Authored-By: Claude <noreply@anthropic.com> * style: 웹 UI를 Vercel 스타일로 전면 리디자인한다 - globals.css: sky-blue 디자인 토큰 (light/dark) - layout.tsx: Pretendard 폰트, ThemeProvider 다크모드 - tailwind.config.ts: success, warning, sidebar 토큰 추가 - sidebar: 접기/펼치기, sky-blue 활성 인디케이터, 모바일 드로어 - header: DarkModeToggle, 페이지 타이틀 자동 매핑 - footer: 미니멀 1줄 푸터 - badge: success/warning variant를 디자인 토큰으로 변경 - landing: Vercel 스타일 히어로 + 6개 기능 카드 - login: BS 로고, 디자인 토큰 기반 폼 - dashboard: stat 카드 + 활동 피드 리디자인 - posts: 컴팩트 테이블, 미니멀 페이지네이션 - ranking: 포디움 카드, 고스트 소트 토글 - curation: 고스트 필터, 소프트 카테고리 뱃지 - profile: 플랫 카드, 아이콘 필, 토큰 기반 뱃지 - admin dashboard: 디자인 토큰 통일, 고스트 퀵 액션 Co-Authored-By: Claude <noreply@anthropic.com> * refactor: 봇 커맨드 파일명을 한글에서 영문으로 변경한다 - 핑.ts → ping.ts, 참가.ts → join.ts, 탈퇴.ts → leave.ts - 참가자목록.ts → member-list.ts, 내정보.ts → my-info.ts - 랭킹.ts → ranking.ts, 현황.ts → status.ts, 통계.ts → stats.ts - 관심분야.ts → interests.ts - admin/휴면.ts → dormant.ts, 휴면해제.ts → dormant-release.ts - admin/벌금전체.ts → fine-all.ts, 벌금면제.ts → fine-exempt.ts - admin/벌금현황.ts → fine-status.ts, 출석수정.ts → attendance-edit.ts - admin/설정.ts → settings.ts, 큐레이션소스.ts → curation-source.ts - index.ts barrel export 경로 업데이트 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 코드 스멜 및 미사용 코드를 정리한다 봇 패키지: - getMembersToPolll 타이포 수정 → getMembersToPoll - isGracePeriodEnded_ 트레일링 언더스코어 제거 - JSDoc 주석 /* → /** 수정 - dm-handler type: string → 'late' | 'absent' 유니온 타입 - round-reporter _client → client 네이밍 정리 - ephemeral: false 불필요한 명시적 기본값 20건 제거 - STUDY_ROLE_NAME, getRankEmoji 중복 제거 → constants.ts 통합 - dead middleware 디렉터리 제거 웹 패키지: - register, verify-email: 하드코딩 컬러 → 디자인 토큰 - admin/attendance, settings, curation, fines, members: 디자인 토큰 통일 - profile/edit: text-green-600 → text-success shared 패키지: - types/index.ts 중복 enum 정의 제거 (schema.ts as const와 충돌) Co-Authored-By: Claude <noreply@anthropic.com> * chore: 기존 프로젝트 기반 코드를 추가한다 - 루트: pnpm workspace 설정, ESLint, Prettier, TypeScript 설정 - packages/bot: Discord 봇 (커맨드, 서비스, 스케줄러, 핸들러, 테스트) - packages/shared: DB 스키마 (Drizzle), 설정, 유틸리티, 마이그레이션 - packages/web: Next.js 대시보드 (API 라우트, UI 컴포넌트, 미들웨어) - 불필요 파일 제거: 루트 Dockerfile.bot, railway.json, debug-test.mjs, package-lock.json Co-Authored-By: Claude <noreply@anthropic.com> * ci: 깃허브 세팅 * chore: CI 워크플로우 추가 및 safe 의존성 버전 업데이트 - GitHub Actions CI 파이프라인 추가 (lint, typecheck, test, build) - pnpm + Node 22 기반 워크플로우 구성 - typescript ^5.9.3, discord.js ^14.25.1, Radix UI 등 safe 범위 버전 업데이트 Co-Authored-By: Claude <noreply@anthropic.com> * chore: pnpm lockfile 갱신 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 테스트 파일 미사용 import 제거 Co-Authored-By: Claude <noreply@anthropic.com> * fix: CI 파이프라인 수정 - typecheck 전 shared 패키지 빌드 추가 (dist 의존성 해결) - test에서 web 제외 (테스트 파일 없음) - 미사용 변수 제거 (rss-poller.property.test.ts) Co-Authored-By: Claude <noreply@anthropic.com> * fix: CI 타입체크 및 테스트 오류 수정 - fine-reminder.ts: fine.type을 'late' | 'absent'로 타입 캐스팅 - rss-poller.property.test.ts: getMembersToPolll 오타를 getMembersToPoll로 수정 - CI test job에 shared 빌드 스텝 추가 (bot 테스트가 shared/db 의존) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: Supabase Auth + Discord OAuth로 인증 시스템 전환 커스텀 JWT(bcrypt + jsonwebtoken + jose) 인증을 Supabase Auth + Discord OAuth로 교체. - Supabase SSR 클라이언트 헬퍼 추가 (client, server, middleware) - OAuth 콜백 라우트 추가 (/auth/callback) - 로그인 페이지를 Discord OAuth 버튼으로 교체 - 모든 API 라우트를 Supabase Auth 기반으로 리팩토링 - 미들웨어를 Supabase 세션 검증으로 교체 - admin 라우트에 Discord ID 기반 권한 체크 추가 - DB 스키마에서 users/sessions 테이블 제거 - Transaction pooler 지원 (prepare: false) - 오픈 리다이렉트, profileImageUrl 검증 등 보안 강화 - 불필요한 파일 삭제 (auth.ts, email.ts, register, verify-email 등) Co-Authored-By: Claude <noreply@anthropic.com> * fix: 코드 리뷰 반영 - 인증 패턴 통일, ID 추출 버그 수정, 미사용 스키마 제거 - admin API(settings, curation, curation/[id])에 withAdminAuth 래퍼 적용 - members/[id] URL 파싱 시 쿼리파라미터 버그 수정 (new URL().pathname 사용) - middleware.ts 관리자 ID 파싱 로직 중복 제거 → isAdminDiscordId() 재사용 - env.ts에서 미사용 authEnvSchema(JWT), emailEnvSchema(Resend) 제거 - CLAUDE.md 최신화 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Root Directory가 packages/web로 설정된 환경에서 outputDirectory가 packages/web/.next로 이중 경로가 되는 문제 수정 Co-Authored-By: Claude <noreply@anthropic.com>
* feat: Supabase Auth 연동 및 코드 정리 - Discord OAuth 콜백 라우트 추가 - /api/auth/me에 userId 반환 추가 - 온보딩 API 검증 로직 강화 - 파트 설정 모듈 분리 (part-config.ts) - 미사용 봇 커맨드 정리 Co-Authored-By: Claude <noreply@anthropic.com> * feat: Supabase Storage 프로필 이미지 업로드 - 아바타 업로드 유틸리티 추가 (2MB, JPG/PNG/WebP 제한) - AvatarUpload 컴포넌트 추가 (드래그&드롭, 미리보기, 로딩) - 온보딩 Step 3 URL 입력 → 파일 업로드로 교체 - 프로필 수정 페이지 URL 입력 → 파일 업로드로 교체 - 프로필 수정에 파트 변경, 자기소개(100~200자), 관심사(3~6개) 통일 - 프로필 수정 API에 파트 필드 및 자기소개 100자 검증 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 헤더 사용자 메뉴 및 사이드바 UI 개선 - 헤더 우측 아바타 클릭 시 드롭다운 메뉴 (프로필 수정, 로그아웃) - 로고를 사이드바에서 헤더로 이동, 클릭 시 대시보드 이동 - 모바일 사이드바에도 로고 표시 - 사이드바에서 프로필 메뉴 제거 (드롭다운으로 대체) - 사이드바 폰트 크기 및 간격 확대 - 프로필 페이지 이메일 미인증 표시 제거 - 한줄 소개 → 자기소개 명칭 통일 - Tailwind content에 lib 경로 추가 (파트 칩 색상 적용) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
- 사이드바에 '스터디원 목록' 메뉴 추가 및 카드형 멤버 목록 페이지 구현 - 파트별 필터링, 소셜 링크 칩, DiceBear 기본 아바타 적용 - 헤더 드롭다운 '프로필 수정' → '프로필' 조회 페이지로 변경 - 소셜 링크(GitHub/LinkedIn/Instagram) 필드 추가 (스키마, API, UI) - 랜덤 아바타 뽑기 기능 (DiceBear 5개 스타일, 8개 생성) - name/nickname 분리: 기존 name → nickname 리네임, 새 name(실명) 필드 추가 - 온보딩/프로필 수정에서 실명(필수) + 닉네임 입력 지원 - Discord username #0 접미사 제거 처리 Co-authored-by: Claude <noreply@anthropic.com>
* chore: Next.js 16.1 + React 19.2 업그레이드 - next 14.2 → 16.1.6, react 18.3 → 19.2.4 - middleware.ts → proxy.ts 리네임 (Next.js 16 컨벤션) - next lint → eslint CLI 마이그레이션 (eslint.config.mjs 추가) - React 19 ESLint 규칙 대응: - header: useSyncExternalStore로 mounted 패턴 교체 - sidebar: SidebarContent 컴포넌트 외부 추출 - input: 빈 인터페이스 → type alias - layout.tsx에 data-scroll-behavior="smooth" 추가 Co-Authored-By: Claude <noreply@anthropic.com> * chore: Tailwind CSS v3 → v4.2 업그레이드 - tailwindcss v3.4 → v4.2.1, postcss 플러그인 → @tailwindcss/postcss - tailwindcss-animate → tw-animate-css 교체 - tailwind.config.ts 삭제 → globals.css @theme 지시어로 마이그레이션 - @tailwind 지시어 → @import "tailwindcss" 변경 - autoprefixer 제거 (v4에 내장) - 컴포넌트 Tailwind v4 클래스명 마이그레이션 (outline-none → outline-hidden 등) - components.json tailwind config 경로 비우기 Co-Authored-By: Claude <noreply@anthropic.com> * chore: next-env.d.ts 경로 업데이트 (Next.js 16 dev 디렉토리) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* refactor: rss-parser → feedsmith 마이그레이션 - rss-parser(deprecated) 제거, feedsmith(TypeScript 네이티브) 추가 - RssService: axios fetch + parseFeed 분리 구조로 변경 - RSS/Atom/JSON/RDF 전체 피드 포맷 지원 (extractFeedItems 헬퍼) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: node-cron → pg-boss 마이그레이션 - node-cron 제거, pg-boss(PostgreSQL 기반 잡 큐) 추가 - 5개 스케줄러에서 cron 의존성 제거, 비즈니스 로직만 유지 - pg-boss 싱글톤 모듈 (job-queue.ts) 생성 - 7개 잡 레지스트리 (scheduler-registry.ts) 생성 - RSS 폴링 → PostService.create → NotificationService 파이프라인 연결 - DATABASE_URL_DIRECT 환경변수 추가 (pg-boss LISTEN/NOTIFY용) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 스케줄러 연결 (pg-boss 잡 큐 → index.ts 통합) - index.ts에서 pg-boss 시작 + 7개 잡 등록 연결 - graceful shutdown에 pg-boss 정리 추가 (onShutdown 콜백) - RSS 폴링, 출석체크, 벌금알림, 회차리포트, 큐레이션 모두 활성화 Co-Authored-By: Claude <noreply@anthropic.com> * docs: CLAUDE.md 기술 스택 및 핵심 파일 최신화 - Bot 기술 스택: feedsmith, pg-boss로 업데이트 - 핵심 파일에 job-queue.ts, scheduler-registry.ts 추가 - 환경변수에 DATABASE_URL_DIRECT 추가 Co-Authored-By: Claude <noreply@anthropic.com> * fix: rss-poller 테스트에서 제거된 stop() 호출 수정 - afterEach에서 poller.stop() → vi.clearAllMocks()로 변경 - node-cron 제거 후 stop() 메서드가 없어 발생한 테스트 실패 수정 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 모노레포 환경에서 .env.local 로딩 경로 수정 - dotenv 로딩 시 cwd + 상위 디렉토리까지 탐색하도록 변경 - packages/* 에서 실행해도 루트 .env.local을 찾을 수 있음 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 시스템 개선 — RSS 크롤링, 태그, 수동 크롤 지원 - curation_sources에 tags, rss_url 컬럼 추가 - INTEREST_OPTIONS 상수를 shared 패키지로 추출 - POST/PATCH API에 tags, rssUrl 필드 지원 + RSS URL 자동 감지 - 수동 크롤링 API 엔드포인트 추가 (POST /api/admin/curation/crawl) - 관리자 페이지에 태그 선택기, RSS URL 입력, 크롤링 실행 버튼 추가 - 봇 curation-crawl 스케줄 KST 8시로 변경 (cron: 0 23 * * *) - 봇 CurationCrawler에 feedsmith 기반 RSS crawlFunction 연결 Co-Authored-By: Claude <noreply@anthropic.com> * fix: Velog URL 패턴 수정, RSS 감지, 대시보드/멤버 API 개선 - Velog /posts 경로 지원 (url-validator, rss.service) - 웹 RSS URL 자동 감지 유틸 추가 (rss-detect.ts) - 대시보드 API memberName → memberNickname 수정 - 멤버 API 정렬/필터 개선 - 포스트 목록 페이지 개선 - RSS 테스트/폴링 스크립트 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 아이템 관리 뷰, 크롤링 진행 모달, 페이지네이션 - 관리자 아이템 목록 API/페이지 추가 (카드 그리드, 필터, 삭제) - 크롤링 API를 SSE 스트리밍으로 전환, 진행률 모달 구현 - 크롤링 시 기간 필터(since) 지원 - 사용자 큐레이션 페이지에 12개씩 페이지네이션 + 번호 UI - 태그 색상을 프라이머리 단일 색상으로 통일 (admin/user 공통) - 태그 필터를 INTEREST_OPTIONS 공유 상수 기반으로 변경 - shadcn Dialog/Progress 컴포넌트 추가 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* refactor: 보안 강화, 반응형 개편, 모듈화 및 로그인 수정 - 세션 갱신 proxy.ts 생성 (Next.js 16 convention) → 로그인 간헐 실패 근본 수정 - 보안: Open Redirect 방지, SSRF 차단 (IPv4/IPv6), API 인증 체크 6건, 보안 헤더 - 모듈화: PageLoading/PageError, PartBadge, TagList, MEMBER_STATUS_CONFIG 공유 컴포넌트 추출 - 큐레이션 god component 분해 (1,087줄 → 220줄 + 3개 컴포넌트) - 반응형: 전 페이지 모바일 카드뷰, 레이아웃 오버플로우 수정, 사이드바 상태 리팩터링 - 코드 품질: MutationObserver 제거, stale closure 수정, dead code 정리 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 스터디원 목록 <a> 중첩 hydration 에러 수정 Link 컴포넌트 내부의 소셜 링크를 <a> → <span role="link">으로 변경하여 HTML spec 위반(<a> 안에 <a>) 및 hydration 에러 해결 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: 활동 점수 시스템 + 랭킹 게이미피케이션 구축 - 활동 점수(activity_scores) 스키마 및 봇 핸들러/서비스 추가 - 랭킹 페이지: 포디움 + Top 10 + 탭별 동적 수치 (총점/포스트/활동) - 탭별 회차 기반 등락 폭(rank delta) 계산 - 관리자 점수 관리 페이지 (부여/조회/요약 API) - 보안 강화: IDOR 방지, 원자적 CTE, 입력 검증, sanitize 유틸 - Drizzle SQL 마이그레이션 gitignore 처리 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 관리자 목록 조회 + 토글 기능 (env + config 병합) - admin.ts: getAdminDiscordIds async 변환, env + config 테이블 병합 - settings API: adminMembers, currentUserDiscordId 반환 - settings 페이지: 관리자 뱃지 리스트 + 셀프 토글 버튼 - scores route: isAdminDiscordId await 적용 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
- 글 조회 시 활동 점수 부여 (2점, 일 5회, 중복/본인 글 제외) - post_views 테이블 + POST_VIEW 점수 타입 추가 - RSS 자동 수집 동의 토글 (온보딩/프로필 편집) - RSS 비동의 시 수동 글 등록 (URL → OG 크롤링, 실패 시 제목 직접 입력) - 관리자 점수 내역 삭제 기능 (커스텀 확인 다이얼로그) - 관리자 멤버 목록에 RSS ON/OFF 배지 표시 - 대시보드 최근 포스트 클릭 시에도 조회 점수 부여 - Serena 설정 추가 (.serena/) Co-authored-by: Claude <noreply@anthropic.com>
* feat: MemberStatus enum에 pending_approval, inactive, ob 상태 추가
회원 승인 시스템 기반 작업. 기존 active/dormant/withdrawn에
pending_approval(승인대기), inactive(비활성), ob(OB) 상태를 추가.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: member-config에 신규 상태 설정 추가
pending_approval(승인대기/warning), inactive(비활성/destructive),
ob(OB/outline) 상태 및 Badge variant 매핑 추가.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: /api/auth/me 응답에 멤버 status 필드 추가
프론트엔드에서 멤버 상태(pending_approval, active, inactive 등)에 따라
리다이렉트 처리를 할 수 있도록 status 필드를 응답에 포함
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: 온보딩 신규 유저 status를 pending_approval로 변경
신규 유저가 온보딩을 완료하면 즉시 active가 아닌 pending_approval 상태로
설정하여 관리자 승인 후에만 대시보드에 접근할 수 있도록 함
기존 유저의 UPDATE 케이스는 변경하지 않음
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: OAuth 콜백에 멤버 상태별 리다이렉트 추가
로그인 시 멤버 status를 조회하여 상태에 따라 적절한 페이지로 리다이렉트:
- pending_approval → /pending (승인 대기 페이지)
- inactive → /inactive (비활성 안내 페이지)
- active → /dashboard (기존 동작 유지)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: UserLayout에 상태 기반 리다이렉트 추가
pending_approval, inactive 상태의 유저를 각각 /pending, /inactive
페이지로 리다이렉트. 차단 페이지 자체는 예외 처리하여 무한 루프 방지.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: /pending 승인대기 페이지 생성
pending_approval 상태 유저가 보는 대기 화면.
스카이블루 Clock 아이콘, 안내 메시지, 로그아웃 버튼 포함.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: /inactive 비활성 계정 페이지 생성
inactive 상태 유저가 보는 차단 화면.
레드 ShieldX 아이콘, 안내 메시지, 로그아웃 버튼 포함.
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: 관리자 API 6개 상태 지원 확장 + 프로필 필드 추가
- GET /api/admin/members: grouped/counts에 pending_approval, inactive, ob 추가
- GET /api/admin/members: 응답에 nickname, interests, resolution, onboardingCompleted 추가
- PUT /api/admin/members/[id]: validStatuses에 6개 상태 전체 포함
- 그룹핑 로직을 동적 키 방식으로 리팩토링
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: 관리자 멤버 페이지 UI 개편 + 승인대기 카드 + 상태 편집
- Task 11: 4개 통계 카드 → 6개 상태 필터 탭 (pill 버튼) 교체
- pending_approval, active, ob, dormant, inactive 탭 추가
- 승인대기 탭 선택 시 카드 그리드 뷰로 전환
- Member 인터페이스에 nickname, bio, interests, resolution,
onboardingCompleted 필드 추가
- MemberCounts/MembersData에 6개 상태 모두 포함
- handleApproveMember / handleRejectMember 핸들러 추가
- Task 12: PendingMemberCard 컴포넌트 신규 생성
- 프로필 이미지, 이름, 닉네임, 파트, 블로그 링크 표시
- bio, interests, resolution 선택적 렌더링
- 승인(활성/OB 선택) / 거절 2단계 액션
- Task 14: MemberFormDialog에 상태 편집 필드 추가
- 편집 모드에서만 상태 select 표시
- MEMBER_STATUS_CONFIG 기반 6개 상태 옵션
- PUT 요청 body에 status 포함
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: groupedMembers 타입을 명시적 객체로 변경 (빌드 에러 수정)
Record<string, ...> 대신 개별 키를 as 타입 단언으로 선언하여
TypeScript strict 모드에서 undefined 가능성 제거.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: 차단 상태 리다이렉트 시 콘텐츠 깜빡임 방지
리다이렉트 중에도 finally에서 onboardingChecked가 true로 설정되어
children이 잠깐 렌더링되던 문제 수정. 리다이렉트 시에는 로딩 화면을
유지하도록 setOnboardingChecked(true)를 성공 경로에서만 호출.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: 페이지 이동 시 onboardingChecked 리셋하여 콘텐츠 깜빡임 방지
pathname 변경 시 onboardingChecked를 false로 리셋하여
API 체크 완료 전까지 로딩 화면 유지.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: lint error - useEffect 내 동기 setState 제거
onboardingChecked boolean 대신 checkedPathname으로 변경하여
pathname 변경 시 자동으로 로딩 상태가 되도록 개선.
react-hooks/set-state-in-effect 룰 위반 해결.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: 게시판 DB 스키마 추가 (board_posts, board_comments) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Tiptap 에디터 의존성 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시판 인증 헬퍼 (getBoardAuth) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시글 목록/작성 API (GET/POST /api/board) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시글 상세/수정/삭제 API (GET/PATCH/DELETE /api/board/[id]) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 댓글 CRUD API (작성/수정/삭제) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Tiptap 에디터 + 렌더러 컴포넌트 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 사이드바 게시판 메뉴 + board-config + UI 컴포넌트 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시판 목록 페이지 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시글 작성 페이지 (Tiptap 에디터) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시글 상세 페이지 + 댓글 컴포넌트 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 게시글 수정 페이지 Co-Authored-By: Claude <noreply@anthropic.com> * fix: API 라우트 타입 에러 수정 (unused params, nullable count) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Tiptap SSR hydration 에러 수정 + CLAUDE.md 업데이트 - Tiptap useEditor에 immediatelyRender: false 추가 (SSR 호환) - CLAUDE.md에 env 파일 위치, DB 마이그레이션 명령어, 멤버 상태 규칙 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 관리자 페이지 접근 거부 시 모달 안내 추가 리다이렉트만 하던 방식에서 AlertDialog 모달로 "관리자만 접근할 수 있습니다" 안내 후 확인 버튼으로 이동하도록 변경 Co-Authored-By: Claude <noreply@anthropic.com> * refactor: 전체 로딩 상태를 스켈레톤 UI로 리팩터링 - shadcn Skeleton 컴포넌트 추가 - PageLoading(스피너+텍스트)을 각 페이지별 맞춤 스켈레톤으로 교체 - 대시보드, 게시판, 랭킹, 프로필, 멤버, 포스트, 관리자 페이지 전체 적용 - 레이아웃(user/admin) 로딩도 스켈레톤으로 변경 - 점수 관리 내부 "불러오는 중..." 텍스트도 스켈레톤으로 교체 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 게시판 행 클릭 이동 + 프로필 이미지 클릭 시 멤버 상세보기 - 공지/일반 글 행 전체 클릭 시 게시글 상세로 이동 (TableRow onClick) - 프로필 이미지(아바타) 클릭 시 /members/[id]로 이동 (stopPropagation) - 비밀글 마스킹된 경우 아바타 링크 비활성화 Co-Authored-By: Claude <noreply@anthropic.com> * feat: MemberAvatar 컴포넌트 + 관리자 뱃지 + 비밀댓글 답글 제한 - MemberAvatar 재사용 컴포넌트 생성 (프로필 사진+닉네임 클릭 시 멤버 상세) - 관리자 칩 표시 (게시판 목록/상세/댓글) - 비밀댓글 대댓글: 댓글작성자/글작성자/관리자만 가능, 강제 비밀 적용 - 중첩 <a> 태그 hydration 에러 수정 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 댓글 삭제 시 확인 모달 추가 - 삭제 버튼 클릭 시 AlertDialog로 확인 후 삭제 - 삭제 중 로딩 상태 표시 + 버튼 비활성화 Co-Authored-By: Claude <noreply@anthropic.com> * feat: Tiptap 에디터 개선 - typography 플러그인 + 코드블록 언어 선택 + 링크 다이얼로그 - @tailwindcss/typography 설치하여 prose 클래스 정상 동작 - 코드블록에 언어 선택 드롭다운 추가 (25개 언어, 구문 강조) - GitHub 스타일 syntax highlighting (라이트/다크 모드) - window.prompt → shadcn Dialog로 링크 입력 UI 개선 - 에디터 focus outline 제거 + 커서 색상 설정 - 에디터 최소 높이 200px → 400px 확대 Co-Authored-By: Claude <noreply@anthropic.com> * docs: CLAUDE.md 최신화 - 기술 스택 버전 + 게시판 핵심 파일 + 컨벤션 보강 - 기술 스택: Next.js 16, React 19, Tailwind v4, Tiptap 추가 - 핵심 파일: board-auth, api-error, member-avatar, tiptap-editor 추가 - 다이얼로그 컨벤션: window.prompt() 금지 추가 Co-Authored-By: Claude <noreply@anthropic.com> * fix: tiptap-editor lint 에러 수정 (no-explicit-any) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: curationItems에 description, thumbnailUrl 컬럼 및 publishedAt 인덱스 추가 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 크롤링 시 RSS description 저장 + og:image 추출 - NormalizedFeedItem에 description 필드 추가 - 각 피드 포맷(Atom/RSS/JSON/RDF)에서 description 추출 - sanitizeDescription: HTML 태그 제거 + 300자 truncate - extractOgImage: 블로그 URL에서 og:image 메타태그 추출 (5초 타임아웃) - curation_items INSERT 시 description, thumbnailUrl 저장 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 API cursor 기반 페이지네이션 + description/thumbnailUrl 반환 Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 유틸리티 (그라디언트 플레이스홀더, 상대시간, scrollbar-hide) Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 페이지 무한스크롤 + 반응형 레이아웃 리디자인 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 큐레이션 cursor 페이지네이션 중복 문제 수정 - 단일 publishedAt cursor → 복합 cursor (publishedAt|id)로 변경 - 동일 publishedAt 아이템 간 id로 정확한 경계 구분 - publishedAt NULL 케이스 처리 - ORDER BY에 NULLS LAST 추가 Co-Authored-By: Claude <noreply@anthropic.com> * fix: cursor SQL에서 Date 객체 → ISO 문자열 캐스팅 수정 Drizzle sql 템플릿에서 Date 객체를 직접 바인딩하면 ERR_INVALID_ARG_TYPE 에러 발생. ISO 문자열 + ::timestamptz 캐스팅으로 수정. Co-Authored-By: Claude <noreply@anthropic.com> * feat: 큐레이션 2차 개선 (맞춤 탭, 검색, 접근성, 보안 강화) - 맞춤(recommended) 탭: 사용자 관심사 기반 태그 겹침 점수 정렬 - 검색 기능: 제목/설명 ILIKE 검색 + 300ms debounce - 태그 # 접두사 + 카드 태그 칩 표시 + 4개 제한 제거 - 모바일 태그 토글 (접기/펼치기) - 보안: ILIKE 와일드카드 이스케이프, 입력 검증, UUID 포맷 체크 - 접근성: aria-pressed/expanded/live, focus-visible, motion-safe - 코드 품질: BASE_SELECT/serializeItem 추출, cursorRef 패턴 - 컨퍼런스 소스 시드 스크립트 추가 Co-Authored-By: Claude <noreply@anthropic.com> * fix: Thumbnail useEffect setState → 렌더 중 상태 조정 패턴으로 변경 react-hooks/set-state-in-effect 린트 에러 수정 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* refactor: 미사용 코드 정리 및 API 응답 패턴 통일 - recharts 미사용 의존성 제거 - api/stats, api/keywords: 미사용 NextRequest import 제거 - api/dashboard: NextResponse.json → successResponse/Errors 헬퍼 통일 - auth/callback: console.log 12개 → dev 환경 가드 2개로 정리 Co-Authored-By: Claude <noreply@anthropic.com> * chore: AI/OpenAI 참조 제거 및 프로젝트 정보 현행화 - .env.example: OPENAI_API_KEY 항목 삭제 - README.md: AI/pgvector 텍스트 제거, 기술 스택 현행화 (Next.js 16, React 19, Tailwind v4) - .gitignore: scripts/ 디렉토리 추가 Co-Authored-By: Claude <noreply@anthropic.com> * docs: 전체 문서 최신화 + 파일명 컨벤션 적용 - CLAUDE.md: AI 참조 제거, 절대경로→상대경로, 문서명 컨벤션 반영 - ARCHITECTURE.md: AI 파이프라인 제거, ER 다이어그램 전체 테이블 반영, 의존성 버전 추가 - TECH-DECISIONS: AI ADR 삭제, Next.js 16 반영 - DEVELOPMENT: OpenAI/pgvector 참조 제거 - CHECKLIST: Phase 2(pgvector)/5(AI) 삭제, Phase 6 현행화 - schema-summary: BoardCategory 값 수정, curation 컬럼 추가 - docs/ 파일명 yy-mm-dd 컨벤션 적용 (ARCHITECTURE.md 제외) - docs/plans/ 파일명 2026- → 26- 변환 - 보안: plans 내 로컬 절대경로 → 상대경로 변환 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 벌금 페이지 다이얼로그 패턴 수정 + 랜딩 페이지 AI 텍스트 제거 - window.confirm/alert → AlertDialog + 인라인 토스트로 교체 (컨벤션 준수) - 랜딩 페이지 AI 요약 & 추천 → 활동 점수 & 랭킹으로 변경 - hero 서브텍스트에서 AI 참조 제거 - 저작권 연도 2025 → 2026 수정 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: 웹 개발 서버 포트 3300으로 변경 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: PWA 홈 화면 추가 지원 (manifest + 아이콘) - manifest.json, 앱 아이콘(SVG/192/512) 추가 - layout.tsx에 PWA 메타 태그 (apple-web-app, theme-color) - Service Worker 없는 가벼운 PWA (홈 화면 추가 전용) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: lockfile 갱신 (recharts 제거 반영) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * remove: 스크립트 제거 * feat: CODEOWNERS & Auto Assign 추가 --------- Co-authored-by: Claude <noreply@anthropic.com>
- 디스코드 채널 구조 설계 및 생성 (5카테고리 13채널 + 운영 4채널) - 회차 시작/종료 알림을 #공지사항(notice_channel)으로 분리 - 회차 시작 시 active 멤버만 개별 멘션 - notice_channel 미설정 시 announcement_channel로 폴백 - 채널 세팅 가이드 문서 추가 - CLAUDE.md, ARCHITECTURE.md 최신화 Co-authored-by: Claude <noreply@anthropic.com>
* feat: 공지 배너 + 풀투리프레시 + UX 개선 (#17) - 랜딩 페이지 인증 리다이렉트 (로그인 시 /dashboard 자동 이동) - 글로벌 공지 배너 (관리자 설정, 접기/닫기 localStorage 유지) - Pull-to-refresh (커스텀 터치 제스처, PWA 최적화) - 하단 탭 바 사용자/관리자 모드 분리 - 사이드바/헤더 관리자 토글 텍스트 통일 - 게시판 API 보안 강화 (트랜잭션, 카테고리 검증, 관리자 권한 체크) - proxy.ts 관리자 인증 await 누락 수정 - 문서 최신화 (CLAUDE.md, 스키마, 패턴, 아키텍처) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: 사이드바 하단 사용자/관리자 토글 제거 프로필 드롭다운에서만 전환 가능하도록 통일. Separator, 토글 링크 제거. 접기 버튼만 유지. Co-Authored-By: Claude <noreply@anthropic.com> * fix: 관리자 모드 하단 탭 바 제거 관리자 페이지에서는 모바일 하단 탭 바를 표시하지 않음. 사용자 모드 5개 메뉴만 유지. Co-Authored-By: Claude <noreply@anthropic.com> * Revert "fix: 관리자 모드 하단 탭 바 제거" This reverts commit fecc8a4. * fix: 관리자 대시보드 Quick Actions 링크 섹션 제거 사이드바에서 동일 메뉴 접근 가능하므로 중복 제거. Co-Authored-By: Claude <noreply@anthropic.com> * fix: UI 워딩/표시 수정 4건 - 글 목록 → 포스트 (사이드바, 하단 탭) - 관리자 페이지에서 공지 배너 미표시 - 참가자 관리 → 멤버 관리 (관리자 페이지 타이틀) - 점수 관리 페이지 Star 아이콘 제거 Co-Authored-By: Claude <noreply@anthropic.com> * fix: 공지 배너에 제목+내용 미리보기 표시, 접기→닫기 통일 - API에서 contentText 추가 반환 - 배너에 제목 + 내용 80자 미리보기 표시 - 3단계 상태(open/collapsed/closed) → 2단계(open/closed)로 단순화 - X 버튼으로 닫으면 완전히 숨김 (새 공지 시 자동 리셋) Co-Authored-By: Claude <noreply@anthropic.com> * fix: 공지 배너 접기 시 제목만 표시 - open: 제목 + 내용 미리보기 - collapsed: 제목만 (컴팩트) - closed: 완전 숨김 (X 버튼) Co-Authored-By: Claude <noreply@anthropic.com> * fix: 공지 배너 접힘 시 제목 폰트 크기 통일 (text-sm) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Tiptap 에디터 툴바에 H1-H3, 구분선, 본문 버튼 추가 - 본문(T): 일반 텍스트로 변환 - H1, H2, H3: 제목 토글 - 구분선(―): 수평선 삽입 Co-Authored-By: Claude <noreply@anthropic.com> * fix: Tiptap 에디터 한글 자소분리 문제 수정 compositionstart/end 이벤트로 IME 조합 중 onUpdate 호출을 차단. 조합 완료 후 rAF로 deferred update 실행. Co-Authored-By: Claude <noreply@anthropic.com> * fix: 공지 배너 API 캐시 제거 max-age=60 캐시가 새 공지 반영을 지연시키는 문제 수정. no-store로 변경하여 항상 최신 데이터 반환. Co-Authored-By: Claude <noreply@anthropic.com> * fix: Pull-to-refresh를 window.location.reload()로 변경 router.refresh()는 서버 컴포넌트만 리페치하므로 클라이언트 데이터 갱신이 안 되는 문제 수정. Co-Authored-By: Claude <noreply@anthropic.com> * docs: CLAUDE.md + patterns.md 최신화 - bottom-nav: 관리자 모드 미표시 반영 - 사이드바: 모드 전환 프로필 드롭다운 전용 - 공지 배너: 제목+내용 미리보기, no-store 캐시, 관리자 미표시 - PTR: window.location.reload() 반영 - Tiptap: H1-H3/구분선 툴바, 한글 IME 패턴 추가 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
- Dialog/AlertDialog: grid → flex flex-col, translate 센터링 → inset-y-0 my-auto - overflow-y-auto 추가로 콘텐츠 클리핑 대신 스크롤 활성화 - slide 애니메이션 origin 48% → 제거 (새 센터링 방식과 불일치) - WebkitOverflowScrolling 제거 (iOS 13 이후 no-op) - globals.css: body[data-scroll-locked] overscroll-behavior-y: auto 추가 - use-pull-to-refresh: 다이얼로그 열림 시 제스처 비활성화 - crawl-modal: base DialogContent에서 flex flex-col 상속으로 중복 제거 Co-Authored-By: Claude <noreply@anthropic.com>
fix: Safari PWA 다이얼로그 스크롤 수정
- 모든 API 라우트를 Errors/successResponse/errorResponse 표준 패턴으로 통일 - withCache() 유틸 추가 (members 60s, ranking 30s Cache-Control) - sonner 토스트 시스템 통합 (inline 토스트 제거) - sanitizeTiptapContent()로 게시판 XSS 방어 (javascript:/data:/vbscript: 차단) - isSafeUrl() SSRF 방어 (posts/manual, curation/crawl) - CSP 헤더 설정 (next.config.js) - 에러 바운더리 추가 (user/admin error.tsx) - 커스텀 404 페이지 추가 - 미인증 API 엔드포인트 수정 (rounds, rounds/[id]) - posts/page.tsx 중복 fetchPosts를 useCallback으로 통합 Co-Authored-By: Claude <noreply@anthropic.com>
feat: 웹 API 표준화 + 보안 강화 + 에러 처리 개선
* feat: 랜딩 페이지 리디자인 + 커스텀 로고/파비콘 - Linear 스타일 다크 모드 원페이지 (7섹션: Nav/Hero/Stats/Bento/HowItWorks/Marquee/CTA) - 큐시즘 블루 그라디언트 (#0091FF → #004DFF) 전면 적용 - Framer Motion 풀 애니메이션 (FadeUp, StaggerContainer, CountUp, DrawLine) - 커스텀 SVG 픽토그램 로고 (펜촉+화살표) + PWA 아이콘 (192/512, maskable) - DB 스탯 ISR 60s (활성 멤버수, 포스트수, 회차) - DiceBear fun-emoji 아바타 마키 소셜 프루프 - prefers-reduced-motion 접근성 대응 - themeColor 라이트/다크 분기, statusBarStyle black-translucent Co-Authored-By: Claude <noreply@anthropic.com> * style: 벤토 그리드 → 균등 3x2 카드 그리드로 변경 Co-Authored-By: Claude <noreply@anthropic.com> * style: 로고 리디자인 — K 레터마크 + 펜 스트로크 모티프 큐시즘 블루 그라디언트 (#0091FF → #004DFF) 볼드 지오메트릭 K + 하단 대각선에 펜촉 디테일 Co-Authored-By: Claude <noreply@anthropic.com> * style: 레트로 터미널 K 로고 + 큐스팅 4th 브랜딩 + 푸터 크레딧 - 로고를 레트로 터미널 K 레터마크로 리디자인 (CRT 스캔라인, 커서 블록, 프롬프트 마커) - 서비스명 '큐스팅 4th'로 통일 (Nav, Header, Footer) - 푸터에 개발자 크레딧 추가 (@bbbang105 & @choihooo) - PWA 아이콘 재생성 (icon-192.png, icon-512.png) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
- 블로그 스터디 / 블로그 글쓰기 스터디 → 큐스팅 4th 일괄 변경 - 로그인 페이지 BS 텍스트 → icon.svg 로고로 교체 - title, description, manifest, logo.svg, header, footer, dashboard 등 전체 반영 Co-Authored-By: Claude <noreply@anthropic.com>
- 로컬 .claude/skills 디렉토리에 10개 전문 스킬 추가 - discord-js-skills 패키지 구조로 코드 템플릿 제공 - 검증 스크립트로 스킬 품질 관리 - TypeScript 기반 완전한 구현 예시 포함 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- 삭제: commands-manager (슬래시 커맨드 시스템) - 삭제: discord-client (이미 완성된 설정 존재) - 삭제: music-bot (프로젝트 범위 범위 벗어남) - 삭제: channel-manager (setup-channels.ts 스크립트로 대체) - 삭제: guild-manager (단일 서버 전용, 웹에서 관리) - 삭제: webhooks-manager (현재 요구사항 없음) - 삭제: moderation-tools (웹 관리자 페이지에서 처리) - 삭제: message-handler (activity-handler.ts로 충분) 보관: - events-handler (새로운 이벤트 핸들러 구현 시 필수) - member-manager (멤버 관련 고급 기능 구현 시 유용) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
삭제: - member-manager (DB 중심 설계와 상충) 단순화: - events-handler: 복잡한 클래스 패턴 → 실용적 참고 문서로 변경 신규 추가: - scheduler-reference: pg-boss 스케줄러 구현 참고 * Singleton 패턴, isRunning 플래그 * Cron 잡 등록, Worker 등록 * Discord 클라이언트 연동 예시 * 프로젝트 기존 스케줄러 참고 - service-pattern: DB 서비스 계층 구현 참고 * Singleton 패턴, CRUD 기본 패턴 * 에러 처리, 커스텀 에러 클래스 * 복잡한 쿼리 (조인, 집계, 그룹화) * 트랜잭션 패턴 * Property-Based Test 예시 최종 보관 스킬 (3개): 1. events-handler: 새로운 이벤트 핸들러 구현 참고 2. scheduler-reference: 새로운 스케줄러 구현 참고 3. service-pattern: 새로운 서비스 구현 참고 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor: 스킬 시스템 정리 및 프로젝트 참고용 스킬 추가
* feat: 주간 랭킹 자동 발송 스케줄러 구현 - WeeklyRanking 스케줄러 추가 (매주 일요일 22:00 KST) - RankingService 추가 (활동 점수 기반 랭킹 계산) - Property-Based Test 15개 통과 - Discord Embed 메시지 포맷 (포디엄 + TOP 15) - KST 날짜 처리 (월요일 00:00 ~ 일요일 23:59) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: pg-boss 큐 초기화 문제 해결 - boss.createQueue() 내부 API로 큐 명시적 생성 - weekly-ranking 스케줄러 활성화 (8개 스케줄러 정상 등록) - job-queue.ts에 pg-boss 설정 추가 (_uuid: 'v1') - scheduler-registry.ts에 큐 생성 로직 추가 문제: boss.schedule()은 큐를 자동 생성하지 않음 해결: boss.work() 전에 boss.createQueue()로 큐 먼저 생성 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: 주간 랭킹 구현 플랜 및 pg-boss 문제 해결 가이드 추가 - 26-03-09-weekly-ranking-implementation.md: 구현 플랜 (상태: 완료) - 26-03-09-pg-boss-queue-troubleshooting.md: 문제 해결 가이드 pg-boss 문제 해결 과정: 1. boss.work() 후 boss.schedule() 순서 변경 (실패) 2. 대기 시간 추가 (실패) 3. boss.send()로 더미 잡 전송 (실패) 4. pg-boss 설정 변경 (실패) 5. boss.createQueue() 내부 API 사용 (성공) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: 린트 에러 수정 - @ts-ignore를 @ts-expect-error로 변경 - 사용하지 않는 discordIdArb 변수 제거 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: CI 타입 체크 에러 수정 - PgBoss 생성자 두 번째 인자 제거 (_uuid 설정) - 사용하지 않는 @ts-expect-error 지시자 제거 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: 주간 랭킹 스케줄러 코드 리뷰 수정 사항 반영 ## 수정 내용 ### 🔴 심각한 이슈 - **KST 날짜 처리 불일치 수정**: `formatKSTDate()` 헬퍼 함수 추가로 KST 시간에서 직접 날짜 포맷팅 - **활동 점수 쿼리 타입 안전성 개선**: 하드코딩된 문자열을 `ActivityScoreType` enum 상수로 변경 ### 🟡 중간 우선순위 이슈 - **경쟁 조건 해결**: `isRunning` 플래그를 Promise 기반 뮤텍스(`runningLock`)로 대체하여 동시 실행 문제 해결 - **빈 랭킹 경고 추가**: `WeeklyRankingResult`에 `warnings` 필드 추가 ### 🟢 낮은 우선순위 이슈 - **매직 넘버 제거**: 포스트 점수 상수 `BLOG_POST_SCORE_POINTS = 30` 추출 - 테스트 코드에서도 동일한 상수 사용 ## 테스트 결과 - ✅ 타입 체크 통과 - ✅ 모든 테스트 통과 (133개 테스트) - ✅ 린트 통과 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- 블로그 원문 보기 + 큐스팅 웹에서 보기 버튼 추가 - 웹 수동등록 알림과 동일한 embed + button 형태로 통일 Co-authored-by: Claude <noreply@anthropic.com>
수동 등록 + RSS 수집 모두에서 새 글 등록 시 작성자 본인을 제외한 active/OB/dormant 멤버에게 FCM 푸시 알림을 발송한다. - shared: NotificationType에 NEW_POST 추가 - web: 내부 API `/api/internal/new-post-push` (Bearer 인증, timing-safe 비교, rate limit 20/min, UUID/길이 검증) - web: 수동 등록 시 별도 after() 블록에서 sendPushToMembers 호출 (Discord 토글과 독립) - bot: RSS 새 글 감지 시 웹 내부 API fire-and-forget 호출 - web: 알림 설정 UI에 '새 글 알림' 토글 추가 - web: 테스트 푸시에 new_post 타입 추가 - web: decodeHtmlEntities 유틸 추가 (RSS 제목 HTML 엔티티 디코딩) - docs: CLAUDE.md, ARCHITECTURE.md 최신화 Co-authored-by: Claude <noreply@anthropic.com>
- 새 글 DB 저장 완료 로그 추가 - 블로그 포스트 점수 부여 로그 추가 - 푸시 알림 성공/스킵 로그 추가 - '포스트 알림' → '디스코드 알림'으로 로그 메시지 명확화 Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(web/bot): 랭킹에서 관리자 및 지정 멤버 제외 - 웹 랭킹 API: 관리자 Discord ID + config `ranking_excluded_ids` 기반 필터링 - 봇 주간 랭킹: env `ADMIN_DISCORD_IDS` + config `ranking_excluded_ids` 기반 필터링 - config 테이블로 제외 대상 관리 (코드 변경 없이 DB에서 추가/제거 가능) Co-Authored-By: Claude <noreply@anthropic.com> * feat(web): 프로필 페이지 UX 개선 - 프로필 수정 버튼을 헤더 우측으로 이동 (하단 → 상단) - 푸시 알림 미허용 시 유도 말풍선 표시 (벨 펄스 애니메이션 + 알림 켜기 CTA) - 알림 켜기 성공 시 상세 설정 페이지로 자동 이동 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
statusBarStyle을 black-translucent에서 default로 변경하여 콘텐츠가 iOS 상태바(시간/배터리) 영역 뒤로 올라가는 문제 해결. Toaster offset도 하단 내비 safe area를 고려하도록 추가. Co-Authored-By: Claude <noreply@anthropic.com>
- RSS 폴링 시 멤버별 배치 URL 중복 체크 (IN query 1개로 변경)
- 기존: 피드 아이템별 개별 SELECT (~344개/cycle)
- 개선: 멤버당 1개 IN 쿼리 (29개/cycle)
- pino logger에 Error serializer 등록 (error: {} → 구조화된 출력)
- 에러 로깅 시 raw Error 객체 직접 전달 (스택 트레이스 보존)
Co-authored-by: Claude <noreply@anthropic.com>
- 투표 미참여자 관리: 참여/미참여 탭, 관리자 수동 DM 발송 (개별/전체) - 마감 리마인더: D-2/D-1/D-day 미제출자 DM (자동 + 수동) - 게시판 이미지: 읽기 모드에서 편집 UI 제거, 클릭 시 라이트박스 (확대/축소) - 불릿 리스트 간격 축소 (prose li > p margin 제거) - 봇 동작 제어: deadline-reminder 큐 생성 추가 - 코드 리뷰 반영: debug log 제거, null memberId 필터, race condition 수정 Co-authored-by: Claude <noreply@anthropic.com>
* feat(shared): add boardPostReactions table for emoji reactions Co-Authored-By: Claude <noreply@anthropic.com> * feat(web): add board post reaction toggle API Co-Authored-By: Claude <noreply@anthropic.com> * feat(web): include reactions data in board post GET response Co-Authored-By: Claude <noreply@anthropic.com> * feat(web): add ReactionBar component and integrate into board detail page - ReactionBar: emoji pill buttons with toggle, hover/long-press member popover - Integrated into board detail page with reactions state and refresh - Fixed TypeScript errors in reactions API route and board GET route Co-Authored-By: Claude <noreply@anthropic.com> * fix(web): reaction API race condition + ReactionBar cleanup - Wrap toggle in transaction to prevent race condition - Add timer cleanup on component unmount - Add aria-label and aria-pressed for accessibility - Check deletedAt on post existence query Co-Authored-By: Claude <noreply@anthropic.com> * feat(web): add emoji reactions to posts + ReactionBar UX improvements - Add postReactions table and API (GET/POST /api/posts/[id]/reactions) - Integrate ReactionBar into post detail page - Add reaction chips with member popover to post list cards - Add SmilePlus picker button to board ReactionBar - Include reaction count in popular post scoring - Add board notice content preview in Discord notifications (500 chars) Co-Authored-By: Claude <noreply@anthropic.com> * fix(web): ReactionBar apiPath prop + fetchReactions order fix - Add apiPath prop to ReactionBar (board/posts) to fix wrong API path - Move fetchReactions before useEffect to fix declaration order - Move REACTION_EMOJIS to module scope to avoid per-render allocation Co-Authored-By: Claude <noreply@anthropic.com> * docs: update CLAUDE.md with emoji reactions conventions Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: D-Day 계산을 KST 캘린더 날짜 기준으로 수정 Math.ceil(timeDiff)에서 KST midnight 기준 날짜 차이로 변경하여 마감일 당일이 D-Day(0), 하루 전이 D-1로 정확히 표시되도록 수정. dashboard, admin/dashboard, rounds API + shared 유틸 모두 통일. Co-Authored-By: Claude <noreply@anthropic.com> * fix: 비밀답글 부모 댓글 작성자 가시성 추가 비밀 답글(isSecret)을 부모 댓글 작성자도 볼 수 있도록 게시판/포스트 댓글 API 마스킹 로직에 parentId 체크 추가. Co-Authored-By: Claude <noreply@anthropic.com> * style(web): 랭킹 포디움 포부 텍스트 모바일 2줄 표시 truncate → line-clamp-2로 변경하여 모바일에서도 포부(resolution)가 2줄까지 보이도록 수정. Co-Authored-By: Claude <noreply@anthropic.com> * feat: Discord 알림 로그 시스템 추가 봇/웹에서 Discord 채널 및 DM으로 보내는 모든 알림의 성공/실패를 DB에 기록하고 관리자 페이지에서 조회. - discord_notification_logs 테이블 추가 (shared 스키마) - 봇: 채널 알림 6종 + DM 5종 로깅 (notification-logger 헬퍼) - 웹: discord-notify 반환타입 확장 + 호출자 로깅 - 관리자 API (GET /api/admin/bot-logs) + UI (탭 추가) - 타입/소스/대상/상태별 필터 + 무한 스크롤 Co-Authored-By: Claude <noreply@anthropic.com> * fix(web): 리뷰 피드백 반영 — bot-logs 캐시 제거, cursor 검증, UI 접근성 - bot-logs API: withCache 제거 (관리자 민감 데이터), cursor 유효성 검증 추가 - notification-logs: IntersectionObserver deps 최적화 (isLoadingMore ref 전환) - 필터 Select 반응형 너비 (모바일 대응) - 상태 도트 크기 확대 + ring + aria-label 접근성 개선 Co-Authored-By: Claude <noreply@anthropic.com> * docs: CLAUDE.md 최신화 — 알림 로그, D-Day 수정, 비밀답글 가시성 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
- D-Day 라벨: days <= 1 → days <= 0 (하루 전 D-Day 표시 버그 수정) - 주간랭킹: webActivityScore에 ADMIN_MANUAL 타입 추가 Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
days <= 1→days <= 0(마감 하루 전에 D-Day로 표시되던 버그 수정)webActivityScore에ADMIN_MANUAL타입 추가 (수동부여 점수가 활동 점수 괄호 안에 표시)Test plan
🤖 Generated with Claude Code