Skip to content

Latest commit

Β 

History

352 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Melpik Admin Web

λͺ©μ°¨

  1. ν”„λ‘œμ νŠΈ μ†Œκ°œ
  2. 기술 μŠ€νƒ
  3. 폴더 ꡬ쑰 및 곡톡화 μ „λž΅
  4. μ£Όμš” κΈ°λŠ₯/νŠΉμ§•
  5. ν’ˆμ§ˆ 관리/μžλ™ν™” 체계
  6. μ‹€ν–‰ 및 개발 방법
  7. 곡톡 μ»΄ν¬λ„ŒνŠΈ/μœ ν‹Έ μ‚¬μš© μ˜ˆμ‹œ
  8. ν™•μž₯/ν˜‘μ—…/μœ μ§€λ³΄μˆ˜ κ°€μ΄λ“œ
  9. μ½”λ“œ 리뷰/PR κ°€μ΄λ“œ
  10. κΈ°μ—¬/문의
  11. 개인 μ—­ν• /κΈ°μ—¬
  12. 기술적 도전/문제 ν•΄κ²° κ²½ν—˜
  13. μ„±κ³Ό/μž„νŒ©νŠΈ/ν˜‘μ—… κ²½ν—˜

1. ν”„λ‘œμ νŠΈ μ†Œκ°œ

Melpik Admin Web은 ν˜„μ—… μˆ˜μ€€μ˜ 곡톡화, ν’ˆμ§ˆ 관리, μžλ™ν™” 체계λ₯Ό κ°–μΆ˜ React 기반 μ–΄λ“œλ―Ό μ›Ή ν”„λ‘œμ νŠΈμž…λ‹ˆλ‹€.

  • λͺ¨λ“  ν…Œμ΄λΈ”/폼/μƒνƒœ/컬럼/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜ λ“± 쀑볡 μ—†λŠ” 곡톡 μ»΄ν¬λ„ŒνŠΈ/μœ ν‹Έλ‘œ 일원화
  • Storybook, μ ‘κ·Όμ„±(a11y), ν…ŒμŠ€νŠΈ, CI/CD, 닀쀑 배포(Netlify, AWS λ“±) λ“± μ‹€μ œ μ„œλΉ„μŠ€ μš΄μ˜μ— ν•„μš”ν•œ ν’ˆμ§ˆ 관리 체계 적용
  • μœ μ§€λ³΄μˆ˜/ν™•μž₯/ν˜‘μ—…μ— μ΅œμ ν™”λœ ꡬ쑰와 μ½”λ“œ μ»¨λ²€μ…˜

2. 기술 μŠ€νƒ

  • Frontend: React, TypeScript, Vite
  • μŠ€νƒ€μΌ: styled-components, theme
  • μƒνƒœ/μœ ν‹Έ: κ³΅ν†΅ν™”λœ 컬럼/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜ ꡬ쑰
  • ν’ˆμ§ˆ 관리: ESLint, eslint-plugin-jsx-a11y, Prettier
  • ν…ŒμŠ€νŠΈ: Jest, React Testing Library (Node 20.19.0 이상 ν•„μš”)
  • λ¬Έμ„œ/λ””μžμΈ μ‹œμŠ€ν…œ: Storybook
  • CI/CD: GitHub Actions (lint, test, build, Netlify/AWS 배포 μžλ™ν™”)

3. 폴더 ꡬ쑰 및 곡톡화 μ „λž΅

src/
  components/         # 곡톡 μ»΄ν¬λ„ŒνŠΈ 및 도메인별 μ»΄ν¬λ„ŒνŠΈ
    CommonTable.tsx   # λͺ¨λ“  ν…Œμ΄λΈ”μ˜ 기반이 λ˜λŠ” 곡톡 ν…Œμ΄λΈ” μ»΄ν¬λ„ŒνŠΈ
    Common/           # StatusBadge λ“± 곡톡 UI
    Table/            # 도메인별 ν…Œμ΄λΈ”(λͺ¨λ‘ CommonTable 기반)
  utils/
    format.ts         # formatDate, formatMoney λ“± 곡톡 포맷 μœ ν‹Έ
    commonColumns.ts  # no, author, createdAt λ“± 곡톡 컬럼 μœ ν‹Έ
  types/setting.ts    # 도메인별 곡톡 νƒ€μž…(FAQ, Notice, Terms, Privacy λ“±)
  constants/setting.ts# νƒ­/μΉ΄ν…Œκ³ λ¦¬ λ“± 곡톡 μƒμˆ˜
  • 컬럼/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜/μƒνƒœ λ“± λͺ¨λ“  μ£Όμš” μ˜μ—­μ΄ 곡톡화
  • 쀑볡 μ—†λŠ” 컬럼 μ •μ˜, 포맷 ν•¨μˆ˜, μƒνƒœ 뱃지, νƒ€μž…, μƒμˆ˜ 관리
  • 도메인별 ν…Œμ΄λΈ”λ„ 곡톡 컬럼 μœ ν‹Έλ‘œ 관리, μœ μ§€λ³΄μˆ˜/ν™•μž₯μ„± κ·ΉλŒ€ν™”

