Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
239a636
docs : basic 요구사항 문서 추가
Hwirin-Kim Jul 28, 2025
4546943
fix : Header 컴포넌트 형식으로 분리
Hwirin-Kim Jul 28, 2025
3ef5fd0
fix : header 주석 변경
Hwirin-Kim Jul 28, 2025
bab7584
fix : productIds, productList 분리
Hwirin-Kim Jul 29, 2025
34bc572
fix : 할인 타이머 분리 완료
Hwirin-Kim Jul 29, 2025
df8af33
fix : onUpdateSelectOptions 수정
Hwirin-Kim Jul 29, 2025
cca6702
fix : select관련 util함수들 같은 폴더로 이동
Hwirin-Kim Jul 29, 2025
f57a0c4
fix : store 구조 변경
Hwirin-Kim Jul 29, 2025
4cd968d
fix : cartStore생성
Hwirin-Kim Jul 29, 2025
ba46c57
fix : lowStockItems 관련 코드 삭제 (쓰이지않음)
Hwirin-Kim Jul 29, 2025
89ae20a
fix : handleCalculate 즉시실행함수 제거
Hwirin-Kim Jul 29, 2025
68661ec
fix : 할인율 계산 분리
Hwirin-Kim Jul 29, 2025
98bd366
fix : 이중for문 제거하고 find로 대체
Hwirin-Kim Jul 29, 2025
f5bb0c4
fix : checkHasItem으로 묶기
Hwirin-Kim Jul 29, 2025
0a6734f
fix : addBtn 이벤트 함수에 스토어 적용
Hwirin-Kim Jul 30, 2025
49700c9
fix : todo - 카트 업데이트는 성공, 장바구니 화면은 아직 실패
Hwirin-Kim Jul 30, 2025
d18f3a6
fix : action에서 조회함수 삭제 및 액션추가 변경
Hwirin-Kim Jul 30, 2025
d09c439
fix : 불필요한 onUpdateSelectOptions호출 삭제
Hwirin-Kim Jul 30, 2025
fdbf42b
fix : store수정 - getter 타입 구분용
Hwirin-Kim Jul 30, 2025
c4e0a09
fix : action type 객체형식으로 수정
Hwirin-Kim Jul 30, 2025
0186dea
fix : addBtn 이벤트함수 구조변경
Hwirin-Kim Jul 30, 2025
8d366ea
fix : 이벤트 분리 완료
Hwirin-Kim Jul 30, 2025
64c2117
fix : handleCalculateCartStuff함수에 주석 추가 (해석용)
Hwirin-Kim Jul 30, 2025
5dfdd15
fix : render와 계산 분리
Hwirin-Kim Jul 30, 2025
a689854
fix : doRenderBonusPoints도 store기반으로 변경
Hwirin-Kim Jul 30, 2025
6cd612b
fix : doRenderBonusPoints를 계산함수에 분리해서 합침
Hwirin-Kim Jul 30, 2025
dfaf7df
fix : 좀 더 추상화
Hwirin-Kim Jul 30, 2025
d915280
fix : doUpdatePricesInCart함수도 변경 완료
Hwirin-Kim Jul 30, 2025
9522923
fix : 데이터관련 전역변수 모두 제거 완료
Hwirin-Kim Jul 30, 2025
e220740
fix : ui로직 분리
Hwirin-Kim Jul 30, 2025
368013d
fix : main함수에 초기화 함수들만 존재
Hwirin-Kim Jul 30, 2025
ee0df0c
fix : 상품 가격 안줄어드는 버그 수정
Hwirin-Kim Jul 30, 2025
5bb7143
fix : main정리
Hwirin-Kim Jul 30, 2025
447bd3b
fix : 인덱스 모듈로 병합
Hwirin-Kim Jul 30, 2025
1ceb31d
fix : 테스트 안되는 문제 해결..
Hwirin-Kim Jul 30, 2025
84c79f6
fix : 변수명 변경
Hwirin-Kim Jul 30, 2025
e642656
fix : 변수명 변경
Hwirin-Kim Jul 30, 2025
349ecda
fix : 매직넘버 변경
Hwirin-Kim Jul 30, 2025
ddcf1d2
fix : 매직넘버 변경
Hwirin-Kim Jul 30, 2025
f0408c8
fix : 매직넘버 변경
Hwirin-Kim Jul 30, 2025
3cc4880
chore : prettier, eslint 설정
Hwirin-Kim Jul 30, 2025
7ae477e
docs : 주석변경
Hwirin-Kim Jul 30, 2025
f10e0c2
docs : 주석변경
Hwirin-Kim Jul 30, 2025
8f8da83
docs : 주석변경
Hwirin-Kim Jul 30, 2025
b606a28
docs : 주석변경
Hwirin-Kim Jul 30, 2025
e3768e3
remove : 사용하지 않는 함수 제거
Hwirin-Kim Jul 30, 2025
3653d2d
fix : es6+ 문법으로 개선
Hwirin-Kim Jul 30, 2025
2e6ffed
fix : 변수명 변경
Hwirin-Kim Jul 30, 2025
787936c
feat : ui컴포넌트 및 테스트 코드 작성
Hwirin-Kim Jul 31, 2025
445cbec
chore : config설정
Hwirin-Kim Jul 31, 2025
938c445
feat : context 설정 및 재고 관리
Hwirin-Kim Jul 31, 2025
217a2d1
fix : 재고 변경 로직 수정
Hwirin-Kim Jul 31, 2025
91b0b9c
fix : test코드 잘못설계된 부분 변경
Hwirin-Kim Jul 31, 2025
5ae7be4
fix : 테스트 코드 수정
Hwirin-Kim Jul 31, 2025
cfff9b7
feat : 할인로직 적용 및 테스트코드 수정
Hwirin-Kim Jul 31, 2025
05d9e3c
fix : UI 원본하고 다른 부분 수정
Hwirin-Kim Jul 31, 2025
d872ef7
fix : 화면에 할인 중복 표시 제거
Hwirin-Kim Jul 31, 2025
0615b59
feat : 추천할인, 번개할인, 테스트코드 작성 완료
Hwirin-Kim Jul 31, 2025
51bb6d0
fix : 초기 상품 선택 되어있도록 변경
Hwirin-Kim Jul 31, 2025
357b00e
refactor : 커서가 해준 리팩토링..
Hwirin-Kim Jul 31, 2025
fcae52b
fix : 재고 음수 문제 수정
Hwirin-Kim Jul 31, 2025
47ada16
remove : 사용하지않는 함수 및 변수 제거
Hwirin-Kim Jul 31, 2025
0c0cb0d
deploy : 배포설정
Hwirin-Kim Jul 31, 2025
0b110ad
refactor : 순수함수 분리
Hwirin-Kim Jul 31, 2025
c6d19ba
docs : 주석 변경
Hwirin-Kim Jul 31, 2025
1f3a786
fix : 재고 문제 해결
Hwirin-Kim Jul 31, 2025
cc18ddb
fix : 타이머알럿 중복적용되는 문제 해결
Hwirin-Kim Jul 31, 2025
e4feab0
CI : advanced test CI
Hwirin-Kim Jul 31, 2025
158341d
Merge branch 'main' into CI-merge
Hwirin-Kim Jul 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
dist
build
coverage
.git
.DS_Store
*.log
pnpm-lock.yaml
package-lock.json
yarn.lock
*.html
41 changes: 41 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": ["eslint:recommended", "prettier"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-unused-vars": "warn",
"no-console": "warn",
"prefer-const": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-template": "error",
"template-curly-spacing": "error",
"arrow-spacing": "error",
"no-duplicate-imports": "error",
"no-useless-rename": "error",
"prefer-destructuring": "warn",
"no-magic-numbers": "warn",
"complexity": ["warn", 10],
"max-depth": ["warn", 4],
"max-lines-per-function": ["warn", 50],
"max-params": ["warn", 4]
},
"overrides": [
{
"files": ["**/*.test.js", "**/__tests__/**/*.js"],
"env": {
"jest": true
},
"rules": {
"no-console": "off"
}
}
]
}
26 changes: 17 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@ jobs:
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- uses: actions/setup-node@v4
with:
node-version: 22

