Podo - Dev Log (2)

11์›” 30์ผ (ํ™”)

์˜ค๋Š˜์€ ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ๋‚˜์š”?

  • Naver, Kakao, Google ๋กœ๊ทธ์ธ ์ธ์ฆ ๊ตฌํ˜„
  • Token Function ๊ตฌํ˜„
  • Middleware ๊ตฌํ˜„
  • OTT Router Controller ๊ตฌํ˜„
  • User, Party, Payment ํŒŒ์ผ ๊ตฌ์กฐ ์žก๊ธฐ

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋‚˜์š”?

  • ์–ด์ œ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
    ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ œ๋Œ€๋กœ ๋ฐ›์•„์ง€์ง€ ์•Š์•˜๋˜ ์ด์œ ๋Š” .env์—์„œ REDIRECT_URI์˜ ํฌํŠธ๊ฐ€ 4000๋ฒˆ์ด ์•„๋‹Œ 3000๋ฒˆ์œผ๋กœ ๋˜์–ด์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
    ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ .env ํŒŒ์ผ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์„œ๋ฒ„์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ €์žฅ ํ›„ nodemon์œผ๋กœ ์ž๋™์œผ๋กœ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ '์„œ๋ฒ„ ์ž์ฒด๋ฅผ ๊ป๋‹ค๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ์ '์ž…๋‹ˆ๋‹ค.
    3000๋ฒˆ์œผ๋กœ ๋ฐ”๊ฟ”๋„ ๊ณ„์† ์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋˜ ์ด์œ ๊ฐ€ ์ด ์  ๋•Œ๋ฌธ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
  • Kakao
    ์ƒํ™ฉ: ํ˜„์žฌ Podo์—์„œ access token ๋ฐœ๊ธ‰ํ•  ๋•Œ ์ด๋ฉ”์ผ๋งŒ ๊ฐ€์ง€๊ณ  ๋งŒ๋“ค๊ธฐ์— ์ด๋ฉ”์ผ ๊ผญ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
    ๋ฌธ์ œ: Kakao ์ธ์ฆ ์†Œ์…œ ๋กœ๊ทธ์ธ์—์„œ ๋น„์ฆˆ ์•ฑ์œผ๋กœ ์Šน๊ฒฉํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฉ”์ผ ์ •๋ณด ์ œ๊ณต ์„ ํƒ ๋™์˜๋งŒ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค. ๋น„์ฆˆ์•ฑ์œผ๋กœ ์Šน๊ฒฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‚ฌ์—…์ž ๋“ฑ๋ก ํ›„ ์‚ฌ์—…์ž ๋“ฑ๋ก ๋ฒˆํ˜ธ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋™์˜ ์•ˆ ํ•˜๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ด๋ฉ”์ผ์ด ๋ณด์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
data: {
    id: 2013122492,
    connected_at: '2021-11-30T02:29:39Z',
    kakao_account: { has_email: true, email_needs_agreement: true }
  }

ํ•ด๊ฒฐ๋ฐฉ์•ˆ: ์„ธ๋ฒˆ์งธ ๋ฐฉ์•ˆ์œผ๋กœ ์ง„ํ–‰ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

  •  Kakao์—์„œ ์ฃผ๋Š” id๋กœ ๊ตฌํ˜„
  •  Kakao ์ธ์ฆ ๋ฐฉ์‹ ์‚ญ์ œ
  •  email์„ ์•ˆ ๋ณด๋‚ด์ค€๋‹ค๋ฉด id๋ฅผ email์— ๋„ฃ๊ธฐ

 

์ƒˆ๋กœ ๋ฐฐ์šด ์ 

  • git log --oneline: log๋ฅผ ํ•œ ์ค„์— ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํž˜๋“  ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๋ชฉ ๊ทผ์œก ํ†ต์ฆ์ด ์žˆ๋Š” ๊ฒƒ ์™ธ์—๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

 

๋‚ด์ผ์€ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • User์˜ Controller์™€ Router ๊ตฌํ˜„
  • Party์˜ Controller์™€ Router ๊ตฌํ˜„ 

 

 

 

 

 

12์›” 1์ผ (์ˆ˜)