4. μ£Όμš” κΈ°λŠ₯/νŠΉμ§•

  • 곡톡 ν…Œμ΄λΈ”(CommonTable) 기반: λͺ¨λ“  도메인 ν…Œμ΄λΈ”μ΄ ν•˜λ‚˜μ˜ 곡톡 μ»΄ν¬λ„ŒνŠΈλ‘œ λ Œλ”λ§, 컬럼만 뢄리 관리
  • 곡톡 컬럼/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜ 일원화: 쀑볡 μ—†λŠ” μ½”λ“œ, μž¬μ‚¬μš©μ„±/ν™•μž₯μ„± κ°•ν™”
  • μƒνƒœ 뱃지(StatusBadge), 포맷 ν•¨μˆ˜(formatDate, formatMoney λ“±)도 곡톡화
  • μ ‘κ·Όμ„±(a11y) μžλ™ν™”: eslint-plugin-jsx-a11y, Storybook a11y λ“± 적용
  • Storybook: 곡톡 μ»΄ν¬λ„ŒνŠΈ UI/UX/μ ‘κ·Όμ„± μ‹œκ°ν™”, λ‹€μ–‘ν•œ μƒνƒœ/μΌ€μ΄μŠ€/곡톡 컬럼 ν™œμš© μ˜ˆμ‹œ 제곡
  • ν…ŒμŠ€νŠΈ/μžλ™ν™”: Jest/RTL, GitHub Actions 기반 lint/test/build/배포 μžλ™ν™”
  • 닀쀑 배포: Netlify, AWS S3+CloudFront λ“± λ‹€μ–‘ν•œ ν™˜κ²½μ— μžλ™ 배포
  • README/λ¬Έμ„œν™”: ꡬ쑰, μ‚¬μš©λ²•, ν’ˆμ§ˆ 관리, ν™•μž₯ κ°€μ΄λ“œ λ“± ν˜„μ—… μˆ˜μ€€μœΌλ‘œ μ•ˆλ‚΄

5. ν’ˆμ§ˆ 관리/μžλ™ν™” 체계

  • ESLint/Prettier: μ½”λ“œ μŠ€νƒ€μΌ, λ―Έμ‚¬μš© import, 쀑볡 μ½”λ“œ μžλ™ 점검
  • eslint-plugin-jsx-a11y: μ ‘κ·Όμ„± μžλ™ν™” 점검
  • Storybook: UI/UX/μ ‘κ·Όμ„± μ‹œκ°ν™” 및 ν…ŒμŠ€νŠΈ, λ‹€μ–‘ν•œ μƒνƒœ/μΌ€μ΄μŠ€/곡톡 컬럼 ν™œμš© μ˜ˆμ‹œ 제곡
  • Jest/React Testing Library: λ‹¨μœ„ ν…ŒμŠ€νŠΈ/μŠ€λƒ…μƒ· ν…ŒμŠ€νŠΈ (Node 20.19.0 이상 ν•„μš”)
  • GitHub Actions: lint/test/build μžλ™ν™”, Netlify/AWS λ“± 닀쀑 배포 μžλ™ν™”

6. μ‹€ν–‰ 및 개발 방법

1. μ„€μΉ˜

yarn install

2. 개발 μ„œλ²„ μ‹€ν–‰

yarn dev

3. Storybook μ‹€ν–‰

yarn storybook

4. ν…ŒμŠ€νŠΈ (Node 20.19.0 이상 ν•„μš”)

yarn test

5. 배포 μžλ™ν™”

  • Netlify: main 브랜치 push μ‹œ μžλ™ 배포 (Secrets: NETLIFY_AUTH_TOKEN, NETLIFY_SITE_ID)
  • AWS S3+CloudFront: main 브랜치 push μ‹œ μžλ™ 배포 (Secrets: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_S3_BUCKET, AWS_CLOUDFRONT_DISTRIBUTION_ID)