- uses: pnpm/action-setup@v2
with:
version: latest

node-version: 20
- name: test basic
run: |
pnpm install
pnpm run test:basic
npm install
npm run test:basic
advanced:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: advanced-test
run: |
npm install
npm run test:advanced
10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
dist
build
coverage
.git
.DS_Store
*.log
pnpm-lock.yaml
package-lock.json
yarn.lock
15 changes: 15 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf",
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"proseWrap": "preserve"
}
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
이번 과제는 더티코드를 클린코드의 형태로 개선을 하는 과제입니다. 주어진 테스트를 통과하면서 원래 기능과 동일한 동작을 하는 코드를 만들어주세요. basic과제는 제공되는 더티코드를 클린코드와 리팩토링 원칙에 입각해서 더 나은 코드로 만들어보세요. 주어진 테스트를 참고삼아 좋은 이름, 좋은 모양, 좋은 구조를 가지는 코드로 만들어 보세요.

[목표]

- /basic 디렉토리에 있는 더티코드를 클린코드로 리팩토링
- 바닐라스크립트를 사용해서 작성된 코드를 클린코드와 리팩토링 원칙에 입각해서 더 나은 코드로 개선
- 추후 React + Typescript로 고도화 리팩토링을 할 예정이니 이를 꼭 염두에 두고 React로 바꿔도 코드가 많이 변경되지 않도록 리팩토링
Expand All @@ -17,26 +18,65 @@
- = 어플리케이션 요구사항을 모두 만족할 것 (/docs/PRD.md 참고)

