포인트 조회 및 관리 시스템 — 개발 진행 가이드
MVP 단계 Next.js 16 · TypeScript · Prisma 100% 완료
계정 정보
프로젝트 현황
17
전체 Task
17
완료 Task
4
개발 Phase
100%
전체 완료율
기술 스택
Next.js 16
App Router
🔷
TypeScript
strict 모드
🎨
shadcn/ui
Tailwind CSS
🗄️
Prisma 5
ORM · MySQL
🐬
MariaDB
외부 호스팅
🔐
jose
JWT · Edge
📊
ExcelJS
xlsx 업로드
🔄
PM2
포트 3003
Phase별 진행률 4 / 4 완료
Phase 1 — 애플리케이션 골격 구축 4 / 4 Task · 100%
Phase 2 — UI/UX 완성 (더미 데이터) 4 / 4 Task · 100%
Phase 3 — 핵심 기능 구현 6 / 6 Task · 100%
Phase 4 — 통합 테스트 및 배포 준비 3 / 3 Task · 100%
단계별 작업 진행 현황 17 / 17 완료
P1
Phase 1 — 애플리케이션 골격 구축
Week 1 · 약 5일 · Next.js 초기 셋업, DB 스키마, 라우트 골격, 타입 정의
✅ 완료
Task작업 내용주요 파일상태
001
프로젝트 초기 셋업 및 환경 구성
Next.js 16 · TypeScript strict · Tailwind CSS · shadcn/ui · ESLint · Prettier · .env.example
package.jsontsconfig.json
✅ 완료
002
Prisma 스키마 및 DB 연결 구성
users · point_histories 모델 · remaining_amount · MariaDB 연결 검증
schema.prismalib/db.ts
✅ 완료
003
라우트 골격 및 레이아웃 구조 생성
App Router 그룹 라우팅 · (auth) · (user)/dashboard · admin/* · 루트 리다이렉트
app/(auth)/app/admin/
✅ 완료
004
TypeScript 타입 정의 및 공통 유틸리티
User · PointHistory · Session · ApiResponse<T> · PaginatedResult<T> · getSession/requireUser/requireAdmin
types/index.tslib/auth.ts
✅ 완료
P2
Phase 2 — UI/UX 완성 (더미 데이터)
Week 2 · 약 5일 · 실제 API 없이 모든 페이지 UI 완성
✅ 완료
Task작업 내용주요 파일상태
005
shadcn/ui 컴포넌트 설치 및 디자인 시스템
button · input · card · table · dialog · form · toast · badge 설치 · 더미 데이터 팩토리 · format.ts 유틸
components/ui/lib/format.ts
✅ 완료
006
인증 페이지 UI (로그인 / 회원가입 / 관리자 로그인)
react-hook-form · zod 클라이언트 검증 · aria-describedby 접근성 · LogoutButton 클라이언트 분리
login-form.tsxregister-form.tsx
✅ 완료
007
사용자 대시보드 UI (잔여액 + 상세 내역)
잔여 포인트 카드 · 내역 테이블 · URL searchParams 페이지네이션 · 모바일 카드 리스트 반응형
dashboard/page.tsxpagination.tsx
✅ 완료
008
관리자 페이지 UI (회원 목록 + 차감 모달 + 엑셀 업로드)
회원 목록 테이블 · 검색/페이지네이션 · 차감 Dialog 모달 · 파일 드롭존(5MB/10,000행)
members-client.tsxupload-zone.tsx
✅ 완료
P3
Phase 3 — 핵심 기능 구현
Week 3~5 · 약 15일 · 더미 데이터를 실제 DB/API로 대체
✅ 완료
Task작업 내용주요 파일상태
009
회원 인증 API 및 세션 관리
POST register · login · logout · bcryptjs 해싱 · SignJWT 8h · HttpOnly Secure Cookie · zod 입력 검증
api/auth/lib/auth.ts
✅ 완료
010
Middleware 라우트 보호 + 이중 권한 검증
jose jwtVerify Edge Runtime · /dashboard·/admin/* 보호 · requireAdmin() 이중 검증 · api-helpers.ts 공통 에러 응답
middleware.tsapi-helpers.ts
✅ 완료
011
포인트 잔여액 / 내역 조회 API
getBalance: SUM(remaining_amount) WHERE type=grant AND expires_at>NOW() · getHistory 페이지네이션 · SSR
lib/points.tsapi/points/
✅ 완료
012
관리자 회원 목록 조회 API
GET /api/admin/members · 검색(이름/이메일) · 페이지네이션 · groupBy 잔여 포인트 집계(N+1 방지)
api/admin/members/
✅ 완료
013
관리자 포인트 차감 (FIFO + Serializable 트랜잭션)
POST /api/admin/points/deduct · expiresAt ASC FIFO · Prisma.$transaction Serializable · deduct 로그 INSERT
api/admin/points/deduct/
✅ 완료
014
엑셀 데이터 업로드 (ExcelJS + 단일 트랜잭션)
POST /api/admin/upload · 5MB/10,000행 · exceljs 파싱 · 이메일·amount 검증 · $transaction INSERT · 중복 방지
api/admin/upload/upload-zone.tsx
✅ 완료
P4
Phase 4 — 통합 테스트 및 배포 준비
Week 6~7 · 약 7일 · 전체 플로우 E2E 검증 · 보안 강화 · 운영 준비
✅ 완료
Task작업 내용주요 파일상태
015
E2E 통합 테스트 (Playwright MCP)
회원 풀플로우 · 관리자 풀플로우 · 권한 시나리오 · 3개 뷰포트(375/768/1280px) · 미들웨어 버그 2건 수정
middleware.ts
✅ 완료
016
보안 강화 (Rate Limit + Env 검증 + Admin 로그)
rate-limit.ts · env.ts(zod) · admin-logger.ts(logs/admin-access.log) · rateLimitResponse() 429
lib/rate-limit.tslib/env.ts
✅ 완료
017
배포 준비 및 운영 문서화
prisma/seed.ts · README.md 재작성 · .env.example 5개 키 · pnpm build warning 0건
prisma/seed.tsREADME.md
✅ 완료
코드 리뷰 수정 이력
Phase 3 코드 리뷰 → 반영 완료
Critical
KST 타임존 오프셋 버그addOneYearKST()의 수동 +9h 오프셋을 Intl.DateTimeFormat("Asia/Seoul")로 교체
Critical
엑셀 업로드 원자성 부재createMany()db.$transaction()으로 래핑하여 부분 INSERT 방지
Major
AdminUploadPage requireAdmin() 누락 — 서버 컴포넌트 진입점에 requireAdmin() 추가 (이중 보호)
Major
차감 모달 잔액 0 미처리currentBalance <= 0 조기 반환으로 차감 불가 안내
Minor
InsufficientBalanceError 문자열 비교instanceof InsufficientBalanceError로 교체, lib/errors.ts 분리
Minor
PointType 문자열 리터럴 중복 — Prisma 생성 enum PointTypetypes/index.ts에서 re-export
Phase 4 코드 리뷰 → 반영 완료
Critical
admin-logger try-catch 누락 — 디스크 쓰기 실패 시 API 500 방지, process.stderr.write로 fallback
Critical
rate-limit Map 메모리 누수setInterval().unref()로 5분마다 만료 엔트리 정리
Major
getJWTSecret() 4곳 중복lib/jwt.ts로 추출 후 middleware · auth · login · register 공유
Major
upload rate limit 순서 오류requireAdmin() 이후로 이동, 관리자 userId 기반 키 사용
Major
deduct rate limit 미적용deduct:admin:{userId} 기준 30/분 rate limit 추가
Major
seed upsert 비밀번호 덮어쓰기update 절에서 password 제거, create에만 포함
Minor
비관리자 리다이렉트 대상 오류/admin/login/dashboard로 변경
Minor
admin 회원목록에 admin 계정 노출where: { role: "user" } 필터 추가
Minor
remainingAmount null 단언 사용grant.remainingAmount!?? 0으로 교체
핵심 설계 원칙
🔐인증 분리
middleware.ts는 jose로 JWT 검증만. bcrypt는 Edge Runtime 불가 — Node.js Route Handler 전용
🛡️이중 권한 검증
Middleware 라우트 보호 + 모든 관리자 API 진입점에서 requireAdmin() 재검증
📊포인트 잔여액 산식
SUM(remaining_amount) WHERE type=grant AND expires_at>NOW() AND remaining_amount>0
FIFO 차감 트랜잭션
ORDER BY expires_at ASC · Prisma.$transaction Serializable · remainingAmount 감산 + deduct 로그 INSERT
🕐소멸 판별 멱등성
expires_at > NOW() 조건만 사용. GET 요청에서 절대 UPDATE 수행 금지
🗓️KST 타임존 처리
Intl.DateTimeFormat("Asia/Seoul")로 expires_at = granted_at + 1년 KST 자동 계산