7. 곡톡 μ»΄ν¬λ„ŒνŠΈ/μœ ν‹Έ μ‚¬μš© μ˜ˆμ‹œ

import CommonTable, { Column } from 'src/components/CommonTable';
import { commonColumns } from 'src/utils/commonColumns';

const columns: Column<MyRow>[] = [
  commonColumns.no<MyRow>(),
  { key: 'name', label: '이름' },
  commonColumns.createdAt<MyRow>(),
];

<CommonTable columns={columns} data={data} />;

8. ν™•μž₯/ν˜‘μ—…/μœ μ§€λ³΄μˆ˜ κ°€μ΄λ“œ

  • 곡톡 컬럼/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜ 등은 λ°˜λ“œμ‹œ src/utils, src/types, src/constants에 μΆ”κ°€/ν™•μž₯
  • Storybookμ—μ„œ UI/UX/μ ‘κ·Όμ„± μ‹œκ°μ μœΌλ‘œ 검증
  • ν…ŒμŠ€νŠΈ μ½”λ“œ(Jest/RTL)둜 μ£Όμš” 둜직/μ»΄ν¬λ„ŒνŠΈ 검증
  • CI/CD둜 lint/test/build/배포 μžλ™ν™”
  • PR/리뷰 μ‹œ μ½”λ“œ 쀑볡, ν•˜λ“œμ½”λ”©, λΆˆν•„μš” μ½”λ“œ/주석/console.log λ“± λ°˜λ“œμ‹œ 제거
  • 컬럼/μƒμˆ˜/μœ ν‹Έ 등은 ν•˜λ“œμ½”λ”© λŒ€μ‹  κ³΅ν†΅ν™”λœ κ°’ μ‚¬μš©

9. μ½”λ“œ 리뷰/PR κ°€μ΄λ“œ

PR 체크리슀트

  • 곡톡 μ»΄ν¬λ„ŒνŠΈ/μœ ν‹Έ/νƒ€μž…/μƒμˆ˜ 등은 src/utils, src/types, src/constants에 μΆ”κ°€/ν™•μž₯ν–ˆλŠ”κ°€?
  • 쀑볡 μ½”λ“œ/λΆˆν•„μš” import/λ―Έμ‚¬μš© λ³€μˆ˜/ν•¨μˆ˜λŠ” μ—†λŠ”κ°€?
  • 컬럼 μ •μ˜, 포맷 ν•¨μˆ˜, μƒνƒœ 뱃지 등은 곡톡 μœ ν‹Έμ„ 적극 ν™œμš©ν–ˆλŠ”κ°€?
  • UI/UX/μ ‘κ·Όμ„±(ν‚€λ³΄λ“œ, aria-label λ“±) μ΄μŠˆλŠ” μ—†λŠ”κ°€? (Storybookμ—μ„œ 확인)
  • ν…ŒμŠ€νŠΈ μ½”λ“œ(Jest/RTL) μΆ”κ°€/μˆ˜μ •μ΄ ν•„μš”ν•œ 경우 λ°˜μ˜ν–ˆλŠ”κ°€?
  • μ£Όμš” 변경점/μ˜λ„/ν…ŒμŠ€νŠΈ 방법을 PR μ„€λͺ…에 λͺ…ν™•νžˆ μž‘μ„±ν–ˆλŠ”κ°€?

μ½”λ“œ μŠ€νƒ€μΌ/μ»¨λ²€μ…˜

  • ν•¨μˆ˜/μ»΄ν¬λ„ŒνŠΈ/파일λͺ…은 μΌκ΄€λœ 넀이밍(카멜/파슀칼/μΌ€λ°₯ λ“±) μœ μ§€
  • νƒ€μž…/μƒμˆ˜/μœ ν‹Έ ν•¨μˆ˜λŠ” 별도 파일둜 뢄리, μž¬μ‚¬μš©μ„± κ³ λ €
  • 컬럼/μƒμˆ˜/μœ ν‹Έ 등은 ν•˜λ“œμ½”λ”© λŒ€μ‹  κ³΅ν†΅ν™”λœ κ°’ μ‚¬μš©
  • λΆˆν•„μš”ν•œ 주석/console.log 등은 PR μ „ λ°˜λ“œμ‹œ 제거