[과제의 취지]

- 나쁜 코드를 몸으로 충분히 느껴보고, 왜 나쁜 코드를 쓰는 것이 나쁜지 이해하기
- 나쁘지 않은 코드만으로 충분하지 않다는 것을 이해하기
- 더 좋은 코드란 무엇인지를 고민하며 나의 코드 취향과 코드 감각 이해하기


## 심확과제: 유지보수 하기 좋은 코드만들기

심화과제는 **기본과제에서 작성한 코드를 기술고도화를 하는 것입니다.** 바닐라 자바스크립트로 되어 있는 코드를 유지보수하기에 유리한 기술스택(React + Typescript)으로 고도화 리팩토링을 진행해주세요.
우리의 목표는 앞으로 유지보수를 더 잘할 수 있도록 하기 위함입니다. 최소 React와 Typescript를 이용한 코드로 개선해주세요. 그 밖의 기술선택과 폴더/파일 구조, 테스트 코드등은 자유입니다.

[목표]

- /advanced 디렉토리에 있는 기본과제 코드를 React + Typescript로 고도화 리팩토링
- /basic 기본과제에서 작성한 코드를 복사해서 /advanced 디렉토리에서 고도화 리팩토링 진행
- 기본과제에서 작성한 코드를 React + Typescript로 고도화 리팩토링

[과제의 취지]

- React가 어떻게 유지보수하기 좋은 코드로 만들어주는지 이해하기
- Typescript가 어떻게 유지보수하기 좋은 코드로 만들어주는지 이해하기
- 내가 추구하는 좋은 코드와 React가 추구하는 코드와 어떻게 다른지 이해하기

## 개발 환경 설정

### 코드 품질 도구

이 프로젝트는 Prettier와 ESLint를 사용하여 코드 품질을 관리합니다.

#### 설치된 도구들

- **Prettier**: 코드 포맷팅
- **ESLint**: 코드 품질 검사 및 자동 수정

#### 사용 가능한 스크립트

```bash
# 코드 품질 검사
pnpm run code:check

# 코드 자동 수정
pnpm run code:fix

# ESLint만 실행
pnpm run lint
pnpm run lint:fix

# Prettier만 실행
pnpm run format
pnpm run format:check
```

#### VS Code 설정

VS Code에서 자동 포맷팅과 린팅을 사용하려면 다음 확장 프로그램을 설치하세요:

- ESLint (`dbaeumer.vscode-eslint`)
- Prettier (`esbenp.prettier-vscode`)

설치 후 파일 저장 시 자동으로 포맷팅과 린팅이 적용됩니다.

## 요청사항

Expand Down
69 changes: 69 additions & 0 deletions docs/basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## 기본과제: 더티코드 개선

이번 과제는 더티코드를 클린코드의 형태로 개선을 하는 과제입니다. 주어진 테스트를 통과하면서 원래 기능과 동일한 동작을 하는 코드를 만들어주세요. basic과제는 제공되는 더티코드를 클린코드와 리팩토링 원칙에 입각해서 더 나은 코드로 만들어보세요. 주어진 테스트를 참고삼아 좋은 이름, 좋은 모양, 좋은 구조를 가지는 코드로 만들어 보세요.

### **1) 과제 세부 내용**

[목표]

- /basic 디렉토리에 있는 더티코드를 클린코드로 리팩토링
- 바닐라스크립트를 사용해서 작성된 코드를 클린코드와 리팩토링 원칙에 입각해서 더 나은 코드로 개선
- 추후 React + Typescript로 고도화 리팩토링을 할 예정이니 이를 꼭 염두에 두고 React로 바꿔도 코드가 많이 변경되지 않도록 리팩토링

[필수조건]

- Prettier와 ESLint를 설치해서 적용할 것
- 테스트 코드 모두 통과할 것
- = 기존 기능과 동일하게 동작할 것
- = 어플리케이션 요구사항을 모두 만족할 것 (/docs/PRD.md 참고)

[과제의 취지]

- 나쁜 코드를 몸으로 충분히 느껴보고, 왜 나쁜 코드를 쓰는 것이 나쁜지 이해하기
- 나쁘지 않은 코드만으로 충분하지 않다는 것을 이해하기
- 더 좋은 코드란 무엇인지를 고민하며 나의 코드 취향과 코드 감각 이해하기

### **2) 체크리스트**

- 코드가 Prettier를 통해 일관된 포맷팅이 적용되어 있는가?
- 적절한 줄바꿈과 주석을 사용하여 코드의 논리적 단위를 명확히 구분했는가?
- 변수명과 함수명이 그 역할을 명확히 나타내며, 일관된 네이밍 규칙을 따르는가?
- 매직 넘버와 문자열을 의미 있는 상수로 추출했는가?
- 중복 코드를 제거하고 재사용 가능한 형태로 리팩토링했는가?
- 함수가 단일 책임 원칙을 따르며, 한 가지 작업만 수행하는가?
- 조건문과 반복문이 간결하고 명확한가? 복잡한 조건을 함수로 추출했는가?
- 코드의 배치가 의존성과 실행 흐름에 따라 논리적으로 구성되어 있는가?
- 연관된 코드를 의미 있는 함수나 모듈로 그룹화했는가?
- ES6+ 문법을 활용하여 코드를 더 간결하고 명확하게 작성했는가?
- 전역 상태와 부수 효과(side effects)를 최소화했는가?
- 에러 처리와 예외 상황을 명확히 고려하고 처리했는가?
- 코드 자체가 자기 문서화되어 있어, 주석 없이도 의도를 파악할 수 있는가?
- 비즈니스 로직과 UI 로직이 적절히 분리되어 있는가?
- 객체지향 또는 함수형 프로그래밍 원칙을 적절히 적용했는가?
- 코드의 각 부분이 테스트 가능하도록 구조화되어 있는가?
- 성능 개선을 위해 불필요한 연산이나 렌더링을 제거했는가?
- 새로운 기능 추가나 변경이 기존 코드에 미치는 영향을 최소화했는가?
- 리팩토링 시 기존 기능을 그대로 유지하면서 점진적으로 개선했는가?
- 코드 리뷰를 통해 다른 개발자들의 피드백을 반영하고 개선했는가?

### 3) 코드를 작성하면서 생각해볼 것