์˜ค๋Š˜์€ ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ๋‚˜์š”?

  • Statement ์—”๋“œํฌ์ธํŠธ ๊ตฌํ˜„์„ ์œ„ํ•ด Controller์™€ Router ๊ตฌํ˜„
  • User Model ์ˆ˜์ •
  • User Seed ์ž‘์„ฑ
  • ์ˆ˜์ •์‚ฌํ•ญ ๋ฐ˜์˜ ์œ„ํ•ด DB Schema, API Document ๋ณ€๊ฒฝ
  • Home banner opacity(ํˆฌ๋ช…๋„) / Seed ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ๊ด€๋ จ Error Debugging

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋‚˜์š”?

  • ํ˜„์ƒ: localhost:3000์œผ๋กœ ํŽ˜์ด์ง€์— ์ ‘์†ํ–ˆ์„ ๋•Œ๋Š” ๋ฐฐ๋„ˆ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. podorang.com์œผ๋กœ ์ ‘์†ํ–ˆ์„ ๋•Œ๋Š” ๋ฐฐ๋„ˆ๊ฐ€ 0.5์ดˆ ์ •๋„ ๋ณด์ด๋‹ค๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ˆ์ดํ•œ ์˜์—ญ์˜ ์—๋Ÿฌ์—ฌ์„œ ํ•ด๊ฒฐ์„ ๋ฏธ๋ฃฐ๊นŒ ํ–ˆ์ง€๋งŒ ๊ฐœ๋ฐœํ•  ๋•Œ ์ œ๋Œ€๋กœ ํ™ˆ ํ™”๋ฉด์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„ ๋””๋ฒ„๊น…์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.
    ์›์ธ: local ์ฝ”๋“œ์™€ deploy ์ฝ”๋“œ๋ฅผ Diffchecker๋ฅผ ํ†ตํ•ด ๋น„๊ตํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์ ์ด ํ•˜๋‚˜๋„ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ์—ฌ๋Ÿฌ ํƒญ๋“ค๊นŒ์ง€ ๋‹ค ๋น„๊ตํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ, localhost:3000์˜ opacity๋Š” 100%, podorang.com์˜ opacity๋Š” 1%์˜€์Šต๋‹ˆ๋‹ค.
    ํ•ด๊ฒฐ: ์ด ๋ถ€๋ถ„์€ ์ œ๊ฐ€ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์ด๋ผ ํ”„๋ก ํŠธ์—”๋“œ ๋ถ„๋“ค๊ณผ ์ƒ์˜ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

  • ํ˜„์ƒ: npx sequelize_cli db:seed:all ๋ช…๋ น์–ด๋กœ ์ „์ฒด seed๊ฐ€ ์‹ฌ์–ด์ง€์ง€ ์•Š๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
    ์›์ธ: npx sequelize-cli db:seed:all๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด abcd ์ˆœ์œผ๋กœ seed๊ฐ€ ๋„ฃ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์˜€์Šต๋‹ˆ๋‹ค.
    ํ•ด๊ฒฐ: ์ด ๋ถ€๋ถ„์€ ํ…Œ์ŠคํŠธํ•˜๋ฉด์„œ ์ž์ฃผ ์จ์•ผ ํ•  ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ์ œ ๋‚˜๋ฆ„์˜ ๊ฐ„๋‹จํ•œ ๋งค๋‰ด์–ผ์„ ๋งŒ๋“ค์–ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
    - npx sequelize-cli db:seed:all๋กœ capital, ott, party Seed ๋„ฃ๊ธฐ
    - npx sequelize-cli db:seed --seed user payment statement๋กœ ๋งˆ์ € user payment statement ๋„ฃ์–ด์ฃผ๊ธฐ

 

  • ํ˜„์ƒ: ERR_HTTP_HEADERS_SENT๋ผ๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
    ์›์ธ: res๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ๋‘ ๋ฒˆ ๋ณด๋ƒˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.
    ํ•ด๊ฒฐ: return res.sendStatus(200).json({ message: "Success" }) ๋Œ€์‹  return res.status(200).json({ message: "Success" })๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํž˜๋“  ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ์–ตํ• ๋งŒํ•œ ์ 

  • git stash์™€ git stash pop ๋ช…๋ น์–ด๋ฅผ ๋ฐฐ์›Œ์„œ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
    git stash ๋ช…๋ น์–ด๋Š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์Œ“์•„๋†“๋Š” ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค.
    git stash pop ๋ช…๋ น์–ด๋Š” ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ €์žฅํ•œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊บผ๋‚ด๊ณ  ๊ทธ ๋‚ด์šฉ์€ ์‚ญ์ œํ•˜๋Š” ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค.
  • git reset HEAD^: commit ์›๋ณต ๊ธฐ๋ณธ ๋ช…๋ น์–ด. default option์€ --mixed์ด๋‹ค.
    git reset --soft HEAD^: commit์„ ์ทจ์†Œํ•˜๊ณ  ํ•ด๋‹น ํŒŒ์ผ๋“ค์€ staged ์ƒํƒœ๋กœ ์›Œํ‚น ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ณด์กด
    git reset --mixed HEAD^: commit์„ ์ทจ์†Œํ•˜๊ณ  ํ•ด๋‹น ํŒŒ์ผ๋“ค์€ unstaged ์ƒํƒœ๋กœ ์›Œํ‚น ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ณด์กด
    git reset --hard HEAD^: commit์„ ์ทจ์†Œํ•˜๊ณ  ํ•ด๋‹น ํŒŒ์ผ๋“ค์€ unstaged ์ƒํƒœ๋กœ ์›Œํ‚น ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์‚ญ์ œ

 