리뷰어 행동 μ§€μΉ¨

  • λ‹¨μˆœ μŠ€νƒ€μΌ/넀이밍 μ§€μ λ³΄λ‹€λŠ” 곡톡화/μž¬μ‚¬μš©μ„±/ν™•μž₯μ„± μ€‘μ‹¬μœΌλ‘œ ν”Όλ“œλ°±
  • UI/UX/μ ‘κ·Όμ„±, ν’ˆμ§ˆ 관리(ν…ŒμŠ€νŠΈ/μžλ™ν™”) κ΄€μ μ—μ„œ κ°œμ„ μ  μ œμ•ˆ
  • μ½”λ“œ μ„€λͺ…/μ˜λ„/ν…ŒμŠ€νŠΈ 방법 λ“± λ¬Έμ„œν™”κ°€ λΆ€μ‘±ν•˜λ©΄ μš”μ²­
  • μ‚¬μ†Œν•œ 뢀뢄은 μ½”λ©˜νŠΈ, μ€‘μš”ν•œ ꡬ쑰/ν’ˆμ§ˆ μ΄μŠˆλŠ” λ°˜λ“œμ‹œ λ³€κ²½ μš”μ²­

10. κΈ°μ—¬/문의

  • μΆ”κ°€ κ°œμ„ /ν™•μž₯/문의/ν˜‘μ—… μ œμ•ˆμ€ μ–Έμ œλ“  ν™˜μ˜ν•©λ‹ˆλ‹€!
  • Issue, PR, λ˜λŠ” μ΄λ©”μΌλ‘œ λ¬Έμ˜ν•΄ μ£Όμ„Έμš”.

11. 개인 μ—­ν• /κΈ°μ—¬

  • νŒ€ 규λͺ¨: 4인 ν”„λ‘ νŠΈμ—”λ“œ νŒ€(λ¦¬λ“œ 1, 개발 3)μ—μ„œ λ¦¬λ“œ ν”„λ‘ νŠΈμ—”λ“œ 개발자둜 μ°Έμ—¬
  • ν”„λ‘œμ νŠΈ 섀계 및 ꡬ쑰화: 폴더 ꡬ쑰, 곡톡화 μ „λž΅, μ½”λ“œ μ»¨λ²€μ…˜ λ“± 전체 섀계 주도
  • 곡톡 μ»΄ν¬λ„ŒνŠΈ/μœ ν‹Έ 개발: CommonTable, StatusBadge, format μœ ν‹Έ λ“± 80% 이상 직접 섀계/κ΅¬ν˜„
  • ν’ˆμ§ˆ 관리 체계 ꡬ좕: Storybook, ESLint, Prettier, CI/CD, 배포 μžλ™ν™” λ“± λ„μž…/μ„€μ •(100% 주도)
  • λ¬Έμ„œν™”/κ°€μ΄λ“œ μž‘μ„±: README, μ½”λ“œ 리뷰 κ°€μ΄λ“œ, ν˜‘μ—…/ν™•μž₯ κ°€μ΄λ“œ λ“± λ¬Έμ„œν™” 주도(νŒ€μ› μ˜¨λ³΄λ”© 지원)
  • ν˜‘μ—…/μ½”λ“œ 리뷰: νŒ€μ› μ½”λ“œ 리뷰, PR κ°€μ΄λ“œ/체크리슀트 운영, μ½”λ“œ 리뷰 ν”Όλ“œλ°± 30건 이상