- **가독성**: 좋은 코드는 읽기 쉽고 이해하기 쉽습니다.
- **유지보수성**: 좋은 코드는 수정사항에 대응하기 쉬우며, 수정에 독립적이고 찾기 쉽습니다.
- **확장성**: 좋은 코드는 새로운 기능을 추가할 때, 기존 코드를 크게 수정하지 않을 수 있습니다.
- **견고성**: 좋은 코드는 에러가 발생했을 경우에도 동작하거나 대응하고, 에러를 발견하기 쉽습니다.
- **“테스트 가능성**: 좋은 코드는 테스트를 작성하기 쉬우며, 단위별 테스트를 할 수 있습니다.”
- **자기문서화**: 좋은 코드는 요구사항을 코드 자체로 이해할 수 있게 합니다.
- **일관성**: 좋은 코드는 같은 규칙과 철학으로 작성되어 예측이 가능합니다.

왜 이 코드가 더 좋아졌는지를 위 기준에 의거해서 설명할 수 있도록 합시다. 그리고 구체적인 방법들은 리팩토링 2판이나 GPT를 통해서 방법들을 함께 찾아보고 논의해보세요.

### 4) 이후 심화과제가 React로 고도화라는 점 잊지 마세요!

리팩토링의 방향성은 React와 닮아야 할 것입니다. React로 바꿀때 최대한 코드의 변경이 없으면 좋겠다고 생각하면서 작성해주세요.

### 5) 테스트 코드를 통해서 사이드 이펙트 점검

리팩토링은 기존 로직에는 변화가 없도록 하는 것이 핵심! 언제나 테스트 코드가 잘 동작하고 있는지 확인을 합시다.

![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/83c75a39-3aba-4ba4-a792-7aefe4b07895/3ee10077-d31c-492a-ae5f-c71c94bbb39b/Untitled.png)
67 changes: 67 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import js from "@eslint/js";
import prettier from "eslint-config-prettier";

export default [
js.configs.recommended,
prettier,
{
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
globals: {
browser: "readonly",
node: "readonly",
document: "readonly",
window: "readonly",
console: "readonly",
alert: "readonly",
setTimeout: "readonly",
setInterval: "readonly",
Math: "readonly",
Date: "readonly",
parseInt: "readonly",
},
},
rules: {
"no-unused-vars": "warn",
"no-console": "warn",
"prefer-const": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-template": "error",
"template-curly-spacing": "error",
"arrow-spacing": "error",
"no-duplicate-imports": "error",
"no-useless-rename": "error",
"prefer-destructuring": "warn",
"no-magic-numbers": "warn",
complexity: ["warn", 10],
"max-depth": ["warn", 4],
"max-lines-per-function": ["warn", 50],
"max-params": ["warn", 4],
},
},
{
files: ["**/*.test.js", "**/__tests__/**/*.js"],
languageOptions: {
globals: {
jest: "readonly",
},
},
rules: {
"no-console": "off",
},
},
{
ignores: [
"node_modules/**",
"dist/**",
"build/**",
"coverage/**",
"*.html",
"pnpm-lock.yaml",
"package-lock.json",
"yarn.lock",
],
},
];
17 changes: 15 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@
"start:advanced": "vite serve --open ./index.advanced.html",
"test": "vitest",
"test:basic": "vitest basic.test.js",
"test:advanced": "vitest advanced.test.js",
"test:ui": "vitest --ui"
"test:advanced": "vitest src/advanced/",
"test:ui": "vitest --ui",
"lint": "eslint src/**/*.js",
"lint:fix": "eslint src/**/*.js --fix",
"format": "prettier --write src/**/*.js",
"format:check": "prettier --check src/**/*.js",
"code:check": "npm run lint && npm run format:check",
"code:fix": "npm run lint:fix && npm run format"
},
"devDependencies": {
"@eslint/js": "^9.32.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/user-event": "^14.6.1",
"@typescript-eslint/eslint-plugin": "^8.38.0",
"@typescript-eslint/parser": "^8.38.0",
"@vitest/ui": "^3.2.4",
"eslint": "^9.32.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.3",
"jsdom": "^26.1.0",
"prettier": "^3.6.2",
"vite": "^7.0.5",
"vitest": "^3.2.4"
}
Expand Down
Loading