๋‚ด์ผ์€ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • ํ† ์Šค API ๊ณต๋ถ€ ๋ฐ ๊ตฌํ˜„
  • ๊ธˆ์œต๊ฒฐ์ œ์› API ๊ณต๋ถ€ ๋ฐ ๊ตฌํ˜„

 

 

 

 

 

12์›” 2์ผ (๋ชฉ)

์˜ค๋Š˜์€ ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ๋‚˜์š”?

  • ๊ธˆ์œต๊ฒฐ์ œ์› API Authorization Code ๋ฐ Access Token ๋ฐœ๊ธ‰
  • ํด๋ผ์ด์–ธํŠธ ๋ฐฐํฌ ์ž๋™ํ™”
  • ์ค‘๊ฐ„๋ณด๊ณ  ๋ฏธํŒ… ์ฐธ์„

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋‚˜์š”?

  • Authorization Code ๋ฐœ๊ธ‰์ด ์ž˜ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์•Œ๊ณ  ๋ณด๋‹ˆ ์—”๋“œํฌ์ธํŠธ๊ฐ€ ๋‹ฌ๋ผ์„œ ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ์„ค์ •ํ•ด์ฃผ๋‹ˆ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํž˜๋“  ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ์นด๋“œ ๊ฒฐ์ œ๋‚˜ ๊ณ„์ขŒ ์กฐํšŒ ๊ฐ™์€ ๋ถ€๋ถ„์€ ๊ธˆ์œต ๊ด€๋ จ ๊ฐœ์ธ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” API์ด๋‹ค ๋ณด๋‹ˆ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์–ด๋ ค์›€์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๋‚ด์ผ์€ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • ๊ธˆ์œต ๊ด€๋ จ API ๊ตฌํ˜„
  • Random Name API ์‚ฌ์šฉํ•˜์—ฌ ๋ณ„๋ช… ์ƒ์„ฑ

 

 

 

 

 

12์›” 3์ผ (๊ธˆ)

์˜ค๋Š˜์€ ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ๋‚˜์š”?

  • ๊ธˆ์œต๊ฒฐ์ œ์› API ๊ณต๋ถ€
  • getRandomName ํ•จ์ˆ˜ ๊ตฌํ˜„ ๋ฐ ์—์ง€ ์ผ€์ด์Šค ์ฒ˜๋ฆฌ
  • Naver์— getRandomName ์ ์šฉ

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋‚˜์š”?

  • getRandomName์€ ์„œ๋ฒ„์—์„œ ์•Œ์•„์„œ name์ด ์ค‘๋ณต์ด ๋˜์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ (while or ์žฌ๊ท€ ํ•จ์ˆ˜ ํ•„์š”) ์ƒ์„ฑํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. Promise ํ˜•ํƒœ ์•ˆ์—์„œ ์ € ๋ถ€๋ถ„์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ฒ˜์Œ์ด๋ผ ์—ฌ๋Ÿฌ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค. (#135 ์ฐธ๊ณ )

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํž˜๋“  ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด์ผ์€ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • Google ๋ฐ Kakao์— getRandomName ์ ์šฉ

 

 

 

 

 

12์›” 4์ผ (ํ† )

์˜ค๋Š˜์€ ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ๋‚˜์š”?

  • Google, Kakao์— nameFunction ์ ์šฉ

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋‚˜์š”?

git reset --hard HEAD^๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. git reset --hard {๋˜๋Œ๋ฆฌ๊ณ  ์‹ถ์€ ์ปค๋ฐ‹ sha1}์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค (#140 ์ฐธ๊ณ )

 

์˜ค๋Š˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํž˜๋“  ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด์ผ์€ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • ๊ธˆ์œต๊ฒฐ์ œ์› API ๊ณต๋ถ€

 

'Challenge > Project Log' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Podo - Dev Log (4)  (0) 2021.12.23
Podo - Dev Log (3)  (0) 2021.12.12
Podo - Dev Log (1)  (0) 2021.11.29
Podo - SR  (0) 2021.11.26
Colorboration (3) - Sprint 3 ํšŒ๊ณ   (2) 2021.11.21