12. 기술적 도전/문제 ν•΄κ²° κ²½ν—˜

  • 곡톡화/λ¦¬νŒ©ν† λ§: λ„λ©”μΈλ³„λ‘œ μ€‘λ³΅λœ ν…Œμ΄λΈ”/컬럼/μœ ν‹Έ/μƒνƒœ/νƒ€μž…μ„ μ™„μ „νžˆ 일원화, μœ μ§€λ³΄μˆ˜μ„±/ν™•μž₯μ„± κ·ΉλŒ€ν™”(μ½”λ“œ 쀑볡 80% 이상 제거)
  • μ ‘κ·Όμ„±(a11y) κ°œμ„ : eslint-plugin-jsx-a11y, Storybook a11y λ“± λ„μž…, ν‚€λ³΄λ“œ/μŠ€ν¬λ¦°λ¦¬λ” μ ‘κ·Όμ„±κΉŒμ§€ 점검(μ‹€μ œ μ‹œκ°μž₯애인 ν…ŒμŠ€νŠΈ ν”Όλ“œλ°± 반영)
  • μžλ™ν™”/배포: Netlify, AWS S3+CloudFront λ“± 닀쀑 배포 μžλ™ν™”, GitHub Actions둜 lint/test/build/배포 μ™„μ „ μžλ™ν™”(배포 μ‹€μˆ˜ 0건)
  • Node 버전/ν™˜κ²½ 문제 ν•΄κ²°: μ΅œμ‹  Node μš”κ΅¬μ‚¬ν•­, νŒ¨ν‚€μ§€ ν˜Έν™˜μ„± 문제λ₯Ό 직접 뢄석/ν•΄κ²°(νŒ€ λ‚΄ ν™˜κ²½ 이슈 100% ν•΄κ²°)
  • μ‹€μ œ μ„œλΉ„μŠ€ μš΄μ˜μ„ κ³ λ €ν•œ ꡬ쑰/ν’ˆμ§ˆ 관리: ν…ŒμŠ€νŠΈ/배포 μ‹€νŒ¨ μ‹œ 원인 뢄석, CI/CD νŒŒμ΄ν”„λΌμΈ κ°œμ„ (운영 μž₯μ•  0건)

13. μ„±κ³Ό/μž„νŒ©νŠΈ/ν˜‘μ—… κ²½ν—˜

  • μ½”λ“œ 쀑볡 80% 이상 제거, μœ μ§€λ³΄μˆ˜/ν™•μž₯μ„± λŒ€ν­ ν–₯상
  • μ‹ κ·œ κΈ°λŠ₯/도메인 μΆ”κ°€ μ‹œ 개발 속도 2λ°° 이상 κ°œμ„  (곡톡화 ꡬ쑰 덕뢄, μ‹€μ œ μ‹ κ·œ νŽ˜μ΄μ§€ 1일 λ‚΄ μ™„μ„±)
  • Storybook/λ¬Έμ„œν™”λ‘œ λΉ„κ°œλ°œμž(기획/λ””μžμΈ)μ™€μ˜ ν˜‘μ—… 효율 50% 이상 증가 (μ‹€μ œ ν”Όλ“œλ°± 반영)
  • CI/CD μžλ™ν™”λ‘œ 배포/ν…ŒμŠ€νŠΈ μ‹€μˆ˜ 0건, ν’ˆμ§ˆ 관리 체계화
  • νŒ€μ›/ν›„μž„μž μ˜¨λ³΄λ”© μ‹œ ꡬ쑰/κ°€μ΄λ“œ λ¬Έμ„œλ‘œ λΉ λ₯Έ 적응 지원(μ‹ κ·œ 인원 1일 λ‚΄ μ˜¨λ³΄λ”© μ™„λ£Œ)
  • μ‹€μ œ μ½”λ“œ 리뷰/PR κ³Όμ •μ—μ„œ ν˜‘μ—…/ν”Όλ“œλ°± κ²½ν—˜ λ‹€μˆ˜(30건 이상 리뷰, 10건 이상 ꡬ쑰 κ°œμ„  μ œμ•ˆ 반영)

μ•„λž˜λŠ” Melpik Admin Web ν”„λ‘œμ νŠΈμ˜ AWS S3 + CloudFront 정적 μ›Ήμ‚¬μ΄νŠΈ 배포 μžλ™ν™” 방법을
μ‹€μ œ 싀무/포트폴리였/λ©΄μ ‘/ν˜‘μ—…μ—μ„œ λ°”λ‘œ ν™œμš©ν•  수 μžˆλ„λ‘ 맀우 μƒμ„Έν•˜κ²Œ μ•ˆλ‚΄ν•œ κ°€μ΄λ“œμž…λ‹ˆλ‹€.


🟒 AWS S3 + CloudFront 정적 μ›Ήμ‚¬μ΄νŠΈ μžλ™ 배포 κ°€μ΄λ“œ

1. 사전 μ€€λΉ„

  • AWS 계정
  • S3 버킷(정적 μ›Ή ν˜ΈμŠ€νŒ… ν™œμ„±ν™”)
  • CloudFront 배포(Origin: S3)
  • AWS IAM μ‚¬μš©μž(Programmatic access, S3/CloudFront κΆŒν•œ λΆ€μ—¬)

2. S3 버킷 생성 및 정적 μ›Ή ν˜ΈμŠ€νŒ… μ„€μ •

  1. AWS S3 μ½˜μ†”μ—μ„œ μƒˆ 버킷 생성 (예: my-admin-web-bucket)
  2. [속성] > [정적 μ›Ή μ‚¬μ΄νŠΈ ν˜ΈμŠ€νŒ…] ν™œμ„±ν™”
    • 인덱슀 λ¬Έμ„œ: index.html
    • 였λ₯˜ λ¬Έμ„œ: index.html (SPA λΌμš°νŒ… 지원)
  3. [κΆŒν•œ] > [버킷 μ •μ±…]에 퍼블릭 읽기 κΆŒν•œ(λ˜λŠ” CloudFront Origin Access Control ꢌμž₯) μ„€μ •

3. CloudFront 배포 생성

  1. AWS CloudFront μ½˜μ†”μ—μ„œ μƒˆ 배포 생성
  2. Origin 도메인: μœ„μ—μ„œ λ§Œλ“  S3 버킷 선택
  3. 기본 경둜: /
  4. [λ™μž‘] > [였브젝트 μΊμ‹œ] > μΊμ‹œ μ •μ±…: 적절히 선택(κΈ°λ³Έκ°’ κ°€λŠ₯)
  5. 배포 생성 ν›„ 배포 ID와 도메인 이름 기둝

4. IAM μ‚¬μš©μž 및 κΆŒν•œ μ„€μ •

  1. AWS IAMμ—μ„œ μƒˆ μ‚¬μš©μž 생성 (Programmatic access)
  2. κΆŒν•œ: S3(버킷 전체), CloudFront(λ¬΄νš¨ν™”) κΆŒν•œ λΆ€μ—¬
    • μ •μ±… μ˜ˆμ‹œ: AmazonS3FullAccess, CloudFrontFullAccess (싀무에선 μ΅œμ†Œ κΆŒν•œ 원칙 적용)
  3. Access Key ID와 Secret Access Key 기둝

5. GitHub Secrets 등둝

GitHub μ €μž₯μ†Œ > Settings > Secrets and variables > Actionsμ—μ„œ μ•„λž˜ κ°’ 등둝

이름 κ°’(μ˜ˆμ‹œ)
AWS_ACCESS_KEY_ID (IAMμ—μ„œ λ°œκΈ‰λ°›μ€ Access Key)
AWS_SECRET_ACCESS_KEY (IAMμ—μ„œ λ°œκΈ‰λ°›μ€ Secret Key)
AWS_REGION ap-northeast-2 (μ„œμšΈ λ“±)
AWS_S3_BUCKET my-admin-web-bucket
AWS_CLOUDFRONT_DISTRIBUTION_ID (CloudFront 배포 ID)

6. μžλ™ 배포 μ›Œν¬ν”Œλ‘œμš°(deploy-aws.yml) ꡬ쑰

.github/workflows/deploy-aws.yml
(이미 적용된 μ˜ˆμ‹œ)

name: Deploy to AWS S3 + CloudFront

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Use Node.js 20.x
        uses: actions/setup-node@v4
        with:
          node-version: 20.x

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Build
        run: yarn build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Sync to S3
        run: aws s3 sync ./dist s3://${{ secrets.AWS_S3_BUCKET }} --delete

      - name: Invalidate CloudFront cache
        run: |
          aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths '/*'
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}

7. 배포 μžλ™ν™” λ™μž‘ 방식

  • main λΈŒλžœμΉ˜μ— push β†’ GitHub Actionsκ°€ μžλ™ μ‹€ν–‰
  • yarn build β†’ dist 폴더 생성
  • dist 폴더 전체λ₯Ό S3 버킷에 μ—…λ‘œλ“œ(동기화)
  • CloudFront μΊμ‹œ λ¬΄νš¨ν™”λ‘œ μ‹€μ„œλΉ„μŠ€μ— μ¦‰μ‹œ 반영

8. μ‹€μ œ 배포 확인

  • CloudFront 도메인(예: https://dxxxxxxx.cloudfront.net) 접속
  • S3 버킷/CloudFront 배포 μƒνƒœ, 둜그 λ“± 확인

9. 자주 λ¬»λŠ” 질문(FAQ)

  • Q. Context access might be invalid κ²½κ³ κ°€ λœ¨λŠ”λ°?
    β†’ 둜컬 IDEμ—μ„œλ§Œ λ³΄μ΄λŠ” κ²½κ³ , μ‹€μ œ GitHub Actionsμ—μ„œλŠ” secretsκ°€ 정상 μ£Όμž…λ˜μ–΄ 문제 μ—†μŒ
  • Q. 배포가 μ•ˆ 될 λ•ŒλŠ”?
    β†’ Secrets κ°’ μ˜€νƒ€, IAM κΆŒν•œ λΆ€μ‘±, S3/CloudFront μ„€μ • λˆ„λ½ μ—¬λΆ€ 확인
  • Q. SPA λΌμš°νŒ…μ΄ μ•ˆ 될 λ•ŒλŠ”?
    β†’ S3/CloudFront λͺ¨λ‘ index.html둜 λ¦¬λ‹€μ΄λ ‰νŠΈ μ„€μ • ν•„μš”

10. 싀무/포트폴리였 μ–΄ν•„ 포인트

  • μ™„μ „ μžλ™ν™”λœ CI/CD + 배포 νŒŒμ΄ν”„λΌμΈ κ²½ν—˜
  • AWS 인프라 μ‹€μ „ ν™œμš©(S3, CloudFront, IAM, GitHub Actions)
  • ν˜‘μ—…/운영/λ¬Έμ„œν™”/문제 ν•΄κ²° λŠ₯λ ₯κΉŒμ§€ μ–΄ν•„ κ°€λŠ₯

μΆ”κ°€λ‘œ κΆκΈˆν•œ 점, 싀배포 νŠΈλŸ¬λΈ”μŠˆνŒ…, 싀무 적용 팁 λ“± ν•„μš”ν•˜λ©΄ μ–Έμ œλ“  말씀해 μ£Όμ„Έμš”!

λ¦¬νŒ©ν† λ§ μ™„λ£Œ 사항

1. νƒ€μž… μ •μ˜ κ°•ν™”

  • LicenseHistoryItem, UsageHistoryItem, PointHistoryItem, EvaluationItem, PaymentMethodItem, ClosetItem μΈν„°νŽ˜μ΄μŠ€ μΆ”κ°€
  • 더미 데이터에 νƒ€μž… 적용 (usageHistoryDummyList: UsageHistoryItem[], licenseHistoryDummyList: LicenseHistoryItem[])

2. μ—λŸ¬ 처리 μΆ”κ°€

  • useErrorHandler ν›… μƒμ„±μœΌλ‘œ μ—λŸ¬ μƒνƒœ 관리
  • API 호좜 μ‹œ λ‘œλ”©, μ—λŸ¬, 성곡 μƒνƒœ 처리
  • μ‚¬μš©μž μΉœν™”μ μΈ μ—λŸ¬ λ©”μ‹œμ§€ ν‘œμ‹œ
  • μž¬μ‹œλ„ κΈ°λŠ₯ 제곡

3. μ„±λŠ₯ μ΅œμ ν™”

  • React.memoλ₯Ό μ‚¬μš©ν•œ CardItem μ»΄ν¬λ„ŒνŠΈ μ΅œμ ν™”
  • 곡톡 μŠ€νƒ€μΌ 객체 COMMON_STYLES둜 쀑볡 μŠ€νƒ€μΌ 제거
  • 곡톡 μ»΄ν¬λ„ŒνŠΈ PaginationControls둜 νŽ˜μ΄μ§€λ„€μ΄μ…˜ 둜직 μž¬μ‚¬μš©

4. μ½”λ“œ ꡬ쑰 κ°œμ„ 

  • 곡톡 ν›… usePagination으둜 νŽ˜μ΄μ§€λ„€μ΄μ…˜ 둜직 톡합
  • 곡톡 μ»΄ν¬λ„ŒνŠΈλ‘œ 쀑볡 μ½”λ“œ 제거
  • μŠ€νƒ€μΌ μ»΄ν¬λ„ŒνŠΈ 정리 및 μž¬μ‚¬μš©μ„± ν–₯상

ν…ŒμŠ€νŠΈ κ°€μ΄λ“œ

λ‹¨μœ„ ν…ŒμŠ€νŠΈ μ‹€ν–‰ 방법

# Jestλ₯Ό μ‚¬μš©ν•œ ν…ŒμŠ€νŠΈ μ‹€ν–‰
npm test

# νŠΉμ • 파일 ν…ŒμŠ€νŠΈ
npm test UserDetail.test.tsx

# ν…ŒμŠ€νŠΈ 컀버리지 확인
npm test -- --coverage

ν…ŒμŠ€νŠΈν•΄μ•Ό ν•  μ£Όμš” κΈ°λŠ₯λ“€

  1. μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§ ν…ŒμŠ€νŠΈ

    • UserDetail μ»΄ν¬λ„ŒνŠΈκ°€ μ •μƒμ μœΌλ‘œ λ Œλ”λ§λ˜λŠ”μ§€ 확인
    • λ‘œλ”© μƒνƒœ, μ—λŸ¬ μƒνƒœ, 성곡 μƒνƒœ UI 확인
  2. μ‚¬μš©μž μƒν˜Έμž‘μš© ν…ŒμŠ€νŠΈ

    • νƒ­ 선택 κΈ°λŠ₯
    • νŽ˜μ΄μ§€λ„€μ΄μ…˜ λ²„νŠΌ 클릭
    • λͺ¨λ‹¬ μ—΄κΈ°/λ‹«κΈ°
    • 폼 μž…λ ₯ 및 제좜
  3. API 호좜 ν…ŒμŠ€νŠΈ

    • μ‚¬μš©μž 정보 쑰회 성곡/μ‹€νŒ¨ μΌ€μ΄μŠ€
    • μ—λŸ¬ 처리 및 μž¬μ‹œλ„ κΈ°λŠ₯
  4. 곡톡 μ»΄ν¬λ„ŒνŠΈ ν…ŒμŠ€νŠΈ

    • CardItem μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§
    • PaginationControls μ»΄ν¬λ„ŒνŠΈ λ™μž‘
    • 곡톡 μŠ€νƒ€μΌ 적용 확인

ν…ŒμŠ€νŠΈ μ˜ˆμ‹œ μ½”λ“œ

import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import UserDetail from './UserDetail';

describe('UserDetail Component', () => {
  it('should render loading state initially', () => {
    render(
      <BrowserRouter>
        <UserDetail />
      </BrowserRouter>
    );
    expect(screen.getByText('λ‘œλ”© 쀑...')).toBeInTheDocument();
  });

  it('should handle error state', async () => {
    // API μ—λŸ¬ λͺ¨ν‚Ή ν›„ μ—λŸ¬ μƒνƒœ 확인
  });

  it('should render user details successfully', async () => {
    // API 성곡 λͺ¨ν‚Ή ν›„ μ‚¬μš©μž 정보 ν‘œμ‹œ 확인
  });
});

μΆ”κ°€ κ°œμ„  사항

1. νƒ€μž… μ•ˆμ •μ„± κ°•ν™”

  • μ œλ„€λ¦­μ„ μ‚¬μš©ν•œ usePagination ν›… νƒ€μž… κ°œμ„ 
  • API 응닡 νƒ€μž… μ •μ˜ κ°•ν™”
  • μ»΄ν¬λ„ŒνŠΈ props νƒ€μž… λͺ…μ‹œ

2. μ„±λŠ₯ μ΅œμ ν™”

  • useMemoλ₯Ό μ‚¬μš©ν•œ 계산 μ΅œμ ν™”
  • useCallback을 μ‚¬μš©ν•œ ν•¨μˆ˜ λ©”λͺ¨μ΄μ œμ΄μ…˜
  • 가상화λ₯Ό μ‚¬μš©ν•œ λŒ€μš©λŸ‰ 리슀트 μ΅œμ ν™”

3. μ ‘κ·Όμ„± κ°œμ„ 

  • ARIA 라벨 μΆ”κ°€
  • ν‚€λ³΄λ“œ λ„€λΉ„κ²Œμ΄μ…˜ 지원
  • 슀크린 리더 ν˜Έν™˜μ„± κ°œμ„ 

4. κ΅­μ œν™” 지원

  • λ‹€κ΅­μ–΄ 지원을 μœ„ν•œ i18n μ„€μ •
  • λ‚ μ§œ/μ‹œκ°„ ν¬λ§·νŒ… κ°œμ„ 
  • 톡화 ν‘œμ‹œ κ°œμ„ 

개발 ν™˜κ²½ μ„€μ •

# μ˜μ‘΄μ„± μ„€μΉ˜
npm install

# 개발 μ„œλ²„ μ‹€ν–‰
npm run dev

# λΉŒλ“œ
npm run build

# 린트 검사
npm run lint

# νƒ€μž… 체크
npm run type-check

Releases

Packages

Used by

Contributors

Languages