<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개인코딩개발공장</title>
    <link>https://jacobowl.tistory.com/</link>
    <description>지극히 이기적인 개발 블로그입니다.
https://nurd.work/</description>
    <language>ko</language>
    <pubDate>Tue, 11 Aug 2026 05:41:34 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>부엉이사장</managingEditor>
    <image>
      <title>개인코딩개발공장</title>
      <url>https://tistory1.daumcdn.net/tistory/5422445/attach/f81fdd7fcd3f47a0b6b2f28efa02dd65</url>
      <link>https://jacobowl.tistory.com</link>
    </image>
    <item>
      <title>데이터 검증하기 dto</title>
      <link>https://jacobowl.tistory.com/362</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;express 사용할때는 각 함수마다 받아오는 데이터를 직접 검증했음.&lt;br /&gt;예를들어 로그인하려는데 아이디 길이나 비밀번호 이런거 정규식 주로 사용함.&lt;br /&gt;nestJs에서는 dto라는게 있어서 매우 편한거같음. 이걸 소개할까함&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 먼저 설치&lt;/p&gt;
&lt;pre id=&quot;code_1749844594951&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install class-validator class-transformer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# main.ts 수정&lt;/p&gt;
&lt;pre id=&quot;code_1749844629166&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  app.useGlobalPipes(new ValidationPipe({
    transform: true,            // DTO 타입 자동 변환
    whitelist: true,            // DTO에 정의되지 않은 속성 제거
    forbidNonWhitelisted: true, // 정의되지 않은 속성이 있으면 400 에러
  }));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 디렉토리 구조&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SyiHk/btsOBYFvwTu/iB9E71I24sYgwK20q2ChaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SyiHk/btsOBYFvwTu/iB9E71I24sYgwK20q2ChaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SyiHk/btsOBYFvwTu/iB9E71I24sYgwK20q2ChaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSyiHk%2FbtsOBYFvwTu%2FiB9E71I24sYgwK20q2ChaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;167&quot; height=&quot;131&quot; data-origin-width=&quot;167&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 dto 디렉토리에 원하는 검증 dto듣을 넣어주샘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 검증값 / test.dto&lt;/p&gt;
&lt;pre id=&quot;code_1749844760054&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import {
  IsDefined,
  IsString,
  MinLength,
  MaxLength,
  Matches,
  IsNotEmpty,
} from 'class-validator';

export class BaboDto {
  @IsDefined({ message: '이름을 입력해주세요.' })
  @IsString()
  @MaxLength(4, { message: '이름은 5자 미만이어야 합니다.' })
  @Matches(/^[가-힣a-zA-Z0-9]+$/, {
    message: '이름에는 특수문자를 포함할 수 없습니다.',
  })
  name: string;
  @IsDefined({ message: '메시지를 안 받았어요.' }) // 이게 꼭 있어야 함
  @IsString({ message: 'message must be a string' })
  @IsNotEmpty({ message: '메시지를 안 받았어요.' })
  @MinLength(10, { message: '메시지는 10자 이상이어야 합니다.' })
  message: string;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test.dto꺼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 프로퍼티들을 어떻게 검증할건지 체크해주는거임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. IsDefined 얘는 이 값이 있어야하는거. 없으면 message 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. isString 얘는 문자열타입이어야 하는거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. MaxLength 는 최대길이. 안맞으면 메세지 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Matches는 정규식으로 검사까지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 여러가지 dto를 만들고 재사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입을 따로 정해뒀으면 타입을 임포트해서 class에 implements로 할수도 있을듯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 컨트롤러에서 설정&lt;/p&gt;
&lt;pre id=&quot;code_1749844940757&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  @Post('babo')
  PostBabo(@Body() dto: BaboDto) {
    //여기부터는 dto검사 끝난 상태임
    return {
      message: '데이터 잘 받았어요!',
      data: dto,
    };
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;babo라는 post요청을 받았을때,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;body를 BaboDto로 검증한다는 거임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 테스트&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NZiKb/btsOAj5Dfh5/ooPMehsHSKSgRzOK6A7nrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NZiKb/btsOAj5Dfh5/ooPMehsHSKSgRzOK6A7nrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NZiKb/btsOAj5Dfh5/ooPMehsHSKSgRzOK6A7nrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNZiKb%2FbtsOAj5Dfh5%2FooPMehsHSKSgRzOK6A7nrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;981&quot; height=&quot;228&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상요청시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비정상 요청시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 프로퍼티 하나 더 추가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vfEiZ/btsOA3HGshf/YqKZEXKucaXNjHGQ98x13k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vfEiZ/btsOA3HGshf/YqKZEXKucaXNjHGQ98x13k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vfEiZ/btsOA3HGshf/YqKZEXKucaXNjHGQ98x13k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvfEiZ%2FbtsOA3HGshf%2FYqKZEXKucaXNjHGQ98x13k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;979&quot; height=&quot;226&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;226&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 프로퍼티 하나 뺴기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLcf1v/btsOBateKlr/yKK8MJM4GVtiq61i2rs000/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLcf1v/btsOBateKlr/yKK8MJM4GVtiq61i2rs000/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLcf1v/btsOBateKlr/yKK8MJM4GVtiq61i2rs000/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLcf1v%2FbtsOBateKlr%2FyKK8MJM4GVtiq61i2rs000%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;989&quot; height=&quot;218&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 아이디 규격위반&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYFgqH/btsOCjbyThf/JS2zQzvIbqugLen0KTJa70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYFgqH/btsOCjbyThf/JS2zQzvIbqugLen0KTJa70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYFgqH/btsOCjbyThf/JS2zQzvIbqugLen0KTJa70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYFgqH%2FbtsOCjbyThf%2FJS2zQzvIbqugLen0KTJa70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;949&quot; height=&quot;181&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 이런식으로 400번대 에러 던져줌. 매우매우 편리할것같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 하드코딩할떄는 아예 규격 미들웨어 다 정해서 힘들었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nestJs로 하면 데이터 받아오는걸 컨트롤러단에서 검증하고 끊어줄 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>javaScript/nestJs</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/362</guid>
      <comments>https://jacobowl.tistory.com/362#entry362comment</comments>
      <pubDate>Sat, 14 Jun 2025 05:20:47 +0900</pubDate>
    </item>
    <item>
      <title>LF CRLF문제</title>
      <link>https://jacobowl.tistory.com/361</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;파일마다 vs코드에서 설정해주는게 여간 귀찮은게 아님.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setting이랑 뭐 깃 다 설정해봣는데 안됐음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;걍 프로젝트마다 eslintrc.js파일을 이렇게 수정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749842301447&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: 'tsconfig.json',
    tsconfigRootDir: __dirname,
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint/eslint-plugin'],
  extends: [
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  root: true,
  env: {
    node: true,
    jest: true,
  },
  ignorePatterns: ['.eslintrc.js'],
  rules: {
    '@typescript-eslint/interface-name-prefix': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    &quot;prettier/prettier&quot;: [&quot;error&quot;, { &quot;endOfLine&quot;: &quot;auto&quot; }], //여기 추가
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gengminy.tistory.com/12&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gengminy.tistory.com/12&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1749842315325&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[NestJs] 따라하면서 배우는 NestJs - 2 (기본적인 CRUD 수행)&quot; data-og-description=&quot;✅ 서비스 의존성 주입 및 전체 READ   ./boards/boards.service.ts import { Injectable } from '@nestjs/common'; @Injectable() export class BoardsService { //일단 로컬 메모리에 저장하는 방식으로 private boards = []; getAllBoards(&quot; data-og-host=&quot;gengminy.tistory.com&quot; data-og-source-url=&quot;https://gengminy.tistory.com/12&quot; data-og-url=&quot;https://gengminy.tistory.com/12&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bv5WZb/hyY8ZmuuRJ/5ktyKcKidi79ImsG7fwn70/img.png?width=300&amp;amp;height=299&amp;amp;face=0_0_300_299,https://scrap.kakaocdn.net/dn/cy2Sjq/hyY39kbp3c/IQA1xAck2tycs69wa8KkWk/img.png?width=300&amp;amp;height=299&amp;amp;face=0_0_300_299,https://scrap.kakaocdn.net/dn/cT1mp5/hyY8NsQcFx/9kxUCWK9W4LI5hN9MkK8IK/img.png?width=1027&amp;amp;height=811&amp;amp;face=0_0_1027_811&quot;&gt;&lt;a href=&quot;https://gengminy.tistory.com/12&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gengminy.tistory.com/12&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bv5WZb/hyY8ZmuuRJ/5ktyKcKidi79ImsG7fwn70/img.png?width=300&amp;amp;height=299&amp;amp;face=0_0_300_299,https://scrap.kakaocdn.net/dn/cy2Sjq/hyY39kbp3c/IQA1xAck2tycs69wa8KkWk/img.png?width=300&amp;amp;height=299&amp;amp;face=0_0_300_299,https://scrap.kakaocdn.net/dn/cT1mp5/hyY8NsQcFx/9kxUCWK9W4LI5hN9MkK8IK/img.png?width=1027&amp;amp;height=811&amp;amp;face=0_0_1027_811');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[NestJs] 따라하면서 배우는 NestJs - 2 (기본적인 CRUD 수행)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;✅ 서비스 의존성 주입 및 전체 READ   ./boards/boards.service.ts import { Injectable } from '@nestjs/common'; @Injectable() export class BoardsService { //일단 로컬 메모리에 저장하는 방식으로 private boards = []; getAllBoards(&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gengminy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>javaScript/nestJs</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/361</guid>
      <comments>https://jacobowl.tistory.com/361#entry361comment</comments>
      <pubDate>Sat, 14 Jun 2025 04:19:29 +0900</pubDate>
    </item>
    <item>
      <title>Team Project - Remember Me</title>
      <link>https://jacobowl.tistory.com/357</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;안녕하세요? Nurd Worker입니다! 반갑습니다. &lt;br /&gt;이번에 소개해드릴 프로젝트는 &lt;b&gt;RememberMe 프로젝트&lt;/b&gt;입니다!&lt;br /&gt;&lt;br /&gt;저는 다른 언어 공부를 할때 따로 A4용지같은데 적어서 공부를 하는데요. 단어를 정리해서 적어놓는것도 시간이 많이 걸리고 가끔은 잃어버리는 경우도 있어서 &lt;b&gt;단어장 어플리케이션&lt;/b&gt;을 만들어봐야겠다 생각하고 시작하게 된 프로젝트입니다ㅎㅎ&lt;br /&gt;&lt;br /&gt;완료된지 얼마안된 프로젝트라 아직 어학공부보다 포트폴리오준비에 전념하고있는데요. &lt;br /&gt;조만간 취직 후, 틈틈히 사용할 예정입니다^^&lt;br /&gt;&lt;br /&gt;Remember Me 프로젝트는 제가 취직할때 정말 &lt;b&gt;많은 점을 어필 할 수 있는 프로젝트&lt;/b&gt;라고 생각합니다.&lt;br /&gt;포트폴리오 프로젝트 중 &lt;b&gt;메인 프로젝트&lt;/b&gt;라고 보시면 되겠네요 ㅎㅎ&lt;br /&gt;&lt;br /&gt;미리 간단히 말씀드리자면,&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;- React + Typescript 첫 경험&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;- 서버리스(Lambda) 서비스&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;- 성능 &amp;amp; 비용 최적화&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;- 유지보수 최적화&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;- 팀프로젝트 진행(팀장)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;이런 점들을 주목하셔서 포스팅을 읽어주시면 감사드리겠습니다^^&lt;br /&gt;&lt;br /&gt;참고로 &lt;b&gt;RememberMe 프로젝트는 현재 배포가 되어있는 상태&lt;/b&gt;입니다~&lt;br /&gt;궁금하시면 링크를 들어오셔서 확인 가능하세요 ^^&lt;br /&gt;그럼 시작하겠습니다~&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;시작하기 전에&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;633&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rX2js/btsL1GBuxAB/jvkKTZLyQkxO7UhFj7Dk3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rX2js/btsL1GBuxAB/jvkKTZLyQkxO7UhFj7Dk3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rX2js/btsL1GBuxAB/jvkKTZLyQkxO7UhFj7Dk3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrX2js%2FbtsL1GBuxAB%2FjvkKTZLyQkxO7UhFj7Dk3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;954&quot; height=&quot;633&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;633&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remember me 프로젝트는 팀프로젝트로 분류해놨지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;두 가지 버전&lt;/b&gt;&lt;/span&gt;으로 나뉩니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;demo버전&lt;/b&gt;은 팀프로젝트로 진행을 했구요~ 이게 &lt;b&gt;초기버전&lt;/b&gt;입니다. 인프라팀원분들 두 분, 개발팀원(nurd worker) 이렇게 만든 프로젝트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 &lt;b&gt;이후에 nurd worker가 따로 좀더 손본 버전&lt;/b&gt;이&lt;b&gt; advanced&lt;/b&gt;버전입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;advanced버전은 test기능을 추가했고 타입설정이라든지 이런것들을 더 추가한 버전입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Remember Me 링크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Remember Me introduction video : &lt;a href=&quot;https://www.youtube.com/watch?v=MEIIWAcPjt0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=MEIIWAcPjt0&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=MEIIWAcPjt0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/i6UTO/hyX71r2yhE/2EnOLv355k3ZwuYGokYVP0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/gSkrE/hyX72kdas2/MhvMkiKezdMalZd88TYHkk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;nurd worker&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/MEIIWAcPjt0&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Remember Me published web site link :&amp;nbsp;&lt;/b&gt;&lt;a href=&quot;https://rememberme.nurd.work/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://rememberme.nurd.work/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737942608457&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Remember Me&quot; data-og-description=&quot;A vocabulary memorization app to help you efficiently learn and retain words.&quot; data-og-host=&quot;rememberme.nurd.work&quot; data-og-source-url=&quot;https://rememberme.nurd.work/&quot; data-og-url=&quot;https://rememberme.nurd.work&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bE4tow/hyX4q1hRF7/lJlwygIeMGJQK3LqOk3391/img.jpg?width=1201&amp;amp;height=631&amp;amp;face=0_0_1201_631&quot;&gt;&lt;a href=&quot;https://rememberme.nurd.work/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rememberme.nurd.work/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bE4tow/hyX4q1hRF7/lJlwygIeMGJQK3LqOk3391/img.jpg?width=1201&amp;amp;height=631&amp;amp;face=0_0_1201_631');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Remember Me&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A vocabulary memorization app to help you efficiently learn and retain words.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rememberme.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Remember Me github&amp;nbsp;Link&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Remember Me &lt;span style=&quot;color: #006dd7;&quot;&gt;advanced&lt;/span&gt; github Link :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;frontend : &lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-front&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nurdworker/rememberme-advanced-front&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1737839383702&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - nurdworker/rememberme-advanced-front&quot; data-og-description=&quot;Contribute to nurdworker/rememberme-advanced-front development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-front&quot; data-og-url=&quot;https://github.com/nurdworker/rememberme-advanced-front&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cdThvR/hyX4pnDFHf/uOjT6aKUzhsmqQ81QfQni1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Xt4Yd/hyX7YBS9TT/RVIvoqWj3K8qcbSgQ4RHqk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-front&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-front&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cdThvR/hyX4pnDFHf/uOjT6aKUzhsmqQ81QfQni1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Xt4Yd/hyX7YBS9TT/RVIvoqWj3K8qcbSgQ4RHqk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nurdworker/rememberme-advanced-front&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/rememberme-advanced-front development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;backend : &lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-back&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nurdworker/rememberme-advanced-back&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1737839407344&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - nurdworker/rememberme-advanced-back&quot; data-og-description=&quot;Contribute to nurdworker/rememberme-advanced-back development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-back&quot; data-og-url=&quot;https://github.com/nurdworker/rememberme-advanced-back&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbFQZP/hyX4ncjUCr/2n4KLPzeDG4nHrSmb3DUA1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/g7hk8/hyX4xTsqcI/mrXKxnGelayH7hzuCCw6c1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-back&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-back&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbFQZP/hyX4ncjUCr/2n4KLPzeDG4nHrSmb3DUA1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/g7hk8/hyX4xTsqcI/mrXKxnGelayH7hzuCCw6c1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nurdworker/rememberme-advanced-back&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/rememberme-advanced-back development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Remember Me &lt;span style=&quot;color: #009a87;&quot;&gt;demo&lt;/span&gt; github organization Link : &lt;a href=&quot;https://github.com/vocaAppServerless&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/vocaAppServerless&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737839579272&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;Remember Me&quot; data-og-description=&quot;Remember Me has 5 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/vocaAppServerless&quot; data-og-url=&quot;https://github.com/vocaAppServerless&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIkPCM/hyX73DcPiC/Q3RLBaDEFNm4AmzPZJVaD0/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/cbWlbT/hyX7Yu8Nf8/jIyiwxSB2ewDMg028pozT1/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/D9phe/hyX7Ufb5XH/0HjdGchKsmLe6zzUKGP6bk/img.png?width=4124&amp;amp;height=2420&amp;amp;face=0_0_4124_2420&quot;&gt;&lt;a href=&quot;https://github.com/vocaAppServerless&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/vocaAppServerless&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIkPCM/hyX73DcPiC/Q3RLBaDEFNm4AmzPZJVaD0/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/cbWlbT/hyX7Yu8Nf8/jIyiwxSB2ewDMg028pozT1/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/D9phe/hyX7Ufb5XH/0HjdGchKsmLe6zzUKGP6bk/img.png?width=4124&amp;amp;height=2420&amp;amp;face=0_0_4124_2420');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Remember Me&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Remember Me has 5 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Remember Me Project &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;Development&lt;span&gt; &lt;/span&gt;&lt;/span&gt;Tech Stacks&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFqAB/btsL23Wv0pK/3vPXEcnDfykAt8fmBPs9kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFqAB/btsL23Wv0pK/3vPXEcnDfykAt8fmBPs9kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFqAB/btsL23Wv0pK/3vPXEcnDfykAt8fmBPs9kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFqAB%2FbtsL23Wv0pK%2F3vPXEcnDfykAt8fmBPs9kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;772&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remember me 프로젝트에서 &lt;b&gt;nurd worker가 개발쪽을 100퍼센트 담당&lt;/b&gt;을 하였는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다로 &lt;b&gt;서버리스 서비스&lt;/b&gt;를 구성했습니다. 사실 &lt;b&gt;람다&lt;/b&gt;가 이 프로젝트의 가장 어려운 부분이었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws sam cli이라고 있는데 아이콘이 생소하시죠? 다람쥐가 도토리를 들고있는 아이콘입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국에서는 많이들 안써보신 툴일겁니다. 포스팅에 자세히 설명드리겠지만, 로컬환경에서 lambda환경을 구성하기위해 사용한 aws툴입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트앤드는 react + type script, 백엔드는 node js, 데이터베이스는 mongo db를 사용헀습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react와 typescript는 처음으로 사용해봤습니다 ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기타 aws 리소스로는 api gateway와, cloud watch, SNS, secret manager를 사용했네요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 현재 테크스택들은 개발담당이었던 제가 사용했던 스택들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀프로젝트에서 팀원분들이 사용하신 스택들은 따로 있습니다. 테라폼, cicd, kibana등 어마무시한것들이 많아요 ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Frontend : React&lt;/li&gt;
&lt;li&gt;Backend: : Node.js, AWS SAM CLI&lt;/li&gt;
&lt;li&gt;Database : MongoDB&lt;/li&gt;
&lt;li&gt;CI/CD : GitHub Actions&lt;/li&gt;
&lt;li&gt;Cloud(AWS) : Lambda, API Gateway, S3, CloudFront, Route53, WAF, Parameter Store, Secrets Manager, Budgets, Chatbot&lt;/li&gt;
&lt;li&gt;IaC : Terraform(HCP Terraform)&lt;/li&gt;
&lt;li&gt;Logging : CloudWatch, Logstash, Elasticsearch, Kibana&lt;/li&gt;
&lt;li&gt;ETC : Git/GitHub, Slack, Notion&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;팀프로젝트 스택 내용은 demo버전 github organization의 readMe 파일에 에 정리&lt;/b&gt;되어있습니다^^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Lambda에서 개발환경 &amp;amp; 배포환경 구분&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xs3n9/btsL1hn3OhM/uvYXqes6KGSu0OQIstkHAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xs3n9/btsL1hn3OhM/uvYXqes6KGSu0OQIstkHAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xs3n9/btsL1hn3OhM/uvYXqes6KGSu0OQIstkHAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxs3n9%2FbtsL1hn3OhM%2FuvYXqes6KGSu0OQIstkHAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;554&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 보통 사용하는 백엔드 개발 환경만 그림으로 간단하게 그려봤는데요.&lt;/p&gt;
&lt;pre id=&quot;code_1737842740273&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트로 코드를 런타임으로 돌리려면 이런식으로 node명령어로 파일을 실행시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 저장만 하면 새로 코드를 다시 실행시켜주는 nodemon을 주로 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;express 프레임워크로 개발한 백엔드 서버의 경우는 스크립트를 nodemon으로 실행하면 로컬에 포트로 서버가 띄워지죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트같은경우는 npm start로 로컬에 프로세스를 띄우고 개발을 하곤하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전 개발을 처음 접하시는분들도 익숙한 개념입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&lt;b&gt; Lambda로 백엔드 서비스를 구성해야하는 remember me 서비스는 어떻게 개발환경과 배포환경을 구분해야할까요&lt;/b&gt;?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 상상이 안됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 사용한 툴이 &lt;b&gt;aws sam cli&lt;/b&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blnxHX/btsL02xYx1P/hTiXJ48KKKIvKDWNoVBUxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blnxHX/btsL02xYx1P/hTiXJ48KKKIvKDWNoVBUxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blnxHX/btsL02xYx1P/hTiXJ48KKKIvKDWNoVBUxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblnxHX%2FbtsL02xYx1P%2FhTiXJ48KKKIvKDWNoVBUxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;511&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws sam cli는 정말 생소한 툴인데요. &lt;b&gt;서버리스 서비스를 로컬에서 돌아가게 만들어주는 aws에서 배포한 툴&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbzxiy/btsL2IZktNO/TNwoYDFDcUxTxyME3ceGx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbzxiy/btsL2IZktNO/TNwoYDFDcUxTxyME3ceGx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbzxiy/btsL2IZktNO/TNwoYDFDcUxTxyME3ceGx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbzxiy%2FbtsL2IZktNO%2FTNwoYDFDcUxTxyME3ceGx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;979&quot; height=&quot;725&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 lambda로 serverless 백엔드 서비스를 람다로 구축하시기위해선 &lt;b&gt;api gateway랑 연결한 lambda로 저런 아키텍쳐&lt;/b&gt;로 운영을 하게되는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SAM CLI로 로컬에서 api gateway, lambda 백엔드 서비스가 구축이 됩니다!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신기하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다는 컨테이너 단위입니다. 때문에 aws sam cli로 로컬환경에서 백엔드 서비스를 만드려면 &lt;b&gt;도커를 설치&lt;/b&gt;하셔야해요.&lt;/p&gt;
&lt;pre id=&quot;code_1737843712007&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sam build --no-cached
sam local start-api --env-vars ./env.json --port 포트번호&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react나 vue, nest js 를 사용하신분들은 build가 익숙하실텐데, sam cli도 사용하시려면 빌드를 먼저해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 에 start-api명령어로 api gateway+lambda환경을 실행 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTUpZM/btsL1erTiAJ/ZE7uFVWHFlPJjZihv9KW3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTUpZM/btsL1erTiAJ/ZE7uFVWHFlPJjZihv9KW3k/img.png&quot; data-alt=&quot;build가 되었네요~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTUpZM/btsL1erTiAJ/ZE7uFVWHFlPJjZihv9KW3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTUpZM%2FbtsL1erTiAJ%2FZE7uFVWHFlPJjZihv9KW3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;507&quot; height=&quot;183&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;build가 되었네요~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nSy6i/btsL12Rur4i/wZlM6QWY18mC7YBLsot95k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nSy6i/btsL12Rur4i/wZlM6QWY18mC7YBLsot95k/img.png&quot; data-alt=&quot;start api명령어를 치면 단일진입점(api gateway endpoint)이 로컬에 생깁니다~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nSy6i/btsL12Rur4i/wZlM6QWY18mC7YBLsot95k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnSy6i%2FbtsL12Rur4i%2FwZlM6QWY18mC7YBLsot95k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;323&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;start api명령어를 치면 단일진입점(api gateway endpoint)이 로컬에 생깁니다~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;명령어 구분&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와같이 코드를 수정을 할때마다 build와 start api명령어로 계속 컨테이너를 띄워줘야 했는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 개발할때 명령어도 따로 나눠야했어요.&lt;/p&gt;
&lt;pre id=&quot;code_1737844357613&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//node 명령어
node -e &quot;require('./src/handlers/test').handler(require('./event.json'), null).then(console.log)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 코드만 테스트하기위해서는 node명령어를 사용헀구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737870852854&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//event.json
{
  &quot;queryStringParameters&quot;: {
    &quot;request&quot;: &quot;connectDb&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더해서 람다에 전달할 event를 json으로 만들어야하구요.&lt;/p&gt;
&lt;pre id=&quot;code_1737844391732&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sam build --no-cached
sam local invoke TestFunction --env-vars ./env.json --event ./event.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 람다 컨테이너하나만 호출하려면 invoke명령어로 해야합니다. (event.json설정해야함)&lt;/p&gt;
&lt;pre id=&quot;code_1737844456348&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sam build --no-cached
sam local start-api --env-vars ./env.json --port 포트번호&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 전체 람다를 띄우는 커맨드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 환경변수도 나눠야했어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dh42sh/btsL1VdZwdj/EfWG1x2DLZsAGfEJo5rroK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dh42sh/btsL1VdZwdj/EfWG1x2DLZsAGfEJo5rroK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dh42sh/btsL1VdZwdj/EfWG1x2DLZsAGfEJo5rroK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdh42sh%2FbtsL1VdZwdj%2FEfWG1x2DLZsAGfEJo5rroK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;155&quot; height=&quot;237&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.env가 있고, env.json이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.env는 node명령어에선 됐는데 build후 람다컨테이너를 띄우면 못가져가더라구요.. 그래서 env.json으로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 중요한건 template.yaml로 띄울 람다 정의와 이것저것 설정을 해야하는데요&lt;/p&gt;
&lt;figure id=&quot;og_1737844736443&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;backend/template.yaml at main &amp;middot; vocaAppServerless/backend&quot; data-og-description=&quot;Contribute to vocaAppServerless/backend development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/vocaAppServerless/backend/blob/main/template.yaml&quot; data-og-url=&quot;https://github.com/vocaAppServerless/backend/blob/main/template.yaml&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bA1Kd2/hyX7TtPu3s/zbgiGHQqhu5ZILgcnWSyS1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/PorLm/hyX4q7VfCS/onTbq0CqSyTYN4B38inVy0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/vocaAppServerless/backend/blob/main/template.yaml&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/vocaAppServerless/backend/blob/main/template.yaml&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bA1Kd2/hyX7TtPu3s/zbgiGHQqhu5ZILgcnWSyS1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/PorLm/hyX4q7VfCS/onTbq0CqSyTYN4B38inVy0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;backend/template.yaml at main &amp;middot; vocaAppServerless/backend&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to vocaAppServerless/backend development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 template.yaml형식대로 정리를 해야해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 template.yaml을 기준으로 sam이 build를 한답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 cicd팀원분도 이 template.yaml을 기준으로 cicd코드를 코딩하셨어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;sam cli를 추천하시나요?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czeebs/btsL2fJOtzo/1Kmk0AN3KeKyl8Xcpe0tLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czeebs/btsL2fJOtzo/1Kmk0AN3KeKyl8Xcpe0tLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czeebs/btsL2fJOtzo/1Kmk0AN3KeKyl8Xcpe0tLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczeebs%2FbtsL2fJOtzo%2F1Kmk0AN3KeKyl8Xcpe0tLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1174&quot; height=&quot;661&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sam은 일단 코드 수정후에 저장한다고 바로 환경에 적용이 안됩니다. ㅡㅡ&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 한 글자만 수정을 하더라도 적용시키려면 build+start api를 다시 해줘야하는데 이 과정이 5분씩 잡아먹어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 제 노트북은 5년된 간신히 숨만 붙어있는 산송장 노트북이라 리소스를 엄청 잡아먹는 sam을 돌릴때마다 팬이 아주 미친듯이 돌아갔답니다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발환경과 배포환경을 완벽히 분리했지만 너무 힘들었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 위에 명령어들 줄줄히 적어놓은게 어떻게든 sam cli를 활용해서 개발을 하려고 발버둥쳤던 흔적입니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경변수도 node명령어 실행때, sam으로 컨테이너 띄웠을때, 실제 배포했을때 전부 다르게 설정해야했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 개발할때마다 control + S를 누르면 바로바로 코드가 프로세스에 적용하게 해줬던 nodemon과 live server등 개발도구들의 소중함을 너무나도 절실히 깨달은 경험이었습니다.. 진짜 여러분들 이거 진짜 체감못하실거에요.. 저 이거하고 탈모왔어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 사실 sam말고 어떻게 람다환경에서의 개발 배포환경을 구분해야할지는 다른 좋은방법이 생각이 안납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 컨테이너 이미지를 만들어서 해야할까요? 아니면 aws에 private네트워크를 만들고 거기서 lambda, api gw를 띄워야할까요? 시도는 안해봤지만 많이 어려울것 같다고 생각드네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 너무 어렵다기보단 짜증이났던 경험이었습니다.. 구글링해도 sam cli에 대한 자료가 거의 없구 gpt도 수집할 자료가없어서인지 엄청 틀리더라구요. 하나하나 조금씩 수정하며 테스트해봐야했는데 테스트할때마다 5분씩 걸리니...하.. 암튼 결국 완성은 했지만요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;람다에 대해서&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/opbV4/btsL1z9Rt10/SLHsmdT0RQopUsAJQQaIBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/opbV4/btsL1z9Rt10/SLHsmdT0RQopUsAJQQaIBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/opbV4/btsL1z9Rt10/SLHsmdT0RQopUsAJQQaIBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FopbV4%2FbtsL1z9Rt10%2FSLHsmdT0RQopUsAJQQaIBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;402&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 이번 포스팅에서 제가 전해드리고 싶은 내용을 말씀드리기위해 개념부터 정리하는 식으로 차근차근 포스팅하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서도 말씀드렸지만 람다를 보통 함수? 라고 생각하시는데요. 람다는 정확히는 &lt;b&gt;컨테이너&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws에서도 람다함수가 하나 호출되면 해당 람다함수의 컨테이너가 띄워지고 이벤트를 받고 처리후에 응답을 주는 구조랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금부터 lambda의 특성중 &lt;b&gt;제가 주목한 특성 세 가지&lt;/b&gt;를 먼저 소개해드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 중요한 부분입니다. &lt;b&gt;성능최적화&lt;/b&gt;에 관련이 있는 내용입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;1. Lambda는 세가지 state가 있습니다. - clod start &amp;amp; warm state &amp;amp; idle state&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4nDCn/btsL2RaC4Vf/nt8eODoGRkmxZi1Nse1l9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4nDCn/btsL2RaC4Vf/nt8eODoGRkmxZi1Nse1l9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4nDCn/btsL2RaC4Vf/nt8eODoGRkmxZi1Nse1l9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4nDCn%2FbtsL2RaC4Vf%2Fnt8eODoGRkmxZi1Nse1l9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;336&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;cold start&lt;/b&gt; : 람다가 막 시작해서 초기화부터 이뤄져야할 상태에요. 한동안 람다에 이벤트가 없어서 컨테이너가 없는 상태라 다시 만들어야하는 상태입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;warm state&lt;/b&gt; : 이미 cold start가 이뤄진 컨테이너라 다음 이벤트를 받을때 컨테이너 초기화가 필요없는 상태에요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;idle state : 한동안 람다에 요청이 없어서 삭제대기중인 상태입니다. 람다는 삭제될수 있다는걸 알려드리고 싶어서 추가했어요. 별로 중요하진않아서 그냥 이런상태가 있다~정도만 생각하시면되요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 들어드릴게요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;734&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNITaa/btsL1939Be9/m6X6m0HvsO9m0AioSDxBb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNITaa/btsL1939Be9/m6X6m0HvsO9m0AioSDxBb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNITaa/btsL1939Be9/m6X6m0HvsO9m0AioSDxBb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNITaa%2FbtsL1939Be9%2Fm6X6m0HvsO9m0AioSDxBb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;734&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;734&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 무찌가 보낸 이벤트는 람다가&lt;b&gt; cold start상태&lt;/b&gt;라서 초기화가 필요해요. 컨테이너가 생성되야하죠. 그래서 이벤트가 10초나 걸려서 처리가 됐죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이후에 도리가 이 람다에 또다시 요청을 합니다. 이때는 무찌가 이미 람다를 따뜻하게 해놨으므로&lt;b&gt; warm state상태&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 처리가 5초밖에 안걸렸네요.&lt;b&gt; warm state인 람다는 이벤트를 더욱 빠르게 처리해줘요.&lt;/b&gt; 이미 cold start때 썼던 메모리룰 기억하고있어서 재사용하면 되거든요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한건 람다는 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;처음 요청을 받으면 cold start상태로 시작&lt;/span&gt;&lt;/b&gt;되고 초기화가 필요하기때문에 이벤트에대한 응답을 비교적 늦게줍니다는 점이에요. 이후로 오는 이벤트는 이미 한번 사용된 람다 컨테이너를 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;재사용할수 있으니까 warm state상태&lt;/span&gt;&lt;/b&gt;라서 더욱 빠른 응답을 주는거죠. 이 부분을 기억해주세요. 밑에 설명할 캐싱기능을 이 람다의 특성들을 고려해서 만들었거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;b&gt;람다는 여러 상태가 있는데 람다컨테이너가 사라지는 타이밍은 저희가 가늠할수 없습니다.&lt;/b&gt; aws만의 규칙이 있겠죠? 이 점도 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;2. 람다의 이벤트 처리방식&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p1yQY/btsL2GHcsgu/MoVsiNUDTKLMoCHuZislUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p1yQY/btsL2GHcsgu/MoVsiNUDTKLMoCHuZislUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p1yQY/btsL2GHcsgu/MoVsiNUDTKLMoCHuZislUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp1yQY%2FbtsL2GHcsgu%2FMoVsiNUDTKLMoCHuZislUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1064&quot; height=&quot;589&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 상황을 가정해봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 동시에 두 이벤트를 클라이언트한테 받았다고 하면요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다는 먼저 들어온 이벤트를 처리하고 있겠죠? 근데 또다른 이벤트가 무찌람다에 요청을 하게되니까 람다는 이걸 동기처리하든, 비동기처리하든 해야한답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결론적으로 람다는 한번에 한 이벤트만 처리합니다!! 매우 중요합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;만약 먼저온 이벤트를 처리중인데 다른이벤트가 오면 받질 않아요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;3. 그럼 람다에 여러 이벤트가 오면 무한히 기다려야하나요? - 람다의 오토스케일링&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUkal/btsL01TitJ4/QzPVLmbTkuJzkr7XXXd0y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUkal/btsL01TitJ4/QzPVLmbTkuJzkr7XXXd0y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUkal/btsL01TitJ4/QzPVLmbTkuJzkr7XXXd0y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUkal%2FbtsL01TitJ4%2FQzPVLmbTkuJzkr7XXXd0y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;686&quot; height=&quot;411&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상황을 가정해볼게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 클라이언트가 람다를 호출했어요. 그럼 람다가 클라이언트의 이벤트를 처리중이겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxF05k/btsL1zaS8W4/cZ3ofZEKc0Kque6M1zCZN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxF05k/btsL1zaS8W4/cZ3ofZEKc0Kque6M1zCZN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxF05k/btsL1zaS8W4/cZ3ofZEKc0Kque6M1zCZN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxF05k%2FbtsL1zaS8W4%2FcZ3ofZEKc0Kque6M1zCZN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;458&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트를 처리중에 두 클라이언트가 갑자기 이벤트를 보냈어요. 그런데 람다는 클라이언트의 이벤트를 처리중이니 이 이벤트들을 받지 못할겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFQEHB/btsL0Otcfvn/kiKNIfDB6fk0Url4K3Axh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFQEHB/btsL0Otcfvn/kiKNIfDB6fk0Url4K3Axh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFQEHB/btsL0Otcfvn/kiKNIfDB6fk0Url4K3Axh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFQEHB%2FbtsL0Otcfvn%2FkiKNIfDB6fk0Url4K3Axh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;865&quot; height=&quot;574&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 람다는 요청을 처리하기위해 자동으로 &lt;b&gt;오토스케일링&lt;/b&gt;이 됩니다!! 똑같은 람다 컨테이너를 여러개 더 만드는거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 람다가 여러 이벤트를 컨테이너 하나당 한 이벤트 라는 규칙을 가지고도 동시에 처리가 가능합니다. js의 비동기처럼요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티프로세싱같은거라고 보시면 되요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 새로 생긴 람다는 새로 만들어지니 초기화가 이뤄져야하니 &lt;b&gt;cold start&lt;/b&gt;일겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 람다의 오토스케일링 특성도 매우 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 이 &lt;b&gt;세가지 람다의 특징&lt;/b&gt;을 꼭 기억해주세요!! 밑에 설명할&lt;b&gt; 캐싱기능과 매우 밀접한 관계&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;람다의 특징을 고려한 캐싱&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nurd worker는 두가지 요소에 대해서 캐싱기능을 고려했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시크릿&lt;/b&gt;과 &lt;b&gt;디비 커넥션&lt;/b&gt;을 &lt;b&gt;캐싱&lt;/b&gt;했어요. 하나씩 나눠서 설명드릴게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Secret부터~~&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SyGFN/btsL2dkTy9l/WazJSb4tMuo9AnAy8MPvxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SyGFN/btsL2dkTy9l/WazJSb4tMuo9AnAy8MPvxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SyGFN/btsL2dkTy9l/WazJSb4tMuo9AnAy8MPvxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSyGFN%2FbtsL2dkTy9l%2FWazJSb4tMuo9AnAy8MPvxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;570&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 말씀드렸듯이 sam cli를 사용했어서 이번 remember me 프로젝트는 환경변수를 세가지로 나눴는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경변수가 뭐 중요한값이니 시크릿이라고 보면됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발환경에선 .env와 env.json을 읽어와서 사용하니 딱히 캐싱까지 할필요없어요. 그냥 그때그때 필요할때마다 읽어와서 갖다쓰면 되니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중요한건 배포환경일때 aws secret manger에서 비밀값을 가져온다는 점이었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;&lt;b&gt;&amp;lt; secret manger의 과금방식 &amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfeXF/btsL1VE2x1p/dgLMUAabNoohFKasU1sOP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfeXF/btsL1VE2x1p/dgLMUAabNoohFKasU1sOP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfeXF/btsL1VE2x1p/dgLMUAabNoohFKasU1sOP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfeXF%2FbtsL1VE2x1p%2FdgLMUAabNoohFKasU1sOP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1043&quot; height=&quot;650&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws 시크릿매니저는 여러가지 과금요소가 있는데요. aws서비스는 다들 api로 이뤄집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;secret manager에서 시크릿값을 가져오는것 또한 api요청으로 받게되는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;과금요소중 하나가 이 api요청의 횟수에 있습니다!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1157&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TjfvG/btsL2R9x6SW/g5lj6fAPe9ZQJXh0gK4Al0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TjfvG/btsL2R9x6SW/g5lj6fAPe9ZQJXh0gK4Al0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TjfvG/btsL2R9x6SW/g5lj6fAPe9ZQJXh0gK4Al0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTjfvG%2FbtsL2R9x6SW%2Fg5lj6fAPe9ZQJXh0gK4Al0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1157&quot; height=&quot;486&quot; data-origin-width=&quot;1157&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 secret값을 필요로하는 이벤트가 매번 발생할때마다 secret manager에 api접근을 한다면 과금이 엄청 되겟죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 캐싱을 구현한겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;&lt;b&gt;&amp;lt; 어떤 식으로 캐싱을 구현했냐면요.. &amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1737851302119&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//전역에 이렇게 시크릿 빈객체를 선언해둠.
let cachedSecrets = {};



// main handler에서 secret 값을 가져오는 함수호출
exports.handler = async (event) =&amp;gt; {
  // caching
  cachedSecrets = (await checkCachedSecrets(cachedSecrets)).secrets;

  // response by request
  switch (requestType) {
    case &quot;type1&quot;:
      return data;
    default:
      console.log(&quot;Invalid request type on lambda:&quot;, requestType);
      return respond(400, { message: &quot;Invalid request from lists get lambda&quot; });
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 코드를 최대한 짧게 보여드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 전역에 &lt;b&gt;cachedSecrets&lt;/b&gt;이라는 빈객체를 만들어놓구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인핸들러(람다가 호출되었을때 실행되는 코드)에서 해당 객체에&lt;b&gt; secret을 체크하는 함수를 호출&lt;/b&gt;해서 시크릿값을 가져옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인수로 현재 cachedSecret객체를 넣어줬죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 저 checkCachedSecrets함수는 어떻게생겼냐면&lt;/p&gt;
&lt;pre id=&quot;code_1737851411800&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const checkCachedSecrets = async (cachedSecrets) =&amp;gt; {
  try {
    if (cachedSecrets.dbSecrets &amp;amp;&amp;amp; cachedSecrets.oauthSecrets) {
      return { message: &quot;there is cached secrets&quot;, secrets: cachedSecrets };
    } else {
      const nonCheckedSecrets = await getSecrets();
      if (!nonCheckedSecrets.dbSecrets || !nonCheckedSecrets.oauthSecrets) {
        throw new Error(&quot;There are some empty secrets from aws&quot;);
      } else {
        const secrets = nonCheckedSecrets;
        return {
          message: &quot;there is cached secrets&quot;,
          secrets: secrets,
        };
      }
    }
  } catch (err) {
    throw new Error(&quot;Failed to retrieve or cache secrets: &quot; + err.message);
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 인수로 받은 secret들이 이미 존재하고 있다면 그대로 리턴을 해주고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 빈객체다? 이러면 &lt;b&gt;getSecrets함수를 호출해서 secret매니저에 api요청을 보내는겁니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 그럼 아까 말씀드렸던 람다의 cold start와 warm start를 살펴봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;br /&gt;&amp;lt; secret&amp;nbsp; 캐싱의 플로우는~ &amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rVYgY/btsL1dfqAli/Ke8tmNrPkvkkDFrgDWkmt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rVYgY/btsL1dfqAli/Ke8tmNrPkvkkDFrgDWkmt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rVYgY/btsL1dfqAli/Ke8tmNrPkvkkDFrgDWkmt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrVYgY%2FbtsL1dfqAli%2FKe8tmNrPkvkkDFrgDWkmt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1059&quot; height=&quot;824&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;cold start시&lt;/b&gt;에 전역에 선언한 secret객체가 비어있는걸 확인후에&lt;b&gt; secret manager에 api요청을 보내서 시크릿값들을 가져옵니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 또 다른 이벤트가 발생하면 아까 cold start시에 사용해놨던&lt;b&gt; secret값이 남아있으므로 이 값을 재사용&lt;/b&gt;하는거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다가 언제 사라질지는 aws맘대로라고 말씀드렸잖아요? 이렇게 코드를 설계하면 한 람다 컨테이너는 이벤트가 매번 오더라도 &lt;b&gt;살아있는 동안 딱 한번만 secret manager에 api요청을 보내&lt;/b&gt;면 되니까 비용이 매우 절약되겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전역변수로 사용한 cachedSecrets 객체는 warm start시에는 데이터가 남아&lt;/b&gt;있답니다. 이 특성을 활용하여 캐싱을 구현하였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;데이터베이스 커넥션 캐싱 !&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1737852631196&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//전역에 null이 할당된 cachedDb
let cachedDb = null;

// main handler
exports.handler = async (event) =&amp;gt; {
  cachedSecrets = (await checkCachedSecrets(cachedSecrets)).secrets;
  cachedDb = (await getDb(cachedDb, cachedSecrets)).db;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 커넥션 캐싱도 마찬가지로 코드가 이렇게 되어있어요. 필요없는건 다 짤랐는데 위에 구조랑 비슷하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 원리입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CvtXG/btsL2dZyFnA/9FPp7tI5G2Im5pFXddG11k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CvtXG/btsL2dZyFnA/9FPp7tI5G2Im5pFXddG11k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CvtXG/btsL2dZyFnA/9FPp7tI5G2Im5pFXddG11k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCvtXG%2FbtsL2dZyFnA%2F9FPp7tI5G2Im5pFXddG11k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;951&quot; height=&quot;820&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 &lt;b&gt;커넥션은 객체형태&lt;/b&gt;입니다~ 그래서 아까 cold start시에 사용했던 커넥션 객체가 메모리에 남아있다면 이 커넥션을 계속 사용해서 그대로 데이터베이스 접근이 가능한거죠~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 커넥션은 비용적인 측면에선 제 무찌 클러스터에서 존재하니까 비용걱정은 없지만 매번 데이터베이스에 접근할때마다 커넥션을 새로 생성한다면 &lt;b&gt;성능저하&lt;/b&gt;가 일어난답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 커넥션을 캐싱해서 사용했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;lt; 왜 pool안썼어요? 바보세요? &amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BoXCd/btsL1AAVNdf/mawYs5K9Tebj0kORQ0cMv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BoXCd/btsL1AAVNdf/mawYs5K9Tebj0kORQ0cMv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BoXCd/btsL1AAVNdf/mawYs5K9Tebj0kORQ0cMv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBoXCd%2FbtsL1AAVNdf%2FmawYs5K9Tebj0kORQ0cMv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;954&quot; height=&quot;679&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 &lt;b&gt;커넥션풀의 목적&lt;/b&gt;을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥션풀을 백엔드서버에서 보통 사용하시는데요(ORM말고..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째로 &lt;b&gt;커넥션의 재사용&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;db요청을 할때마다 커넥션을 만들고 끊고 하는건 낭비입니다. 위에 설명드렸듯이요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 풀에 커넥션을 따놓고 db요청이 있을때마다 재사용을 할 수 있죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째로는 동시에 여러 요청이 왔을때 비동기적으로 코드가 돌아갈때(웹 api처리같은거요) &lt;b&gt;db요청을 비동기적&lt;/b&gt;으로하기 위함입니다. 비동기적으로 처리하려면 여분의 커넥션이 여러개 필요하겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 커넥션풀에 데이터베이스에 여러 커넥션을 따와놓죠. 그림에선 다섯개를 따왔네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bsb4C/btsL1WYjXBj/kgWIQJu63e9c7u7xztAsN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bsb4C/btsL1WYjXBj/kgWIQJu63e9c7u7xztAsN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bsb4C/btsL1WYjXBj/kgWIQJu63e9c7u7xztAsN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBsb4C%2FbtsL1WYjXBj%2FkgWIQJu63e9c7u7xztAsN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1167&quot; height=&quot;689&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 여러 클라이언트가 짧은간격으로 db요청을 한다면 여러 api요청을 처리할텐데요. 커넥션 하나를 여러 실행컨텍스트에서 나눠쓸수 없으니 아까 미리 쟁여왔던 커넥션을 하나씩 갖다 쓰게 해주는거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 커넥션 풀 개념인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 커넥션 풀을 만약 람다에 적용하면 어떻게될까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k8lM8/btsL1G2t2Ux/H3j1Hrc06ITmtqK3xJgCIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k8lM8/btsL1G2t2Ux/H3j1Hrc06ITmtqK3xJgCIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k8lM8/btsL1G2t2Ux/H3j1Hrc06ITmtqK3xJgCIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk8lM8%2FbtsL1G2t2Ux%2FH3j1Hrc06ITmtqK3xJgCIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;505&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다 컨테이너가 커넥션 다섯개를 미리 따왔다고 가정해볼게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 혹시 기억하시나요? &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;람다 컨테이너 하나는 이벤트를 동시에 하나밖에 처리못합니다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lg9FF/btsL176kKE7/dKJFKUqKX24tmwhL2RtMn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lg9FF/btsL176kKE7/dKJFKUqKX24tmwhL2RtMn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lg9FF/btsL176kKE7/dKJFKUqKX24tmwhL2RtMn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLg9FF%2FbtsL176kKE7%2FdKJFKUqKX24tmwhL2RtMn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1193&quot; height=&quot;678&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 이 이유입니다. 람다는 이벤트를 동시에 하나밖에 처리못해요. 그래서 커넥션 다섯개를 따왔어도 어차피 한개만 쓸수밖에없다는거에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커넥션 풀의 커넥션을 재사용한다는 점&lt;/b&gt;은 람다에 적용하고싶어서 &lt;b&gt;커넥션 객체를 캐싱하는 방식&lt;/b&gt;으로 코드를 구현했구,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커넥션을&lt;/b&gt; &lt;b&gt;여러개 안정적으로 확보해둔다는 풀의 특징&lt;/b&gt;은 쓰기 싫어서 &lt;b&gt;풀을 사용하지 않았습니다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buPB9s/btsL2mWwMD6/hODJsRKW3miD2w1MOSfEmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buPB9s/btsL2mWwMD6/hODJsRKW3miD2w1MOSfEmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buPB9s/btsL2mWwMD6/hODJsRKW3miD2w1MOSfEmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuPB9s%2FbtsL2mWwMD6%2FhODJsRKW3miD2w1MOSfEmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;885&quot; height=&quot;638&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약에 람다가 오토스케일링을 한다면 한 람다 컨테이너마다 커넥션을 다섯개씩 따올테니 그만큼 커넥션 낭비는 심해질겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;백엔드 람다코드 템플릿화&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드에서 중요한점만 정리하는데도 많네요 ㅠㅠ 읽느라 고생하십니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 백엔드 람다코드의 템플릿화를 말씀드릴건데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737854976733&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// import necessary functions
const {
  checkCachedSecrets,
  getDb,
  auth: { getOauthMiddleWareResult },
  apiResource: { respond },
} = require(&quot;./rbm-helper&quot;);

// declare cached data
let cachedSecrets = {};
let cachedDb = null;

// handlers
const handlerFuncs1 = async (event, authResult, email) =&amp;gt; {
  try {
	핸들러 코드 실행~
  } catch (error) {
	에러처리
  }
};

const handlerFuncs2 = async (event, authResult, email) =&amp;gt; {
  try {
	핸들러 코드 실행~
  } catch (error) {
	에러처리
  }
};

// main handler
exports.handler = async (event) =&amp;gt; {
  //get params request and email
  const requestType = event.queryStringParameters?.request;
  const email = decodeURIComponent(event.queryStringParameters?.email);

  // caching
  cachedSecrets = (await checkCachedSecrets(cachedSecrets)).secrets;
  cachedDb = (await getDb(cachedDb, cachedSecrets)).db;

  //auth middle ware
  const authResult = await getOauthMiddleWareResult(
    event,
    email,
    cachedSecrets,
    cachedDb
  );
  if ([400, 401, 419, 500].includes(authResult.code)) {
    return respond(authResult.code, {
      authResponse: authResult.authResponse,
    });
  }

  // response by request
  switch (requestType) {
    case &quot;요청타입1&quot;:
      return handlerFuncs1(event, authResult, email);
    case &quot;요청타입2&quot;:
      return handlerFuncs2(event, authResult, email);
    default:
      console.log(&quot;Invalid request type on this lambda:&quot;, requestType);
      return respond(400, { message: &quot;Invalid request from this lambda&quot; });
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대한 짧게 요약했는데도 이러네요..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remember me 프로젝트의 모든 람다코드는 이렇게 템플릿화를 해놨어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NBAjj/btsL1YIFsfx/AzlhfPt42ASwaGkgvnemkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NBAjj/btsL1YIFsfx/AzlhfPt42ASwaGkgvnemkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NBAjj/btsL1YIFsfx/AzlhfPt42ASwaGkgvnemkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNBAjj%2FbtsL1YIFsfx%2FAzlhfPt42ASwaGkgvnemkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;733&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림으로 보여드리자면 이렇습니다. &lt;b&gt;모든 람다코드가 이렇게 템플릿으로 규격화 되어있어요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 &lt;b&gt;유지보수&lt;/b&gt;를 할때 추가기능이 있다면 추가적인 핸들러만 추가하면되고, 버그난 플로우는 해당부분만 찾아서 손보면 되겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 유저 인증기능을 아직은 설명안드렸는데요~ 유저인증이 필요한 기능이있으면 저렇게 미들웨어 코드를 거치게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remember me 프로젝트는 개인단어장 어플이다보니회원가입뺴고 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;거의 다&lt;span&gt; &lt;/span&gt;&lt;/span&gt;인증요청이에요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저인증관련한건 밑에서 더 설명드릴예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;frontend&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djvYbO/btsL23vszPU/tpqtaruKFuSTyXEsiA33p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djvYbO/btsL23vszPU/tpqtaruKFuSTyXEsiA33p1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djvYbO/btsL23vszPU/tpqtaruKFuSTyXEsiA33p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjvYbO%2FbtsL23vszPU%2FtpqtaruKFuSTyXEsiA33p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;426&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 이제 좀 머리좀 식히고 갈게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이번 프로젝트에서 타입스크립트와 리액트를 처음 사용해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 쓰는거라 많이 서투르지만 제가 가장 중요하게 생각했던건 &lt;b&gt;전역데이터 설정&lt;/b&gt;이었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R4NZ7/btsL1WqwhX4/oblMBwiN6v1rm6uIJrjkWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R4NZ7/btsL1WqwhX4/oblMBwiN6v1rm6uIJrjkWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R4NZ7/btsL1WqwhX4/oblMBwiN6v1rm6uIJrjkWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR4NZ7%2FbtsL1WqwhX4%2FoblMBwiN6v1rm6uIJrjkWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1002&quot; height=&quot;280&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. auth.ts&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인증관련 함수와 인터셉터&lt;/b&gt;가 있어요. 정적으로 return해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. staticData.ts&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적인 데이터나 함수, 큐만드는 생성자 클래스가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. queueContext.tsx&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐 데이터를 전역에서 참조하기 위한 큐를 useContext로 전역에 뿌렸어요. &lt;b&gt;queue&lt;/b&gt;는 useState훅으로 만들어서 상태로 사용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. fucs.ts&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역에서 쓰는 함수지만 얘네들은&lt;b&gt; redux스토어 값에 접근 및 수정&lt;/b&gt;이 필요한 함수들입니다. 때문에 &lt;b&gt;커스텀훅&lt;/b&gt;으로 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. store.ts&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리덕스&lt;/b&gt; 상태값들이 저장되어있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 처음 리액트를 사용해보는지라 미숙하지만 이렇게 데이터와 상태들을 전역에서 참조가능하게 사용했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;프론트엔드의 성능 및 비용 최적화 - batch queue&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz9VUo/btsL007XSLW/6ZlxtklqRZeiO3C8n7Tgl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz9VUo/btsL007XSLW/6ZlxtklqRZeiO3C8n7Tgl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz9VUo/btsL007XSLW/6ZlxtklqRZeiO3C8n7Tgl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcz9VUo%2FbtsL007XSLW%2F6ZlxtklqRZeiO3C8n7Tgl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;721&quot; height=&quot;483&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;일단 들어가기 앞서서&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;람다의 과금요소&lt;/b&gt;부터 생각해볼게요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;람다는 과금요소가 여러가지 있지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;호출횟수&lt;/b&gt;에 따라서도 과금이 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 평생 free tier로 운영되는 서비스지만 제한호출횟수를 넘길지 혹시 모르잖아요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nGZUE/btsL18Efefc/kFzMHj1kyKSjXPRFHaR0T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nGZUE/btsL18Efefc/kFzMHj1kyKSjXPRFHaR0T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nGZUE/btsL18Efefc/kFzMHj1kyKSjXPRFHaR0T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnGZUE%2FbtsL18Efefc%2FkFzMHj1kyKSjXPRFHaR0T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;939&quot; height=&quot;492&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 걱정스러웠던 경우는 단어나 단어장에 대한 업데이트 기능이었어요. 그림과같이 단어 뜻을 여러번 바꾸거나 할일이 많을텐데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단어장 특성상, 단어를 수정하거나 오답노트에 추가한다거나, 삭제한다거나 여러번 수정기능이 있거니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴때마다 람다를 호출하면 비용이 꽤 많이나오겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 데이터를 쌓아서 한번에 보내는 방식이 필요했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 데이터가 더 커지잖아? 생각하실수도 있는데 우리가 평소 보내는 api요청 객체에 비해서는 새발의 피입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;api 요청 객체가 생각보다 커요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새발의 피만큼 용량적은 axios 객체를 열번보내는것보다 새발의피 열방울 들어있는 axios객체 하나보내는게 훨씬 용량이 적거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;단어 수정 정보를 큐에 쌓자~&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT7ExD/btsL2R2P2zz/Is6X46HZe4kamiEQ8ipk2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT7ExD/btsL2R2P2zz/Is6X46HZe4kamiEQ8ipk2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT7ExD/btsL2R2P2zz/Is6X46HZe4kamiEQ8ipk2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT7ExD%2FbtsL2R2P2zz%2FIs6X46HZe4kamiEQ8ipk2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;594&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 단어를 수정할때마다 큐에 정보를 쌓았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;546&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3e5DO/btsL1toVopm/R1cv05kckZyy6QEODhA2C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3e5DO/btsL1toVopm/R1cv05kckZyy6QEODhA2C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3e5DO/btsL1toVopm/R1cv05kckZyy6QEODhA2C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3e5DO%2FbtsL1toVopm%2FR1cv05kckZyy6QEODhA2C1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1271&quot; height=&quot;546&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;546&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;word queue는 트리거로 람다함수 호출을 등록했고 큐 트리거 발동조건을 queue데이터 10개로 설정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이전에는 10번 보내야할 람다 호출이 한번으로 줄어들었네요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;추가적인 queue 최적화&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y8eYG/btsL00AcVrY/VaFSdrUmC6SmkyzbcQyKiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y8eYG/btsL00AcVrY/VaFSdrUmC6SmkyzbcQyKiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y8eYG/btsL00AcVrY/VaFSdrUmC6SmkyzbcQyKiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy8eYG%2FbtsL00AcVrY%2FVaFSdrUmC6SmkyzbcQyKiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;516&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;516&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 무찌를 바보라고 등록했다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각이 바뀌어서 똥개로 바꿨다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 멍청이 라고 수정을 했다고 하면 &lt;b&gt;이전에 수정했던 두 데이터는 필요가 없겠죠&lt;/b&gt;? 가장 마지막 결과만 있으니까요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 큐데이터를 추가할때마다, &lt;b&gt;같은 단어의 수정기록이 있다면 삭제&lt;/b&gt;해주게 프로그래밍 해놨어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 효율이 batch queue를 도입함으로써 열배 좋아졌었는데, 이렇게 중복수정도 처리한다면 열배이상으로 더 좋아지겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;트리거 발동조건 (큰 실수..)&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 사용자가 탭을 닫거나 꺼버릴때 이 큐가 트리거가 발동되기 전이라면 데이터베이스에는 이 수정 기록이 안남을겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 전&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737876935660&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  window.addEventListener(&quot;beforeunload&quot;, (event) =&amp;gt; {
    if (
      window.location.href.includes(
        &quot;https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount&quot;
      )
    ) {
      return;
    }
    saveListsQueueDataAtDb();
    saveWordsQueueDataAtDb()
      .then(() =&amp;gt; {
        event.preventDefault();
      })
      .catch((error) =&amp;gt; {
        console.error(&quot;Error saving data:&quot;, error);
        event.preventDefault();
      });
  });&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 beforeunload라고 윈도우 전역객체에서 이벤트리스너를 만들었는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 &lt;b&gt;모바일에서 할때는 적용이안되더라구요&lt;/b&gt; ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 호환성을 고려안한 제 잘못이죠..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직까지 마땅한 트리거가 생각이안나서 임시방편으로 라우터 이동시에 큐를 람다에 보내는 코드를 추가해놓긴 했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737877114459&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  useEffect(() =&amp;gt; {
    console.log(&quot;라우터가 변경되었습니다!&quot;, location.pathname);
    if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
      saveListsQueueDataAtDb();
      saveWordsQueueDataAtDb();
    }
  }, [location, saveListsQueueDataAtDb, saveWordsQueueDataAtDb]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우터 변경시 람다호출하는 코드를 임시방편으로 추가해놨어요 ㅠㅠ(코드에선 아이폰만해놨지만 지금은 모바일로바꿨어요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 실수죠 뭐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;유저인증 플로우&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAFDTm/btsL2ngTaBB/sikZWJuVyzHf4RUmDOClC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAFDTm/btsL2ngTaBB/sikZWJuVyzHf4RUmDOClC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAFDTm/btsL2ngTaBB/sikZWJuVyzHf4RUmDOClC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAFDTm%2FbtsL2ngTaBB%2FsikZWJuVyzHf4RUmDOClC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;519&quot; height=&quot;538&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 회원가입, 유저인증, 인증처리 등의 유저인증에 관한 기능은 &lt;b&gt;google oauth&lt;/b&gt;를 사용하여 &lt;b&gt;jwt방식&lt;/b&gt;으로 구현했습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 아빠 또갈까 프로젝트도 cognito와 google oauth로 jwt를 사용했지만, access token만 사용했거든요. 코그니토는 refresh토큰을 적용하기 복잡합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이번에 remember me 프로젝트는&lt;b&gt; refresh 토큰 &lt;/b&gt;또한 사용했습니다~&lt;/p&gt;
&lt;figure id=&quot;og_1737878673216&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;'security' 카테고리의 글 목록&quot; data-og-description=&quot;지극히 이기적인 개발 블로그입니다.&quot; data-og-host=&quot;jacobowl.tistory.com&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/category/security&quot; data-og-url=&quot;https://jacobowl.tistory.com/category/security&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ccNkqr/hyX7T8uAIN/FDjX2r6hQeMJekUo2Svvm1/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/mi0Zp/hyX70meR1D/9B7ZF9MGcWcDHWQuS1mEkK/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/maORk/hyX4AvUicy/tKtfizVzQiLSINJ7jdKByk/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593&quot;&gt;&lt;a href=&quot;https://jacobowl.tistory.com/category/security&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/category/security&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ccNkqr/hyX7T8uAIN/FDjX2r6hQeMJekUo2Svvm1/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/mi0Zp/hyX70meR1D/9B7ZF9MGcWcDHWQuS1mEkK/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/maORk/hyX4AvUicy/tKtfizVzQiLSINJ7jdKByk/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'security' 카테고리의 글 목록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지극히 이기적인 개발 블로그입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jacobowl.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jwt방식에 대한건 security카테코리의 포스팅을 참고해주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;어떤점이 특별하냐면요&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jwt방식으로 유저인증을 구현하시는 방법은 개발자분들마다 다르더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nurd worker는 최대한 사용자의 편의성을 최고로 중요시하거든요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이런 상황이 있다고 한다면 어떻게 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sthCr/btsL2lDnffJ/7et19azT046h4SLL3e2VX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sthCr/btsL2lDnffJ/7et19azT046h4SLL3e2VX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sthCr/btsL2lDnffJ/7et19azT046h4SLL3e2VX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsthCr%2FbtsL2lDnffJ%2F7et19azT046h4SLL3e2VX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1069&quot; height=&quot;481&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌가 어제까지 remember me 프로젝트로 단어공부를 헀답니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 자고 일어나서 다시 공부를 하려고해요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMpq4Y/btsL0V0vXoV/TL5XSGlWdTqjfrXfdPlFMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMpq4Y/btsL0V0vXoV/TL5XSGlWdTqjfrXfdPlFMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMpq4Y/btsL0V0vXoV/TL5XSGlWdTqjfrXfdPlFMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMpq4Y%2FbtsL0V0vXoV%2FTL5XSGlWdTqjfrXfdPlFMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;968&quot; height=&quot;472&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이렇게 access token이 만료가 되어있는 상태일겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1037&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cp6GBJ/btsL24nDfcX/fknufKf6UYL0yP8nFX4sqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cp6GBJ/btsL24nDfcX/fknufKf6UYL0yP8nFX4sqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cp6GBJ/btsL24nDfcX/fknufKf6UYL0yP8nFX4sqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcp6GBJ%2FbtsL24nDfcX%2FfknufKf6UYL0yP8nFX4sqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1037&quot; height=&quot;600&quot; data-origin-width=&quot;1037&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면이 그대로입니다. remember me는 개인단어장용 어플리케이션이므로 인증된 요청이어야만 보이는 화면이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로고침을 안한채로 다음날 다시 보니까 인증이 필요한 화면이 그대로 남아있습니다. 하지만 access token은 만료된 상태일겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황에서 무찌가&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;b&gt;만약 인증이 필요한 버튼 을 클릭&lt;/b&gt;&lt;/span&gt;하면 어떻게될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;remember me 프로젝트에서는 refresh 토큰 갱신과 함께 기존 요청에 대한 응답도 해주게됩니다!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;어떻게 했냐면..&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wTczM/btsL3jLCTOO/L3jcqAL7Dw8TOhYB7Xna20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wTczM/btsL3jLCTOO/L3jcqAL7Dw8TOhYB7Xna20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wTczM/btsL3jLCTOO/L3jcqAL7Dw8TOhYB7Xna20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwTczM%2FbtsL3jLCTOO%2FL3jcqAL7Dw8TOhYB7Xna20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1233&quot; height=&quot;631&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1737879455045&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;rememberme-advanced-front/front/src/auth.ts at main &amp;middot; nurdworker/rememberme-advanced-front&quot; data-og-description=&quot;Contribute to nurdworker/rememberme-advanced-front development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-front/blob/main/front/src/auth.ts&quot; data-og-url=&quot;https://github.com/nurdworker/rememberme-advanced-front/blob/main/front/src/auth.ts&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jpGaW/hyX4pusVcQ/waMph7qhyDs2DsS74yNOe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eqGwJG/hyX4x68vWG/6Tffu1x970fnzNwv7t9B3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-front/blob/main/front/src/auth.ts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-front/blob/main/front/src/auth.ts&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jpGaW/hyX4pusVcQ/waMph7qhyDs2DsS74yNOe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eqGwJG/hyX4x68vWG/6Tffu1x970fnzNwv7t9B3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;rememberme-advanced-front/front/src/auth.ts at main &amp;middot; nurdworker/rememberme-advanced-front&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/rememberme-advanced-front development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답인터셉터를 보시면 이렇습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 가져오면 너무 지저분해질것같아 설명만 드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답을 받았을때 &lt;b&gt;419응답을 받으면 기존에 보냈던 axios요청을 통째로 다시&lt;/b&gt;보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다만 헤더값에 refresh토큰을 추가&lt;/b&gt;해서 다시보내죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1737879547135&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;rememberme-advanced-back/backend/src/handlers/rbm-helper.js at main &amp;middot; nurdworker/rememberme-advanced-back&quot; data-og-description=&quot;Contribute to nurdworker/rememberme-advanced-back development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-back/blob/main/backend/src/handlers/rbm-helper.js&quot; data-og-url=&quot;https://github.com/nurdworker/rememberme-advanced-back/blob/main/backend/src/handlers/rbm-helper.js&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cmtnt3/hyX7WjPETI/stHJZ8umbijsBvq6X3piV0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/dvBmba/hyX4reI4YP/VkERa41keiqTGlX3qBKrKk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/rememberme-advanced-back/blob/main/backend/src/handlers/rbm-helper.js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/rememberme-advanced-back/blob/main/backend/src/handlers/rbm-helper.js&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cmtnt3/hyX7WjPETI/stHJZ8umbijsBvq6X3piV0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/dvBmba/hyX4reI4YP/VkERa41keiqTGlX3qBKrKk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;rememberme-advanced-back/backend/src/handlers/rbm-helper.js at main &amp;middot; nurdworker/rememberme-advanced-back&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/rememberme-advanced-back development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 백엔드 인증 미들웨어에서 해당요청을 검증하고 처리한후,&lt;b&gt; authResult에 새로운 access token을 담아서 보냄&lt;/b&gt;과 동시에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;answer프로퍼티에 기존 했던 요청에 대한 데이터도&lt;/b&gt; 응답해주게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇몇 서비스들은 로그아웃을 하게 한다거나 버벅거림이 있겠지만 nurd worker는 사용자 편의성을 중요시하므로 이렇게 사용자가 access token이 만료된걸 전혀 느끼지 못하게 인증기능을 구현을 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 코드를 보시면 아시겠지만 따로 &lt;b&gt;refresh갱신을 위한 api자체가 없습니다&lt;/b&gt;. 걍 미들웨어에서 다 처리해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;토큰 로그 db 저장&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다쪽 미들웨어 코드를 보시면 아시겠지만 토큰로그를 저장해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안이 더욱 좋아졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 구현할생각은 없었는데 &lt;b&gt;google oauth api가&lt;/b&gt; access token을 검증하는 api를 보낼때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;access token이 만료된거든 위조된거든 똑같은 invalid token이라는 응답&lt;/b&gt;을 줍니다 ㅡㅡ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 jwt포스팅 시리즈에서도 보셨듯이 전 두가지 조건을 동시에 만족해야 새로운 acess token을 발급해줬거든요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. refresh 토큰이 유효해야한다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. access token이 만료되었어야한다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두가지 조건을 and조건으로 만족해야 준다고했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;google oauth가 2번 조건을 명확하게 해주질 못했어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 db에 token로그라는 collection을 따로 만들어서 토큰을 기록해두고 이 기록에따라서 만료조건을 체크했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;팀프로젝트 - 첫 팀장으로써 진행&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;휴.. 지금까지 읽어주셔서 감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터는 팀프로젝트에 대해서 짧게 설명드릴게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1555&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbBZT9/btsL2JD1sgJ/h1ixsAvQk6YYKKWNY0c5kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbBZT9/btsL2JD1sgJ/h1ixsAvQk6YYKKWNY0c5kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbBZT9/btsL2JD1sgJ/h1ixsAvQk6YYKKWNY0c5kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbBZT9%2FbtsL2JD1sgJ%2Fh1ixsAvQk6YYKKWNY0c5kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1555&quot; height=&quot;853&quot; data-origin-width=&quot;1555&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 노션을 사용을 주로 하였어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트가 급하게 시작이 되어서 노션제작을 후딱 한다음 회의하면서 사용방법을 알려드렸어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에 보이는것보다 더욱 많은데, 자세한 내용은 직접 독자분과 만날 기회가 있다면 알려드리겠습니다 ^^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yg9r6/btsL0XD5MeQ/OFuCfmj1H2LJIu2U00Ar5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yg9r6/btsL0XD5MeQ/OFuCfmj1H2LJIu2U00Ar5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yg9r6/btsL0XD5MeQ/OFuCfmj1H2LJIu2U00Ar5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyg9r6%2FbtsL0XD5MeQ%2FOFuCfmj1H2LJIu2U00Ar5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;832&quot; height=&quot;874&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 캘린터로 팀원분들의 진행상황을 확인했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 이전에 아빠 또갈까 프로젝트에서 task 방식으로 협업하는걸 보고 저도 적용했습니다 ㅎㅎ(저는 고라파덕입니다..ㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;925&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mV01m/btsL07sBHk7/XKQvfUdeuKnhMBS6CP3X3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mV01m/btsL07sBHk7/XKQvfUdeuKnhMBS6CP3X3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mV01m/btsL07sBHk7/XKQvfUdeuKnhMBS6CP3X3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmV01m%2FbtsL07sBHk7%2FXKQvfUdeuKnhMBS6CP3X3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1066&quot; height=&quot;925&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;925&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 개인마다 task를 정리해서 기록했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 혼자 작성한 task만 저 사진에 보이는 task의 다섯배정도 됩니다 ㅋㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 nurd worker가 취준할떄 면접관이셔서 증명을 원하시거나 혹은 친해지시면 자세히 노션을 보여드릴 수 있습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저기에 서로 사용했던 중요데이터나 이런정보도 있어서 노션을 배포해서 블로그에 공개를 하기는 어렵네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;시연영상 촬영&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dddtAI/btsL3lQdcPg/0AKYmWHdUrkJgwjT2Kiqp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dddtAI/btsL3lQdcPg/0AKYmWHdUrkJgwjT2Kiqp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dddtAI/btsL3lQdcPg/0AKYmWHdUrkJgwjT2Kiqp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdddtAI%2FbtsL3lQdcPg%2F0AKYmWHdUrkJgwjT2Kiqp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;742&quot; height=&quot;611&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgZmpV/btsL2AfXPh5/rt6QPEDpsH5aMwMFit01m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgZmpV/btsL2AfXPh5/rt6QPEDpsH5aMwMFit01m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgZmpV/btsL2AfXPh5/rt6QPEDpsH5aMwMFit01m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgZmpV%2FbtsL2AfXPh5%2Frt6QPEDpsH5aMwMFit01m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;742&quot; height=&quot;578&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;922&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldbld/btsL0WrD2lJ/3C5sFVdEzk9HyBkaFcjeZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldbld/btsL0WrD2lJ/3C5sFVdEzk9HyBkaFcjeZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldbld/btsL0WrD2lJ/3C5sFVdEzk9HyBkaFcjeZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fldbld%2FbtsL0WrD2lJ%2F3C5sFVdEzk9HyBkaFcjeZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;922&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;922&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 특별하게 요청드렸던것은 본인이 개발한 분야에대한 &lt;b&gt;시연영상&lt;/b&gt;을 제작해달라고 말씀드렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜이랬냐면, 사실 저희가 프로젝트를 만들고나서는 보통 대게는 서비스를 중지하게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브에 코드만 달랑 남겨두거나 하게되죠. 실제로 demo버전은 프로젝트 종료후 바로 배포중지가 되었어요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 나중에 프로젝트로 사용하려면 까먹기도하고 사용했던 툴들이 갖가지 버전문제로 에러를 일으킬수도 있어요. 실제 로컬에라도 배포가 되어야 증명이 될텐데.. 난감해지죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 무무티비프로젝트도 VM이 다섯개에 컨테이너만 열개이상 띄워져있는데 1년전에 프로젝트를 다시 띄우고 하려면 기억도안나고 에러도 많이 날겁니다. 그래서 nurd worker도 무무티비 포스팅에 사용된 영상 소스들을 모두 당시에 프로젝트 종료후 바로 촬영해놨던겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영상으로 기록을 남기는건 중요하다&lt;/b&gt;고 봅니다. 가장 좋은 방법은 실제 배포해놓는것이지만 현실적으로 어렵거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취직을 목표로 하는 경우 면접관분들이 진짜 개발했다는걸 믿지 않을확률이 크거든요. (사실 저도 잘 안믿습니다 ㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&amp;nbsp; nurd worker 또한 &lt;b&gt;프로젝트마다 영상작업&lt;/b&gt;을 하고있고 &lt;b&gt;구현영상남기는걸 굉장히 중요하게 생각&lt;/b&gt;해요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 이 프로젝트를 다시 사용하실때 필요하실거라고 판단되서 오더를 드렸었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저한테 증명해서 뭐가중요한가요 전 테라폼같은 고급 스킬 볼줄도 모르는데요ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀원분들이 좀 독특한 팀장을 만나 고생을 좀 하시긴 한것같기도 하네요 ㅎㅎㅎ&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;프로젝트 피드백&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yh39U/btsL1F3EEhN/KtKCXdTTO5OgPWryk0Thf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yh39U/btsL1F3EEhN/KtKCXdTTO5OgPWryk0Thf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yh39U/btsL1F3EEhN/KtKCXdTTO5OgPWryk0Thf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyh39U%2FbtsL1F3EEhN%2FKtKCXdTTO5OgPWryk0Thf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;736&quot; height=&quot;640&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs0fT5/btsL3iFXc2U/401gSwgPVjysekjVUXBIjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs0fT5/btsL3iFXc2U/401gSwgPVjysekjVUXBIjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs0fT5/btsL3iFXc2U/401gSwgPVjysekjVUXBIjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs0fT5%2FbtsL3iFXc2U%2F401gSwgPVjysekjVUXBIjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;748&quot; height=&quot;732&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nurd worker가 팀원분들에게 받은 피드백입니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 평가를 받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스터디는 많이 진행해봤었으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔지니어로써 팀을 이끌기는 처음이라 많이 미숙했던점도 많았고 반성할점도 많았던것 같습니다 ^^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;아키텍쳐&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;demo 버전 아키텍쳐&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN5QKT/btsL2bHMmRn/au1iOI3jRwcduRFMvSPDKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN5QKT/btsL2bHMmRn/au1iOI3jRwcduRFMvSPDKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN5QKT/btsL2bHMmRn/au1iOI3jRwcduRFMvSPDKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN5QKT%2FbtsL2bHMmRn%2Fau1iOI3jRwcduRFMvSPDKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;735&quot; height=&quot;268&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coXv4D/btsL1sKiIUp/kwHB5iOBaKICOqIFmkRQrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coXv4D/btsL1sKiIUp/kwHB5iOBaKICOqIFmkRQrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coXv4D/btsL1sKiIUp/kwHB5iOBaKICOqIFmkRQrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoXv4D%2FbtsL1sKiIUp%2FkwHB5iOBaKICOqIFmkRQrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;460&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbavVw/btsL3kRi48i/LPoYE7iX6kKEMIEIXzu1k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbavVw/btsL3kRi48i/LPoYE7iX6kKEMIEIXzu1k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbavVw/btsL3kRi48i/LPoYE7iX6kKEMIEIXzu1k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbavVw%2FbtsL3kRi48i%2FLPoYE7iX6kKEMIEIXzu1k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;739&quot; height=&quot;424&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFO98T/btsL1CFBev9/qCX8LXcv3SqPoTF8VFoBJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFO98T/btsL1CFBev9/qCX8LXcv3SqPoTF8VFoBJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFO98T/btsL1CFBev9/qCX8LXcv3SqPoTF8VFoBJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFO98T%2FbtsL1CFBev9%2FqCX8LXcv3SqPoTF8VFoBJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;212&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvLBsn/btsL2oUpcel/xjdlTtpR4CqsXq6q08J9zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvLBsn/btsL2oUpcel/xjdlTtpR4CqsXq6q08J9zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvLBsn/btsL2oUpcel/xjdlTtpR4CqsXq6q08J9zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvLBsn%2FbtsL2oUpcel%2FxjdlTtpR4CqsXq6q08J9zk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;258&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc6OHQ/btsL3mhhQRp/PKUyOlwgWa4EWCnaUfCbsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc6OHQ/btsL3mhhQRp/PKUyOlwgWa4EWCnaUfCbsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc6OHQ/btsL3mhhQRp/PKUyOlwgWa4EWCnaUfCbsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc6OHQ%2FbtsL3mhhQRp%2FPKUyOlwgWa4EWCnaUfCbsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;623&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프라 팀원분들이 그려주신 &lt;b&gt;demo버전 아키텍쳐&lt;/b&gt;입니다. 역시 인프라팀분들 실력이 어마어마합니다 ㄷㄷ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;demo 버전은 &lt;b&gt;프론트&lt;/b&gt;서버를 &lt;b&gt;s3버킷&lt;/b&gt;에서 정적호스팅 하였구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 &lt;b&gt;백엔드&lt;/b&gt;는 &lt;b&gt;api gateway와 람다 구조&lt;/b&gt;로 이용하였구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;는 &lt;b&gt;몽고디비&lt;/b&gt;를 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기타 등등 여러가지 있답니다 ㅎㅎ 저도 잘 모르는것들이 많네요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;advanced 아키텍쳐&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wl7BN/btsL3hAhBBJ/oBeBQ2hy68R0ArJwKDIX1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wl7BN/btsL3hAhBBJ/oBeBQ2hy68R0ArJwKDIX1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wl7BN/btsL3hAhBBJ/oBeBQ2hy68R0ArJwKDIX1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWl7BN%2FbtsL3hAhBBJ%2FoBeBQ2hy68R0ArJwKDIX1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1183&quot; height=&quot;662&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 배포된 remember me 프로젝트 advanced버전의 아키텍쳐입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프론트&lt;/b&gt; 웹서버는 &lt;b&gt;무찌 클러스터&lt;/b&gt;에서 운영이 되어있구요.&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백엔드&lt;/b&gt;는&lt;b&gt; AWS의 api gateway + lambda구조&lt;/b&gt;로 운영되고있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 추가적으로 cloud watch와 SNS를 사용한 알람을 구현해놨습니다^^ (과금 무섭..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;는 &lt;b&gt;무찌 클러스터의 mongo db&lt;/b&gt;를 사용하고 있답니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;Conclusion&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;사실 remember me 프로젝트는 acsap프로젝트의 약간 상위버전? 으로 간단하게&lt;br /&gt;react와 type script를 사용한 어플리케이션으로 간단하게 준비하려고 한 개인 프로젝트였습니다.&lt;br /&gt;&lt;br /&gt;근데 마침 너드림덱 프로젝트가 막 끝났을때 이전 네트워크 국비과정을 함께하셨던 분들이 연락이 오셨어요.&lt;br /&gt;프로젝트를 같이 하자고 하시길래 얼떨결에 팀프로젝트로 변해버린 프로젝트입니다. ㅋㅋ&lt;br /&gt;온라인으로 진행한 프로젝트였고 팀원한분은 프로젝트 시작하자마자 취업합격통보를 받으셨는데 책임감있게 해주셔서 감사드리네요.&lt;br /&gt;&lt;br /&gt;암튼 하다보니 막 욕심도 나고 해서 여러가지 고려사항을 많이 녹여낸 프로젝트가 되었고&lt;br /&gt;취업할때 굉장히 많은 포인트들을 어필할 수 있는 프로젝트라고 생각이 드네요. (때문에 포스팅도 토나오게 많이적었네요....)&lt;br /&gt;&lt;br /&gt;긴 글 읽어주셔서 감사합니다 ^^&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>project/teamProject</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/357</guid>
      <comments>https://jacobowl.tistory.com/357#entry357comment</comments>
      <pubDate>Sun, 26 Jan 2025 10:33:16 +0900</pubDate>
    </item>
    <item>
      <title>개발단 db 마이그레이션</title>
      <link>https://jacobowl.tistory.com/356</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;예전에 기존에 사용하던 클라우드의 데이터베이스를 다른 인스턴스로 마이그레이션 할 일이 있었다..&lt;br /&gt;너무 비쌈 ㅡㅡ&amp;nbsp;&lt;br /&gt;그래서 코드로 반복문과 setinterval을 사용하여 직접 데이터를 옮겼었는데 포스팅해봄.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시연영상&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;환경셋팅&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xvPJS/btsL0HHUqxw/fVaKk1GP5kV2DxsdKhKi61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xvPJS/btsL0HHUqxw/fVaKk1GP5kV2DxsdKhKi61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xvPJS/btsL0HHUqxw/fVaKk1GP5kV2DxsdKhKi61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxvPJS%2FbtsL0HHUqxw%2FfVaKk1GP5kV2DxsdKhKi61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;228&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 마이그레이션을 위해 샘플 mysql인스턴스를 생성하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나는 bf-db, 다른 하나는 af-db라고 이름지었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bf-db라는 인스턴스의 데이터베이스의 데이터들을 af-db로 옮길것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;각 EC2인스턴스에 mysql설치&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737763051727&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mysql설치하기
sudo apt update
sudo apt install mysql-server

# mysql에 루트유저로 접속
mysql -u root -p
비밀번호 입력

# 데이터베이스를 만들고 유저 생성
SHOW GRANTS FOR 'muzzi'@'%';
GRANT CREATE ON *.* TO 'muzzi'@'%';
FLUSH PRIVILEGES;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;muzzi라는 유저만들고 유저권한주샘&lt;/li&gt;
&lt;li&gt;참고로 mysql외부접속도 열어줘야함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;mysql 워크벤치 접속&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;113&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjz5Or/btsL03chXu1/UVtO9YUu5zJmdMJEyAriMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjz5Or/btsL03chXu1/UVtO9YUu5zJmdMJEyAriMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjz5Or/btsL03chXu1/UVtO9YUu5zJmdMJEyAriMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjz5Or%2FbtsL03chXu1%2FUVtO9YUu5zJmdMJEyAriMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;113&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;113&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워크 벤치 접속해서 각각 mydatabase라는 데이터베이스 커넥션을 연결해줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;각 db접속 정보 정리&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737763589141&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BF_HOST=&quot;123.123.123.123&quot;
BF_USER=&quot;muzzi&quot;
BF_PASSWORD=&quot;babo&quot;
BF_DATABASE=&quot;mydatabase&quot;
BF_PORT=&quot;3306&quot;

AF_HOST=&quot;456.456.456.456&quot;
AF_USER=&quot;muzzi&quot;
AF_PASSWORD=&quot;babo&quot;
AF_DATABASE=&quot;mydatabase&quot;
AF_PORT=&quot;3306&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드단에서 이렇게 환경변수 지정해주고 연결할 준비를 마쳤음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;코드단&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1737763154400&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - nurdworker/dev-migration-mysql&quot; data-og-description=&quot;Contribute to nurdworker/dev-migration-mysql development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/dev-migration-mysql&quot; data-og-url=&quot;https://github.com/nurdworker/dev-migration-mysql&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cslINh/hyX7ZnavyH/4t0eqYFpa94WiuCsW86l3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iq4JL/hyX7PrjTmv/DZy8Dq7UKKEPg7kbvVMV51/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/dev-migration-mysql&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/dev-migration-mysql&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cslINh/hyX7ZnavyH/4t0eqYFpa94WiuCsW86l3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iq4JL/hyX7PrjTmv/DZy8Dq7UKKEPg7kbvVMV51/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nurdworker/dev-migration-mysql&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/dev-migration-mysql development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브 코드이다.&lt;/p&gt;
&lt;h1&gt;1. 데이터 베이스 연결&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경변수쓸꺼고 mysql2모듈 쓸거임&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const dotenv = require(&quot;dotenv&quot;);
const mysql = require(&quot;mysql2&quot;);

dotenv.config();
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;풀만들기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;roboconf&quot;&gt;&lt;code&gt;const bf_pool = mysql.createPool({
  connectionLimit: 10, // 최대 연결 수
  host: process.env.BF_HOST,
  user: process.env.BF_USER,
  password: process.env.BF_PASSWORD,
  database: process.env.BF_DATABASE,
  port: process.env.BF_PORT,
});

const af_pool = mysql.createPool({
  connectionLimit: 10, // 최대 연결 수
  host: process.env.AF_HOST,
  user: process.env.AF_USER,
  password: process.env.AF_PASSWORD,
  database: process.env.AF_DATABASE,
  port: process.env.AF_PORT,
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 저장해둔 환경변수로 풀 만드는 코드.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀 안만들어도 되겠지만 연결 한두번하다가 커넥션리밋 넘을거라 써줌&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터베이스 연결확인&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const checkDatabaseConnection = (pool) =&amp;gt; {
  return new Promise((resolve, reject) =&amp;gt; {
    pool.getConnection((err, connection) =&amp;gt; {
      if (err) {
        reject(err);
      } else {
        connection.release();
        resolve();
      }
    });
  });
};

const checkAllDatabaseConnections = async () =&amp;gt; {
  try {
    await Promise.all([
      checkDatabaseConnection(bf_pool),
      checkDatabaseConnection(af_pool),
    ]);
    console.log(
      &quot;\\x1b[48;2;128;0;128m Start \\x1b[0m 모든 데이터베이스가 마이그레이션할 준비가 되었습니다!&quot;
    );
    return true;
  } catch (error) {
    // console.error(&quot;데이터 베이스가 연결되지 않았습니다.&quot;, error);
    console.error(&quot;데이터 베이스가 연결되지 않았습니다.&quot;);
    return false;
  }
};

checkAllDatabaseConnections();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 베이스 연결됐는지 확인하고 연결안됐으면 멈추게 프로미스 반환하는 비동기함수로 썼음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;2. 샘플데이터 넣기&lt;/h1&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const dotenv = require(&quot;dotenv&quot;);
const mysql = require(&quot;mysql2&quot;);

dotenv.config();

// MySQL Pool 생성
const bf_pool = mysql.createPool({
  connectionLimit: 10,
  host: process.env.BF_HOST,
  user: process.env.BF_USER,
  password: process.env.BF_PASSWORD,
  database: process.env.BF_DATABASE,
  port: process.env.BF_PORT,
});

// 랜덤한 숫자를 생성하는 함수
const getRandomNumber = (min, max) =&amp;gt; {
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

// 샘플 데이터 생성 함수
const generateSampleData = () =&amp;gt; {
  const sampleData = [];
  for (let i = 1; i &amp;lt;= 60; i++) {
    const id = `user${i}`;
    const detail = `Sample detail ${i}`;
    sampleData.push({ id, detail });
  }
  return sampleData;
};

// MySQL에 샘플 데이터 삽입 함수
const insertSampleDataToDatabase = async (sampleData) =&amp;gt; {
  const connection = await bf_pool.promise().getConnection();
  try {
    await connection.query(
      &quot;CREATE TABLE IF NOT EXISTS users (user_idx INT AUTO_INCREMENT PRIMARY KEY, id VARCHAR(255) UNIQUE, detail TEXT)&quot;
    );

    // 삽입할 데이터를 배열로 변환
    const values = sampleData.map(({ id, detail }) =&amp;gt; [id, detail]);

    // INSERT 쿼리 실행
    await connection.query(&quot;INSERT INTO users (id, detail) VALUES ?&quot;, [values]);
    console.log(&quot;Sample data inserted successfully.&quot;);
  } catch (error) {
    console.error(&quot;Error inserting sample data:&quot;, error);
  } finally {
    connection.release();
  }
};

// 샘플 데이터 생성
const sampleData = generateSampleData();

// 샘플 데이터를 MySQL에 삽입
insertSampleDataToDatabase(sampleData);

// 샘플 데이터 생성 함수
const generateSamplePostData = () =&amp;gt; {
  const samplePostData = [];
  for (let i = 1; i &amp;lt;= 110; i++) {
    const title = `Post ${i} Title`;
    const content = `Post ${i} Content`;
    samplePostData.push({ title, content });
  }
  return samplePostData;
};

// MySQL에 샘플 데이터 삽입 함수
const insertSamplePostDataToDatabase = async (samplePostData) =&amp;gt; {
  const connection = await bf_pool.promise().getConnection();
  try {
    await connection.query(
      &quot;CREATE TABLE IF NOT EXISTS posts (post_id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), content TEXT)&quot;
    );

    // 삽입할 데이터를 배열로 변환
    const values = samplePostData.map(({ title, content }) =&amp;gt; [title, content]);

    // INSERT 쿼리 실행
    await connection.query(&quot;INSERT INTO posts (title, content) VALUES ?&quot;, [
      values,
    ]);
    console.log(&quot;Sample post data inserted successfully.&quot;);
  } catch (error) {
    console.error(&quot;Error inserting sample post data:&quot;, error);
  } finally {
    connection.release();
  }
};

// 샘플 데이터 생성
const samplePostData = generateSamplePostData();

// 샘플 데이터를 MySQL에 삽입
insertSamplePostDataToDatabase(samplePostData);

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bf디비에 일단 데이터가 있어야하니까 코드로 랜덤하게 데이터 넣는 함수 썼음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블은 우리서비스 메인인 users랑 posts테이블 두개로 했음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;3. bf디비에 테이블 설정 그대로 af테이블에 만들기&lt;/h1&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// 테이블 그대로 만들기

const getTableDefinitions = async (pool) =&amp;gt; {
  return new Promise((resolve, reject) =&amp;gt; {
    pool.query(&quot;SHOW TABLES&quot;, (error, results) =&amp;gt; {
      if (error) {
        reject(error);
      } else {
        const tables = results.map((row) =&amp;gt; Object.values(row)[0]);
        const tableDefinitions = [];
        const promises = tables.map((table) =&amp;gt; {
          return new Promise((resolve, reject) =&amp;gt; {
            pool.query(`SHOW CREATE TABLE ${table}`, (error, results) =&amp;gt; {
              if (error) {
                reject(error);
              } else {
                const createTableStatement = results[0][&quot;Create Table&quot;];
                tableDefinitions.push(createTableStatement);
                resolve();
              }
            });
          });
        });
        Promise.all(promises)
          .then(() =&amp;gt; resolve(tableDefinitions))
          .catch(reject);
      }
    });
  });
};

const getTableCreationQueries = async () =&amp;gt; {
  try {
    const tableDefinitions = await getTableDefinitions(bf_pool);
    return tableDefinitions;
  } catch (error) {
    // console.error(&quot;테이블 생성 쿼리가 실패했습니다.&quot;, error);
    console.error(&quot;테이블 생성 쿼리가 실패했습니다.&quot;);
    return [];
  }
};

const createTableQuery = async () =&amp;gt; {
  return await getTableCreationQueries();
};
const makeConditionQuery = async () =&amp;gt; {
  const queries = await createTableQuery();
  const modifiedQueries = queries.map((query) =&amp;gt; {
    // CREATE TABLE 문에 IF NOT EXISTS 조건 추가
    return query.replace(&quot;CREATE TABLE&quot;, &quot;CREATE TABLE IF NOT EXISTS&quot;);
  });
  return modifiedQueries;
};

// af 디비에 테이블 만들기
const createTablesInAfDatabase = async (queries) =&amp;gt; {
  const connection = await af_pool.promise().getConnection();
  try {
    for (const query of queries) {
      await connection.query(query);
      const tableName = query.match(/`([^`]*)`/)[1];
      console.log(
        `\\x1b[48;2;255;255;0m Info \\x1b[0m 테이블 ${tableName}가 생성되었습니다.`
      );
    }
    console.log(
      &quot;\\x1b[48;2;0;0;255m In Progress \\x1b[0m 마이그레이션 후 테이블이 정상적으로 생성되었습니다!&quot;
    );
  } catch (error) {
    console.error(&quot;이전할 데이터베이스의 테이블 생성이 실패했습니다.&quot;);
  } finally {
    connection.release();
  }
};
const makeTablesToAF = async () =&amp;gt; {
  await createTablesInAfDatabase(await makeConditionQuery());
};
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테이블 데피니션 함수로 완전 똑같은 테이블 정보 가져오는 함수를 썼음.&lt;/li&gt;
&lt;li&gt;테이블 생성 쿼리 생성함수를 만들었음&lt;/li&gt;
&lt;li&gt;테이블 생성하는 쿼리함수에 if not exist조건이 안붙길래 이 조건 붙여주는 함수를 썼음.&lt;/li&gt;
&lt;li&gt;테이블 갯수에 따라서 어레이에다가 그만큼 테이블 생성쿼리를 만들어줌.&lt;/li&gt;
&lt;li&gt;마지막 테이블 생성 함수를 만들었음. 여기서 저 어레이 담긴거 순회하면서 테이블 만들거임&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;4. 데이터 순회하기&lt;/h1&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const moveTableDataFromBFtoAF = async (bfTableName, afTableName) =&amp;gt; {
  let success = false; // 초기값은 실패로 설정

  const bfConnection = await bf_pool.promise().getConnection();
  const afConnection = await af_pool.promise().getConnection();

  try {
    let offset = 0;
    const batchSize = 50;
    let bfData = [];

    // BF 데이터베이스에서 데이터를 검색
    while (true) {
      const [rows] = await bfConnection.query(
        `SELECT * FROM ${bfTableName} LIMIT ${offset}, ${batchSize}`
      );
      if (rows.length === 0) break; // 더 이상 데이터가 없으면 종료
      bfData = rows;

      // AF 데이터베이스에 데이터 삽입
      const values = bfData.map((row) =&amp;gt; Object.values(row));
      await afConnection.query(`INSERT INTO ${afTableName} VALUES ?`, [values]);

      // 2초 대기
      await new Promise((resolve) =&amp;gt; setTimeout(resolve, 1000));

      // 오프셋 증가
      offset += batchSize;
      console.log(
        `\\x1b[48;2;0;0;255m In Progress \\x1b[0m${bfTableName}테이블의 ${offset}rows까지의 데이터가 이전되었습니다.`
      );
    }

    console.log(`${bfTableName}테이블의 데이터 이동이 완료되었습니다.`);
    success = true; // 성공 시 true로 설정
  } catch (error) {
    // console.error(`데이터 이동 중 오류 발생:`, error);
    console.error(`\\x1b[48;2;255;0;0m Fail \\x1b[0m 데이터 이동 중 오류 발생`);
    console.log(
      `\\x1b[48;2;255;255;0m Info \\x1b[0m 에러 발생으로 인해 ${afTableName} 테이블의 모든 데이터를 삭제합니다.`
    );
    await afConnection.query(`DELETE FROM ${afTableName}`);
  } finally {
    bfConnection.release();
    afConnection.release();
    return success; // 성공 또는 실패 여부 반환
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;db과부하를 막기위해 테이블들 이름 들어있는 어레이를 따로 빼고 이걸 순회하는 식으로 했음.&lt;/li&gt;
&lt;li&gt;또한 한번에 너무 많은 데이터가 들어가는걸 막기위해 한번에 50row씩만 조회하고 넣는 코드를 짰음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;5. 마이그레이션 하기&lt;/h1&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const migration = async () =&amp;gt; {
  try {
    await checkAllDatabaseConnections();
    await showTableList();
    await makeTablesToAF();
    const tableLists = await getTableList(bf_pool);

    for (const table of tableLists) {
      const success = await moveTableDataFromBFtoAF(table, table);
      if (!success) {
        console.log(
          `\\x1b[48;2;255;0;0m Fail \\x1b[0m 테이블 ${table}의 데이터 마이그레이션 실패`
        );
        await clearAllTablesData(); // 모든 테이블의 데이터를 삭제
        return;
      }
    }

    console.log(
      &quot;\\x1b[48;2;0;255;0m Success \\x1b[0m 모든 테이블의 데이터 마이그레이션이 완료되었습니다.&quot;
    );
  } catch (error) {
    console.error(
      &quot;\\x1b[48;2;255;0;0m Fail \\x1b[0m 마이그레이션 중 오류 발생:&quot;,
      error
    );
  }
};

const clearAllTablesData = async () =&amp;gt; {
  const tableLists = await getTableList(af_pool);
  for (const table of tableLists) {
    await af_pool.promise().query(`DELETE FROM ${table}`);
    console.log(
      `\\x1b[48;2;255;0;0m Fail \\x1b[0m ${table} 테이블의 데이터가 모두 삭제되었습니다.`
    );
  }
};

migration();
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최종적인 마이그레이션함수임&lt;/li&gt;
&lt;li&gt;위에서 만든 함수에서 주요기능들은 전역에서 호출한게 없음. 애초에 이전단계가 완료안되면 걍 에러터지게 설계해버림&lt;/li&gt;
&lt;li&gt;clearAllTablesData함수는 테이블 리스트를 순회하면서 각각 데이터를 넣는데, 예를들어 users테이블은 마이그레이션이 완료됐는데 posts테이블은 중간에 에러터져서 데이터 다 지우면 하나는 됐고 하나는 안되는 귀찮은 일이 생겨서 걍 하나 에러터지면 이전 성공한 테이블도 데이터 다 지워주는 함수 만들었음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Trouble&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;database라는 데이터를 만드니까 예약어에 포함되서 에러가 팡팡떳다. 만들고나서 안되는게 짜증나는데 만들떄 그냥 만들어주지말지 왜 만들어지게해놓고 db접근에서 오류나게 해놨는지 모르겄음&lt;/li&gt;
&lt;li&gt;mysql모듈을 썼는데 구닥다리라 유저권한 암호화방식 오류가 계속나서 mysql2를 썼음&lt;/li&gt;
&lt;li&gt;bf디비에 있는 테이블들을 조회하고 어레이에 담아서 af디비에 똑같이 만들게 하는 코드를 썻는데 foreign key가 설정된 테이블을 먼저 만들면 안된다. 이건 코드단에서 더 신경써야하는거임&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;추가적으로 생각해봐야 할 것&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 완전 자동화를 한다면 인프라단의 테라폼, 쉘스크립트등이 필요할듯. 인스턴스만들고 뭐 안에다가 디비 설치하고 이런거 하려면 개발단만으로는 안되니까.&lt;/li&gt;
&lt;li&gt;이 주제에서는 연습은 mysql to mysql이다. 만약 다른 데이터베이스 같은경우는 모듈을 추가적으로 받아와야하고 쿼리문 문법도 조금씩 써야하니 ORM을 같이써야할듯&lt;/li&gt;
&lt;li&gt;네트워크는 완전 퍼블릭으로 열어놓은 상태인데 민감한 데이터베이스 마이그레이션이니 현업에서는 프라이빗 네트워크끼리 해야할듯.&lt;/li&gt;
&lt;li&gt;DMS에서 어려웠던 온프레미스 to 클라우드 마이그레이션도 이걸로는 가능하다. 두 인스턴스 사이에 내 로컬컴퓨터가 껴있는 상태에서 한거니까.&lt;/li&gt;
&lt;li&gt;DMS에서 안됐던 AUTO INCREMENT 조건도 저기 테이블 쿼리 자동생성 함수에서 가져와준다.&lt;/li&gt;
&lt;li&gt;데이터가 조금씩 형식이 바뀌는 경우도 있을것같은데 예를들어 쇼핑몰 도메인 컬럼이 있는데 새로운 쇼핑몰 도메인으로 내용을 바꿔야 한다면 이 데이터들만 수정하는 마이그레이션 해야한다면 코드단에서 조절하면 될거임.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>project/miniCode</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/356</guid>
      <comments>https://jacobowl.tistory.com/356#entry356comment</comments>
      <pubDate>Sat, 25 Jan 2025 09:04:52 +0900</pubDate>
    </item>
    <item>
      <title>Team Project - 아빠또갈까?</title>
      <link>https://jacobowl.tistory.com/355</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;안녕하세요? Nurd Worker입니다! 반갑습니다. &lt;br /&gt;이번에 소개해드릴 프로젝트는 &lt;b&gt;아빠또갈까? 프로젝트&lt;/b&gt;&amp;nbsp;입니다!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;네트워크 국비과정&lt;/b&gt;의 파이널 프로젝트로 만들게 된 &lt;b&gt;제 개발 인생에서의 첫 팀프로젝트&lt;/b&gt;입니다^^&lt;br /&gt;&lt;b&gt;가족 여행 어플리케이션&lt;/b&gt;을 만들어서 aws에 배포하는 구조로 제작한 프로젝트에요.&lt;br /&gt;&lt;br /&gt;저희는 총 &lt;b&gt;다섯명&lt;/b&gt;의 팀원분과 프로젝트를 진행했습니다 ㅎㅎ&lt;br /&gt;처음으로 하는 팀프로젝트였는데 운이좋게도 팀원분들이 전부 좋은 분들이셔서 알차게 프로젝트를 마쳤었네요.&lt;br /&gt;지금도 연락을 하고 계시고 작년 겨울에도 만났네요ㅎㅎㅎ&lt;br /&gt;&lt;br /&gt;&lt;b&gt;네트워크 교육과정&lt;/b&gt;이었기 때문에 개발자가 굉장히 귀했답니다.&lt;br /&gt;&lt;b&gt;nurd worker또한 개발자로써&lt;/b&gt; 팀에 들어가서 팀원으로 프로젝트를 진행하였어요.&amp;nbsp;&lt;br /&gt;개발자가 귀했기 때문에 &lt;b&gt;개발팀이 두명&lt;/b&gt; 밖에 안됐어서 개발쪽에서의 프로젝트 완성도는 지금와서 다시보면 많이 모자른것같아요 ㅎㅎ&lt;br /&gt;&lt;br /&gt;말씀드렸듯이 개발팀과 인프라팀, 현업자들이 일하는 방식을 모방하기위해 &lt;b&gt;완전히 분업&lt;/b&gt;을 하였기 때문에 이 포스팅에선 제가 맡은 파트에대해서만 자세히 설명드릴 예정이고 이외의 팀프로젝트에 대한 포스팅을 하겠습니다.&lt;br /&gt;&lt;br /&gt;그럼 재밋게 읽어주세요 ^^&lt;/blockquote&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;아빠또갈까 링크&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아빠 또갈까 introduction video : &lt;/b&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TGAjqTpG0Xc&amp;amp;ab_channel=workernurd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;b&gt;https://www.youtube.com/watch?v=TGAjqTpG0Xc&amp;amp;ab_channel=workernurd&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=TGAjqTpG0Xc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cn62Ls/hyX4sYUl2H/Ywcp6aX1ptyk2UaZKsyeOK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bXDbTy/hyX7O621rt/Gvaka2nmm3loniAgTgXPtK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;nurd worker&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/TGAjqTpG0Xc&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;아빠 또갈까 github organization link :&lt;/b&gt; &lt;a href=&quot;https://github.com/DGA-PROJECT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://github.com/DGA-PROJECT&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;DGA-PROJECT&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;DGA-PROJECT has 8 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/DGA-PROJECT&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/A92Me/hyX4vgT4Qz/CwfcEJWwYcSGCcNR7e4LP1/img.jpg?width=280&amp;amp;height=280&amp;amp;face=136_159_158_183,https://scrap.kakaocdn.net/dn/bflx9W/hyX73bV5We/eySSrq3VNLPaEcUgvudQ5k/img.jpg?width=280&amp;amp;height=280&amp;amp;face=136_159_158_183,https://scrap.kakaocdn.net/dn/GuIcK/hyX70M21B6/VpukCGKJWu7yZTryTJaQZ1/img.jpg?width=3300&amp;amp;height=2383&amp;amp;face=0_0_3300_2383&quot; data-og-url=&quot;https://github.com/DGA-PROJECT&quot;&gt;&lt;a href=&quot;https://github.com/DGA-PROJECT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/DGA-PROJECT&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/A92Me/hyX4vgT4Qz/CwfcEJWwYcSGCcNR7e4LP1/img.jpg?width=280&amp;amp;height=280&amp;amp;face=136_159_158_183,https://scrap.kakaocdn.net/dn/bflx9W/hyX73bV5We/eySSrq3VNLPaEcUgvudQ5k/img.jpg?width=280&amp;amp;height=280&amp;amp;face=136_159_158_183,https://scrap.kakaocdn.net/dn/GuIcK/hyX70M21B6/VpukCGKJWu7yZTryTJaQZ1/img.jpg?width=3300&amp;amp;height=2383&amp;amp;face=0_0_3300_2383');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DGA-PROJECT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DGA-PROJECT has 8 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFeQdP/btsL2cF1AJT/EMIyPfWph7jcjMKYUbTFh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFeQdP/btsL2cF1AJT/EMIyPfWph7jcjMKYUbTFh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFeQdP/btsL2cF1AJT/EMIyPfWph7jcjMKYUbTFh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFeQdP%2FbtsL2cF1AJT%2FEMIyPfWph7jcjMKYUbTFh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;468&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;팀 구성은 어떻게 되었나요?&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b829Qp/btsL1t9Me5K/xxyqHy9WqK8Fd1eArv6sqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b829Qp/btsL1t9Me5K/xxyqHy9WqK8Fd1eArv6sqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b829Qp/btsL1t9Me5K/xxyqHy9WqK8Fd1eArv6sqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb829Qp%2FbtsL1t9Me5K%2FxxyqHy9WqK8Fd1eArv6sqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;560&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;저희팀은 총&lt;b&gt; 다섯명&lt;/b&gt;이서 프로젝트를 진행했습니다!&lt;br /&gt;소갯글에서도 적어놨듯이 저희팀은 인프라팀, 개발팀으로 &lt;b&gt;완전한 분업&lt;/b&gt;을 하였습니다 ㅎㅎ&lt;br /&gt;nurd worker는 개발팀에서 &lt;b&gt;개발을 담당&lt;/b&gt;하였어요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;개발스택&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/maCWL/btsL0CsNaeP/FIqUS0L6DU2g8YCXfNaJ4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/maCWL/btsL0CsNaeP/FIqUS0L6DU2g8YCXfNaJ4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/maCWL/btsL0CsNaeP/FIqUS0L6DU2g8YCXfNaJ4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmaCWL%2FbtsL0CsNaeP%2FFIqUS0L6DU2g8YCXfNaJ4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1031&quot; height=&quot;636&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;저는 역시나&lt;b&gt; vue js 와 nodejs&lt;/b&gt;로 풀스택 개발을 하였습니다 ㅎㅎ&lt;br /&gt;저랑 같이 개발을 담당하셨던 팀원분은&lt;b&gt; java&lt;/b&gt;를 사용하셨고 JPA를 사용하신걸로 알고있습니다. 저는 java에 대해선 잘몰라요 ㅋㅋ&lt;br /&gt;데이터베이스는 &lt;b&gt;aws RDS데이터베이스&lt;/b&gt;를 사용하였는데, &lt;b&gt;postgre sql&lt;/b&gt;로 선택했습니다.&lt;br /&gt;또한 깃허브는 organization을 사용해서 협업하였고 각자 담당한 레포지토리를 구성했어요~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;위에 스택을 보시면 뭔가 특이하지않나요?&lt;br /&gt;저는 프론트앤드 백엔드 두개를 나누어 작업하였는데, 팀원인 개발자분은 프론트앤드 백엔드를 JAVA랑 JPA프레임웤을 사용하셨죠? 저희는 MSA가 주제인 프로젝트라 서로 다른 언어로 개발을 했어도 한 서비스를 같이 개발할 수 있었어요.&lt;br /&gt;렌더링방식도 &lt;b&gt;CSR과 SSR방식으로 달랐는데 &lt;/b&gt;한 서비스내에서 동작을하게됐습니다. next js가 필요가 없겠네요 ㅎㅎ&lt;br /&gt;또한 레포지토리또한 전혀 겹치는게 없었어요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;처음 하는 프로젝트인데 한 레포지토리를 함께 만지는 협업을 못해서 많이 아쉽긴 헀습니다.&lt;br /&gt;하지만 서로 다른 언어를 가지고 한 서비스를 같이 개발할 수 있다는게 바로 &lt;b&gt;MSA의 장점&lt;/b&gt;중 하나랍니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;개발 협업경험이 없게되어 아쉬웠거든요&lt;br /&gt;그래서 따로 깃허브 협업하기 혼자놀기 포스팅을 따로 작성을 했습니다ㅋㅋㅋ 참고하세요~&lt;br /&gt;&lt;a href=&quot;https://jacobowl.tistory.com/349&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://jacobowl.tistory.com/349&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://jacobowl.tistory.com/350&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://jacobowl.tistory.com/350&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;프론트앤드 파일 전송 구조&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbDvKZ/btsL1dMRT1f/4sAGmnsludAxAEHJ0DQQqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbDvKZ/btsL1dMRT1f/4sAGmnsludAxAEHJ0DQQqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbDvKZ/btsL1dMRT1f/4sAGmnsludAxAEHJ0DQQqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbDvKZ%2FbtsL1dMRT1f%2F4sAGmnsludAxAEHJ0DQQqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1057&quot; height=&quot;665&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;저희 팀 서비스 도메인은 daddygo.vacations입니다.&amp;nbsp;&lt;br /&gt;루트 경로(www.daddygo.vacations)로 들어가면 nurd worker가 vue js로 코딩한&lt;b&gt; SPA방식 프론트데이터를 &lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;S3버킷에서&lt;/b&gt;&lt;/span&gt;&lt;b&gt; 응답&lt;/b&gt;받게됩니다. 그림에서 보이시죠?&lt;br /&gt;그리고 또 다른 팀원분은 board 게시판기능을 위주로 개발하셨는데요. &lt;b&gt;팀원분이 개발하신 프론트는 SSR방식으로 동작하는데요~ 클라이언트는 이 프론트 데이터를&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; EKS pod&lt;/b&gt;&lt;/span&gt;&lt;b&gt;에서 직접 받게&lt;/b&gt;됩니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이런구조로 희안하게&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 두 렌더링 방식을 모두 활용&lt;/b&gt;&lt;/span&gt;&lt;b&gt;하는 서비스를 완성&lt;/b&gt;할 수 있었습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SwRHu/btsL0m4MFoI/rba6oKQlU3gG0rSQqZfqk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SwRHu/btsL0m4MFoI/rba6oKQlU3gG0rSQqZfqk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SwRHu/btsL0m4MFoI/rba6oKQlU3gG0rSQqZfqk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSwRHu%2FbtsL0m4MFoI%2Frba6oKQlU3gG0rSQqZfqk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;707&quot; height=&quot;642&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위설명을 조금더 정리한 그림이에요 ㅎㅎ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;Nurd Worker는 어떤걸 개발하였나요? #1 - member&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m5Tim/btsL0MWa6sn/mFALfPyi7rpkX6NxByp1Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m5Tim/btsL0MWa6sn/mFALfPyi7rpkX6NxByp1Sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m5Tim/btsL0MWa6sn/mFALfPyi7rpkX6NxByp1Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm5Tim%2FbtsL0MWa6sn%2FmFALfPyi7rpkX6NxByp1Sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;652&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는&lt;b&gt; 회원가입&lt;/b&gt;과 &lt;b&gt;유저 로그인앤아웃&lt;/b&gt;을 개발하였습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BhpCz/btsL0Ol8ZnP/BwE4nNsbQFEo4iqKhWn0X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BhpCz/btsL0Ol8ZnP/BwE4nNsbQFEo4iqKhWn0X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BhpCz/btsL0Ol8ZnP/BwE4nNsbQFEo4iqKhWn0X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBhpCz%2FbtsL0Ol8ZnP%2FBwE4nNsbQFEo4iqKhWn0X0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;687&quot; height=&quot;673&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKFnkF/btsL1rqDP2F/NidstPVeMlQHLW5iiDouU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKFnkF/btsL1rqDP2F/NidstPVeMlQHLW5iiDouU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKFnkF/btsL1rqDP2F/NidstPVeMlQHLW5iiDouU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKFnkF%2FbtsL1rqDP2F%2FNidstPVeMlQHLW5iiDouU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;591&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JWT로그인방식&lt;/b&gt;과 &lt;b&gt;AWS cognito&lt;/b&gt;를 사용하여 개발하였습니다~&lt;br /&gt;cognito는 JWT방식으로 로그인을 구현해주는 AWS서비스중 하나인데요. 많이들 생소하신 서비스일겁니다 ㅎㅎ&lt;br /&gt;그리고 전 유저 편의성을 최우선으로 생각하므로&lt;b&gt; google oauth&lt;/b&gt;를 연동하여 로그인을 구현했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yiIAr/btsL01yH2va/MpVOPkuF190DxqpiWKx21k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yiIAr/btsL01yH2va/MpVOPkuF190DxqpiWKx21k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yiIAr/btsL01yH2va/MpVOPkuF190DxqpiWKx21k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyiIAr%2FbtsL01yH2va%2FMpVOPkuF190DxqpiWKx21k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;507&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 cognito만으로는 그렇게 좋다할 장점은 없는것 같지만 다른 AWS서비스와 연동이 된다는 점이 좋더라구요. &lt;br /&gt;저희는 백엔드 통신을 &lt;b&gt;api gateway&lt;/b&gt;를 사용하였는데요. &lt;b&gt;cognito랑 이 api gateway와 연동&lt;/b&gt;했습니다!!&lt;br /&gt;이러면 was단, 즉 &lt;b&gt;백엔드에서 아예&lt;/b&gt; &lt;b&gt;토큰 검증하는 로직 자체를 만들필요가 없어요&lt;/b&gt;!! ㅋㅋ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그냥 api gateway에서 헤더값을 검사후에 인증이 필요한 api요청에대해서는 코그니토로 먼저 토큰 검사를 한후, 토큰이 정상이면 제기능을 수행하구, 토큰이 이상하면 api gateway단에서 걍 끊어버립니다 ㅋㅋ&lt;br /&gt;엄청 간단하죠? (사실 코그니토 처음 만드는게 더 어렵긴..했음 ㅋㅋㅋ)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;참고로 코그니토로 간편 로그인을 구현하니 refresh token은 안되는것 같더라구요. 구현하려면 따로 백단에 SDK로 코그니토 서버와 통신하여야 합니다. 때문에 access token만 설정했습니다.&lt;br /&gt;하지만 토큰 만료시간을 설정할수있어서 10시간유효하게 만들었어요 ㅋㅋㅋ&lt;br /&gt;remember me 프로젝트는 google oauth로 로그인을 구현하였는데, google oauth만으로는 access token 유효시간을 길게 늘릴수가 없더라구요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;국비과정에서 저희팀만 유일하게 &lt;b&gt;google oauth와 cognito를 연동&lt;/b&gt;하여 로그인을 구현했습니다(나름 뿌듯 ㅋㅋ)&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;jwt / introduction &amp;amp; access token&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;IntroductionJWT를 아주 예전에 접한적이 있다. 지금도 코찔이지만 그때 난 코찔찔찔이였기때문에 이해가 어려웠는데.. 훈련소에서 cognito와 google oauth로 직접 로그인을 구현해보면서 자세히 알게됐&quot; data-og-host=&quot;blog.nurd.work&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/331&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Xeziq/hyX7ZtVwvy/85Id1hawnFhpykmCcLStK0/img.png?width=800&amp;amp;height=451&amp;amp;face=0_0_800_451,https://scrap.kakaocdn.net/dn/m2JnZ/hyX4qfFujP/3LkZMtAyfClinu7Su2xmg0/img.png?width=800&amp;amp;height=451&amp;amp;face=0_0_800_451,https://scrap.kakaocdn.net/dn/RKFvy/hyX7TUM5nq/cVj9jqZb65wQRRIkzV8Mm1/img.png?width=916&amp;amp;height=522&amp;amp;face=0_0_916_522&quot; data-og-url=&quot;https://blog.nurd.work/331&quot;&gt;&lt;a href=&quot;https://blog.nurd.work/331&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/331&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Xeziq/hyX7ZtVwvy/85Id1hawnFhpykmCcLStK0/img.png?width=800&amp;amp;height=451&amp;amp;face=0_0_800_451,https://scrap.kakaocdn.net/dn/m2JnZ/hyX4qfFujP/3LkZMtAyfClinu7Su2xmg0/img.png?width=800&amp;amp;height=451&amp;amp;face=0_0_800_451,https://scrap.kakaocdn.net/dn/RKFvy/hyX7TUM5nq/cVj9jqZb65wQRRIkzV8Mm1/img.png?width=916&amp;amp;height=522&amp;amp;face=0_0_916_522');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;jwt / introduction &amp;amp; access token&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;IntroductionJWT를 아주 예전에 접한적이 있다. 지금도 코찔이지만 그때 난 코찔찔찔이였기때문에 이해가 어려웠는데.. 훈련소에서 cognito와 google oauth로 직접 로그인을 구현해보면서 자세히 알게됐&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;jwt / refresh token&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;Introductionjson web token 보안방법에서 refresh token에 대해서 차근차근 포스팅하겠다. 처음부터 와라라락 써버리면 읽는 사람들은 머리가 터질것이기 때문.공부 목적이길래 코드가 매우 더러울것이다&quot; data-og-host=&quot;blog.nurd.work&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/343&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cFhptw/hyX71edrWq/bvuLKMnt7St6b8YwI9wp3k/img.png?width=545&amp;amp;height=67&amp;amp;face=0_0_545_67,https://scrap.kakaocdn.net/dn/dwCtsl/hyX4mj2Ju5/udGbLKqQsNHgQLCl3saFTk/img.png?width=545&amp;amp;height=67&amp;amp;face=0_0_545_67,https://scrap.kakaocdn.net/dn/cW6ePl/hyX4k7BcDL/uOj1Dn61CprM3TjlYdnOKK/img.png?width=952&amp;amp;height=574&amp;amp;face=0_0_952_574&quot; data-og-url=&quot;https://blog.nurd.work/343&quot;&gt;&lt;a href=&quot;https://blog.nurd.work/343&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/343&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cFhptw/hyX71edrWq/bvuLKMnt7St6b8YwI9wp3k/img.png?width=545&amp;amp;height=67&amp;amp;face=0_0_545_67,https://scrap.kakaocdn.net/dn/dwCtsl/hyX4mj2Ju5/udGbLKqQsNHgQLCl3saFTk/img.png?width=545&amp;amp;height=67&amp;amp;face=0_0_545_67,https://scrap.kakaocdn.net/dn/cW6ePl/hyX4k7BcDL/uOj1Dn61CprM3TjlYdnOKK/img.png?width=952&amp;amp;height=574&amp;amp;face=0_0_952_574');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;jwt / refresh token&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Introductionjson web token 보안방법에서 refresh token에 대해서 차근차근 포스팅하겠다. 처음부터 와라라락 써버리면 읽는 사람들은 머리가 터질것이기 때문.공부 목적이길래 코드가 매우 더러울것이다&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;jwt / interceptor, module, middleware를 활용한 jwt플로우&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;Introduction이전 jwt포스팅 시리즈중 access토큰까지는 그래도 코드를 봐줄만했으나 refresh토큰이 추가된 순간 아주 코드가 더럽고 불결해졌다. 이걸 깔끔하게 하기위해서 jwt토큰로직을 interceptor, modu&quot; data-og-host=&quot;blog.nurd.work&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/344&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cy7Vva/hyX73XpsxN/S1wScDv2s52TrCUvrQaNfK/img.png?width=326&amp;amp;height=55&amp;amp;face=0_0_326_55,https://scrap.kakaocdn.net/dn/cgYsde/hyX4p18nqa/37ArVWIHO3YTovfdklkpi1/img.png?width=326&amp;amp;height=55&amp;amp;face=0_0_326_55,https://scrap.kakaocdn.net/dn/vfaC9/hyX71SOZxP/7SV4nJFHes6MNRmLxbyrWK/img.png?width=937&amp;amp;height=514&amp;amp;face=0_0_937_514&quot; data-og-url=&quot;https://blog.nurd.work/344&quot;&gt;&lt;a href=&quot;https://blog.nurd.work/344&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/344&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cy7Vva/hyX73XpsxN/S1wScDv2s52TrCUvrQaNfK/img.png?width=326&amp;amp;height=55&amp;amp;face=0_0_326_55,https://scrap.kakaocdn.net/dn/cgYsde/hyX4p18nqa/37ArVWIHO3YTovfdklkpi1/img.png?width=326&amp;amp;height=55&amp;amp;face=0_0_326_55,https://scrap.kakaocdn.net/dn/vfaC9/hyX71SOZxP/7SV4nJFHes6MNRmLxbyrWK/img.png?width=937&amp;amp;height=514&amp;amp;face=0_0_937_514');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;jwt / interceptor, module, middleware를 활용한 jwt플로우&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Introduction이전 jwt포스팅 시리즈중 access토큰까지는 그래도 코드를 봐줄만했으나 refresh토큰이 추가된 순간 아주 코드가 더럽고 불결해졌다. 이걸 깔끔하게 하기위해서 jwt토큰로직을 interceptor, modu&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jwt에 대한 포스팅은 이 포스팅들을 보시면 됩니다~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Nurd Worker는 어떤걸 개발하였나요? #2 - LeaderBoard&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VBjh1/btsL1BM6NmE/Kta7boYKKraDZzWx9EQMQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VBjh1/btsL1BM6NmE/Kta7boYKKraDZzWx9EQMQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VBjh1/btsL1BM6NmE/Kta7boYKKraDZzWx9EQMQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVBjh1%2FbtsL1BM6NmE%2FKta7boYKKraDZzWx9EQMQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1052&quot; height=&quot;609&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;리더보드입니다.&lt;br /&gt;저희 어플리케이션에 들어오시면 처음 마주치시는 화면이에요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;게시글들의 필터링 조건마다(좋아요수, 식당랭킹, 지역랭킹 등) 순서대로 보여주는 화면입니다.&lt;br /&gt;nurd worker는 어플리케이션의 첫 화면이라 &lt;b&gt;이미지작업과 디자인에 치중&lt;/b&gt;했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;딱히 기술적으론 설명드릴게 없네요..ㅋㅋ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;Nurd Worker는 어떤걸 개발하였나요? #3 - Search&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/naoGi/btsL2bN39P2/4C7Mmm1uSzPKOsSYeF3Q21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/naoGi/btsL2bN39P2/4C7Mmm1uSzPKOsSYeF3Q21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/naoGi/btsL2bN39P2/4C7Mmm1uSzPKOsSYeF3Q21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnaoGi%2FbtsL2bN39P2%2F4C7Mmm1uSzPKOsSYeF3Q21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;707&quot; height=&quot;668&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저렇게 원하는 게시글의 필터링을 정해서 게시글 데이터를 가져오는 기능입니다~&lt;br /&gt;이 기능을 구현하기위해 저는 &lt;b&gt;db쿼리문을 조건적으로 바꾸는 코딩&lt;/b&gt;을 했습니다.&lt;br /&gt;예시코드를 보여드리자면~&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const selectArea = (area) =&amp;gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!Array.isArray(selected.area)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selected.area = [];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!selected.area.includes(area)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (selected.area.includes(&quot;all&quot;) &amp;amp;&amp;amp; area !== &quot;all&quot;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// &quot;all&quot;이 이미 있는 경우 다른 값을 추가하지 않음
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selected.area = [area];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else if (area == &quot;all&quot;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selected.area = [&quot;all&quot;];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// &quot;all&quot;이 없는 경우 새로운 지역을 추가
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selected.area.push(area);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 짧게 보여드리자면, 지역부분 선택을 이렇게 선택한 filter를 정해서 백단에 보냈습니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const areaString = (selected) =&amp;gt; {
&amp;nbsp;&amp;nbsp;if (selected.area[0] == &quot;all&quot;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;&quot;;
&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ` AND area IN ${createAreaTuple(selected.area)}`;
&amp;nbsp;&amp;nbsp;}
};

const travelTypeString = (selected) =&amp;gt; {
&amp;nbsp;&amp;nbsp;if (selected.travelType == &quot;all&quot;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;&quot;;
&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ` AND travel_type = '${selected.travelType}'`;
&amp;nbsp;&amp;nbsp;}
};

const destiTypeString = (selected) =&amp;gt; {
&amp;nbsp;&amp;nbsp;if (selected.destiType == &quot;all&quot;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;&quot;;
&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return ` AND desti_type = '${selected.destiType}'`;
&amp;nbsp;&amp;nbsp;}
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백단코드 전부는 너무 길어서 짧게만 보여드리자면, 저는 db에 데이터를 요청할때 쿼리문을 쓰거든요.&lt;br /&gt;저렇게 쿼리문 스트링을 조건부로 return하는 함수들을 만들어서 스트링을 템플릿 리터럴로 쿼리문을 만들어서 db요청을 보냈어요&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;dga-search/server.js at main &amp;middot; DGA-PROJECT/dga-search&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;아빠, 또 갈까 ? - 검색 CI/CD (Github Action). Contribute to DGA-PROJECT/dga-search development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/DGA-PROJECT/dga-search/blob/main/server.js&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bx9GpS/hyX4xZ92Zs/Pp5EX5VmcXm4rFb3gTd4y0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ehWnEK/hyX7Tgb1HS/tIhQjslZb86CpDX6WTDtW1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot; data-og-url=&quot;https://github.com/DGA-PROJECT/dga-search/blob/main/server.js&quot;&gt;&lt;a href=&quot;https://github.com/DGA-PROJECT/dga-search/blob/main/server.js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/DGA-PROJECT/dga-search/blob/main/server.js&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bx9GpS/hyX4xZ92Zs/Pp5EX5VmcXm4rFb3gTd4y0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ehWnEK/hyX7Tgb1HS/tIhQjslZb86CpDX6WTDtW1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;dga-search/server.js at main &amp;middot; DGA-PROJECT/dga-search&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아빠, 또 갈까 ? - 검색 CI/CD (Github Action). Contribute to DGA-PROJECT/dga-search development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;search의 백단 코드입니다ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sql인젝션 공격에 위험할수도 있는 방법이긴 합니다 ㅠㅠ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;++협업을 위한 test버튼들&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl8KND/btsL0MWbzfN/B0NiyWgIb0qnvajytzlhSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl8KND/btsL0MWbzfN/B0NiyWgIb0qnvajytzlhSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl8KND/btsL0MWbzfN/B0NiyWgIb0qnvajytzlhSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl8KND%2FbtsL0MWbzfN%2FB0NiyWgIb0qnvajytzlhSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;600&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;인프라팀과의 협업이기때문에 저렇게&lt;b&gt; 테스트 버튼&lt;/b&gt;을 만들어드렸어요.&lt;br /&gt;(오래전 프로젝트라 이미지가 사라져서 remember me test zone 버튼 사진으로 대체합니다~)&lt;br /&gt;저희는 아직 현업자가 아니고 모두 배우는 사람들이었기에 개발팀이나 인프라팀이나 시행착오가 많았습니다&lt;br /&gt;때문에 개발단에서 저렇게 api통신을 체크하거나 db통신을 체크하는 버튼들을 만들어드리면&lt;br /&gt;인프라팀원분들이 배포하면서 제대로 연결이되었는지, 환경변수가 제대로 읽혀졌는지 등을 테스트 하실 수 있었고 실제로 활용하셨습니다~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;개발단 마이그레이션&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;GitHub - nurdworker/dev-migration-mysql&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;Contribute to nurdworker/dev-migration-mysql development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/dev-migration-mysql/tree/main&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mdEGO/hyX7QRiAnJ/Onk6wy9J0mMwWaxe0XIEHk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cIGe5n/hyX4tjadBT/jTnEB4VXnYoPkpQppuIvK0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot; data-og-url=&quot;https://github.com/nurdworker/dev-migration-mysql&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/dev-migration-mysql&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/dev-migration-mysql/tree/main&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mdEGO/hyX7QRiAnJ/Onk6wy9J0mMwWaxe0XIEHk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cIGe5n/hyX4tjadBT/jTnEB4VXnYoPkpQppuIvK0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mdEGO/hyX7QRiAnJ/Onk6wy9J0mMwWaxe0XIEHk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cIGe5n/hyX4tjadBT/jTnEB4VXnYoPkpQppuIvK0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nurdworker/dev-migration-mysql&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/dev-migration-mysql development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;github 코드를 보시면, bf_db와 af_db로 각각 데이터베이스 연결하는 환경변수만 설정해두면 테이블과 컬럼등을 자동으로 체크하여 sql데이터베이스가&lt;b&gt; 마이그레이션&lt;/b&gt;이 됩니다. 물론 서로 같은 종류의 db라는 설정이구(로컬 mysql과 aws RDS mysql처럼요.) 부하체크해서 컨트롤하는 기능없이 setInterval로 분산을 처리한 단순한 코드이지만 동작은 잘 합니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;저 역시도 당시에 데이터베이스를 따로 사용하고 있었는데 비용이 많이나와서 &lt;b&gt;해당 코드를 활용하여 약 10000row 정도 되는 데이터를 옮겼습니다.&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;저희팀은 결성이 된게, 제가 같이 프로젝트를 진행하고 싶은 팀장님을 찾아가서 두 명이서 먼저 결성이 된 팀이었습니다 ㅎㅎ&lt;br /&gt;당시에 팀장님은 마이그레이션을 주제로 하고싶다고 하셨는데요, 결국 팀이 결성되고 MSA가 주제가 되어 마이그레이션을 조금밖에 다루지 못했답니다.&lt;br /&gt;때문에 프로젝트 막바지에 제가 개발단 마이그레이션을 따로 혼자 준비해서 전해드렸어요.(발표에는 추가 안하셨지만 ㅠㅠ)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;발표 목차&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;785&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v0Vqx/btsL1CZzDj9/iEkZApQME12gT2LCjut911/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v0Vqx/btsL1CZzDj9/iEkZApQME12gT2LCjut911/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v0Vqx/btsL1CZzDj9/iEkZApQME12gT2LCjut911/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv0Vqx%2FbtsL1CZzDj9%2FiEkZApQME12gT2LCjut911%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1397&quot; height=&quot;785&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;785&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희팀 발표 목차인데요~ 저는 인천&lt;b&gt; dev with MSA&lt;/b&gt;, 강릉 &lt;b&gt;dev with Cloud&lt;/b&gt;쪽 발표내용을 맡았었네요 ㅎㅎ&lt;br /&gt;(이미지도 직접그렸어요 ㅋㅋㅋ)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;task 방식 협업&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chhKN0/btsL1XoX4G4/aOGrNhBBzH8xvBSBFLtFO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chhKN0/btsL1XoX4G4/aOGrNhBBzH8xvBSBFLtFO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chhKN0/btsL1XoX4G4/aOGrNhBBzH8xvBSBFLtFO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchhKN0%2FbtsL1XoX4G4%2FaOGrNhBBzH8xvBSBFLtFO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;820&quot; height=&quot;688&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;팀장님이 노션을 만드시고 저렇게&lt;b&gt; task&lt;/b&gt;를 만들어서 계속 업로드하라고하셨는데요&lt;br /&gt;너무 좋은 방법인것같아서 remember me 프로젝트에서 제가 팀장으로 진행할때도 이 task방식으로 팀원분들과 협업하였습니다 ㅎㅎ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;인프라 아키텍쳐&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bynEsl/btsL1DRQYdB/YHFLuHYDB7eDN520hC6rrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bynEsl/btsL1DRQYdB/YHFLuHYDB7eDN520hC6rrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bynEsl/btsL1DRQYdB/YHFLuHYDB7eDN520hC6rrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbynEsl%2FbtsL1DRQYdB%2FYHFLuHYDB7eDN520hC6rrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1262&quot; height=&quot;558&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 인프라 팀원분들이 만드신 최종 아키텍쳐인데요~ 멋지죠?&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;솔직히 제가 한 개발내용은 많이 복잡한게 없고 딱히 돋보이는 기능들이 없네요..ㅋㅋ 지금와서 구현동영상을 편집하다보니 잔실수들도 좀 보입니다 ㅋㅋㅋ&lt;br /&gt;&lt;br /&gt;지금와서 회고해보면..&lt;br /&gt;&lt;br /&gt;저희팀이 처음 기획단계때 보여지는게 중요하다고 의견이 많이 나와서 제가 일러스트레이터를 다루니 &lt;b&gt;디자인쪽에 신경을 많이 써달라 오퍼&lt;/b&gt;를 받았거든요.&lt;br /&gt;하루종일 프로젝트 작업을 했지만 거의&lt;b&gt; 50퍼센트 이상이 그림 작업인 일러스트레이터 디자인작업&lt;/b&gt;이었습니다 ㅠㅠ&lt;br /&gt;어플리케이션에서 사용하는 이미지들, 영상작업, ppt에 필요한 이미지제작등, 이런 작업들을 제가 했어요.&lt;br /&gt;(nurd worker는 디자이너분들을 이해할수 있는 개발자입니다 ㅋㅋㅋ)&lt;br /&gt;&lt;br /&gt;당시 제 생각은 이랬습니다.&lt;br /&gt;&lt;br /&gt;솔직히 제 개인적인 입장으로 봤을때는 그다지 득이 되는 방향은 아니었죠. 저는 개발자가 되고싶은거지 디자이너 지망생이 아니니까요.&lt;br /&gt;더 나아가선 아무리 개발자라도 aws 300만크레딧이 프로젝트 기간동안만 한정적으로 주어지는데 EKS같은 비싼 리소스들을 다루는 인프라팀에 들어가서 프로젝트를 하고싶은 생각도 있었답니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하지만 팀이라는게 모두가 이득을 취하는 방향으로만 가려고한다면 그 팀은 제대로 진행될 수 없을거라고 생각을 합니다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;실제로 다른팀은 개발쪽 담당을 정하느라 분쟁이 있기도 했었구요 ㄷㄷ&lt;br /&gt;&lt;br /&gt;때문에 내색없이 팀원으로써 최선을 다했고 완성도가 높게 결말지어진 프로젝트였다고 생각합니다.&lt;br /&gt;긴 글 읽어주셔서 감사합니다~!&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이미지 소스 출처&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;GREEN&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://kr.freepik.com/free-vector/hand-drawn-spring-landscape_12239753.htm#query=forest&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=9308e5cf-0e60-4775-8bf4-ec5a22d49e32&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Hand&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/hand-drawn-spring-landscape_12239753.htm#query=forest&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=9308e5cf-0e60-4775-8bf4-ec5a22d49e32&quot; target=&quot;_self&quot;&gt;&lt;span&gt;-drawn&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/hand-drawn-spring-landscape_12239753.htm#query=forest&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=9308e5cf-0e60-4775-8bf4-ec5a22d49e32&quot; target=&quot;_self&quot;&gt;&lt;span&gt; spring&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/hand-drawn-spring-landscape_12239753.htm#query=forest&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=9308e5cf-0e60-4775-8bf4-ec5a22d49e32&quot; target=&quot;_self&quot;&gt;&lt;span&gt; landscape&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ZOO&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Zoo&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt; or&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt; petting&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt; zoo&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt; cartoon&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/zoo-or-petting-zoo-cartoon-design-open-zoo-wild-animals-and-visitors_2238486.htm#query=zoo&amp;amp;position=5&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67b7dfe4-5d76-4a9b-a9a1-3624a02999a5&quot; target=&quot;_self&quot;&gt;&lt;span&gt; design&lt;/span&gt;&lt;/a&gt; (작가: Vectorpouch, Freepik)&lt;/li&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://kr.freepik.com/free-vector/flat-world-animal-day-background_30591432.htm#query=animals&amp;amp;position=22&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=ce4e6f9a-4759-4753-b823-220d6af4bca6&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Flat&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/flat-world-animal-day-background_30591432.htm#query=animals&amp;amp;position=22&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=ce4e6f9a-4759-4753-b823-220d6af4bca6&quot; target=&quot;_self&quot;&gt;&lt;span&gt; world&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/flat-world-animal-day-background_30591432.htm#query=animals&amp;amp;position=22&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=ce4e6f9a-4759-4753-b823-220d6af4bca6&quot; target=&quot;_self&quot;&gt;&lt;span&gt; animal&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/flat-world-animal-day-background_30591432.htm#query=animals&amp;amp;position=22&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=ce4e6f9a-4759-4753-b823-220d6af4bca6&quot; target=&quot;_self&quot;&gt;&lt;span&gt; day&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/flat-world-animal-day-background_30591432.htm#query=animals&amp;amp;position=22&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=ce4e6f9a-4759-4753-b823-220d6af4bca6&quot; target=&quot;_self&quot;&gt;&lt;span&gt; background&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;BLUE&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Beach&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; from&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; the&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; top&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; in&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; paper&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://kr.freepik.com/free-vector/beach-from-the-top-in-paper-style_2499260.htm#query=beach&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=67d445a0-92e7-4b84-b658-ba994e7b182c&quot; target=&quot;_self&quot;&gt;&lt;span&gt; style&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;애 얼굴&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://www.freepik.com/free-vector/flat-emoticons-cute-girl_1011883.htm#page=2&amp;amp;query=kide%20emotion&amp;amp;position=35&amp;amp;from_view=search&amp;amp;track=ais&amp;amp;uuid=b582ada2-0930-4c99-92a5-ac2bfb97e327&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Flat&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-emoticons-cute-girl_1011883.htm#page=2&amp;amp;query=kide%20emotion&amp;amp;position=35&amp;amp;from_view=search&amp;amp;track=ais&amp;amp;uuid=b582ada2-0930-4c99-92a5-ac2bfb97e327&quot; target=&quot;_self&quot;&gt;&lt;span&gt; emoticons&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-emoticons-cute-girl_1011883.htm#page=2&amp;amp;query=kide%20emotion&amp;amp;position=35&amp;amp;from_view=search&amp;amp;track=ais&amp;amp;uuid=b582ada2-0930-4c99-92a5-ac2bfb97e327&quot; target=&quot;_self&quot;&gt;&lt;span&gt; cute&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-emoticons-cute-girl_1011883.htm#page=2&amp;amp;query=kide%20emotion&amp;amp;position=35&amp;amp;from_view=search&amp;amp;track=ais&amp;amp;uuid=b582ada2-0930-4c99-92a5-ac2bfb97e327&quot; target=&quot;_self&quot;&gt;&lt;span&gt; girl&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;할아버지&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Flat&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt; Dia&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt; de&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt; los&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt; Abuelos&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/flat-dia-de-los-abuelos-illustration_13914243.htm#page=8&amp;amp;query=grandfather&amp;amp;position=46&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=4ced87a1-5484-4450-b1be-27a355954024&quot; target=&quot;_self&quot;&gt;&lt;span&gt; illustration&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;아빠 + 아이들&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Happy&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt; flat&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt; design&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt; father's&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt; day&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/happy-flat-design-father-s-day-family_7709910.htm#query=father&amp;amp;position=0&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=7a11906a-a809-4aa4-8fd2-623d8126532b&quot; target=&quot;_self&quot;&gt;&lt;span&gt; family&lt;/span&gt;&lt;/a&gt; (Freepik)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;엄마&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출처: &lt;a href=&quot;https://www.freepik.com/free-vector/motherhood-concept-illustration_7119281.htm#page=6&amp;amp;query=mother&amp;amp;position=21&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=d72b2bea-fce8-4f6f-9523-b2079475a2ab&quot; target=&quot;_self&quot;&gt;&lt;span&gt;Motherhood&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/motherhood-concept-illustration_7119281.htm#page=6&amp;amp;query=mother&amp;amp;position=21&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=d72b2bea-fce8-4f6f-9523-b2079475a2ab&quot; target=&quot;_self&quot;&gt;&lt;span&gt; concept&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.freepik.com/free-vector/motherhood-concept-illustration_7119281.htm#page=6&amp;amp;query=mother&amp;amp;position=21&amp;amp;from_view=search&amp;amp;track=sph&amp;amp;uuid=d72b2bea-fce8-4f6f-9523-b2079475a2ab&quot; target=&quot;_self&quot;&gt;&lt;span&gt; illustration&lt;/span&gt;&lt;/a&gt; (Image by Storyset, Freepik)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>project/teamProject</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/355</guid>
      <comments>https://jacobowl.tistory.com/355#entry355comment</comments>
      <pubDate>Fri, 24 Jan 2025 10:56:18 +0900</pubDate>
    </item>
    <item>
      <title>Personal Project - MuzziCluster</title>
      <link>https://jacobowl.tistory.com/354</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;안녕하세요? Nurd Worker입니다! 반갑습니다. &lt;br /&gt;이번에 소개해드릴 프로젝트는&lt;b&gt; Muzzi Cluster&amp;nbsp;프로젝트&lt;/b&gt;&amp;nbsp;입니다!&lt;br /&gt;&lt;br /&gt;무찌 클러스터 프로젝트는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 온프레미스 클러스터&lt;/b&gt;&lt;/span&gt;를 직접 구현한 프로젝트입니다.&lt;br /&gt;당연히&lt;b&gt; 네트워크와 쿠버네티스, 인프라&lt;/b&gt;가 주제입니다ㅎㅎㅎ&lt;br /&gt;&lt;br /&gt;예전에 사용했던 &lt;b&gt;오래된 노트북으로 직접 클러스터&lt;/b&gt;를 만들었습니다~(c타입 포트도 없는 오래된 ㅎㅎㅎ)&lt;br /&gt;부모님 드린다고 했는데 안가지신다고하셔서 묵혀뒀다가 이번 기회에 활용해봤네요~&lt;br /&gt;나름 관리는 열심히했어서 부품도 업그레이드해서 서버용으로는 문제없이 돌아갑니다ㅋㅋ&lt;br /&gt;&lt;br /&gt;현재 세 가지 어플리케이션이 배포되어있는데요~&lt;br /&gt;&lt;b&gt;포트폴리오와 acsap, rememberme프로젝트&lt;/b&gt;가 &lt;b&gt;모두 무찌클러스터에서 배포한거랍니다~&lt;/b&gt;&lt;br /&gt;참고로 무찌클러스터는 영상이나 깃허브 자료가없어요~ 직접 배포한 어플리케이션에 접속하시면 돌아가는게 확인가능하시니까요.&lt;br /&gt;&lt;br /&gt;그럼 재밋게 읽어주세요~&lt;/blockquote&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;왜 무찌클러스터인가요?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bejLuw/btsLXsYgtRm/QKigV1avlyLyyXcqEb9GPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bejLuw/btsLXsYgtRm/QKigV1avlyLyyXcqEb9GPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bejLuw/btsLXsYgtRm/QKigV1avlyLyyXcqEb9GPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbejLuw%2FbtsLXsYgtRm%2FQKigV1avlyLyyXcqEb9GPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1039&quot; height=&quot;623&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;제 동생이 하나 있는데요. 무찌라는 강아지입니다.&amp;nbsp;&lt;br /&gt;저는 쿠버네티스를 공부할때마다 클러스터는 구름?같은 이미지로 생각을 하게되요.&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;'k8s' 카테고리의 글 목록&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;지극히 이기적인 개발 블로그입니다.&quot; data-og-host=&quot;jacobowl.tistory.com&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/category/k8s&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpmSa7/hyX4lZAjqx/KBnYQTRHkyMUEErqkABbHk/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/cTOpHB/hyX4vOFaV5/Px1J234vw6EEaqNRsJf2k1/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/GVsiN/hyX7TUFCoY/96r3AAKPDwdSjGS4Ok6E0K/img.png?width=387&amp;amp;height=686&amp;amp;face=0_0_387_686&quot; data-og-url=&quot;https://jacobowl.tistory.com/category/k8s&quot;&gt;&lt;a href=&quot;https://jacobowl.tistory.com/category/k8s&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/category/k8s&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpmSa7/hyX4lZAjqx/KBnYQTRHkyMUEErqkABbHk/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/cTOpHB/hyX4vOFaV5/Px1J234vw6EEaqNRsJf2k1/img.jpg?width=593&amp;amp;height=593&amp;amp;face=0_0_593_593,https://scrap.kakaocdn.net/dn/GVsiN/hyX7TUFCoY/96r3AAKPDwdSjGS4Ok6E0K/img.png?width=387&amp;amp;height=686&amp;amp;face=0_0_387_686');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'k8s' 카테고리의 글 목록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지극히 이기적인 개발 블로그입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jacobowl.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 이 블로그의 쿠버네티스 관련 포스팅들을 보면 구름이 가끔 그려져 있답니다 ㅎㅎ&lt;br /&gt;근데 구름? 하면 무찌 얼굴을 닮았죠? 그래서 &lt;b&gt;무찌클러스터 프로젝트&lt;/b&gt;라고 이름짓게 되었습니다~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;기술스택&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baRwv8/btsLYEKkH3i/KgHUpi7dkg3sSVRx168ok0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baRwv8/btsLYEKkH3i/KgHUpi7dkg3sSVRx168ok0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baRwv8/btsLYEKkH3i/KgHUpi7dkg3sSVRx168ok0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaRwv8%2FbtsLYEKkH3i%2FKgHUpi7dkg3sSVRx168ok0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1247&quot; height=&quot;690&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;무찌클러스터는 당연히 &lt;b&gt;쿠버네티스&lt;/b&gt;로 구축했습니다~ 그리고 많은 어플리케이션 리소스를 쿠버네티스 전용&lt;b&gt; iac 도구&lt;/b&gt;인 &lt;b&gt;헬름&lt;/b&gt;으로 배포했어요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;모니터링&lt;/b&gt;을 하기위해서 &lt;b&gt;grafana, prometheus&lt;/b&gt;를 구축했고, 로그 모니터링을 위해 &lt;b&gt;loki&lt;/b&gt;도 겸했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;이미지 스토리지&lt;/b&gt;도 따로 구축하였습니다. &lt;b&gt;harbor&lt;/b&gt;를 사용했구요&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;데이터베이스&lt;/b&gt;는 몽고디비와 sql(비밀)디비를 설치해놨습니다. rememberme 프로젝트의 데이터베이스가 현재 무찌클러스터에서 데이터를 보관하구있어요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;또한 슬랙알람을 활용하여 클러스터의 알람을 연결했답니다 ^^&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;쿠버네티스 설치&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;VMware ubuntu 환경에서 k8s환경 구축하기.(2024 11월 기준 가능)&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;# 바뀌어서 설치가 안되는부분만 최상단에 적음!! 시간이없어서 정리는 못하나, 바뀐부분만 적용하면 k8s클러스터 설치가능합니다.&amp;nbsp;2024년 9월 포스팅인데 현재 2024/11월 기준 9월에 포스팅한 방법&quot; data-og-host=&quot;blog.nurd.work&quot; data-og-source-url=&quot;https://jacobowl.tistory.com/314&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Un5Bg/hyX4uWyc0E/ZZQ5hgZpAbjIxOcOlSbxj1/img.png?width=240&amp;amp;height=163&amp;amp;face=0_0_240_163,https://scrap.kakaocdn.net/dn/bOvQr5/hyX7YPdeO0/P6hMKAJxnbEiw5IcWEhYH0/img.png?width=240&amp;amp;height=163&amp;amp;face=0_0_240_163,https://scrap.kakaocdn.net/dn/T4uHe/hyX4n391hw/Kv5iDBkk1ZngCAaX0DcRLk/img.png?width=423&amp;amp;height=430&amp;amp;face=0_0_423_430&quot; data-og-url=&quot;https://blog.nurd.work/314&quot;&gt;&lt;a href=&quot;https://blog.nurd.work/314&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jacobowl.tistory.com/314&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Un5Bg/hyX4uWyc0E/ZZQ5hgZpAbjIxOcOlSbxj1/img.png?width=240&amp;amp;height=163&amp;amp;face=0_0_240_163,https://scrap.kakaocdn.net/dn/bOvQr5/hyX7YPdeO0/P6hMKAJxnbEiw5IcWEhYH0/img.png?width=240&amp;amp;height=163&amp;amp;face=0_0_240_163,https://scrap.kakaocdn.net/dn/T4uHe/hyX4n391hw/Kv5iDBkk1ZngCAaX0DcRLk/img.png?width=423&amp;amp;height=430&amp;amp;face=0_0_423_430');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;VMware ubuntu 환경에서 k8s환경 구축하기.(2024 11월 기준 가능)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;# 바뀌어서 설치가 안되는부분만 최상단에 적음!! 시간이없어서 정리는 못하나, 바뀐부분만 적용하면 k8s클러스터 설치가능합니다.&amp;nbsp;2024년 9월 포스팅인데 현재 2024/11월 기준 9월에 포스팅한 방법&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 설치는 이전에 포스팅을 해놨는데요.&lt;br /&gt;&lt;b&gt;최근에 쿠버네티스 설치방법이 바뀌어서&lt;/b&gt; 많은 혼란이 있었습니다.. 마침 무찌클러스터 프로젝트 시작하려던 참이었거든요.&lt;br /&gt;구글링해도 최근방법은 잘 안나올거에요. 저또한 k8s클러스터를 수없이 많이 구축해봤지만(컴퓨터가 들었다놓으면 전원이 나가요ㅋㅋ) 최근업데이트때문에 많은 고생을 했습니다 ㅠ&lt;br /&gt;위 포스팅은 해당 업데이트된 내용을 찾아서 추가했던 포스팅입니다 ㅠㅠ 정말 이렇게 설치가 어려울줄은.. 몰랐어요&lt;br /&gt;&amp;nbsp;&lt;br /&gt;참고로 쿠버네티스는 많은 분들이 어렵다고 생각하시는데, 개인적으로 &lt;b&gt;가장 큰이유가 설치&lt;/b&gt;때문이라고 생각하는 코찔이입니다..&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;앱들은 어떻게 배포가되나요?&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;693&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kyxmc/btsLXsDXTZy/0nyhcUatLkY8dGi0S77cKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kyxmc/btsLXsDXTZy/0nyhcUatLkY8dGi0S77cKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kyxmc/btsLXsDXTZy/0nyhcUatLkY8dGi0S77cKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkyxmc%2FbtsLXsDXTZy%2F0nyhcUatLkY8dGi0S77cKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;693&quot; height=&quot;710&quot; data-origin-width=&quot;693&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 그림처럼 무찌클러스터에는 앱서비스 전용 &lt;b&gt;인그레스&lt;/b&gt;를 진입점으로 잡아놨어요.&lt;br /&gt;그리고 트래픽이 오면 각각의 네임스페이스에 바인딩된&lt;b&gt; external name&lt;/b&gt;서비스에 연결을 설정해놨습니다.&lt;br /&gt;때문에 제 배포된 프로젝트들의 링크에 접속하면 인그레스가 트래픽을 구분하여 해당 리소스 네임스페이스에 전달해줍니다~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;각각 앱서비스들의 리소스는 어떻게 생겼나요?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgcEk3/btsL1fDZwXL/sAyrQCcY4H29t9bbTYD9b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgcEk3/btsL1fDZwXL/sAyrQCcY4H29t9bbTYD9b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgcEk3/btsL1fDZwXL/sAyrQCcY4H29t9bbTYD9b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgcEk3%2FbtsL1fDZwXL%2FsAyrQCcY4H29t9bbTYD9b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;796&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;물론 앱마다 서로 조금씩 리소스 차이가 있지만 앱서비스들의 리소스는 대략적으로 저렇게 생겼답니다.&lt;br /&gt;&lt;b&gt;서비스&lt;/b&gt;가 일단 트래픽을 받구요. 이 서비스는 아까 각 external name 서비스들이랑 바인딩이 되었으니까 트래픽을 받게되죠.&lt;br /&gt;그리고&lt;b&gt; 컨트롤러&lt;/b&gt;가 서비스 역할을 하는 pod들을 관리해줍니다.&lt;br /&gt;또한&lt;b&gt; 오토스케일링&lt;/b&gt;을 설정해둬서 pod가 트래픽이 많으면 자동으로 오토스케일링되게 설정해놨습니다.&lt;br /&gt;그리고 해당 앱 네임스페이스마다 &lt;b&gt;network policy&lt;/b&gt;를 설정해둬서 보안을 신경썼어요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그럼 위에 ingress 트래픽과 각 앱 서비스는 이렇게 되겠죠?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vFB1J/btsL1edUAjK/pUJPUiZoqiPjlRoykkJRgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vFB1J/btsL1edUAjK/pUJPUiZoqiPjlRoykkJRgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vFB1J/btsL1edUAjK/pUJPUiZoqiPjlRoykkJRgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvFB1J%2FbtsL1edUAjK%2FpUJPUiZoqiPjlRoykkJRgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1240&quot; height=&quot;757&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;각 앱서비스에 맞는 네임스페이스에 인그레스 트래픽이 전달이되어 &lt;b&gt;세가지 앱을 운영&lt;/b&gt;할 수 있게 된거랍니다 ㅎㅎ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;기타 인프라&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7kIA1/btsLYNtAn5v/oYtCQLnhY1Wx03R5FDcqAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7kIA1/btsLYNtAn5v/oYtCQLnhY1Wx03R5FDcqAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7kIA1/btsLYNtAn5v/oYtCQLnhY1Wx03R5FDcqAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7kIA1%2FbtsLYNtAn5v%2FoYtCQLnhY1Wx03R5FDcqAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1218&quot; height=&quot;638&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;저는 &lt;b&gt;모니터링&lt;/b&gt;과 &lt;b&gt;이미지 스토리지&lt;/b&gt;, 그리고 &lt;b&gt;데이터베이스&lt;/b&gt;를&amp;nbsp; 모두 &lt;b&gt;헬름&lt;/b&gt;으로 깔았어요~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;모니터링&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;br /&gt;&lt;/span&gt;grafana, prometheus, loki&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPBFEe/btsLXTg4DHe/xKmIXyW913k9wd3sQPUkMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPBFEe/btsLXTg4DHe/xKmIXyW913k9wd3sQPUkMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPBFEe/btsLXTg4DHe/xKmIXyW913k9wd3sQPUkMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPBFEe%2FbtsLXTg4DHe%2FxKmIXyW913k9wd3sQPUkMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1062&quot; height=&quot;646&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;저는 &lt;b&gt;모니터링 도구&lt;/b&gt;로 &lt;b&gt;grafana, prometheus, loki&lt;/b&gt;를 활용했는데요~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;grafana 대시보드&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1649&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgFoc7/btsLXvOnvax/lb3aLyNY3LyzUjWf8dos80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgFoc7/btsLXvOnvax/lb3aLyNY3LyzUjWf8dos80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgFoc7/btsLXvOnvax/lb3aLyNY3LyzUjWf8dos80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgFoc7%2FbtsLXvOnvax%2Flb3aLyNY3LyzUjWf8dos80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1649&quot; height=&quot;528&quot; data-origin-width=&quot;1649&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 node쪽 리소스를 보여드리자면, 저렇게 리소스를 한눈에 볼 수 있게 대시보드를 만들었습니다.&lt;br /&gt;쿼리짜는게 생각보다 너무 어렵더라구요 ㅠㅠ 아직도 잘못짜겠네요..&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdhjYb/btsLXVTEjod/i23QPK3zxKKJdKcQ1knAak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdhjYb/btsLXVTEjod/i23QPK3zxKKJdKcQ1knAak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdhjYb/btsLXVTEjod/i23QPK3zxKKJdKcQ1knAak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdhjYb%2FbtsLXVTEjod%2Fi23QPK3zxKKJdKcQ1knAak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;244&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 pod별 리소스 사용량도 모니터링중인데 현재 가장 많이 잡아먹고 있는 리소스는&lt;b&gt; 프로메테우스&lt;/b&gt;입니다. 하긴 계속 클러스터를 감시해야하니 바쁠수밖에 없죠.&lt;br /&gt;리소스들을 모두 보여드리고싶지만 보안적으로 위험할것같아서 전부 올려드리지는 못하겠네요 ㅠ&lt;br /&gt;저랑 친하신분들은 저희집에 초대해서 직접 보여드릴게요~(무찌가 엄청 짖을텐데 무서워마세요..)&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;loki&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCIQCc/btsLZY8IGC0/uWaBgkP32qsj51L2o9dTuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCIQCc/btsLZY8IGC0/uWaBgkP32qsj51L2o9dTuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCIQCc/btsLZY8IGC0/uWaBgkP32qsj51L2o9dTuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCIQCc%2FbtsLZY8IGC0%2FuWaBgkP32qsj51L2o9dTuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;906&quot; height=&quot;505&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그라파나는 원래 &lt;b&gt;리소스 모니터링&lt;/b&gt; 전용 도구입니다. 전 &lt;b&gt;로그모니터링&lt;/b&gt;을 하고싶었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 rememberme 프로젝트 팀원분은 인프라로 취직하셨는데 kibana를 쓰시더라구요.&lt;br /&gt;전 그라파나에&lt;b&gt; loki&lt;/b&gt;를 연동하여서 로그 모니터링을 구성했습니다.&lt;br /&gt;예시로 사진처럼 로그가 찍히는데요. 저렇게 나쁜 요청들도 많이 온답니다..&lt;br /&gt;&amp;nbsp;&lt;br /&gt;참고로 로키는 한국에서는 많이들 사용을 안하셔서 영문으로 구글링해서 정보를 얻느라 좀 애먹었습니다 ㅠㅠ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;slack&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 프로메테우스랑 슬랙을 연결하여 클러스터에 이상이 있을시 알람설정을 해놨습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JWGog/btsLZ33btRn/ATkKAV2A5dL6Izc9T739gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JWGog/btsLZ33btRn/ATkKAV2A5dL6Izc9T739gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JWGog/btsLZ33btRn/ATkKAV2A5dL6Izc9T739gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJWGog%2FbtsLZ33btRn%2FATkKAV2A5dL6Izc9T739gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;907&quot; height=&quot;377&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 설정하는게 너무어렵기도하고 전 슬랙을 별로 안좋아해요.&lt;br /&gt;항상 알람이 늦게오더라구요.. 제가 잘 못만져서 그런걸수도 있지만요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;이미지 스토리지 - harbor&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/34KrV/btsLZtuxfb6/wTCHhj2qge1dKhEcYJEjkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/34KrV/btsLZtuxfb6/wTCHhj2qge1dKhEcYJEjkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/34KrV/btsLZtuxfb6/wTCHhj2qge1dKhEcYJEjkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F34KrV%2FbtsLZtuxfb6%2FwTCHhj2qge1dKhEcYJEjkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;382&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하버&lt;/b&gt;는 &lt;b&gt;이미지 스토리지&lt;/b&gt;입니다. 레지스트리라고도 합니다.&lt;br /&gt;이미지 저장용으로 사용하고있는데요~&lt;br /&gt;도커허브가 유료로 되었다는 소식을 들었어서 한번 해볼까? 하고 따로 만들었습니다.&lt;br /&gt;하버가 보안을 많이 신경써야하니, 이것저것 설정할게 많더라구요..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;887&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9aVKC/btsL39K45r2/kvO2P3HCtfT0CCh0RkqCO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9aVKC/btsL39K45r2/kvO2P3HCtfT0CCh0RkqCO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9aVKC/btsL39K45r2/kvO2P3HCtfT0CCh0RkqCO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9aVKC%2FbtsL39K45r2%2FkvO2P3HCtfT0CCh0RkqCO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1900&quot; height=&quot;887&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;887&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;998&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FnI23/btsLYKwXcjB/r8Nk75wCYrTvF6kt415DK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FnI23/btsLYKwXcjB/r8Nk75wCYrTvF6kt415DK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FnI23/btsLYKwXcjB/r8Nk75wCYrTvF6kt415DK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFnI23%2FbtsLYKwXcjB%2Fr8Nk75wCYrTvF6kt415DK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;998&quot; height=&quot;272&quot; data-origin-width=&quot;998&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진은 일부분만 보여드렸습니다 ㅠㅠㅠ 보안상 위험할것같아서요.&lt;br /&gt;이미지 저장이 주 목적이지만 전 헬름차트를 보관용으로 쓰고있습니다.&lt;br /&gt;나중에 또다시 클러스터를 구축한다면 구축해놓은 하버를 사설레지스트리로 사용할 수 있겠죠~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;데이터베이스들~&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AdI1E/btsLXUtHzuq/KVjAOKzrxiCUxZyH8EWkB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AdI1E/btsLXUtHzuq/KVjAOKzrxiCUxZyH8EWkB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AdI1E/btsLXUtHzuq/KVjAOKzrxiCUxZyH8EWkB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAdI1E%2FbtsLXUtHzuq%2FKVjAOKzrxiCUxZyH8EWkB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;238&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;데이터베이스&lt;/b&gt; 또한 무찌클러스터에 배포했습니다.&lt;br /&gt;데이터베이스를 클라우드에서 사용해보신 분들은 다들 아시겠지만, 매우매우 가격이 비쌉니다 ㅠㅠ&lt;br /&gt;물론 데이터를 안전하게 보관해주니 장점이 크지만 저같은 코찔이들은 포트폴리오로 쓰려고 데이터베이스를 하나 이용하려해도 최소 월 5만원이상이나 하니 배보다 배꼽이 크죠 ㄷㄷ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그래서 전 따로 무찌클러스터에 데이터베이스를 만들었어요.&lt;br /&gt;어떤 데이터베이스들인지는 하나하나 자세히 설명 못드리지만, 공개한 몽고디비는 현재 rememberme 서비스에서 데이터베이스로 사용하고 있습니다~&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba1G23/btsLXT9h6kM/meGwkO2GcPCOxMTAjLecCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba1G23/btsLXT9h6kM/meGwkO2GcPCOxMTAjLecCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba1G23/btsLXT9h6kM/meGwkO2GcPCOxMTAjLecCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba1G23%2FbtsLXT9h6kM%2FmeGwkO2GcPCOxMTAjLecCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1513&quot; height=&quot;218&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그라파나에서 이렇게 체크를 하고있습니다 ㅎㅎ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;앱과 기타 인프라 아키텍쳐&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFhDB3/btsL1WQ6Hsv/798A6Eo7pDnQCe39iZvdL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFhDB3/btsL1WQ6Hsv/798A6Eo7pDnQCe39iZvdL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFhDB3/btsL1WQ6Hsv/798A6Eo7pDnQCe39iZvdL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFhDB3%2FbtsL1WQ6Hsv%2F798A6Eo7pDnQCe39iZvdL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;668&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;이제 그래도 좀 인프라 같죠?ㅋㅋ&lt;br /&gt;글자가 작아서 잘 안보이시곘네요ㅠㅠ&lt;br /&gt;암튼 공개가능한 인프라들에 대해서 이렇게 아키텍쳐가 그려진답니다~&lt;br /&gt;&lt;br /&gt;참고로 모든 인프라들이 저장공간도 사용하기떄문에 우측상단에&lt;b&gt; persistent volume&lt;/b&gt;도 그려놨습니다~&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;Security Bot&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4YTGa/btsLZYHEoVZ/4tLVcBbo0wZ2iWYJKRq3a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4YTGa/btsLZYHEoVZ/4tLVcBbo0wZ2iWYJKRq3a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4YTGa/btsLZYHEoVZ/4tLVcBbo0wZ2iWYJKRq3a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4YTGa%2FbtsLZYHEoVZ%2F4tLVcBbo0wZ2iWYJKRq3a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;282&quot; height=&quot;196&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;클러스터에서&lt;b&gt; 보안역할&lt;/b&gt;을 하는 봇을 만들어뒀습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;모든 기능을 말씀드리기는 어렵지만, 한가지만 예시를 드려드리자면,&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;Time: 2025. 1. 23. 오후 5:42:59
IP: 142.93.32.68
User-Agent: Mozilla/5.0 Keydrop
Host: 123.456.123.456
Path: /.env
Status: 400

Time: 2025. 1. 23. 오후 7:49:47
IP: 147.185.133.122
User-Agent: -
Host: _
Path: -
Status: 400

Time: 2025. 1. 23. 오후 8:23:25
IP: 20.118.69.178
User-Agent: Mozilla/5.0 zgrab/0.x
Host: 123.456.123.456
Path: /manager/html
Status: 400

Time: 2025. 1. 24. 오전 1:12:40
IP: 162.158.170.136
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Host: nurd.work
Path: /wordpress/wp-admin/setup-config.php
Status: 200&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 메세지가 제 휴대폰으로 실시간으로 옵니다.&lt;br /&gt;딱봐도 .env파일을 탈취하려고 하거나, 관리자권한을 탈취하기위한 해킹요청이죠..ㅠㅠ&lt;br /&gt;진짜 엄청 많이옵니다.. 혹시 직접 배포하시는분들 조심하셔야합니다 하루에도 수십개가 옵니다 ㄷㄷ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;security bot이 하는 역할이 여러가지 있지만 한가지로 이런 역할을 해주고있어요.&lt;br /&gt;직접 코딩을 해서 만들었습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;최종 아키텍쳐&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/md6Ph/btsL0HVnpyW/2jYS24BsQLA7OmIvgciTK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/md6Ph/btsL0HVnpyW/2jYS24BsQLA7OmIvgciTK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/md6Ph/btsL0HVnpyW/2jYS24BsQLA7OmIvgciTK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmd6Ph%2FbtsL0HVnpyW%2F2jYS24BsQLA7OmIvgciTK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1139&quot; height=&quot;814&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;지금까지 설명드린 그림들을 전부 합쳐봤는데요~&amp;nbsp;&lt;br /&gt;이렇게 클러스터를 운영하고 있답니다ㅎㅎㅎ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;글자가 안보일까봐 클러스터 배경을 검은계열로 했는데 무찌가 먹구름이 되었네요ㅋㅋㅋ&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;온프레미스로 직접 서버를 구축하는걸 평소 항상 해보고싶었어서 재밋게 구축했네요.&lt;br /&gt;&lt;br /&gt;현재 실제로 운영되는 클러스터이고&lt;b&gt; 제 포트폴리오의 애플리케이션 대부분 무찌클러스터에서 운영&lt;/b&gt;되고 있습니다.&lt;br /&gt;이러한 이유로 자세하게 어떤식으로 구성을 했고 보안설정을 어떻게 하였는지는 공개가 어렵네요 ㅠㅠ&amp;nbsp;&lt;br /&gt;아직까지도 혹시 여러 공격을 받아서 무찌 클러스터가 취직전에 터질까 조마조마합니다 ㅠㅠㅠ&lt;br /&gt;&lt;br /&gt;사실 네트워크 국비교육과정을 들은 이유도 &lt;b&gt;온프레미스&lt;/b&gt;로 직접 서버를 만들어보고 싶어서 들어갔던건데요.&lt;br /&gt;파이널프로젝트때 솔직히 온프레미스로 만들어보고 싶었는데 aws수업이다보니 aws로 아빠또갈까 프로젝트를 만들었답니다 ㅎㅎ 이번기회에 직접 온프레미스 서버를 구축할수 있어서 좋은 경험이었어요.&lt;br /&gt;&lt;br /&gt;그리고 추가적으로 &lt;b&gt;쿠버네티스&lt;/b&gt;로 서버를 운영하면 &lt;b&gt;보안적&lt;/b&gt;으로도 좋고 &lt;b&gt;유지보수&lt;/b&gt;로써도 매우 좋습니다. 설치가 어려울뿐 저같은 코찔이도 이렇게 활용할 수 있는 기술이니 모르시는 분들은 배우시는걸 추천드립니다~!&lt;br /&gt;&lt;br /&gt;이상 &lt;b&gt;무찌클러스터 프로젝트&lt;/b&gt;였습니다 ^^&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>project/selfProject</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/354</guid>
      <comments>https://jacobowl.tistory.com/354#entry354comment</comments>
      <pubDate>Fri, 24 Jan 2025 08:31:47 +0900</pubDate>
    </item>
    <item>
      <title>Personal Project - NurdreamDek</title>
      <link>https://jacobowl.tistory.com/353</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;안녕하세요? Nurd Worker입니다! 반갑습니다. &lt;br /&gt;이번에 소개해드릴 프로젝트는 &lt;b&gt;NurdreamDek 프로젝트&lt;/b&gt; 입니다!&lt;br /&gt;&lt;br /&gt;너드림덱은 간단하게 요약하면 &lt;b&gt;원격 메크로 프로그램&lt;/b&gt;입니다 ㅎㅎ&lt;br /&gt;스트림덱과 같은 기능을 코드로 구현한 프로그램이라고 보시면 됩니다.&lt;br /&gt;&lt;br /&gt;이 프로젝트는 &lt;b&gt;백엔드 기능&lt;/b&gt;을 위주로 어필할 수 있는 프로젝트라고 생각해요~&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;다만!!&lt;/b&gt; &lt;/span&gt;죄송하지만 프로그램이 상당히 &lt;b&gt;보안적으로 민감한 기능&lt;/b&gt;들이 있답니다. &lt;br /&gt;또한 현재 Nurd Worker가 작업을할때 계속 사용중입니다.&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;때문에 &lt;b&gt;깃허브 코드는 공개하지 않으며,&lt;/b&gt; &lt;b&gt;개발 스택&lt;/b&gt;과 &lt;b&gt;아키텍쳐&lt;/b&gt;, &lt;b&gt;보안설정 &lt;/b&gt;또한 &lt;b&gt;자세히&lt;/b&gt; &lt;b&gt;공개하지 않습니다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;포스팅에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;기술적인 구현방식&lt;/b&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;플로우&lt;/b&gt;&lt;/span&gt;를 위주로 설명드릴거에요.&lt;br /&gt;전체공개가 되는 공간이니만큼 조심스러울수밖에 없는 점 양해부탁드립니다^^&lt;br /&gt;&lt;br /&gt;&lt;b&gt;너드림덱 기능은 &lt;span style=&quot;color: #ee2323;&quot;&gt;introduction 비디오&lt;/span&gt;를 먼저 시청하시고 포스팅을 읽어보시면 이해가 쉬우실겁니다.&lt;br /&gt;&lt;/b&gt;목차마다 짧은 동영상을 첨부해놓긴했지만 핸드폰으로 사용한다는 점을 모르시면 이게뭐야 하실거에요 ㅎㅎ&lt;br /&gt;&lt;br /&gt;그럼 재밋게 읽어주세요~&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;NurdreamDek 링크&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;nurdreamdek introduction video :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt; &lt;a href=&quot;https://youtu.be/7xdWBNWA4y0?si=EtJkvDq-7fHQ9ota&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/7xdWBNWA4y0?si=EtJkvDq-7fHQ9ota&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=7xdWBNWA4y0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/Ga3DV/hyX4zDlc9K/ydpVZoBaHkJ5aKerh3kSak/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ctZtK7/hyX4mYknPY/dZUWOyAPnt97ZJSBT0IPN1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;nurd worker&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/7xdWBNWA4y0&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;간단한 프로그램 소개&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mdb0I/btsLXRB1P0U/28IVYiJNcaKSdW8z6jtdB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mdb0I/btsLXRB1P0U/28IVYiJNcaKSdW8z6jtdB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mdb0I/btsLXRB1P0U/28IVYiJNcaKSdW8z6jtdB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmdb0I%2FbtsLXRB1P0U%2F28IVYiJNcaKSdW8z6jtdB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;990&quot; height=&quot;538&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일에서 데스크탑을 조작하는 프로그램입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터를 조작하는 리모컨? 같은 느낌이라고 보시면됩니다 ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;화면 구성&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;599&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcxEbY/btsLS3YGRPQ/JBB1qYwXCKqEJ7fRYAzCDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcxEbY/btsLS3YGRPQ/JBB1qYwXCKqEJ7fRYAzCDK/img.png&quot; data-alt=&quot;카테고리 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcxEbY/btsLS3YGRPQ/JBB1qYwXCKqEJ7fRYAzCDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcxEbY%2FbtsLS3YGRPQ%2FJBB1qYwXCKqEJ7fRYAzCDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1301&quot; height=&quot;599&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카테고리 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0T3tF/btsLUna9K2l/PPfj6ZmN6BmRmPTXdpYc5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0T3tF/btsLUna9K2l/PPfj6ZmN6BmRmPTXdpYc5K/img.png&quot; data-alt=&quot;일러스트레이터 카테고리의 기능 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0T3tF/btsLUna9K2l/PPfj6ZmN6BmRmPTXdpYc5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0T3tF%2FbtsLUna9K2l%2FPPfj6ZmN6BmRmPTXdpYc5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1300&quot; height=&quot;544&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;일러스트레이터 카테고리의 기능 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너드림덱의 화면구성은 아주 단순합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 원하는 기능 카테고리를 선택하여 들어갈 수 있습니다. 포스팅에선 &lt;b&gt;일러스트레이터 기능&lt;/b&gt;을 설명드릴 예정입니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카테고리 화면에서 일러스트레이터 버튼을 누르면, 두번째 기능 화면으로 넘어가는데요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 기능은 어떤건지, 어떻게 기능 구현을 하였는지 포스팅할 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - Align&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt; &lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bworbp/btsLVMf5E4D/nfIRS1nKvUzrhxgSVz1Jtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bworbp/btsLVMf5E4D/nfIRS1nKvUzrhxgSVz1Jtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bworbp/btsLVMf5E4D/nfIRS1nKvUzrhxgSVz1Jtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbworbp%2FbtsLVMf5E4D%2FnfIRS1nKvUzrhxgSVz1Jtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;988&quot; height=&quot;329&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 첫번째줄에 있는 align기능인데요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 이미지나 오브젝트들을 정렬을 해주는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;키보드메크로&lt;/b&gt;를 구현하여&lt;b&gt; 단축키&lt;/b&gt;를 눌러 해당 버튼 이벤트를 받으면 키보드 키가 눌러지게 하여 기능 구현하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - Drop Shadow&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;difficulty :&lt;/span&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi754U/btsLUsXznG6/G6agmF7qC0MzdtMXZKz3dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi754U/btsLUsXznG6/G6agmF7qC0MzdtMXZKz3dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi754U/btsLUsXznG6/G6agmF7qC0MzdtMXZKz3dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi754U%2FbtsLUsXznG6%2FG6agmF7qC0MzdtMXZKz3dk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;475&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째 줄에서 마지막에 있는 drop shadow아이콘입니다. 메이플스토리에서 쉐도우파트너 아이콘으로 만들었어요 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선택한 오브젝트에 그림자 효과를 주는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시나 이또한 &lt;b&gt;키보드 메크로와 단축키 조합으로&lt;/b&gt; 쉽게 만들었어요 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - Double Align&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #9d9d9d; text-align: center;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AjAJU/btsLTH2m35a/axzUtc8CZIIsCFShkQIf01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AjAJU/btsLTH2m35a/axzUtc8CZIIsCFShkQIf01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AjAJU/btsLTH2m35a/axzUtc8CZIIsCFShkQIf01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAjAJU%2FbtsLTH2m35a%2FaxzUtc8CZIIsCFShkQIf01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;866&quot; height=&quot;487&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ROW, COL이란 글자가 있는 기능은 세개이상의 오브젝트가 있을때, 가운데정렬과 동시에 간격조절도 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가운데정렬은 &lt;b&gt;키보드메크로&lt;/b&gt;, 간격조절하는 기능은&lt;b&gt; 이미지인식 기반&lt;/b&gt; &lt;b&gt;마우스메크로&lt;/b&gt;로 구현했어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세히보시면 마우스가 빠르게 움직였다가 제자리로 돌아오는걸 확인가능하십니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;왜 distribute기능은 키보드메크로로 안했냐면, 일러스트레이터는 아주아주 기능이 많습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 원하는 기능들의 단축키설정을 따로 해줘야하는데, &lt;b&gt;아주 많은 기능들이 단축키 설정조차 불가능한 경우가 많습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간격을 조절하는 distribute또한 단축키설정을 못하더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 키보드와 마우스, 두 가지 방법을 조합해서 구현했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능이 서로 &lt;b&gt;동기적으로 처리&lt;/b&gt;가 되야겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - artboard align&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #9d9d9d; text-align: center;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX5SxU/btsLTHOIOj3/Qmu8TI8BNrWjzOqWS5Dy00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX5SxU/btsLTHOIOj3/Qmu8TI8BNrWjzOqWS5Dy00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX5SxU/btsLTHOIOj3/Qmu8TI8BNrWjzOqWS5Dy00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX5SxU%2FbtsLTHOIOj3%2FQmu8TI8BNrWjzOqWS5Dy00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;877&quot; height=&quot;507&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아트보드 가운데정렬 기능입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동영상을 보시면 하얀색 바탕이 일러스트레이터에서 artboard라는건데요~ 그림으로 치면 도화지같은거라고 생각하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 도화지를 기준으로 오브젝트가 가운데로 정렬되게 하는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;마우스 메크로&lt;/b&gt;와 &lt;b&gt;이미지 인식&lt;/b&gt;을 기반으로 프로그래밍했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 영상도 매의 눈으로 자세히 보시면 아주 빠르게 마우스가 상단에 버튼을 두번 빠르게 클릭하고 제자리로 돌아오는걸 확인이 가능합니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;artboard align기능또한 단축키 설정에서 단축키를 설정을 할수가 없었죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능 소개 - font&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #9d9d9d; text-align: center;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JRdSD/btsLUYPlSFJ/U8xHB70b6uN7MpTzuOkSs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JRdSD/btsLUYPlSFJ/U8xHB70b6uN7MpTzuOkSs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JRdSD/btsLUYPlSFJ/U8xHB70b6uN7MpTzuOkSs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJRdSD%2FbtsLUYPlSFJ%2FU8xHB70b6uN7MpTzuOkSs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1198&quot; height=&quot;535&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;font기능&lt;/b&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상을 보시면 못생긴 궁서체들이 각자 설정한 폰트로 변하는걸 확인 가능하십니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트 오브젝트들을 원하는 글꼴로 바로 바꿔주는 기능입니다. 제가 자주쓰는 폰트들을 너드림덱 기능으로 만들어놨습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일러스트레이터를 사용하시면 많이들 불편해하시는게 매번 글자체를 따로 찾아서 설정하고 하기가 굉장히 불편합니다 ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 즐겨찾기 기능도있고 하시지만 그것조차 불편하기에 그냥 아예 파일하나에 글자체들을 저장해놓고 쓰시곤 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능구현부터는 난이도가 확올라갔는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상으로 보시면 딱히 어려울것없지만 이 기능은&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; JSX파일&lt;/b&gt;&lt;/span&gt;로 일러스트레이터 프로그램을 조작한겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일러스트레이터는 스크립트로 동작합니다!!(완전완전 중요!!)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시로 잘난체 font기능 스크립트파일을 보여드리자면&lt;/p&gt;
&lt;pre id=&quot;code_1737440525819&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var newFontName = &quot;JalnanOTF&quot;;

function changeFontInSelectedText(fontName) {
  var doc = app.activeDocument;

  if (doc.selection.length === 0 || !(doc.selection[0] instanceof TextFrame)) {
    return;
  }

  var selectedTextFrame = doc.selection[0];

  try {
    selectedTextFrame.textRange.characterAttributes.textFont =
      app.textFonts.getByName(fontName);
  } catch (e) {
    alert(&quot;can not find font: &quot; + fontName);
  }
}

changeFontInSelectedText(newFontName);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 자바스크립트로 되어있어요. 해당 스크립트를 일러스트에서 실행하면 기능이 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 원래는 font기능을 마우스메크로와 이미지인식으로 구현하려 하였으나, 밑에 더 설명할 드롭오브젝트 기능을 구현하다가 JSX파일로 구현이 가능한걸 발견하였고 font기능을 싹다 바꿨어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 인식기능은 사실 효율이 아주 안좋습니다ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 정말정말 고생해서 찾은 방법입니다 ..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - Drawing&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #9d9d9d; text-align: center;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx9LaX/btsLTQEGUA3/m36RadHcfF7SIeWOyH8S70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx9LaX/btsLTQEGUA3/m36RadHcfF7SIeWOyH8S70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx9LaX/btsLTQEGUA3/m36RadHcfF7SIeWOyH8S70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx9LaX%2FbtsLTQEGUA3%2Fm36RadHcfF7SIeWOyH8S70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;634&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;drawing기능&lt;/b&gt;입니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼은 하나지만 상당히 어려운 기능이었습니다.. 너드림덱에서 백엔드의 꽃이라고 생각하는 기능이었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 안쓰는 핸드폰으로 너드림덱으로 쓰려고 만든건데, 마침 제가 안쓰는 핸드폰이 갤럭시 노트 핸드폰이었습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 갤럭시 노트 기종에는 스마트펜이 들어있어서 만들어보자~ 하고 구현하기로 결심했습니다 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;drawing기능은 많은분들이 궁금해하실것 같아서 자세히 설명 드릴게요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 선이란 개념부터!! -&amp;gt; 좌표&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bplKuv/btsLVeEsufx/J3WZjCYVr7VmIKSLdzCelk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bplKuv/btsLVeEsufx/J3WZjCYVr7VmIKSLdzCelk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bplKuv/btsLVeEsufx/J3WZjCYVr7VmIKSLdzCelk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbplKuv%2FbtsLVeEsufx%2FJ3WZjCYVr7VmIKSLdzCelk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;362&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 점이 세개가 연속적으로 모이면 선이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽에서 오른쪽으로 드로잉을 할경우 점이 연속적으로 찍힐겁니다. 그래서 좌표데이터를 총 세개 (오른쪽 그림에서 객체)를 기록해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 점은 location_x, location_y라는 오른쪽 자료에서 &lt;b&gt;객체&lt;/b&gt;형식으로 좌푯값을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 저 세개의 점의 좌표객체를 배열에 순서대로 넣었습니다. 이렇게 기록되서 짧은 선이 되었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 선은 오른쪽 자료에서&lt;b&gt; 배열&lt;/b&gt;이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드로잉기능에서 모든 선(획)은 이런식으로 &lt;b&gt;배열안에 객체 구조&lt;/b&gt;로 데이터를 입력받아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 그럼 좌표데이터를 어떻게 나눠야할까?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djogJW/btsLUscsPNF/eKr7OUezKEy8Dc8AZLjlZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djogJW/btsLUscsPNF/eKr7OUezKEy8Dc8AZLjlZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djogJW/btsLUscsPNF/eKr7OUezKEy8Dc8AZLjlZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjogJW%2FbtsLUscsPNF%2FeKr7OUezKEy8Dc8AZLjlZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;522&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 들어볼게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'가'라는 글자를 쓸때 총 &lt;b&gt;세 획&lt;/b&gt;으로 끊어서 작성을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 획마다 점(좌표 객체)이 엄청 많겠죠? 이 객체들이 들어있는 어레이가 한 획이 되도록 위에 설명과 같이 설계를 했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 세 획이니까 아까 설명드린 어레이가 총 세개 나오겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 좌표데이터를 생성하고 나누는 로직은 어떻게 구현해야하나?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방식에서 주목해야할 주제는 두 가지에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 한 어레이 안에서 좌표의 순서는 순서대로 나열되어야함.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 각 획을 구분하는 기준을 정해야함.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgAZXj/btsLVL9DcAI/iNTQryF1Mw7WpXAh9bDo1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgAZXj/btsLVL9DcAI/iNTQryF1Mw7WpXAh9bDo1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgAZXj/btsLVL9DcAI/iNTQryF1Mw7WpXAh9bDo1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgAZXj%2FbtsLVL9DcAI%2FiNTQryF1Mw7WpXAh9bDo1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;995&quot; height=&quot;646&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 &lt;b&gt;한 어레이 안에서 좌표의 순서는 순서대로 나열되어야한다는 점 &lt;/b&gt;부터 살펴보죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트가 드로잉 동작을 할떄, 펜의 좌표가 기록이 되어야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건은 좌표가 &lt;b&gt;이전 좌표와 비교해서 변했다는 조건&lt;/b&gt;입니다. 짧은시간동안 지속적으로 좌표를 체크하고, 좌표가 계속 변하면 좌표객체를 리턴하는 함수를 호출했어요. 그리고 이 좌표함수의 리턴값을 어레이에 지속적으로 push했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNvKbI/btsLT3xwaw5/yjPfIKs3o5GVTOKrxLUxik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNvKbI/btsLT3xwaw5/yjPfIKs3o5GVTOKrxLUxik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNvKbI/btsLT3xwaw5/yjPfIKs3o5GVTOKrxLUxik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNvKbI%2FbtsLT3xwaw5%2FyjPfIKs3o5GVTOKrxLUxik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;545&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아주 아주 중요한건&lt;/b&gt; &lt;b&gt;2번, &lt;b&gt;각 획을 구분하는 기준&lt;/b&gt; &lt;/b&gt;인데, 이 어레이를 획당 구분하려면 어떻게 하냐는점이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연속적으로 좌표데이터가 들어오긴 하는데.. 한획을 마치고 다른 획을 쓰더라도 좌표가 변한건 맞잖아요? 이걸 구분하는 트리거를 잡아야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 다른획을 쓸떄 두 좌표의 거리가 멀면을 조건을 담아야할까요? 이렇게 하면 아주 빠르게 드로잉한경우에 획이 끊길거에요. (물론 프론트에서 좌표데이터를 수집하는 로직에 달려있지만요..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 저는 &lt;b&gt;시간에 주목&lt;/b&gt;했습니다. 타이머 변수를 만들어서 &lt;b&gt;타이머&lt;/b&gt;를 쟀어요. 지금까지 어레이에 담긴 좌표데이터 마지막에 들어간 시간에서 새로 들어오는 좌표데이터가 입력되는 시간이 차이가 &lt;b&gt;50ms이상&lt;/b&gt;이면 어레이를 나눈거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게해서 획당 좌표데이터 묶음(어레이)을 &lt;b&gt;완벽하게 구분&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;데스크탑에서 좌표묶음 데이터의 처리는 어떻게 처리할까? - IO 시각이 규칙적이지 않다.. =&amp;gt; 태스크큐!!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n0dRU/btsLUf5x6pK/6tuI1xDeDguKjAfYXc8BMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n0dRU/btsLUf5x6pK/6tuI1xDeDguKjAfYXc8BMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n0dRU/btsLUf5x6pK/6tuI1xDeDguKjAfYXc8BMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn0dRU%2FbtsLUf5x6pK%2F6tuI1xDeDguKjAfYXc8BMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;893&quot; height=&quot;612&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일에서 drawing을 해서 좌표데이터를 데스크탑에 순서대로 보냈다고 한다면, 이 좌표데이터가 보내지는 시각은 일단&lt;b&gt; 불규칙적&lt;/b&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 첫번째 획을 입력한 후, 0.1초후에 두번쨰 획을 보낸다면, 데스크탑의 drawing함수가 아직 첫번쨰 획 작업을 안끝내놨을수도 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 세번째 획 데이터를 보낼때는 두번째획의 작업을 보낸지 100년후에 보냈으니 이미 두번째 획은 처리를 끝낸지 한참 지난 후죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사람이 그리는거니까 불규칙할수밖에&lt;/b&gt; 없으니 당연한겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이걸 어떻게 처리를 해야할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 &lt;b&gt;태스크큐 자료형&lt;/b&gt;을 활용했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1330&quot; data-origin-height=&quot;743&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZqPGj/btsLVNOIiDL/RRBKLKYa4EGkrcmNQktMCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZqPGj/btsLVNOIiDL/RRBKLKYa4EGkrcmNQktMCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZqPGj/btsLVNOIiDL/RRBKLKYa4EGkrcmNQktMCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZqPGj%2FbtsLVNOIiDL%2FRRBKLKYa4EGkrcmNQktMCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1330&quot; height=&quot;743&quot; data-origin-width=&quot;1330&quot; data-origin-height=&quot;743&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 데스크탑에서는 모바일에서 들어오는 좌표어레이를 바로 drawing함수에 넣어 호출하는게 아니라, &lt;b&gt;일단 큐에 넣습니다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 drawing함수는 이 큐에 데이터를 기반으로 현재 있는 큐에 들어있는 맨 앞에있는 첫번쨰 데이터부터 동기적으로 처리해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BIfpW/btsLWwEkKyU/AMgWPAMK91iZb2bhBGPb71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BIfpW/btsLWwEkKyU/AMgWPAMK91iZb2bhBGPb71/img.png&quot; data-alt=&quot;tq&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BIfpW/btsLWwEkKyU/AMgWPAMK91iZb2bhBGPb71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBIfpW%2FbtsLWwEkKyU%2FAMgWPAMK91iZb2bhBGPb71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;839&quot; height=&quot;854&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;tq&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 가정했던 첫번째획이 들어오고 0.1초후에 두번째 획이 들어오고 백년후에 세번째획이 들어오는 상황을 가정해봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우에는 위 그림처럼 플로우가 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐의 핵심은 &lt;b&gt;선입 선출&lt;/b&gt;이라는겁니다 ㅎㅎ 편의점알바를 많이해봐서 익숙한 개념이었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 큐도 여러종류가 있는데 drawing기능에서는 task queue라고 과제?같은 느낌으로 일단 먼저들어온걸 처리하고 다음 데이터를 처리하는데 이런 과제큐들이 지속적으로 쌓인다는 느낌입니다. 자바스크립트도 스택과 큐 방식으로 비슷하게 돌아갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 큐자료형을 remember me 단어장 프로젝트에서도 활용하였는데 batch queue형식으로 사용했어요.(remember me 프로젝트 포스팅에서 확인하세요~)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 큐라고 하면 array를 생각하기 쉬우나, 어레이는 인덱싱이 있어서 효율이 안좋답니다. 그래서 전 &lt;b&gt;class로 구현&lt;/b&gt;했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이 플로우를 설계 및 테스트하면서 엄청 큰 트러블이 생겼었는데 ㅠㅠ 관심있으시면 문의주세요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 데스크탑에서와 모바일에서의 드로잉 시작점 차이&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모바일에서 좌표어레이를 하나 보냈다면, 데스크탑에서는 현재 마우스 포인터 위치에서 드로잉이 시작되게 하고싶었어요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgdghp/btsLVM9458R/nfDX2SsKLnsVoSzXafKkr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgdghp/btsLVM9458R/nfDX2SsKLnsVoSzXafKkr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgdghp/btsLVM9458R/nfDX2SsKLnsVoSzXafKkr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgdghp%2FbtsLVM9458R%2FnfDX2SsKLnsVoSzXafKkr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1160&quot; height=&quot;678&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방법은 이랬습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모바일에서 저렇게 획당 좌표데이터 묶음인 어레이를 데스크탑에 보냅니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럼 이제 데스크탑에서 이 좌표의 첫번째 좌표객체와, 현재 마우스 포인터의 좌표위치를 객체로 만든 좌푯값과 계산을하여 차잇값(그림에서 delta)을 가지고 나머지 좌표데이터 객체들에도 전부 연산을 해줍니다!&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럼 데스크탑의 현재 마우스 위치 기준으로 해당 획이 그려집니다 ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 어라? 왜이렇게 그려질까?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckTiFW/btsLUWjUlAI/bDlT7coG1NrZfjvsntt8iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckTiFW/btsLUWjUlAI/bDlT7coG1NrZfjvsntt8iK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckTiFW/btsLUWjUlAI/bDlT7coG1NrZfjvsntt8iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckTiFW%2FbtsLUWjUlAI%2FbDlT7coG1NrZfjvsntt8iK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1103&quot; height=&quot;692&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일에서 저렇게 '가'라는 글씨를 썼는데, 데스크탑에선 저런식으로 이상하게 드로잉이 됐습니다 ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유가 뭘까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EvUsf/btsLUTtUg8V/hcx380oujMg3GJVRIkAv70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EvUsf/btsLUTtUg8V/hcx380oujMg3GJVRIkAv70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EvUsf/btsLUTtUg8V/hcx380oujMg3GJVRIkAv70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEvUsf%2FbtsLUTtUg8V%2Fhcx380oujMg3GJVRIkAv70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;978&quot; height=&quot;690&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 획의 좌표묶음 어레이는 데스크탑에서 함수에 인수로 들어가서 드로잉이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 문제는 바로! 아까 &lt;b&gt;위에서 편의성을 위해 만든 delta값이 문제&lt;/b&gt;였어요. delta를 한 함수마다 매번 계산을 하는데, 이러다 보니 다음으로 들어오는 좌표어레이에 매번 델타값을 연산하다보니 실제 마우스가 움직이는 드로잉기능에서 마우스 시작점 위치가 한 함수마다 끝점으로 도달하니 저런 문제가 생긴것이었어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLlA82/btsLVw0Im0p/AKh2MAtySwxkYKC0tWjXq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLlA82/btsLVw0Im0p/AKh2MAtySwxkYKC0tWjXq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLlA82/btsLVw0Im0p/AKh2MAtySwxkYKC0tWjXq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLlA82%2FbtsLVw0Im0p%2FAKh2MAtySwxkYKC0tWjXq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1172&quot; height=&quot;814&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 처음 좌표어레이를 호출했을때 계산한 delta값을 전역으로 빼놓습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 두번째 좌표어레이를 인수로 넣어 호출된 함수는 이 delta값이 존재하는지 체크한 후, 있다면 초기 delta값을 계산하는 코드를 실행하지 않고 전역에있는 delta값을 재사용해서 본인 어레이에 좌표계산을 하면 됩니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 방식은 뭐 다들 사용하시면서 자주 설계하시는데, 전 플래그라고 보통 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플래그를 지정해서 코드실행을 제어하는거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에서는 함수라고 획당 하나의 실행컨텍스트를 생성하는 식으로 그렸는데 사실은 획 하나당 프로세스 하나라서 &lt;b&gt;멀티프로세스&lt;/b&gt;에서 플래그를 참조했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;drawing기능 성능개선&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상을 보시더라도 실제 모바일에서 그리는것과 데스크탑에서 그려지는것과 딜레이가 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 최대한 줄여봤지만 여전히 존재하더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 &lt;b&gt;수학적&lt;/b&gt;으로 줄여봤는데요&lt;/p&gt;
&lt;pre id=&quot;code_1737453526307&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (let i = 1; i &amp;lt; data.length - 1; i++) {
    const point = data[i];
    const adjusted_x = point.x + delta_x;
    const adjusted_y = point.y + delta_y;
    const dx = adjusted_x - last_x;
    const dy = adjusted_y - last_y;
    const distance = Math.sqrt(dx ** 2 + dy ** 2);
    
    if (distance &amp;gt; min_distance) {
        adjusted_data.push({ x: adjusted_x, y: adjusted_y });
        last_x = adjusted_x;
        last_y = adjusted_y;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 함수를 보시면 이전의 xy좌표값과 현재 xy좌표값의 차이가 너무 짧을경우 해당 좌표를 뺐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 5px이하일경우 해당 좌표객체를 제거하는 로직으로해서 drawing 함수가 계산해야하는 좌표수를 최대한 줄였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피타고라스의 원리 생각하시면되요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 실제로 영상을 보시면 ㅇ을 그릴때 실제보다 조금더 비율이 작게 그려진답니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커브가 심할수록 뭉개지더라구요 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 못알아볼정도는 아니니 이대로 진행했습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능소개 - Drop object&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #9d9d9d; text-align: center;&quot;&gt;difficulty :&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEy9C5/btsL1tveknT/nxeco8e72zCbkVDZlsK82K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEy9C5/btsL1tveknT/nxeco8e72zCbkVDZlsK82K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEy9C5/btsL1tveknT/nxeco8e72zCbkVDZlsK82K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEy9C5%2FbtsL1tveknT%2Fnxeco8e72zCbkVDZlsK82K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;955&quot; height=&quot;498&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드랍오브젝트는 아주 심플하죠 ㅎㅎ 그냥 그림을 바로 가져와주는 기능입니다. 단순하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 정말 구현하기 힘들었습니다 ㅠㅠ 왜냐면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미지가 아니라 오브젝트를 가져와야 했기 때문입니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;# 이미지와 오브젝트 차이?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;영상을 보시면 차이가 뭔지 아실거에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자이너분들은 익숙한 개념이지만 엔지니어분들은 뭔 차이인지 모르시기 때문에.. 영상으로 첨부했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 단순하게 그림을 가져오는겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 일러스트에서 오브젝트는 각각의 포인터가 살아있어서 수정이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 가져와서 오브젝트처럼 만드는 기능이 있지만(이미지 트레이서) 이미지가 거의 90%는 망가지고 오브젝트들끼리의 설정들도 다 깨지게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html css로 예를들면, 단순하게 웹사이트 이미지를 해석해서 ai가 간격을 죄다 픽셀단위로 css코드를 짜주는것과 같구(피그마 ㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오브젝트는 플렉스박스로 정렬기능을 구현한건과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능을 보시면 디자이너분들이 맘에들어하실 기능같아요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2eIC7/btsLWOF2z16/5tIq7Kh8E1DPegCki33T1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2eIC7/btsLWOF2z16/5tIq7Kh8E1DPegCki33T1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2eIC7/btsLWOF2z16/5tIq7Kh8E1DPegCki33T1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2eIC7%2FbtsLWOF2z16%2F5tIq7Kh8E1DPegCki33T1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;129&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 자주 우려먹는 이 타이틀 이미지도 너드림덱 drop object에 등록된 오브젝트인데요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글자를 입력하면 자동으로 박스가 커집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 이미지로 가져와서 붙였다면 글자를 입력할수도, 글자를 입력해도 배경이 안늘어나겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;오브젝트라는게 아주아주 중요합니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;오브젝트 즐겨찾기 기능 같은거 없어? - 심볼&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 일러스트레이터를 잘 다루는 편은 아니라 분명 있음직할 기능인데 찾을 수가 없었어요.. 아시는 디자이너분들은 알려주세요 ㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 찾아보니 심볼이라는 기능이 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boGmTv/btsLXVj5GCo/zKDrXo503hQemhRqJni8N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boGmTv/btsLXVj5GCo/zKDrXo503hQemhRqJni8N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boGmTv/btsLXVj5GCo/zKDrXo503hQemhRqJni8N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboGmTv%2FbtsLXVj5GCo%2FzKDrXo503hQemhRqJni8N1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;252&quot; height=&quot;147&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능은 아마 디자이너분들도 생소한 기능일겁니다. 저도 몰랐어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 기능이냐면 오브젝트들을 심볼로 등록하고 이 오브젝트를 한번에 수정하면 다른 오브젝트들도 똑같이 변하는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nurd worker는 이 심볼기능에서&lt;b&gt; '오브젝트를 가져와 쓰는기능' 만&lt;/b&gt; 사용하고 싶었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;심볼끼리 링크를 끊자! - break link기능&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;101&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOP4JB/btsLVKdg75p/lsKQ7dM3IudBJcLb3ftEzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOP4JB/btsLVKdg75p/lsKQ7dM3IudBJcLb3ftEzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOP4JB/btsLVKdg75p/lsKQ7dM3IudBJcLb3ftEzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOP4JB%2FbtsLVKdg75p%2FlsKQ7dM3IudBJcLb3ftEzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;101&quot; height=&quot;101&quot; data-origin-width=&quot;101&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소개영상에서도 뭔지 모를것같은 이런 버튼이 너드림덱에 있는데 이게 심볼 링크를 끊는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 drop object로 오브젝트를 가져오더라도 여전히 심볼입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 오브젝트를 수정하더라도 다른 object도 똑같이 변경이 되어버리죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;drop object는 이미지를 가져오는 기능만 사용해야하니 링크를 끊어줄 필요성이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 링크를 끊는 버튼을 따로 만들었습니다. 이미지 기반 마우스 메크로로 만들었습니다 ^^&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 따로 버튼을 안만들고 drop object에 전부 넣어놨거든요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이미지기반 메크로는 말씀드렸다시피 자주 실수를 합니다. 그래서 따로 그냥 뺴놨어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;일러스트레이터는 스크립트로 동작합니다! - JSX&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 font기능에서 JSX파일로 동작하게 한걸 설명드렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실은 drop object기능을 구현하다가 발견한 방법이에요. 그 후에 font도 jsx파일로 스크립트로 전부 변경했죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각해봅시다. 만약 drop object를 사용하려 심볼까지 만들어놨다 하더라도, 심볼패널에서 해당 오브젝트를 가져와야하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbWlnJ/btsLYeDKRpS/sFBGh6TS7nV3bEBW0cRwQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbWlnJ/btsLYeDKRpS/sFBGh6TS7nV3bEBW0cRwQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbWlnJ/btsLYeDKRpS/sFBGh6TS7nV3bEBW0cRwQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbWlnJ%2FbtsLYeDKRpS%2FsFBGh6TS7nV3bEBW0cRwQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;150&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 심볼패널에서 원하는 오브젝트를 클릭후 화면에 드래그래서 가져와야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이미지기반 클릭 앤 드래그를 설정해야하는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말씀드렸다시피 이미지기반 메크로는 인식율이 많이 안좋을 뿐더러,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 오브젝트를 이미 하나 불러왔는데 또 drop object를 사용하면 어떻게될까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4kxZB/btsLW6l8nKT/YzaWMh1gthipR0dKgsstPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4kxZB/btsLW6l8nKT/YzaWMh1gthipR0dKgsstPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4kxZB/btsLW6l8nKT/YzaWMh1gthipR0dKgsstPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4kxZB%2FbtsLW6l8nKT%2FYzaWMh1gthipR0dKgsstPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;233&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이미지를 인식하는데 현재 화면에 있는 object(방금 끌어온것)가 있고, 심볼 패널에 있는 object중 어떤걸 선택할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 왼쪽에 이미지, 오른쪽 심볼패널에 있는 이미지(짝은거) 중에서 고민하다가 아무거나 클릭해버리겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 사이징 문제도 이미지기반 인식에 크게 문제가됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 이미지더라도 사이즈가 달라져버리면 이미지를 잘 못찾습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 복잡한걸 억지로 해결하기 너무 어렵습니다. 때문에 다른 방법을 모색중에 JSX파일로 스크립트로 동작하게하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말정말 어렵게 찾은 방법입니다 ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사실 이번 포스팅에 있는 기능중, &lt;b&gt;드랍오브젝트가 가장 가장 어려웠습니다&lt;/b&gt; ㅠㅠ&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍적으로 어렵다기보다는 원하는 기능을 실제로 구현하기위해 방법들을 스스로 찾아야했고 찾는중 정말 많은 실패를 했었어요.. 중간에 그냥 하지말까도 생각해봤습니다 ㅠㅠ&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;드로잉기능도 만만치않게 복잡하고 어려웠지만 개인적으로는 드랍오브젝트 기능이 드로잉보다 어려웠다고 느꼈어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;Conclusion&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;nurd worker는 돈이 없답니다 ㅠ&lt;br /&gt;그러나 엔지니어의 피가 흐르고 있었기 때문에ㅋㅋㅋ 장비욕심은 항상 있어요. 그래서 생일날이나 이런 좋은날에 가끔 스스로에게 장비를 사줘요.(작년에는 2만원짜리 키보드사줌 ㅋㅋ)&lt;br /&gt;&lt;br /&gt;전 스트림덱을 너무 갖고 싶었습니다. 그러나 인터넷에 보시면 버튼 여덟개 꼴랑있는 최소사양모델이 10만원중반대부터 시작을 합니다. 또한 구매후에 필요한 어플리케이션에 필요한 플러그인같은것도 따로 사야한다고 하더라구요ㄷㄷ&lt;br /&gt;돈없으면 죽어야지.. 가 아니라 &lt;b&gt;돈없으니 만들어보자!&lt;/b&gt; 하고 시작한 프로젝트입니다 ㅋㅋ &lt;br /&gt;이게 좀웃기지만 너드림덱 프로젝트의 찐 동기입니다 ㅋㅋㅋ&lt;br /&gt;&lt;br /&gt;하지만 만들고보니 선이 연결되어야하는 단점이있는 스트림덱보다 원격으로 작동할수 있다는 장점이 있었고,&lt;br /&gt;스트림덱 디바이스에서는 불가능한 drawing기능도 구현이 됐습니다(갤럭시노트님 ㄳㄳ)&lt;br /&gt;또한 휴대폰에서 쓸 수 있으니 디바이스도 딱히 필요없는? 장점이 있는것 같네요&lt;br /&gt;&lt;br /&gt;가장 큰 장점은 &lt;b&gt;원하는 기능을 직접 만들어서 커스텀 할 수 있다는 점 &lt;/b&gt;이라고 생각합니다 ㅋㅋ&lt;br /&gt;&lt;br /&gt;아무튼 읽어주셔서 감사합니다~&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u6pZB/btsLWb8eHYr/EKNYOCEizA1Al2fnZpueyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u6pZB/btsLWb8eHYr/EKNYOCEizA1Al2fnZpueyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u6pZB/btsLWb8eHYr/EKNYOCEizA1Al2fnZpueyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu6pZB%2FbtsLWb8eHYr%2FEKNYOCEizA1Al2fnZpueyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;868&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트러블슈팅 기록한거.. 이런거 거의 다섯배이상 튀어나왔슴..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRlVeV/btsLXuNPYx1/kNc7PXaoRsefh5dYrLeHb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRlVeV/btsLXuNPYx1/kNc7PXaoRsefh5dYrLeHb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRlVeV/btsLXuNPYx1/kNc7PXaoRsefh5dYrLeHb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRlVeV%2FbtsLXuNPYx1%2FkNc7PXaoRsefh5dYrLeHb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;427&quot; height=&quot;503&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 네.. 아무일도 없었습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>project/selfProject</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/353</guid>
      <comments>https://jacobowl.tistory.com/353#entry353comment</comments>
      <pubDate>Tue, 21 Jan 2025 19:05:23 +0900</pubDate>
    </item>
    <item>
      <title>Personal Project - ACSAP</title>
      <link>https://jacobowl.tistory.com/352</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;안녕하세요? Nurd Worker입니다! 반갑습니다. &lt;br /&gt;이번에 소개해드릴 프로젝트는 &lt;b&gt;acsap프로젝트&lt;/b&gt;입니다!&lt;br /&gt;프로젝트 계기는 국비교육과정을 들으면서 스터디를 만들게 되었는데요. 이때 팀원분들과 저 또한 자격증 공부를 더욱 효율성 있게 하기위해서 제작했던 프로젝트입니다ㅎㅎ&lt;br /&gt;스터디를 진행하면서 최대한의 퍼포먼스를 내기위해 만들었고 스터디원분들 전원 자격증 취득하신 보람찼던 경험이었어요.&lt;br /&gt;&lt;br /&gt;acsap 어플리케이션은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;현재 배포가 되어있는 상태&lt;/b&gt;&lt;/span&gt;입니다. &lt;b&gt;직접 방문 가능&lt;/b&gt;하세요.&lt;br /&gt;&lt;br /&gt;약 1년전에 개발한 프로그램이라 기억이 가물가물하지만 소개 시작해보겠습니다~&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;acsap 링크&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;acsap intruduction video : &lt;a href=&quot;https://youtu.be/gWS7EZV8OXM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/gWS7EZV8OXM&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=gWS7EZV8OXM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/caygnv/hyX4qFSjAU/tAwJif67mtdz8cqckBWYl1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/xJIDd/hyX4tvP5F2/KyBQIoJbHSQj8J6Rnki5J0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;nurd worker&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/gWS7EZV8OXM&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;acsap github repository : &lt;a href=&quot;https://github.com/nurdworker/acsap&quot;&gt;https://github.com/nurdworker/acsap&lt;/a&gt; &lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737309716001&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - nurdworker/acsap&quot; data-og-description=&quot;Contribute to nurdworker/acsap development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nurdworker/acsap&quot; data-og-url=&quot;https://github.com/nurdworker/acsap&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dsRSJZ/hyX0u3V8XL/TiIeudLm3MeNK4cpNvWII0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/O1sIq/hyX0lMHHek/fbQUTzddtfek0140GJKrh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nurdworker/acsap&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nurdworker/acsap&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dsRSJZ/hyX0u3V8XL/TiIeudLm3MeNK4cpNvWII0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/O1sIq/hyX0lMHHek/fbQUTzddtfek0140GJKrh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nurdworker/acsap&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nurdworker/acsap development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;acsap published web site link : &lt;a href=&quot;https://acsap.nurd.work&quot;&gt;https://acsap.nurd.work&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737310083945&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;acsap&quot; data-og-description=&quot;&quot; data-og-host=&quot;acsap.nurd.work&quot; data-og-source-url=&quot;https://acsap.nurd.work&quot; data-og-url=&quot;https://acsap.nurd.work&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://acsap.nurd.work&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://acsap.nurd.work&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;acsap&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;acsap.nurd.work&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;개발스택&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOqVoy/btsLSABgzV9/kr4hEIfK3TthtkpAjDbd8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOqVoy/btsLSABgzV9/kr4hEIfK3TthtkpAjDbd8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOqVoy/btsLSABgzV9/kr4hEIfK3TthtkpAjDbd8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOqVoy%2FbtsLSABgzV9%2Fkr4hEIfK3TthtkpAjDbd8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1225&quot; height=&quot;468&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프론트엔드&lt;/b&gt;는 제가 주로 사용하던 &lt;b&gt;vue.js&lt;/b&gt;를 사용하여 제작을 하였습니다. 사실 이 프로젝트가 거의 프론트엔드로만 구성되었다고 보셔도 됩니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백엔드&lt;/b&gt;는 역시 주로 사용하였던&lt;b&gt; nodejs&lt;/b&gt;의 &lt;b&gt;express&lt;/b&gt; 프레임워크로 개발하였구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;는 &lt;b&gt;mysql&lt;/b&gt;을 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 배포한 &lt;b&gt;인프라&lt;/b&gt;는&lt;b&gt; aws lightsail&lt;/b&gt;을 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obZfR/btsLScARXOD/kZ1eepnN7t4RK7NWC8Npm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obZfR/btsLScARXOD/kZ1eepnN7t4RK7NWC8Npm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obZfR/btsLScARXOD/kZ1eepnN7t4RK7NWC8Npm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobZfR%2FbtsLScARXOD%2FkZ1eepnN7t4RK7NWC8Npm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;920&quot; height=&quot;567&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프라에 대해서 더 소개해드리자면요~ 돈이 없는 취준생이라 aws 월 5달러짜리&lt;b&gt; lightsail인스턴스&lt;/b&gt;로 배포를 하였고 역시나 돈이없기때문에 ㅋㅋ 인스턴스 하나에 web, was, db를 싹다 쑤셔박았습니다 ㅎㅎ 그래서 원티어 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드로 거의 동작하는 프로그램이기때문에 백엔드와 db는 보조로써 역할만 했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실제로 현재 체험용으로 배포된 acsap웹은 프론트엔드로만&lt;/b&gt; 배포된 정적사이트입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;어떤 목적으로 만들었나요?&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 스터디를 모집하였을때, 저희는 자격증 시험에 대한 정보가 전혀 없던 상태였습니다ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 시험정보를 모아서 공부를 차근차근 하던중에 문제풀이앱이 있으면 굉장히 효율적이라는 생각이 들더라구요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 급하게 최대한 빨리 해당 어플리케이션을 만드려고 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 제가 주목하였던 요소들은 이렇습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;국비교육과정을 병행하며 자격증 시험을 준비하여야 하기에, 시간이 굉장히 모자르다고 판단하였습니다. 때문에 훈련기관까지 출퇴근하는 시간에 지하철, 버스 등에서 공부할 수 있도록 모든 기기에서 접속이 가능한 어플리케이션이어야 했습니다. &amp;rarr; &lt;b&gt;web기반 웹 어플리케이션으로 제작&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;문제량이 상당히 많았습니다.(약 400개) 때문에 자주 틀리는 문제등을 따로 저장하여 공부할수 있는 기능이 필요했습니다 &amp;rarr; &lt;b&gt;오답노트 기능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;실제 본인의 공부를 테스트할수 있는 기능이 필요했어요 &amp;rarr; &lt;b&gt;semi test기능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;너무 바쁘므로 최대한 빨리 프로그램을 완성해야했습니다 &amp;rarr; &lt;b&gt;유저인증, 백엔드 로직 등은 최대한 간소화&lt;/b&gt;하고 &lt;b&gt;프론트엔드 기반&lt;/b&gt;으로 돌아가게 설계, &lt;b&gt;익숙한 언어 및 프레임워크 활용&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt; vce프로그램과 상당히 유사한데?&lt;br /&gt;&lt;/b&gt; &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckFEoQ/btsLTSt2L5o/oRxSsWxAxDtiJ7rtZsLvaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckFEoQ/btsLTSt2L5o/oRxSsWxAxDtiJ7rtZsLvaK/img.png&quot; data-alt=&quot;vce 프로그램&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckFEoQ/btsLTSt2L5o/oRxSsWxAxDtiJ7rtZsLvaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckFEoQ%2FbtsLTSt2L5o%2FoRxSsWxAxDtiJ7rtZsLvaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;362&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vce 프로그램&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객관식 문제 자격증을 준비하신 분들은 많이들 아시는 &lt;b&gt;vce프로그램&lt;/b&gt;이있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 정보가 상당히 부족한 상태로 스터디를 모집했기에 초기에 vce프로그램의 존재조차 몰랐어요 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 처음에는 a4용지로 문제들을 인쇄하여 같이 공부하는 식으로 시작을 하다가 acsap프로젝트를 만들어서 공유해드렸습니다. 그러다보니 vce프로그램이 있다는것을 알게되었습니다ㅎㅎㅎ 사람들 생각하는건 다 비슷한가봐요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 중요한건 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;막상 만들고 보니, vce프로그램보다 acsap어플리케이션이 더욱 좋았습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;vce는 exe프로그램입니다&lt;/b&gt;. 컴퓨터환경에서 동작하죠. 하지만 &lt;b&gt;acsap는 웹기반 어플리케이션&lt;/b&gt;이라 모든 기기에서 공부가 가능했습니다. 저희는 국비과정을 병행하기에 제가 여러번 스터디원분들께 학원에서는 수업에 집중하고 자격증공부는 출퇴근시간에 acsap로 공부하라고 수차례 강조드렸습니다. 저역시도 자격증 공부의 90퍼센트는 출퇴근시간에 공부하였습니다.&lt;/li&gt;
&lt;li&gt;vce는 틀린문제만 다시 확인하게 해주는 기능이 있긴 하지만, 자주 틀리는 문제를 따로 담을 수 있는 오답노트 기능이 없었습니다. &lt;b&gt;acsap는 초기설계부터 오답노트기능을 만들었어요.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;스터디를 하다보니 문제에 대한 &lt;b&gt;키워드를 정하는 방식&lt;/b&gt;이 굉장히 효과적이었습니다. 근데 저희 스터디에는 어플리케이션의 운영자가 팀원이잖아요? 그래서 바로 개발해드렸습니다. 문제량이 400개가 넘었어서 공부할수록 정말 혼란스러운데, &lt;b&gt;키워드기능&lt;/b&gt;을 정말 좋아하셨습니다. vce프로그램은 키워드 기능이 없습니다.&lt;/li&gt;
&lt;li&gt;1번에서 말씀드렸듯이 모바일이나 태블릿으로 출퇴근 시간에 공부를 해야한다고 수차례 강조를 드렸습니다. vce는 휴대폰으로는 작동이 안되는걸로 아는데, 안드로이드버전은 있다고 하더라구요. 하지만 a&lt;b&gt;csap는 아이폰 ios기기에서도 웹기반이기떄문에 브라우저만 동작하면 문제없이 동작을 합니다&lt;/b&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 장점들로 뒤늦게 vce프로그램이 있다는 사실을 알게되었으나, 제가만든 acsap프로그램이 더욱 장점이 많았습니다 ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련기간이 끝나고 취직을 하신 몇 팀원분들도 추가 자격증 취득을 준비하신다고 재배포해달라고 요청하셨던 프로그램입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt; 어떤 구조로 동작합니까?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자잘한 프레임워크의 코드나 함수는 일일히 설명을 안드리겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1077&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1Fdnq/btsLSelakrm/HuFGX3NYTXDnrqiurWpuuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1Fdnq/btsLSelakrm/HuFGX3NYTXDnrqiurWpuuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1Fdnq/btsLSelakrm/HuFGX3NYTXDnrqiurWpuuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Fdnq%2FbtsLSelakrm%2FHuFGX3NYTXDnrqiurWpuuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1077&quot; height=&quot;501&quot; data-origin-width=&quot;1077&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;acsap 웹어플리케이션의 동작방식은 단순해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 데이터들을 &lt;b&gt;브라우저 스토리지인 local storage에 저장하고 이 데이터를 자바스크립트가 가져와서 동적 렌더링을 해줍니다&lt;/b&gt;. 실제로 데스크탑 브라우저로 개발자도구를 키시면 확인가능하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setting에서 json파일을 넣어주면 local strorage에 question_data와 answer_data를 json strinigify로 스트링으로 변환하여 넣어준다음 이걸 자바스크립트로 parsing해서 사용을 한답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 브라우저를 닫았다 켜도 도메인에 대한 영구적인 데이터가 남아있는 localStorage특성상 매번 따로 데이터를 설정해줄 필요가 없는거죠. 스터디 팀원분들에게도 문제데이터를 처음 입력만 해주고 이후로는 따로 설정해드린게 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 오류가생기면 setting에서 delete 데이터 버튼으로 어느정도 해결이 가능한겁니다. (모바일은 개발자도구를 못키기때문에 만들었어요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소개 영상에는 안나온 기능들 &lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;테스트를 보던중에 브라우저를 닫거나, 다른 메뉴에 다녀와도 테스트 데이터가 남아있습니다. 지속적으로 계속 테스트를 보실 수 있어요.&lt;/li&gt;
&lt;li&gt;키워드기능은 전역데이터로 저장되므로, 소개영상에서 나온 general questions뿐 아니라 semi test, 오답노트 등에서도 해당 문제에 저장한 키워드를 확인 가능해요.&lt;/li&gt;
&lt;li&gt;현재 배포된 acsap는 한 기기에서의 한 브라우저단위로 데이터가 저장되어 다른 기기로 공부를 병행할경우 keyword데이터를 매번 새로 설정해줘야합니다. 실제로 사용하였던 acsap어플은 setting에서 bring put keyword data 버튼으로 키워드 데이터를 db에 저장 후, 다른 기기에서 import해서 데이터를 가져오는 방식으로 사용했습니다. (백엔드 db구축 필요)&lt;/li&gt;
&lt;li&gt;question.json데이터 양식을 보시면 img url프로퍼티도 있으나 실제 코드에선 안썼습니다. 초반에 사용하게했는데 굳이 필요없을것같아서 걍 뺐어요. 필요하신분들은 github코드를 클론하셔서 이미지를 따로 외부스토리지같은곳에 저장하시고 url로 임포트하는 이미지 태그를 작성하셔서 사용하시면됩니다.&lt;/li&gt;
&lt;li&gt;답변보기 버튼을 누르면 다음 문제로 넘어가도 답이 보이지만, 키워드는 다음 문제로 넘어갈때 자동으로 꺼집니다. 잘모르는 문제에대한 힌트같은 기능이라 꺼지게 만들었어요~&lt;/li&gt;
&lt;li&gt;semi test를 보실경우 설정한 문제범위의 문제들이 랜덤으로 섞입니다.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 현재 배포된 acsap프로젝트는 어떻게 사용하나요? &lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;문제 데이터 넣기&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;acsap를 사용하시기 위해선 먼저 question.json데이터와 answer json데이터를 setting에서 넣어주어야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양식은 이렇습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737309113222&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// question.json
[
  {
    &quot;question_number&quot;: 1,
    &quot;correct_answer_index&quot;: &quot;A&quot;,
    &quot;question_ko&quot;: &quot;무찌는 처음 데려왔을 때 몸무게는 몇 kg이었습니까?&quot;,
    &quot;question_en&quot;: &quot;What was Muzzi's weight when he was first adopted?&quot;,
    &quot;reference_link&quot;: null,
    &quot;img_src&quot;: null,
    &quot;etc&quot;: null
  },
  {
    &quot;question_number&quot;: 2,
    &quot;correct_answer_index&quot;: &quot;A&quot;,
    &quot;question_ko&quot;: &quot;무찌의 가장 좋아하는 과일은 무엇입니까?&quot;,
    &quot;question_en&quot;: &quot;What is Muzzi's favorite fruit?&quot;,
    &quot;reference_link&quot;: null,
    &quot;img_src&quot;: null,
    &quot;etc&quot;: null
  }
]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1737309079510&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// answer.json
[
  {
    &quot;content_ko&quot;: &quot;3kg&quot;,
    &quot;content_en&quot;: &quot;3kg&quot;,
    &quot;index_answer&quot;: &quot;A&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 1
  },
  {
    &quot;content_ko&quot;: &quot;6kg&quot;,
    &quot;content_en&quot;: &quot;6kg&quot;,
    &quot;index_answer&quot;: &quot;B&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 1
  },
  {
    &quot;content_ko&quot;: &quot;9kg&quot;,
    &quot;content_en&quot;: &quot;9kg&quot;,
    &quot;index_answer&quot;: &quot;C&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 1
  },
  {
    &quot;content_ko&quot;: &quot;귤&quot;,
    &quot;content_en&quot;: &quot;tangerines&quot;,
    &quot;index_answer&quot;: &quot;A&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 2
  },
  {
    &quot;content_ko&quot;: &quot;사과&quot;,
    &quot;content_en&quot;: &quot;apple&quot;,
    &quot;index_answer&quot;: &quot;B&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 2
  },
  {
    &quot;content_ko&quot;: &quot;배&quot;,
    &quot;content_en&quot;: &quot;pear&quot;,
    &quot;index_answer&quot;: &quot;C&quot;,
    &quot;etc&quot;: null,
    &quot;question_number&quot;: 2
  }
 ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 question.json파일과 answer.json파일을 제작하셔서 넣어주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 스터디는 처음 문제데이터가 pdf파일로 준비되어있어서 제가 python으로 급하게 코드를 짜서 json데이터를 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;question은 문제고, answer는 객관식 문제 보기입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qowyg/btsLRoaMOrP/CAkPumJOjqpewTJTy68baK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qowyg/btsLRoaMOrP/CAkPumJOjqpewTJTy68baK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qowyg/btsLRoaMOrP/CAkPumJOjqpewTJTy68baK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqowyg%2FbtsLRoaMOrP%2FCAkPumJOjqpewTJTy68baK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;170&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적절하게 문제데이터를 json파일로 만든 후, setting에서 업로드하셔서 사용하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 한번만 셋팅해놓으면 계속 사용가능하세요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 배포된 acsap어플리케이션은 기본 데이터가 muzzi에 대한 퀴즈로 저장되어있는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;본인이 원하는 문제와 답변 json데이터를 setting에서 한번 입력해주시면 로컬스토리지에 저장되어 우선적으로 사용되기에 무찌문제는 안보이실거에요. 커스텀하실 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;유저 인증기능을 사용하고싶어요&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 배포된 acsap에서는 유저가 기본 tester으로 설정하게 되어있는데요. 이 방식에서도 문제없이 사용가능하시나, 소개영상에서의 유저인증 기능을 원하시면 acsap의 깃허브 코드를 클론하셔서 배포하신 후 사용하시면 됩니다. 다만 백단과 데이터베이스를 필요로 하므로, 데이터베이스구축과 .env 시크릿은 알맞게 하셔야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;다른기기도 병행해서 사용하고싶어요. 키워드가 공유가 안되서 불편합니다!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키워드기능을 다른기기와 병행해서 쓰시고싶으시면 백엔드와 db가 있어야합니다. 때문에 따로 배포를 하시거나 로컬로 배포후 사설네트워크내에서 사용하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구축이 되셨으면 setting에서 두가지 버튼을 누르시면 현재기기의 키워드데이터를 db에 덮어쓰기하고 불러오기 가능합니다. 사실 더욱더 정교하게 하고싶었으나 당시에 교육과정과 자격증 준비를 병행하는중 만든 어플이라 제가 시간이 너무없었습니다 ㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 기능들은 알아서 추가 삭제하시고 사용하시면 됩니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하기 불편하시면, 그냥 로컬스토리지 키워드 데이터 스트링을 복사하신후 원하시는 기기의 로컬스토리지 값을 추가하시면 됩니다 ^^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 어떤 trouble이 있었고 어떻게 해결하셨나요? &lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저비용으로 만든 프로그램이다보니 생긴 트러블인데요. 처음에는 백엔드단에서 바로 question data와, answer데이터를 api로 응답해주는 방식으로 설계했습니다. 하지만 월 5달러짜리 인스턴스이기에 400문항의 데이터를 스트링으로 한번에 넘겨주는데 인스턴스가 계속 폭파되었습니다 ㅠ 그래서 &lt;b&gt;프론트엔드에서 데이터를 등록하는 방식&lt;/b&gt;으로 바꿨습니다. 때문에 setting이라는 메뉴가 따로 생긴겁니다.&lt;/li&gt;
&lt;li&gt;프론트엔드에서 데이터를 입력하는 방식으로 바꿨으나, 초기에는 스트링을 복붙해서 입력하는 형식이었는데요. 말씀드렸듯이 데이터가 워낙 크다보니 붙여넣기 하는데에도 몇십초씩 기다리고 먹통이되어 question, answer데이터로 따로 나눠서 입력하게 바꿨습니다.&lt;/li&gt;
&lt;li&gt;이렇게해도 데이터가 워낙 커서 복붙방식으로는 렉이 많이 걸리더라구요. 그래서&lt;b&gt; json파일자체를 임포트하는 현재 방식으로 최종&lt;/b&gt;적으로 바뀌었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;Conclusion&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;매우 급하게 만든 프로젝트라 모달같은거도 따로 안만들고 alert나 prompt등 브라우저 기본기능을 사용하였어요(진짜 싫어함 ㅋㅋ)&amp;nbsp;&lt;br /&gt;코드도 정리가 잘 안되어있어서 부끄럽네요. 유저인증기능은 나 해킹해줘~정도로 단순합니다 ㅋㅋㅋ&lt;br /&gt;&lt;br /&gt;하지만 acsap는 &lt;b&gt;제가 처음으로 스터디를 하면서 개발을 접목시킨 프로젝트&lt;/b&gt;라 의미가 큽니다ㅎㅎㅎ &lt;br /&gt;스터디원 분들도 전부 활용을 잘 해주셨어요. 때문에 고민없이 프로젝트로 등록을 하게 되었습니다.&lt;br /&gt;&lt;br /&gt;또한 스터디를 진행하면서 팀장으로써 어떤 자세로 팀을 이끌어가야하는지 많이 배운 경험이기도 했었습니다.&lt;br /&gt;&lt;br /&gt;긴 포스팅 읽어주셔서 감사합니다~&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>project/selfProject</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/352</guid>
      <comments>https://jacobowl.tistory.com/352#entry352comment</comments>
      <pubDate>Mon, 20 Jan 2025 03:03:33 +0900</pubDate>
    </item>
    <item>
      <title>공부하는데 내가 가진 철학? 같은거</title>
      <link>https://jacobowl.tistory.com/351</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;예전에는 난 뭐 프로그래밍에 프 자도 몰랐던 시절에 적었던 글인데, 자료를 뒤지다보니까 떠서 포스팅해봄ㅋㅋ&lt;br /&gt;옛날부터 공부는 안하고 철학? 이런게 관심이 많았음.&lt;br /&gt;그래서 보헤미안에 대해서 알게되었었따.&lt;br /&gt;&lt;br /&gt;보헤미안과 브루주아 두가지 사상에 대해서 책을 읽었었는데, 뭐 당연히 타이틀만 봐도 서양철학이다. 이 글은 동양철학중 하나인 장자와 보헤미안을 짬뽕해서 쓴 글이었음.&lt;br /&gt;한 10년전에 적은 글같은데 기억이 정확히는 안난다 ㅋㅋ&lt;br /&gt;&lt;br /&gt;사실 지금까지 코딩을 하는데 진짜 그지같이 지냈다. 누가보기엔 실패한 인생이라고 할거다.. 혼자서 공부하니까 애초에 사람을 안만나기도 했는데, 뭐 그냥 팩트는 사람들은 남의 인생에 관심이없다 ㅋㅋ&lt;br /&gt;암튼 주말 편의점알바를 하면서 한달벌어서 생활비로 쓰고 이런 하루살이? 같은 패턴으로 살았었따.&lt;br /&gt;뭐 보통사람들은 주변사람들을 많이 의식하니까.. 이런게 불행한 삶이라고 생각하겠지만 난 이런 철학에 관심있던 어린시절덕분에 약간 멘탈이 우울하지 않았던것같다. 물론 무찌랑 지내면서 너무 행복하기도 했었음. 코딩도 솔찍히 시간가는줄 모르게 재밋음 ㅋㅋ&lt;br /&gt;&lt;br /&gt;암튼 최근에 인터넷글을 보고 알게됐는데 일론머스크가 사업을 시작할때 썰이라고 봤는데&lt;br /&gt;아버지가 사업을 엄청 반대했단다. 그래서 일론머스크 스스로 딱 몇개월동안 사업하면서 최소한으로 돈을 써보자! 하고 하루 1달러로 지내보는걸 테스트해봤단다. 이렇게 지내는게 도저히 못버티겠으면 사업접자 하고 시작했단다. 하루 1달러니까 오렌지랑 빵 대용량사서 처묵처묵하면서 진행해봤는데 나름 살만해서 사업을 시작했다고 한다. 뭐 구라도 좀 있겠지만 약간 이런 가난하더라도 행복할 수 있는? 그런 개념이 보헤미아이다.&lt;br /&gt;&lt;br /&gt;나도 사실 하루 1달러보다는 훨씬 더 쓰지만 계속 사업하고 코딩하고 집안에 처박혀 지내면서 이 보헤미안 철학이 나름 도움이 된거같음.&amp;nbsp;&lt;br /&gt;그리고 생각보다 인간의 생명력은 질기고 대한민국이 복지가 좋아서 이렇게 존버타는게 나름 할만하다.(사회적으론 개암이긴할테지만.) 근데 사람들이 못버티고 도전도차 하지 않는건 하도 우리 어릴때부터 성공한인생, 패배한인생 ㅈ된인생 이런개념들을 주변에서 귀에 너무 때려박아서 인거같음..&lt;br /&gt;&lt;br /&gt;암튼 나처럼 그지같이 바퀴벌레처럼(취업타이틀을 바퀴벌레 개발자도 생각해봤음 ㅋㅋ) 살면서 도전하는 사람들에게 이런 철학이 있으면 도움이 될것같아서 포스팅해본다.&lt;br /&gt;그리고 내 다른 포스팅들은 전부 초딩이 쓴것같은데 ㅋㅋ 나도 맘먹으면 이런 글 쓸 수 있다는 나름 반전? 같은거 보여주고 싶기도 함 ㅋㅋㅋ&lt;/blockquote&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;시작하면서.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 약 230년 전, 애덤스미스(경제학의 대가)는 &lt;u&gt;&lt;i&gt;'&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;보이지 않는 손&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;'(1) &lt;/i&gt;&lt;/u&gt;의 용어를 통해 현대사회의 시장구조를 제시했다. 생산자가 소비자의 수요를 만족시키기 위해 움직이도록 하는 이 경제론은 자유민주주의 국가에서 개인의 경제활동의 자유를 보장한다는 기본적인 사상이 담겨있음과 동시에 이러한 국가에서 시장구조가 유지될 수 있는 방향성을 제시한다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 이 이론은 이름에서부터 알 수 있듯이 보이지 않는 손, 즉 인간의 욕심이 인간 스스로에게 간접적인 압력을 가한다. 하지만 인간의 욕심의 무한함과 그에 따른 불만족의 구조는 이 개념에서 다루지 못하였고, 사회성을 갖는 동물인 인간에게 이러한 보이지 않는 손에 강요받는 '욕심'과 그 욕심의 실패에 따른 '좌절'은 현대사회에서의 크고 작은 문제로써 대두되었다. 이러한 현대사회의 가시적 성과(문명발달)에 감춰진 현대인들의 심적 불안의 이면은 장자철학이 요즘 들어 주목받는 이유이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 장자는 개인 본인의 수양을 통해 세상사에서 상처받지 않을 수 있음을 제시한다. 필자는 개인적인 견해로써 무기 무용 무공을 '윤리적인 가치관'으로써 사회가 우리에게 강요한다고 생각했다. 하지만 장자는 이러한 개념을 도덕적으로 강요받는 것이 아닌 인간의 '방어체계'로써 세상을 더욱더 현명하게 보고, 다른 측면으론 '자기합리화'의 방향을 찾을 수 있도록 도와준다. 물론 나는 자기합리화가 부정적인 측면만 갖는다고 생각하지 않는다. &lt;u&gt;&lt;i&gt;'&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;정의의 어머니는 자기합리화가 아니라 누가 말할 수 있는가&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;?&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;'(2) &lt;/i&gt;&lt;/u&gt;라는 말도 있듯이 말이다. 심재를 통한 수양, 그로인한 좌망의 경지, 조철, 견독은 비로소 장자철학의 목표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;보헤미아&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 장자철학을 접하며 총괄적으로 얻을 수 있는 답변은 '욕심을 버려라'였다. 욕심은 단순한 물질에 대한 욕심뿐만 아니라 무지, 무공, 무기, 무고금 등 공과 지식, 심지어 자기 자신과 시간까지 잊으라고 말하고 있다. (물론 더욱더 자세하게 보면 우리에게 욕심이란 개념과 이 개념들은 다소 차이가 있을 수 있다. 하지만 본인은 己, 시간 등 또한 인간이 흔히 자신이 가지고 있는 '재산'으로써 세속적인 성격을 띠고 있다고 판단을 하였기 때문에 언급한다.) 장자는 욕심을 버림과 동시에 독자의 인생도 더 이상 불안함과 답답함에서 벗어날 수 있다고 말한다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 필자는 장자철학을 접하면서 과거에 읽었던 &lt;u&gt;&lt;i&gt;알랭드 보통의 '불안'(3) &lt;/i&gt;&lt;/u&gt;이라는 책이 기억났다. 이 책은 본인이 심적으로 불안했던 20살 시절에 자주 가는 대형서점에서 당시의 불안한 마음과 일치했던 책 제목에 홀리듯이 구매 했던 책이다. 이 책에서는 서양철학의 분석적이고 진단하려는 성격을 드러내며 불안에대해 설명하였는데 불안의 원인을 사랑의 결핍, 물질주의, 능력주의, 불확실성 등으로 규정짓고 이에 따른 역사적인 해결방법으로 종교, 예술, 보헤미아 철학 등을 예로 들었다. 이중 본인인 가장 주목했던 부분은 &lt;u&gt;&lt;i&gt;'보헤미아'(4)&lt;/i&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Byzkt/btsLHmp0hbD/gVHGmU50f6xFKc0HvIjoy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Byzkt/btsLHmp0hbD/gVHGmU50f6xFKc0HvIjoy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Byzkt/btsLHmp0hbD/gVHGmU50f6xFKc0HvIjoy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FByzkt%2FbtsLHmp0hbD%2FgVHGmU50f6xFKc0HvIjoy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;152&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; 보헤미아는 세속적인 것들에 개의치 않고 자유분방하게 사는 사람들을 칭한다. 이들은 가장 최소한으로 필요로 하는 욕구만 충당시킬 뿐, 그 이상의 인간의 저장본능(초과한 욕심)을 철저히 거부한다. 이들은 &lt;u&gt;&lt;i&gt;브루주아(5)&lt;/i&gt;&lt;/u&gt;의 개념과 반대성향을 띈다. (브루주아는 현대사회에서 가장 모범적인 모델이 되는 보헤미아와 상반되는 개념이다. )&lt;br /&gt;&amp;nbsp; &amp;nbsp; 이는 장자철학의 '외물','무용'과 상당히 유사한 개념을 갖는다. 이 책에서는 &lt;u&gt;&lt;i&gt;'약 30달러로 집짓기'(6) &lt;/i&gt;&lt;/u&gt;등 다소 현실적으로 허무맹랑한 내용들을 소개하였는데 이러한 부분은 우리 인간의 삶의 최소욕구가 사실 너무 과장되어 있다는 것을 설명하고 싶었던 것 같다. 물론 이 글에 다 적지는 못하지만 극단적 보헤미안들의 사례들이 많았다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 필자는 상당한 불안함에 묻혀 허우적거릴 때 쯤, 이 책을 접했다. 물론 이 책에서 언급한 불안의 원인 부분이 내 불안에 담겨 있었겠지만 보헤미아 철학은 이 모든 것들을 아울렀고 본인은 부분적 보헤미안으로써 삶을 살고 있다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 장자철학 또한 이러한 보헤미아 철학과 유사하다. 보헤미안들은 단순히 물질적인 욕망을 무시하는 것뿐만 아니라 숲에서 술과 유희, 유락을 즐긴다. 책에서는 &lt;u&gt;&lt;i&gt;보헤미안들이 나체로 자유롭게 포도주를 마시는 그림(7)&lt;/i&gt;&lt;/u&gt;이 삽화되어있다. 그들은 가난하게 지내며 다양한 창작활동을 겸한다. 그들에게 대비해야할 미래는 너무나 가까이 있는 미래뿐이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 이러한 특성들은 장자의 삶이 가난했지만 자유롭게 글을 쓰던 모습과 자연스럽게 일치했다. 장자철학과 보헤미아는 모두 그들이 게으르다는 것을 의미하지 않는다. 누군가는 이러한 철학을 가지며 사는 사람들을 게으르고 발전 없는 사람으로 따가운 시선을 보낼지 모르겠으나, 게으름과 이러한 철학들은 차이가 있다. 장자는 대붕의 우화처럼 끊임없이 시련을 극복하는 모델을 이상적으로 삼았고, 보헤미아 또한 그들은 마냥 노는 것이 아닌 창작활동을 겸하는 경우가 많다. 그들은 세속적인 욕심을 이상점을 향하는 길에서의 원료로 사용하지 않는다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 또한 욕심을 버린다는 것은 단순히 자기반성적인 성격을 띠지 않는다. 글의 초반에서도 언급했듯이 이 욕심은 사회에서 나에게 가지도록 강요한 욕심이기 때문이다. 본인이 장자철학을 접하며 느낀 것은 장자는 이러한 세속적인 사회를 비웃는 듯이 우화를 써내려갔지만 그는 이러한 욕심을 갖는 시발점을 비웃지는 않는다. 때문에 그는 끝없이 심재하며, 좌망의 경지로 다가갈 수 있도록 수양하는 것을 가르쳐왔다. 어떻게 보면 이것은 장자, 그 또한 이러한 세속적인 욕심을 가졌던 시발점을 가졌었기 때문이 아닐까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AsHrO/btsLHzJtG7X/JwaO97IeOfQb0s76B9m9m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AsHrO/btsLHzJtG7X/JwaO97IeOfQb0s76B9m9m1/img.png&quot; data-alt=&quot;(6) Alain De Botton, 정영목 옮김 『Status Anxiety』, 「BOHEMIA」, 은행나무, 2011, p275 28.12달러로 집짓기.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AsHrO/btsLHzJtG7X/JwaO97IeOfQb0s76B9m9m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAsHrO%2FbtsLHzJtG7X%2FJwaO97IeOfQb0s76B9m9m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;347&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(6) Alain De Botton, 정영목 옮김 『Status Anxiety』, 「BOHEMIA」, 은행나무, 2011, p275 28.12달러로 집짓기.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x4mDm/btsLHnJdC63/LfTFYhVfVtfD66tk5uNSk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x4mDm/btsLHnJdC63/LfTFYhVfVtfD66tk5uNSk0/img.png&quot; data-alt=&quot;(7) Picnic:Nusch and Paul Eluard,Lee Miller, Man Ray, and Ady Fidelin &amp;amp;Icirc;le Sainte-Marguerite,Cannes,France,1937. photo by Roland Penrose [see also:] via Поль Элюар -알랭드 보통 『Status Anxiet y』,에 삽화된 사진이다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x4mDm/btsLHnJdC63/LfTFYhVfVtfD66tk5uNSk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx4mDm%2FbtsLHnJdC63%2FLfTFYhVfVtfD66tk5uNSk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;471&quot; height=&quot;337&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(7) Picnic:Nusch and Paul Eluard,Lee Miller, Man Ray, and Ady Fidelin &amp;Icirc;le Sainte-Marguerite,Cannes,France,1937. photo by Roland Penrose [see also:] via Поль Элюар -알랭드 보통 『Status Anxiet y』,에 삽화된 사진이다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi5Ir6/btsLGPsJZaN/KdOQFkhdHA5KfFTD9bPbG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi5Ir6/btsLGPsJZaN/KdOQFkhdHA5KfFTD9bPbG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi5Ir6/btsLGPsJZaN/KdOQFkhdHA5KfFTD9bPbG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi5Ir6%2FbtsLGPsJZaN%2FKdOQFkhdHA5KfFTD9bPbG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;70&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;70&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;천균&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 중학교 1학년 당시, 본인은 [설득하는 글쓰기]라는 국어 수업을 학교에서 받은 경험이 있다. 이 당시에 어떤 토론주제에 대해서 개인의 생각을 주장, 설득하는 글을 쓰는 것이었는데, 대게는 이 주제에 대해서 찬성과 반대파가 나뉘었었다. 하지만 본인은 이 글 쓰기 당시 찬성과 반대하는 의견들을 서로 중용하여 중간점을 찾으려고 노력했었다. 그리고 이 완성후 글을 제출한 나는 낮은 점수를 받았었다. 궁금한 마음에 선생님께 왜 점수가 이렇게 낮은지에 대하여 이의를 제기했었는데 선생님의 대답은 &amp;ldquo;찬성과 반대중 하나를 골라야지 양측 의견을 반반씩 수용하면 설득력이 떨어진다.&amp;rdquo;였다. 본인은 그래도 이것은 해결책이 될 수 있고 양측이 서로 양보하면 가능한 방법이 아니냐고 반박하였으나 선생님은 끝내 내 이의제기를 받아들이지 않으셨다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 이러한 경우는 크고 작은 사회에서 빈번히 발생하는 경우이다. 본인의 위치에서 반대파에게 조금이라도 양보하여 중용책을 제시하면 손해를 보게 된다. 때문에 사람들은 본인의 주장에서 절대 작은 부분 또한 양보하지 않으며 대립구도를 결성하는 것이 보통의 사회현상이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 장자는 &quot;천예에 의해 조화시키고 만연에 맡기라.&quot; 라고 하였다. 그는 완벽한 옳고 그름은 없다고 말한다. 또한 장자는 원숭이 이야기(조삼모사)와 황희와 머슴의 이야기에서 얘기하듯이 '천균', 즉 양가적 입장을 설명한다. 이는 이분법적 사고를 타파하여 상대도 옳고 나도 옳다는 장자철학의 개념인데 현대인들의 이분법적인 흑백논리에 빠진 상황에 대한 방향을 제시한다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 예시로써 법원의 &lt;u&gt;&lt;i&gt;국&lt;/i&gt;&lt;/u&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, Malgun Gothic, 맑은 고딕, dotum, 돋움, sans-serif;&quot;&gt;&lt;u&gt;&lt;i&gt;민참여재판(8)&lt;/i&gt;&lt;/u&gt;&lt;/span&gt;의 경우 제 3자의 객관적인 판단을 최종판결에 참고로써 사용한다. 피의자와 피해자, 죄의 유무와 경중을 최종판단하는 법원의 역할이 최대한 객관적이기 위해 도입한 제도가 아닌가? &lt;br /&gt;&amp;nbsp; &amp;nbsp; 배심원들과 판사는 최대한 객관적으로 '도추'의 자리에 서야한다. 때문에 배심원들은 무작위선정으로써 사회각기분야의 사람들을 초빙하는데 이는 그들에게 편견, 즉 성심의 영향을 최소화하기 위함이며 다수결의 원칙을 따르는 것 또한 혹시 모르는 편견의 역할을 최소화하기 위함이다. 도추의 자리에 서있는 자에게 흑백논리주장을 강요해서는 안 된다. 자신의 주장만 강요함으로써 해결책 없이 토론만 지속되거나, 누군가 더욱더 자극적으로 토론했느냐가 다수결 판단의 지시등이 되어 상대방의 의견을 묵살해버리는 것이 과연 옳은 것일까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkhY7P/btsLGQkUpiF/o1eNrqYXB9WPRSsTY5CyyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkhY7P/btsLGQkUpiF/o1eNrqYXB9WPRSsTY5CyyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkhY7P/btsLGQkUpiF/o1eNrqYXB9WPRSsTY5CyyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkhY7P%2FbtsLGQkUpiF%2Fo1eNrqYXB9WPRSsTY5CyyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;126&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;죽음에 대한 태도&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 장자의 죽음에 대한 태도는 초연하다. 보통의 죽음에 초연한 사람들에게 드러나는 종교적 성격도 띄지 않았다. 철학의 무게가 그를 초연하게 만든 것일까? 장자는 죽음을 단순히 기가 흩어지고 모이는 현상으로써 설명하고, 왜 누구도 경험하지 못 한 죽음을 우리는 두려워 하고 슬퍼하는가 의문을 던진다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 죽음은 인간에게 필사적으로(필사적이라는 말을 쓰는 것도 우습다.), 또는 본능적으로 피하려고 하는 대상이다. 하지만 죽음은 우리가 언젠가 마주칠 대상이며 인간의 노력으로써 변화시키는 것은 죽음과 만남의 시각밖에 없을 뿐이다. 장자의 '명'에 따른 안명론의 측면으로 보면 이것 또한 모순이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; 죽음에 대한 글을 쓰기에 앞서 필자는 죽음후의 세계를 두려워하는 사람들에게 앞으로 설명할 이 가설을 설명하고 싶다. 본인은 죽음에 대한 생각을 해 본적이 있다. 사실 이 가설의 시발점은 죽음과 관련이 없는 것이었고, 물리학도로써 시간에 대한 개념을 중요시 여기는 성격 때문에 수면과 시간을 연관 지어 생각해 본 적이 있다. 다소 철학적인 부분이 될 수도 있지만 본인은 최대한 현실적으로 가능한 개념을 도입했었다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 누구나 수면을 했을 때 아주 긴 시간을 경험했지만 현실은 짧은 시간이 흘러갔었고, 반대로 아주 짧은 시간을 꿈속에서 흘러 보냈는데 현실의 시간은 배로 흘러간 경험들이 있을 것이다. 이러한 꿈을 통한 시간의 조정은 &lt;u&gt;&lt;i&gt;&amp;lsquo;&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;나의 눈&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;&amp;lsquo;(9)&lt;/i&gt;&lt;/u&gt;의 개념과 관련 있다. 만약 인간이 수동적으로 꿈의 시간을 수동적으로 조절할 수 있다면, 현실의 시간을 절약할 수 있을 것이고 이것은 제 n차 과학혁명일 것이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 본인은 역으로 이러한 생각에서, 혹시 우리의 현실 세계가 꿈이 아닐까 하는 생각을 한 적이 있다. 우리는 모두 꿈을 꾸고 있는 것이며, 그 꿈의 세계를 공유하고 있다. 이는 장자의 호접몽과도 비슷한 개념을 갖는다. 또한 시간조절의 개념은 포함되지 않지만 이와 비슷한 개념은 영화 매트릭스의 &lt;u&gt;&lt;i&gt;'&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;매트릭스 세계&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;'(10)&lt;/i&gt;&lt;/u&gt;이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 이러한 긍정적인 상상으로 미루어 암아 죽음은 결코 두려워 할 필요가 없다. 본인은 죽음이후의 인식이 비과학적인 이론으로써밖에 설명될 수밖에 없다는 인식을 지적한다. 죽음이후 상황의 모든 이론들이 누군가에겐 비현실적인 이론으로써 설명될 수밖에 없으며, 과학적인 죽음은 과학적으로 無가 됨을 주장하는 이론에 반론을 들고 싶었다. 따라서 우리는 현실적으로나 비현실적으로나 죽음이후의 세계를 알 수 없다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; 열심히 설명한 것과는 무색하게 장자철학에서 죽음 후 사후세계가 어떠한 모습인지는 중요하지 않다. 장자에게 죽음은 우리에게 있어 흘러가는 사건일 뿐이다. 죽음과 그 후의 사후세계를 본능적인 두려움으로써 겁낼 필요는 없을 것이다. 장자가 죽음을 두려워하지 않는 가치관은 불확실성이 꼭 두려움과 비극, 슬픔과 연결되지는 않는다는 것을 설명한다. 필자 또한 죽음이 어떤 모습으로 본인 앞에 나타날지 모르고 아직 죽음과의 만남은 먼 훗날의 상황이라 생각하기 때문에 두렵지 않은 것일 수도 있으나, 현재로썬 죽음에 대해 장자철학에서 설명하는 태도와 유사한 태도를 갖고 있다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 죽음과 마주칠 때, 무한한 두려움과 공포에 빠질 것인가, &lt;u&gt;&lt;i&gt;파블로 피카소&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;(Pablo Picasso)(11)&lt;/i&gt;&lt;/u&gt;처럼 환영할 것인가가 중요한 것이 아니라, 우리에게 '죽음' 그 자체가 지나간다는 것이 중요하지 않을까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ndmkM/btsLG2rQF0E/aXAyzDKDcb4qeDmzEV0DI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ndmkM/btsLG2rQF0E/aXAyzDKDcb4qeDmzEV0DI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ndmkM/btsLG2rQF0E/aXAyzDKDcb4qeDmzEV0DI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FndmkM%2FbtsLG2rQF0E%2FaXAyzDKDcb4qeDmzEV0DI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;616&quot; height=&quot;146&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;&lt;b&gt;&quot;역사에 if는 없다.&quot;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 장자는 공자와 맹자의 천명이라는 개념과 다르게 '명'의 개념을 사용하였다. 자신의 힘으로 바꿀 수 없는 세상의 흐름에 자신을 맡기고 편안히 머무른다는 '안명론'이다. 이는 숙명적인, 즉 운명이 정해져있다는 개념과는 다소 차이가 있다. 장자는 피할 수 없는 '명'에 의해 고통 받지 말고 받아들이는 자세를 권유한다. 또한 이는 단지 현재의 상황에 대한 장자철학으로 비춰질 수 있으나 이는 과거와 미래, 즉 삶의 전체에서 상통하는 개념이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 부제목 &lt;u&gt;&lt;i&gt;&quot;&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;역사에 &lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;if&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;는 없다&lt;/i&gt;&lt;/u&gt;&lt;u&gt;&lt;i&gt;.&quot;(12)&lt;/i&gt;&lt;/u&gt;는 역사학자 ＥＨ카의 발언이다. 이 발언은 역사는 이미 지난 것이며, 그것은 우리의 힘으로 바꿀 수 없으며 이미 지난 역사에 가정을 더해 현실에 좌절할 필요가 없다는 의미이다. 이는 지난 역사에서 배울 점을 찾지 말라는 뜻은 아니다. 단지 지난 과거에 대해 여러 가정을 개입시켜 한탄하는 역사학자들을 비꼬기 위한 발언이었다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 더하여 개인의 경험으로 봤을 때, 필자 또한 이러한 경우를 많이 겪었다. 중요한 시험을 앞두고 아프게 되어서 정말 열심히 준비한 시험을 망친 일, 힘들게 모았던 돈이 하루아침 실수로 사라진 일등, 여러 좌절을 부르는 사건사고를 겪은 적이 많았고 앞으로도 겪을 것이다. 하지만 이러한 사건들에 대해, 나의 힘으로 어쩔 수 없는, 없었던 일들에 대해 지속적인 고민을 하면 무슨 소용이 있을까? 나의 부모님의 문제, 나의 건강문제, 나의 우연히 마주쳤던 수많은 불행들 등, 많은 현재의 사건에 영향을 주는 피할 수 없던 일들. 이러한 문제들은 나를 낙담시킨 적도 많았으나 이러한 낙담에 파묻혀 지냈다면 현재의 나는 있을 수가 없었을 것이다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 현재 대한민국의 시국 또한 그렇다. 현재의 정세에 슬퍼하며, 과거에 가정을 삽입하며 아쉬워하는 국민들이 상당히 많다. 하지만 이미 지난 일은 역사가 되었고 이러한 사건을 과거로 돌아가서 슬퍼할 필요는 없는 것이다. 이 지나간 비극은 (신이 있다면)신을 제외한 누군가도 바꿀 수 없다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 이미 버스는 지나갔다. 지나간 버스를 향해 욕을 하든, 발길질을 하든 무슨 소용이 있겠는가.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/demGFx/btsLHQjSIQZ/burqpf6bdTSR0iB88qQ3F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/demGFx/btsLHQjSIQZ/burqpf6bdTSR0iB88qQ3F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/demGFx/btsLHQjSIQZ/burqpf6bdTSR0iB88qQ3F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdemGFx%2FbtsLHQjSIQZ%2Fburqpf6bdTSR0iB88qQ3F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;16&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;16&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJSW0O/btsLG01RmQm/WlPjoDhC6MWdkEQypBNCt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJSW0O/btsLG01RmQm/WlPjoDhC6MWdkEQypBNCt1/img.png&quot; data-alt=&quot;풀밭 위의 점심 식사 [Le D&amp;amp;eacute;jeuner sur l'herbe]- 오르세 미술관 직접 촬영 사진 / 화면 전경에 옷을 입지 않은 상태로 그려진 여성은 신화에 등장하는 여신이나 님프가 아니라 동시대 여성인 빅토린 뫼랑(Victorine Louise Meurent, 1844-1927)이라는 것을 당시 관람자들은 불편해했고, 이 여성이 옷을 잘 갖춰 입은 부르주아 남성들-이들 역시 실존 인물들을 모델로 했다-과 함께 있는 것으로 묘사된 것에서는 부르주아의 위선을 지적당하는 것 같은 당혹감을 느꼈다. -네이버 지식백과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJSW0O/btsLG01RmQm/WlPjoDhC6MWdkEQypBNCt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJSW0O%2FbtsLG01RmQm%2FWlPjoDhC6MWdkEQypBNCt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;304&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;풀밭 위의 점심 식사 [Le D&amp;eacute;jeuner sur l'herbe]- 오르세 미술관 직접 촬영 사진 / 화면 전경에 옷을 입지 않은 상태로 그려진 여성은 신화에 등장하는 여신이나 님프가 아니라 동시대 여성인 빅토린 뫼랑(Victorine Louise Meurent, 1844-1927)이라는 것을 당시 관람자들은 불편해했고, 이 여성이 옷을 잘 갖춰 입은 부르주아 남성들-이들 역시 실존 인물들을 모델로 했다-과 함께 있는 것으로 묘사된 것에서는 부르주아의 위선을 지적당하는 것 같은 당혹감을 느꼈다. -네이버 지식백과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고문헌 외 자료&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adam Smith&amp;nbsp;지음,&amp;nbsp;『An Inquiry into the Nature and Causes of the Wealth of Nations』,1776&lt;br /&gt;Tr Try&amp;nbsp;지음,&amp;nbsp;『정의』, 2008&lt;br /&gt;Alain De Botton&amp;nbsp;지음,&amp;nbsp;정영목 옮김&amp;nbsp;『Status Anxiety』,&amp;nbsp;은행나무, 2011&lt;br /&gt;Tr Try&amp;nbsp;지음,&amp;nbsp;『Energy direction』, 2008&lt;br /&gt;Keanu Reeves&amp;nbsp;감독,&amp;nbsp;『The Matrix』, 1999&lt;br /&gt;Edward Hallett Carr,&amp;nbsp;역사학자,&amp;nbsp;『역사란 무엇인가』&lt;br /&gt;보헤미아,&amp;nbsp;부르주아,&amp;nbsp;국민참여재판&amp;nbsp;-네이버 지식백과&lt;/p&gt;</description>
      <category>personal/ponderings</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/351</guid>
      <comments>https://jacobowl.tistory.com/351#entry351comment</comments>
      <pubDate>Wed, 8 Jan 2025 23:15:47 +0900</pubDate>
    </item>
    <item>
      <title>git 활용 step 3rd-#2 / collaborator로 협업하기</title>
      <link>https://jacobowl.tistory.com/350</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introduction&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;이번에는 collaborator로 협업하기 포스팅을 해보겠다.&lt;br /&gt;협업하기 포스팅 fork에서는 각자의 깃허브 계정에 레포지토리를 fork로 복제해와서 pull request를 날리는 방식으로 협업을 했지만, collaborator는 한 레포지토리를 가지고 여러 팀원이 협업하는 방식이다.&lt;br /&gt;&lt;br /&gt;때문에 fork보다 더욱더 직관적이고 이해하기는 더 쉬울듯?&lt;br /&gt;암튼 할말 없어서 바로 시작해봄&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFwp4F/btsLHpeQqtN/KSKwJkBzp6Fk2v11aPRSi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFwp4F/btsLHpeQqtN/KSKwJkBzp6Fk2v11aPRSi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFwp4F/btsLHpeQqtN/KSKwJkBzp6Fk2v11aPRSi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFwp4F%2FbtsLHpeQqtN%2FKSKwJkBzp6Fk2v11aPRSi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;893&quot; height=&quot;540&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 fork로 협업하기 포스팅처럼 이렇게 환경구성을 헀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 각자의 컴퓨터에서 협업을 하는 그림이기 때문에 무찌와 도리 모두 컴퓨터가 존재하다는 상황을 만들기위해 우분투 이미지로 VM을 팠고 각자의 github의 계정으로 로컬상에 로그인을 해둔 상태임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;collaborator로 협업하기는 어떤 구조야?&lt;/span&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beO25X/btsLFKExhRP/34t5EdGOBKbsjRBXCQ1B40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beO25X/btsLFKExhRP/34t5EdGOBKbsjRBXCQ1B40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beO25X/btsLFKExhRP/34t5EdGOBKbsjRBXCQ1B40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeO25X%2FbtsLFKExhRP%2F34t5EdGOBKbsjRBXCQ1B40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1069&quot; height=&quot;692&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통은 팀장이 레포지토리를 하나 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 각 멤버들은 해당 코드를 가지고 코딩을 한 후, push를 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public레포지토리라도 본인 계정이 아니면 push권한은 없기때문에 push를 못하지만, collaborator로 멤버들을 초대하면, 멤버들은 해당 권한을 얻게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 fork로 협업하기에서 private레포지토리를 fork해가기위해 강아지 개발자들을 collaborator로 초대한것도 같은맥락임..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해보자&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5Bms2/btsLHCdVwtk/vrlARVjsnBusbSvET8hVs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5Bms2/btsLHCdVwtk/vrlARVjsnBusbSvET8hVs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5Bms2/btsLHCdVwtk/vrlARVjsnBusbSvET8hVs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5Bms2%2FbtsLHCdVwtk%2FvrlARVjsnBusbSvET8hVs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;842&quot; height=&quot;307&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 팀장이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 할 레포지토리를 colla-puppy-project라는 이름으로 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 강아지 개발자들을 협력자로 초대하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOshcE/btsLG7ef8eR/Cd7mYlYuePGx2kNTDi9VZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOshcE/btsLG7ef8eR/Cd7mYlYuePGx2kNTDi9VZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOshcE/btsLG7ef8eR/Cd7mYlYuePGx2kNTDi9VZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOshcE%2FbtsLG7ef8eR%2FCd7mYlYuePGx2kNTDi9VZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1164&quot; height=&quot;693&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setting탭을 누르고 collaborators라는 탭을 누른다. 그후 add people클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egJwYP/btsLG6GpWX4/dTuVFat0MUyrsta6KLFj4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egJwYP/btsLG6GpWX4/dTuVFat0MUyrsta6KLFj4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egJwYP/btsLG6GpWX4/dTuVFat0MUyrsta6KLFj4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegJwYP%2FbtsLG6GpWX4%2FdTuVFat0MUyrsta6KLFj4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;308&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;muzziworker를 검색해서 초대하자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eBjz6r/btsLF0f1Cit/kDTXPM0dhi9Z9nobmX4C2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eBjz6r/btsLF0f1Cit/kDTXPM0dhi9Z9nobmX4C2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eBjz6r/btsLF0f1Cit/kDTXPM0dhi9Z9nobmX4C2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeBjz6r%2FbtsLF0f1Cit%2FkDTXPM0dhi9Z9nobmX4C2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;261&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌에게 초대장을 보냈다. 현제 초대가 pending상태라고 떠있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCZsaZ/btsLGdTCdZD/zGjOtIaWep3seY67toiMfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCZsaZ/btsLGdTCdZD/zGjOtIaWep3seY67toiMfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCZsaZ/btsLGdTCdZD/zGjOtIaWep3seY67toiMfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCZsaZ%2FbtsLGdTCdZD%2FzGjOtIaWep3seY67toiMfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;945&quot; height=&quot;307&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 무찌의 시점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브에 가니까 메세지가 와있다. 그럼 초대장이 와있는걸 확인가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKKH2l/btsLHM8wZPE/QLwdlY9B9KMFypfPWfFJC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKKH2l/btsLHM8wZPE/QLwdlY9B9KMFypfPWfFJC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKKH2l/btsLHM8wZPE/QLwdlY9B9KMFypfPWfFJC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKKH2l%2FbtsLHM8wZPE%2FQLwdlY9B9KMFypfPWfFJC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;482&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님이 초대를 줬다. 수락하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 테스트를 해볼까?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nJhU2/btsLE2eAPjk/ZuNn6FPNOgmbpRyV0Wymw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nJhU2/btsLE2eAPjk/ZuNn6FPNOgmbpRyV0Wymw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nJhU2/btsLE2eAPjk/ZuNn6FPNOgmbpRyV0Wymw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnJhU2%2FbtsLE2eAPjk%2FZuNn6FPNOgmbpRyV0Wymw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;305&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌 컴퓨터에서 팀장님 레포지토리를 clone했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 받아온걸 확인함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 clone은 퍼블릭 레포지토리면 누구나 가능하기때문에 이건 중요한게 아니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kYLq6/btsLFQxPK8o/S3V5ZhBURjF2ItAW2j1T2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kYLq6/btsLFQxPK8o/S3V5ZhBURjF2ItAW2j1T2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kYLq6/btsLFQxPK8o/S3V5ZhBURjF2ItAW2j1T2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkYLq6%2FbtsLFQxPK8o%2FS3V5ZhBURjF2ItAW2j1T2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;380&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌는 직접 app.js파일을 수정했다. bowwow라는 코드를 추가하고 remote에 추가된 팀장님 레포지토리주소에 commit후 push했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push가 무사히 이뤄진걸 확인함.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OmjBj/btsLGOfahE2/H1LU50OkIw1hmgNqePx30k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OmjBj/btsLGOfahE2/H1LU50OkIw1hmgNqePx30k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OmjBj/btsLGOfahE2/H1LU50OkIw1hmgNqePx30k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOmjBj%2FbtsLGOfahE2%2FH1LU50OkIw1hmgNqePx30k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;925&quot; height=&quot;374&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 팀장님의 레포지토리에 main브랜치로 직접적으로 push가 되었고 무찌가 커밋한 내용이 그대로 업데이트가 되었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 collaborator로 무찌가 초대가 안되었다면 상상도 못할일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 한 레포지토리에 각 개발자가 접근권한이 생기고 코드를 업데이트할 수 있는게 바로 collaborator협업방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;현재 코드 최신상태 업데이트하기&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNgtoc/btsLFwmdAVl/b1UtkaP6akkMzSyT6yJ43K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNgtoc/btsLFwmdAVl/b1UtkaP6akkMzSyT6yJ43K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNgtoc/btsLFwmdAVl/b1UtkaP6akkMzSyT6yJ43K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNgtoc%2FbtsLFwmdAVl%2Fb1UtkaP6akkMzSyT6yJ43K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;672&quot; height=&quot;140&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 팀장 nurd worker의 시점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌가 이미 push를 한 상태이지만 팀장의 컴퓨터에서 해당 프로젝트 디렉토리는 무찌가 commit한 코드가 업데이트가 안된상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴때 업데이트를 하기 위해선 pull을 하면 된다&lt;/p&gt;
&lt;pre id=&quot;code_1736256531759&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git pull &amp;lt;레포지토리주소&amp;gt; &amp;lt;브랜치&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ADNc5/btsLG0flJGj/rSxqBwRA9sNzZTwFZF1MH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ADNc5/btsLG0flJGj/rSxqBwRA9sNzZTwFZF1MH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ADNc5/btsLG0flJGj/rSxqBwRA9sNzZTwFZF1MH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FADNc5%2FbtsLG0flJGj%2FrSxqBwRA9sNzZTwFZF1MH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;110&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lDX5M/btsLG1FjnxF/oJW96Q0H5vbFLUSb3fWul0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lDX5M/btsLG1FjnxF/oJW96Q0H5vbFLUSb3fWul0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lDX5M/btsLG1FjnxF/oJW96Q0H5vbFLUSb3fWul0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlDX5M%2FbtsLG1FjnxF%2FoJW96Q0H5vbFLUSb3fWul0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;425&quot; height=&quot;93&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 pull을 해오면 해당 레포지토리의 해당 브랜치상태가 업데이트 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 자체가 전체적으로 공유되니까 사실 설명할게 별로 없는거같음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;무찌가 왜 main브랜치로 push하는데!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌는 아주 건방지기 때문에 팀장만이 다뤄야하는 main브랜치에 계속 push를 하고 있다. 이렇때 어떻게 제제를 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레포지토리 admin을 제외한 나머지 collaborators들은 push를 할 수 없는 branch룰을 만들면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biS5Ga/btsLHrjg4vs/M9zMeii28Z9jZ0y3GioXYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biS5Ga/btsLHrjg4vs/M9zMeii28Z9jZ0y3GioXYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biS5Ga/btsLHrjg4vs/M9zMeii28Z9jZ0y3GioXYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiS5Ga%2FbtsLHrjg4vs%2FM9zMeii28Z9jZ0y3GioXYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;379&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장은 해당 레포지토리의 setting을 들어가서 branches에서 add branch ruleset버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckeCIN/btsLG16mreV/zfoxrH9RhxWZ96kWkm39E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckeCIN/btsLG16mreV/zfoxrH9RhxWZ96kWkm39E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckeCIN/btsLG16mreV/zfoxrH9RhxWZ96kWkm39E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckeCIN%2FbtsLG16mreV%2FzfoxrH9RhxWZ96kWkm39E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;708&quot; height=&quot;203&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 룰 이름을 정하자. 무찌를 막기위해 muzzi-stop이라는 이름으로 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 enforcement status를 active로 활성화해주자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b86ubZ/btsLHL2R9mg/gDCDJBtPM42NVKt0gq0jCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b86ubZ/btsLHL2R9mg/gDCDJBtPM42NVKt0gq0jCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b86ubZ/btsLHL2R9mg/gDCDJBtPM42NVKt0gq0jCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb86ubZ%2FbtsLHL2R9mg%2FgDCDJBtPM42NVKt0gq0jCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;269&quot; data-filename=&quot;edited_blob&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 add bypass버튼을 눌러서 repository admin을 선택한다. 그럼 role이 추가가 될거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 이 룰을 제한하지 않는 사용자? 방법같은 조건을 설정하는것같음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repository admin을 선택한건 이 룰이 admin에게는 적용이 안된다는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main브랜치에 push할 수 있는건 이 레포지토리 주인인 nurd worker뿐이라는 뜻임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckKi7F/btsLHSAQ79r/4YjzrcSgmzDl0PsJ3nfDnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckKi7F/btsLHSAQ79r/4YjzrcSgmzDl0PsJ3nfDnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckKi7F/btsLHSAQ79r/4YjzrcSgmzDl0PsJ3nfDnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckKi7F%2FbtsLHSAQ79r%2F4YjzrcSgmzDl0PsJ3nfDnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;403&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크롤을 내려서 target branch를 선택하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌가 main브랜치로 계속 push하므로 main브랜치에 이 룰을 적용한다는것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;include by pattern버튼을 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/42WEf/btsLFJeuWWn/rPMbsBmd498cx0h7ZjOvWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/42WEf/btsLFJeuWWn/rPMbsBmd498cx0h7ZjOvWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/42WEf/btsLFJeuWWn/rPMbsBmd498cx0h7ZjOvWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F42WEf%2FbtsLFJeuWWn%2FrPMbsBmd498cx0h7ZjOvWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;286&quot; height=&quot;245&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main브랜치를 적어주고 add inclusion pattern버튼을 클릭.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 패턴으로 했어서 조건식같이 적을수있다. 사진에 example이 나와있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 dori라는 글자가 들어간 모든 브랜치에 push를 못하게 하려면 *dori*라는 패턴식을 입력해주면됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diibP5/btsLFyYB3ld/bQrsbKrDPy31CPUxgaK641/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diibP5/btsLFyYB3ld/bQrsbKrDPy31CPUxgaK641/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diibP5/btsLFyYB3ld/bQrsbKrDPy31CPUxgaK641/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiibP5%2FbtsLFyYB3ld%2FbQrsbKrDPy31CPUxgaK641%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;853&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 룰을 정해주는데 push하지말라는거니까 update를 못하게 금지하면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 저거 하고&amp;nbsp; 젤 아래 create 버튼 클릭하샘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 테스트해보자&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3Ob6J/btsLFyEk8N1/EyDhvYFj98HKyDPpuP8vMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3Ob6J/btsLFyEk8N1/EyDhvYFj98HKyDPpuP8vMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3Ob6J/btsLFyEk8N1/EyDhvYFj98HKyDPpuP8vMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3Ob6J%2FbtsLFyEk8N1%2FEyDhvYFj98HKyDPpuP8vMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;109&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 팀장이 test rule이라는 코드를 작성 한후, push를 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/therH/btsLG6fmMuj/qsG1WEEPJgAB967TgsaKnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/therH/btsLG6fmMuj/qsG1WEEPJgAB967TgsaKnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/therH/btsLG6fmMuj/qsG1WEEPJgAB967TgsaKnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtherH%2FbtsLG6fmMuj%2FqsG1WEEPJgAB967TgsaKnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;373&quot; height=&quot;205&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 push 된걸 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 무찌컴퓨터에서 push를 해보면?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I5RHj/btsLG2jUC1P/nxO6fJkqK2Z9b6y0HOHyo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I5RHj/btsLG2jUC1P/nxO6fJkqK2Z9b6y0HOHyo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I5RHj/btsLG2jUC1P/nxO6fJkqK2Z9b6y0HOHyo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI5RHj%2FbtsLG2jUC1P%2FnxO6fJkqK2Z9b6y0HOHyo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;335&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌는 main브랜치로 push하는게 금지가 되어버렸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nixwT/btsLFLDqBzC/ftGpcjOkc92UcczCyrEvL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nixwT/btsLFLDqBzC/ftGpcjOkc92UcczCyrEvL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nixwT/btsLFLDqBzC/ftGpcjOkc92UcczCyrEvL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnixwT%2FbtsLFLDqBzC%2FftGpcjOkc92UcczCyrEvL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;665&quot; height=&quot;232&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인을 위해 muzzi-dev라는 브랜치를 만들어서 push를 해봤는데 이건 잘 되는걸 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 팀장은 제한을 할 수 있는거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;pull request사용하기&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 fork로 협업할때만 pull request를 사용하는줄 알았는데 collaborator로 협업할때도 pull request를 사용할수 있더라?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해볼까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 상황에서 현재 muzzi-dev라는 브랜치에서 무찌가 코드를 업데이트 후, push를 해놨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치룰을 또만들어보자~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eLHowY/btsLGbaA1Ag/rL1o2kcY1kRtu8KxfvrN1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eLHowY/btsLGbaA1Ag/rL1o2kcY1kRtu8KxfvrN1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eLHowY/btsLGbaA1Ag/rL1o2kcY1kRtu8KxfvrN1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeLHowY%2FbtsLGbaA1Ag%2FrL1o2kcY1kRtu8KxfvrN1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1005&quot; height=&quot;471&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장이 새로운 룰셋을 만들자. 이름은 걍 한글로 풀리퀘스트룰이라고 만들음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 muzzi stop룰은 삭제해줬음.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPOjbi/btsLFC0SEzs/FemkHMHcG3tIyEJaFmqka1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPOjbi/btsLFC0SEzs/FemkHMHcG3tIyEJaFmqka1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPOjbi/btsLFC0SEzs/FemkHMHcG3tIyEJaFmqka1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPOjbi%2FbtsLFC0SEzs%2FFemkHMHcG3tIyEJaFmqka1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;286&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타겟도 아까 룰이랑 똑같이하샘&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/da1dxl/btsLFDkCwZs/Ub6Un9BaWddK2yNg360cJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/da1dxl/btsLFDkCwZs/Ub6Un9BaWddK2yNg360cJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/da1dxl/btsLFDkCwZs/Ub6Un9BaWddK2yNg360cJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fda1dxl%2FbtsLFDkCwZs%2FUb6Un9BaWddK2yNg360cJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;692&quot; height=&quot;610&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;룰은 저 require a pull request before merging을 체크하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;승인자수는 1,&amp;nbsp;코드 오너의 리뷰가 필요하다고 설정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 저장~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;++ 추가해서 위에 무찌가 main브랜치로 push를 하는걸 금지하는 restrict update룰은 체크안하고 현재 pull request룰만 살려줘도 무찌는 main 브랜치에&amp;nbsp; push할 수 없다. 그냥 main브랜치가 변하려면 pull request가 있어야한다는 조건이라고 생각하면 댐&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOfuLO/btsLFZ9i1GU/XEWMEHw4DVGSPsYE16pY20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOfuLO/btsLFZ9i1GU/XEWMEHw4DVGSPsYE16pY20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOfuLO/btsLFZ9i1GU/XEWMEHw4DVGSPsYE16pY20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOfuLO%2FbtsLFZ9i1GU%2FXEWMEHw4DVGSPsYE16pY20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;260&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 몰랐던거라 테스트해봤는데 pull request로만 merge하는 브랜치라고 push자체가 안됐음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 조건 다 만들려면 지금 이 룰셋대로만 하면됨. restrict update도 같이하면 충돌나니까 걍 풀리퀘스트룰만 만드샘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;테스트 해보자~&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlQZNe/btsLFwzRgf4/KkwnJcBc2KEKl9EC0kkAYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlQZNe/btsLFwzRgf4/KkwnJcBc2KEKl9EC0kkAYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlQZNe/btsLFwzRgf4/KkwnJcBc2KEKl9EC0kkAYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlQZNe%2FbtsLFwzRgf4%2FKkwnJcBc2KEKl9EC0kkAYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;187&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 테스트를 위해서 걍 first commit으로 리셋했음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJYr5r/btsLGerq4rj/zX9P2fBHYge80Tv0TiiV10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJYr5r/btsLGerq4rj/zX9P2fBHYge80Tv0TiiV10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJYr5r/btsLGerq4rj/zX9P2fBHYge80Tv0TiiV10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJYr5r%2FbtsLGerq4rj%2FzX9P2fBHYge80Tv0TiiV10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;288&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌시점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌가 muzzi-dev에 수정한 코드를 commit후, muzzi-dev 브랜치에 push 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btCg3y/btsLGdMOFja/FC4KXuPS0kiFzV9KPuuZp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btCg3y/btsLGdMOFja/FC4KXuPS0kiFzV9KPuuZp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btCg3y/btsLGdMOFja/FC4KXuPS0kiFzV9KPuuZp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtCg3y%2FbtsLGdMOFja%2FFC4KXuPS0kiFzV9KPuuZp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;829&quot; height=&quot;264&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;muzzi-dev브랜치에 해당 커밋이 잘 올라왔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caaqvM/btsLGPd2eJ3/4AtqNKc800W103fUNJRJK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caaqvM/btsLGPd2eJ3/4AtqNKc800W103fUNJRJK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caaqvM/btsLGPd2eJ3/4AtqNKc800W103fUNJRJK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaaqvM%2FbtsLGPd2eJ3%2F4AtqNKc800W103fUNJRJK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;950&quot; height=&quot;225&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 무찌가 깃허브에서 pull request를 생성하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dO1eDG/btsLGcAyKyn/cfRfskGZQZcfsVOdi2d0c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dO1eDG/btsLGcAyKyn/cfRfskGZQZcfsVOdi2d0c1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dO1eDG/btsLGcAyKyn/cfRfskGZQZcfsVOdi2d0c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdO1eDG%2FbtsLGcAyKyn%2FcfRfskGZQZcfsVOdi2d0c1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;946&quot; height=&quot;426&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌는 main브랜치에 직접 push할 수 없으니 자기가 짠 코드가 있는 muzzi-dev브랜치 코드를 main에 merge해달라고 pull request를 보내는거다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwPT1F/btsLFhvTIeX/WOvkDhS5wphG1ZndJlwdD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwPT1F/btsLFhvTIeX/WOvkDhS5wphG1ZndJlwdD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwPT1F/btsLFhvTIeX/WOvkDhS5wphG1ZndJlwdD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwPT1F%2FbtsLFhvTIeX%2FWOvkDhS5wphG1ZndJlwdD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;929&quot; height=&quot;626&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검토후 pull request ㄱㄱ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xCOxq/btsLFJevrIe/Gg2GeYi81o23JoKEhSkMi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xCOxq/btsLFJevrIe/Gg2GeYi81o23JoKEhSkMi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xCOxq/btsLFJevrIe/Gg2GeYi81o23JoKEhSkMi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxCOxq%2FbtsLFJevrIe%2FGg2GeYi81o23JoKEhSkMi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;592&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 적고 풀리퀘스트를 생성해주자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;643&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZlKlT/btsLGY9KQxf/wuKJCN8nOBBkgM7zbEBJ20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZlKlT/btsLGY9KQxf/wuKJCN8nOBBkgM7zbEBJ20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZlKlT/btsLGY9KQxf/wuKJCN8nOBBkgM7zbEBJ20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZlKlT%2FbtsLGY9KQxf%2FwuKJCN8nOBBkgM7zbEBJ20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;919&quot; height=&quot;643&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;643&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거부가 되었다. 리뷰어의 승인이 필요하다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxt1yq/btsLFiuLZrk/6F8NjHU1H4T5ismasNoj41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxt1yq/btsLFiuLZrk/6F8NjHU1H4T5ismasNoj41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxt1yq/btsLFiuLZrk/6F8NjHU1H4T5ismasNoj41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxt1yq%2FbtsLFiuLZrk%2F6F8NjHU1H4T5ismasNoj41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1164&quot; height=&quot;401&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 팀장 시점이다. 해당 pull request를 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mRWic/btsLFZ9iKuk/rD1MjwWuko6iXCvWbHuPtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mRWic/btsLFZ9iKuk/rD1MjwWuko6iXCvWbHuPtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mRWic/btsLFZ9iKuk/rD1MjwWuko6iXCvWbHuPtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmRWic%2FbtsLFZ9iKuk%2FrD1MjwWuko6iXCvWbHuPtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1139&quot; height=&quot;566&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;566&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치를 로컬에 가져와서 테스트는 해봤다고 가정하고.. 일단 코드가 맘에든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;review를 추가해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdSOan/btsLFc9p9qY/LK3YHLEg6Y1EIxAfKkDdY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdSOan/btsLFc9p9qY/LK3YHLEg6Y1EIxAfKkDdY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdSOan/btsLFc9p9qY/LK3YHLEg6Y1EIxAfKkDdY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdSOan%2FbtsLFc9p9qY%2FLK3YHLEg6Y1EIxAfKkDdY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1148&quot; height=&quot;639&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리뷰 내용을 적어주고 승인(approve)을 해주자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTwUXo/btsLGbhntPD/AW6w8O9SPrqnLpgJQbpYVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTwUXo/btsLGbhntPD/AW6w8O9SPrqnLpgJQbpYVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTwUXo/btsLGbhntPD/AW6w8O9SPrqnLpgJQbpYVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTwUXo%2FbtsLGbhntPD%2FAW6w8O9SPrqnLpgJQbpYVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;833&quot; height=&quot;860&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님의 칭찬과함께 초록색체크표시가 빰빰하게 떴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장은 저 아래 merge pull request버튼을 눌러 최종적으로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rJm9A/btsLFzXCNNI/0klQxoqjLdjVO2fKXU8Zp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rJm9A/btsLFzXCNNI/0klQxoqjLdjVO2fKXU8Zp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rJm9A/btsLFzXCNNI/0klQxoqjLdjVO2fKXU8Zp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrJm9A%2FbtsLFzXCNNI%2F0klQxoqjLdjVO2fKXU8Zp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;837&quot; height=&quot;132&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 merge를 하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFt30w/btsLHx4Qzcq/flOkYP88wVLgdZYBg3vVz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFt30w/btsLHx4Qzcq/flOkYP88wVLgdZYBg3vVz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFt30w/btsLHx4Qzcq/flOkYP88wVLgdZYBg3vVz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFt30w%2FbtsLHx4Qzcq%2FflOkYP88wVLgdZYBg3vVz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;948&quot; height=&quot;254&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌의 시점에서 무찌계정에 메세지가 와있었고 팀장님이 승인했다고 잘 떴다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님이 merge를 confirm하는순간&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceJP7V/btsLFxSXoj9/OAheB8YBfp7636D4OzOnT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceJP7V/btsLFxSXoj9/OAheB8YBfp7636D4OzOnT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceJP7V/btsLFxSXoj9/OAheB8YBfp7636D4OzOnT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceJP7V%2FbtsLFxSXoj9%2FOAheB8YBfp7636D4OzOnT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;674&quot; height=&quot;60&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 이렇게 pull request로도 작업이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;++ 추가해서 pr보내세요~ 막 이러는게 pull request라는걸 방금 코딩하다보니 알게되었다.. 소름 ㄷㄷ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;collaborator에서 중요한건 뭘까?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fork에서 작업할때는 내가 내맘대로 설정한 협업방식에선 각각 개발자들이 본인 레포지토리 main브랜치를 기준으로 코딩을 하고&amp;nbsp; 팀장 레포의 특정브랜치로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;pull requet를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 보낼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 초기 설정이 좀 복잡하고 코드 최신상태를 가져오는게 좀 짜쳤지만서도..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신에 본인 레포에서 브랜치관리는 비교적 자유로운 느낌이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 collaborator로 협업할때는 한 레포지토리를 여러 개발자가 접근하니까 브랜치 작명, 및 운영이 굉장히 중요할것 같다는 느낌이 든다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 브랜치 네이밍 규칙 등을 만들어서 puppy world프로젝트를 진행해볼까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시작하기에 앞서, 브랜치 종류 소개&lt;/span&gt;&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main : 가장 중심이 되는 브랜치로 배포버전을 여기에 push merge함&lt;/li&gt;
&lt;li&gt;develop : 개발할때 중심이 되는 브랜치&lt;/li&gt;
&lt;li&gt;feature : 특정 기능을 개발할떄 만드는 브랜치&lt;/li&gt;
&lt;li&gt;release : develop브랜치를 최종적으로 테스트하고 main 브랜치에 push하는 브랜치&lt;/li&gt;
&lt;li&gt;hotfix : 중간에 버그가생긴걸 고치려고 만드는 브랜치. 버그고치고 develop과 main브랜치에 merge&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 브랜치들을 만들건데 이건 git flow전략에서 브랜치 종류를 정리한거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 내가 이해한대로 짧게 적었는데, 여기서 주저리주저리 안적고 아래에 직접 해보면서 차근차근 해보면서 이해해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 환경셋팅&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQi6vt/btsLIC5UqLZ/fhX0dC4c2kr1BKH4tZ8YuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQi6vt/btsLIC5UqLZ/fhX0dC4c2kr1BKH4tZ8YuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQi6vt/btsLIC5UqLZ/fhX0dC4c2kr1BKH4tZ8YuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQi6vt%2FbtsLIC5UqLZ%2FfhX0dC4c2kr1BKH4tZ8YuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1155&quot; height=&quot;330&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장인 nurd worker는 새로운 레포지토리를 팠다. puppy-project&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 방법대로 collaborator들로 muzzi, dori개발자분들을 초대했고, main브랜치에 pull request룰을 만들어놨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 각 개발자들이 로컬 디렉토리에 해당 프로젝트를 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;main브랜치와 develop브랜치&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmdJdh/btsLIexSMJt/33TGNwpmB8HGdhEMkREgZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmdJdh/btsLIexSMJt/33TGNwpmB8HGdhEMkREgZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmdJdh/btsLIexSMJt/33TGNwpmB8HGdhEMkREgZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmdJdh%2FbtsLIexSMJt%2F33TGNwpmB8HGdhEMkREgZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;368&quot; height=&quot;356&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 팀장인 nurd worker는 main브랜치가 있는 상태에서 develop브랜치를 만들었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xW2jj/btsLHpfSIh2/CmvtM69MPHre7AAjCX4hok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xW2jj/btsLHpfSIh2/CmvtM69MPHre7AAjCX4hok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xW2jj/btsLHpfSIh2/CmvtM69MPHre7AAjCX4hok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxW2jj%2FbtsLHpfSIh2%2FCmvtM69MPHre7AAjCX4hok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1002&quot; height=&quot;446&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성도는 이렇다. 팀장을 포함한 모든 개발자는 모두 개발을 한 코드들을 develop브랜치에 merge한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DFr2t/btsLHNtzJpd/kkYegLTMYUrdvkF66sNR81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DFr2t/btsLHNtzJpd/kkYegLTMYUrdvkF66sNR81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DFr2t/btsLHNtzJpd/kkYegLTMYUrdvkF66sNR81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDFr2t%2FbtsLHNtzJpd%2FkkYegLTMYUrdvkF66sNR81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1006&quot; height=&quot;488&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;develop브랜치의 커밋이 잘 동작되는지 확인 후(이건 release 브랜치를 하는데, 좀따설명)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 동작된다면 팀장은 최종적으로 develop브랜치의 커밋이 main브랜치에 merge한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화살표 끝에 aws가 있는건, 인프라단에 cicd가 구성되어있으면 develop브랜치는 테스트용 인프라, main브랜치는 현재 배포된 인프라에 배포되는걸 표현하는거임. 브랜치에다가 각 인프라 cicd를 붙여주면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRYwND/btsLIeq5tRd/5Hzj7ot7BuJMKRInfq9Xe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRYwND/btsLIeq5tRd/5Hzj7ot7BuJMKRInfq9Xe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRYwND/btsLIeq5tRd/5Hzj7ot7BuJMKRInfq9Xe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRYwND%2FbtsLIeq5tRd%2F5Hzj7ot7BuJMKRInfq9Xe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;427&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 현재 app.js파일에 welcome코드가 있는 상태로 first commit이 복사되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기능개발을 해볼까? feature브랜치&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRN5VS/btsLImbehqg/SXRQ9wqYS6Pik98NjpZKoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRN5VS/btsLImbehqg/SXRQ9wqYS6Pik98NjpZKoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRN5VS/btsLImbehqg/SXRQ9wqYS6Pik98NjpZKoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRN5VS%2FbtsLImbehqg%2FSXRQ9wqYS6Pik98NjpZKoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;410&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님이 무찌에게 user기능을 만들라고 시켰다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌는 user.js라는 파일을 만들고, 거기에 코드를 적어넣었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 commit후에 push를 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsKspd/btsLFEdjo5V/IRHmmL4D9r7zK4BuoSlJZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsKspd/btsLFEdjo5V/IRHmmL4D9r7zK4BuoSlJZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsKspd/btsLFEdjo5V/IRHmmL4D9r7zK4BuoSlJZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsKspd%2FbtsLFEdjo5V%2FIRHmmL4D9r7zK4BuoSlJZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;299&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레포지토리의 feature/user이라는 브랜치가 잘 push되었고, user.js라는 파일이 생겼다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;633&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FeYYq/btsLIoUpGV8/uWMgyg7ESdttuCBXNanN4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FeYYq/btsLIoUpGV8/uWMgyg7ESdttuCBXNanN4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FeYYq/btsLIoUpGV8/uWMgyg7ESdttuCBXNanN4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFeYYq%2FbtsLIoUpGV8%2FuWMgyg7ESdttuCBXNanN4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;923&quot; height=&quot;633&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;633&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 이런 상태이다. 무찌가 feature/user이라는 브랜치를 만들었고, user.js라는 파일을 추가했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 user feature finish라는 커밋을 헀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 팀장님이 이 기능을 로컬에서 테스트해보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;97&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpo6VY/btsLGPTCGNc/eDB0FkxKdPR0dvQwL7UGV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpo6VY/btsLGPTCGNc/eDB0FkxKdPR0dvQwL7UGV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpo6VY/btsLGPTCGNc/eDB0FkxKdPR0dvQwL7UGV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdpo6VY%2FbtsLGPTCGNc%2FeDB0FkxKdPR0dvQwL7UGV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;211&quot; height=&quot;97&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;97&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 해보니 맘에드셨다. 따라서 무찌의 feature/user 브랜치를 develop 브랜치에 merge하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 레포지토리의 develop브랜치에 push했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BtY7g/btsLIbnwu5d/U93xfA8YM8z74OhanEkKJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BtY7g/btsLIbnwu5d/U93xfA8YM8z74OhanEkKJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BtY7g/btsLIbnwu5d/U93xfA8YM8z74OhanEkKJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBtY7g%2FbtsLIbnwu5d%2FU93xfA8YM8z74OhanEkKJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;244&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레포지토리를 확인하니 user.js파일이 제대로 올라왔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F5k4b/btsLHQjI5bp/A4Y1NGmPIkfeX50TLaX84k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F5k4b/btsLHQjI5bp/A4Y1NGmPIkfeX50TLaX84k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F5k4b/btsLHQjI5bp/A4Y1NGmPIkfeX50TLaX84k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF5k4b%2FbtsLHQjI5bp%2FA4Y1NGmPIkfeX50TLaX84k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;993&quot; height=&quot;644&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무찌의 user feature finish라는 커밋이 develop브랜치에 merge되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 현재 develop브랜치의 최종커밋은 user.js파일이 있는 상태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;도리가 코드를 더 수정하고싶대! feature&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님은 무찌의 user기능이 맘에들어서 develop브랜치에 merge했다. 근데 도리는 무찌의 코드가 맘에 안든다. 때문에 무찌가 개발한 feature/user브랜치를 부모브랜치로 새로운 브랜치를 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b35ylv/btsLINl1Kd5/kEdWu1KHqpureh1jZSvovk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b35ylv/btsLINl1Kd5/kEdWu1KHqpureh1jZSvovk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b35ylv/btsLINl1Kd5/kEdWu1KHqpureh1jZSvovk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb35ylv%2FbtsLINl1Kd5%2FkEdWu1KHqpureh1jZSvovk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;216&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도리가 최신 업데이트 내용을 fetch하고 feature/user브랜치로 switch했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xSCwq/btsLHNUKlAZ/FbHJlZCxjNc8TXoUsEjKik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xSCwq/btsLHNUKlAZ/FbHJlZCxjNc8TXoUsEjKik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xSCwq/btsLHNUKlAZ/FbHJlZCxjNc8TXoUsEjKik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxSCwq%2FbtsLHNUKlAZ%2FFbHJlZCxjNc8TXoUsEjKik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;718&quot; height=&quot;407&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 새로운 기능을 개발할것이므로 feature/user_strong이라는 브랜치를 새로만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 user기능이 단순하게 hello dog user라고하니까 너무 약해보여서 도리는 느낌표 두개를 더 붙여서 격히 환영하는 느낌의 코드로 수정을 헀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 finish strong feature라는 커밋으로 레포지토리에 해당 브랜치 내용을 push하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LA2w4/btsLG0m6Zh2/hcsBfByEVhERmk1Zxi4jbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LA2w4/btsLG0m6Zh2/hcsBfByEVhERmk1Zxi4jbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LA2w4/btsLG0m6Zh2/hcsBfByEVhERmk1Zxi4jbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLA2w4%2FbtsLG0m6Zh2%2FhcsBfByEVhERmk1Zxi4jbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;832&quot; height=&quot;382&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레포지토리도 이렇게 잘 push된걸 확인 가능.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br1Xr3/btsLGZ2LfbC/nwAgEiOVg0Y1aEO5NhxOeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br1Xr3/btsLGZ2LfbC/nwAgEiOVg0Y1aEO5NhxOeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br1Xr3/btsLGZ2LfbC/nwAgEiOVg0Y1aEO5NhxOeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr1Xr3%2FbtsLGZ2LfbC%2FnwAgEiOVg0Y1aEO5NhxOeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;687&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 이런상태이다. 도리가 feature/user_strong이라는 브랜치를 만들고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 feature/user브랜치 코드를 수정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 팀장님의 선택이 남았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nkRT5/btsLGaqcI0q/Wa73Qcj4ZZ4uNKO0CVPC80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nkRT5/btsLGaqcI0q/Wa73Qcj4ZZ4uNKO0CVPC80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nkRT5/btsLGaqcI0q/Wa73Qcj4ZZ4uNKO0CVPC80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnkRT5%2FbtsLGaqcI0q%2FWa73Qcj4ZZ4uNKO0CVPC80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;79&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;79&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님은 도리의 코드도 맘에 들어서 develop브랜치에 merge후에 push하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EvTuR/btsLHt3grVx/i7ij7CzgwqysSjVEEEdYak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EvTuR/btsLHt3grVx/i7ij7CzgwqysSjVEEEdYak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EvTuR/btsLHt3grVx/i7ij7CzgwqysSjVEEEdYak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEvTuR%2FbtsLHt3grVx%2Fi7ij7CzgwqysSjVEEEdYak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1139&quot; height=&quot;623&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장님이 develop branch에 도리의 코드를 merge했으므로 최종적으로 도리의 최종커밋인 finish strong feature 커밋상태가 develop브랜치의 최종커밋이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;드디어&amp;nbsp; 강아지 개발자들과의 puppy 프로젝트가 완성되었다! 배포ㄱㄱ release브랜치&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxGllT/btsLGa4N1sN/UZEx4q5J0K0sn8GSyvkG0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxGllT/btsLGa4N1sN/UZEx4q5J0K0sn8GSyvkG0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxGllT/btsLGa4N1sN/UZEx4q5J0K0sn8GSyvkG0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxGllT%2FbtsLGa4N1sN%2FUZEx4q5J0K0sn8GSyvkG0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;588&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 도리의 commit인 finish strong feature을 가지고 만들거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장은 develop브랜치를 부모 브랜치로 해서 release/1.0.0브랜치를 만들자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dslCTn/btsLId6PO1r/pW31CEOlbvUpiK4ueWajBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dslCTn/btsLId6PO1r/pW31CEOlbvUpiK4ueWajBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dslCTn/btsLId6PO1r/pW31CEOlbvUpiK4ueWajBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdslCTn%2FbtsLId6PO1r%2FpW31CEOlbvUpiK4ueWajBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;109&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장은 releqse/1.0.0 브랜치로 switch한 후, 버전을 주석으로 입력하고 커밋한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsoTW7/btsLGbCFMRw/tDwGCPyBBvCwrXZsyKHLIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsoTW7/btsLGbCFMRw/tDwGCPyBBvCwrXZsyKHLIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsoTW7/btsLGbCFMRw/tDwGCPyBBvCwrXZsyKHLIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsoTW7%2FbtsLGbCFMRw%2FtDwGCPyBBvCwrXZsyKHLIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;354&quot; height=&quot;52&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;release version 1.0.0 confirm이라는 커밋을 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9KznI/btsLHoBe2EB/kt40l5WVk6N6cbHrSjstk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9KznI/btsLHoBe2EB/kt40l5WVk6N6cbHrSjstk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9KznI/btsLHoBe2EB/kt40l5WVk6N6cbHrSjstk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9KznI%2FbtsLHoBe2EB%2Fkt40l5WVk6N6cbHrSjstk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;139&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 레포지토리에 push하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biN9Vw/btsLIzauHLG/U0s3caw9SoHtK2L6bBUsw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biN9Vw/btsLIzauHLG/U0s3caw9SoHtK2L6bBUsw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biN9Vw/btsLIzauHLG/U0s3caw9SoHtK2L6bBUsw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiN9Vw%2FbtsLIzauHLG%2FU0s3caw9SoHtK2L6bBUsw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;445&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;445&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOwro7/btsLG1l6oHq/LanPbvjXPXqacJmr7pgzB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOwro7/btsLG1l6oHq/LanPbvjXPXqacJmr7pgzB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOwro7/btsLG1l6oHq/LanPbvjXPXqacJmr7pgzB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOwro7%2FbtsLG1l6oHq%2FLanPbvjXPXqacJmr7pgzB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;993&quot; height=&quot;574&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 이런 상태이다. 팀장은 release/1.0.0브랜치에서 최종 커밋을 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 이제 배포를 위해 main브랜치에 pull request를 보내자~&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 들어왔다. 이제 pull request를 만들자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0D6Ha/btsLIyWYPCj/iR6UKeedaFJ2xAZJX6asG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0D6Ha/btsLIyWYPCj/iR6UKeedaFJ2xAZJX6asG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0D6Ha/btsLIyWYPCj/iR6UKeedaFJ2xAZJX6asG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0D6Ha%2FbtsLIyWYPCj%2FiR6UKeedaFJ2xAZJX6asG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;399&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브 페이지에서 release/1.0.0브랜치를 main브랜치에 pull request하는걸 만들자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZxUPy/btsLHqlaCRo/cGZkmXvaKaqv6deJXYS3N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZxUPy/btsLHqlaCRo/cGZkmXvaKaqv6deJXYS3N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZxUPy/btsLHqlaCRo/cGZkmXvaKaqv6deJXYS3N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZxUPy%2FbtsLHqlaCRo%2FcGZkmXvaKaqv6deJXYS3N0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;620&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 확인후 create pull request&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;789&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnRREf/btsLIBe8v6v/VWgx4T2Q0uk1a8dzS6KXRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnRREf/btsLIBe8v6v/VWgx4T2Q0uk1a8dzS6KXRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnRREf/btsLIBe8v6v/VWgx4T2Q0uk1a8dzS6KXRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnRREf%2FbtsLIBe8v6v%2FVWgx4T2Q0uk1a8dzS6KXRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;839&quot; height=&quot;789&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;789&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엑스 뜨는건 룰셋 만들어놔서그럼..&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxGt4h/btsLG26m37h/nbGAWK8PbTn5MyXoCbGGzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxGt4h/btsLG26m37h/nbGAWK8PbTn5MyXoCbGGzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxGt4h/btsLG26m37h/nbGAWK8PbTn5MyXoCbGGzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxGt4h%2FbtsLG26m37h%2FnbGAWK8PbTn5MyXoCbGGzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;826&quot; height=&quot;311&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강아지 개발자 muzzi가 승인.. 원래 이러면 안되는데..? pull request를 만든 사람은 리뷰를 작성 못하나보다. 무찌한테 시킬걸..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음암. 암튼 중요한게 아니니 일단 mergeㄱㄱ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IrXtV/btsLGiOVMag/2935brAOlniz5BSVocLlRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IrXtV/btsLGiOVMag/2935brAOlniz5BSVocLlRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IrXtV/btsLGiOVMag/2935brAOlniz5BSVocLlRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIrXtV%2FbtsLGiOVMag%2F2935brAOlniz5BSVocLlRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;845&quot; height=&quot;179&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 됐다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qPUm2/btsLHBAnHmh/VkVa28sY9IfQwxRijuRmb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qPUm2/btsLHBAnHmh/VkVa28sY9IfQwxRijuRmb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qPUm2/btsLHBAnHmh/VkVa28sY9IfQwxRijuRmb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqPUm2%2FbtsLHBAnHmh%2FVkVa28sY9IfQwxRijuRmb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1171&quot; height=&quot;558&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 이렇게 깃 flow전략으로 1.0.0버전이 잘 배포가 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배포가 된 1.0.0버전에서 버그가 발견? / hotfix브랜치&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포되서 잘 굴러가던 우리 puppy project가 갑자기 버그가 발견되었따.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이걸 급하게 고쳐봐야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c33Rix/btsLHTAO1E5/BmsjESdTkkAEq7827pEeYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c33Rix/btsLHTAO1E5/BmsjESdTkkAEq7827pEeYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c33Rix/btsLHTAO1E5/BmsjESdTkkAEq7827pEeYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc33Rix%2FbtsLHTAO1E5%2FBmsjESdTkkAEq7827pEeYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;380&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 main브랜치의 1.0.0버전기준으로 hotfix/1.0.1브랜치를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1736330151662&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//main브랜치에서  자식브랜치 hot fix생성
git branch hotfix/1.0.1
git switch hotfix/1.0.1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQ6Y6N/btsLIyvT6kY/KDINnaIvmYtEHS7LuDyfi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQ6Y6N/btsLIyvT6kY/KDINnaIvmYtEHS7LuDyfi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQ6Y6N/btsLIyvT6kY/KDINnaIvmYtEHS7LuDyfi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQ6Y6N%2FbtsLIyvT6kY%2FKDINnaIvmYtEHS7LuDyfi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;128&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 fix bug라는 주석을 추가하여 버그를 고쳤다 ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tc3DF/btsLIa90kuT/WdATpf1kgmFxC97wMULxf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tc3DF/btsLIa90kuT/WdATpf1kgmFxC97wMULxf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tc3DF/btsLIa90kuT/WdATpf1kgmFxC97wMULxf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTc3DF%2FbtsLIa90kuT%2FWdATpf1kgmFxC97wMULxf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;66&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 fix bug / 1.0.1이라는 커밋을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 hot fix로 버그를 고치면 버전이 약간 상승된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R6Gvf/btsLImCjVnb/X9sR52O6h9GfuskuXfiwO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R6Gvf/btsLImCjVnb/X9sR52O6h9GfuskuXfiwO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R6Gvf/btsLImCjVnb/X9sR52O6h9GfuskuXfiwO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR6Gvf%2FbtsLImCjVnb%2FX9sR52O6h9GfuskuXfiwO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;206&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hotfix브랜치 상태를 레포지토리에 push&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfR5S6/btsLFELA5sA/zEvUVMtp7BwOyGfDQNkW2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfR5S6/btsLFELA5sA/zEvUVMtp7BwOyGfDQNkW2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfR5S6/btsLFELA5sA/zEvUVMtp7BwOyGfDQNkW2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfR5S6%2FbtsLFELA5sA%2FzEvUVMtp7BwOyGfDQNkW2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;812&quot; height=&quot;260&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 업데이트가 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/80Qbl/btsLIzBA7b8/QEQ40uimovcJKDeCyQSQa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/80Qbl/btsLIzBA7b8/QEQ40uimovcJKDeCyQSQa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/80Qbl/btsLIzBA7b8/QEQ40uimovcJKDeCyQSQa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F80Qbl%2FbtsLIzBA7b8%2FQEQ40uimovcJKDeCyQSQa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;891&quot; height=&quot;497&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 fix bug /1.0.1이라는 커밋을 만들어준상태임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 이제 pull request를 날리자!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hotfix 브랜치에서 중요한건, main브랜치에서 hotfix브랜치를 만든다는 점과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;버그수정 후, 단순히 main브랜치에 merge를 하는게 아니라, develop브랜치에도 merge해줘야 한다는게 중요하다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lQx5y/btsLHBNXEgg/2BKKt5GftkgwGkgUw2tUBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lQx5y/btsLHBNXEgg/2BKKt5GftkgwGkgUw2tUBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lQx5y/btsLHBNXEgg/2BKKt5GftkgwGkgUw2tUBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlQx5y%2FbtsLHBNXEgg%2F2BKKt5GftkgwGkgUw2tUBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;938&quot; height=&quot;637&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 무찌계정으로 pull request를 해보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 main브랜치로 hotfix브랜치를 merge해달라는 pull request&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cprAQZ/btsLHrEv6f4/jJxJ0yQzzqUPbPTaWJlKE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cprAQZ/btsLHrEv6f4/jJxJ0yQzzqUPbPTaWJlKE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cprAQZ/btsLHrEv6f4/jJxJ0yQzzqUPbPTaWJlKE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcprAQZ%2FbtsLHrEv6f4%2FjJxJ0yQzzqUPbPTaWJlKE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;905&quot; height=&quot;500&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 develop브랜치로 merge해달라는 pull request&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두개의 pull request를 만드는거&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJqnT/btsLHUfq39O/QCxeMuh1iW2jwPUKhf5Kx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kJqnT/btsLHUfq39O/QCxeMuh1iW2jwPUKhf5Kx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kJqnT/btsLHUfq39O/QCxeMuh1iW2jwPUKhf5Kx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkJqnT%2FbtsLHUfq39O%2FQCxeMuh1iW2jwPUKhf5Kx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;448&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nurdworker시점으로 두개의 pull request가 와있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘다 받아주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVg798/btsLILV5R2W/rGkkCUJdPQ95t9k4FxQO20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVg798/btsLILV5R2W/rGkkCUJdPQ95t9k4FxQO20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVg798/btsLILV5R2W/rGkkCUJdPQ95t9k4FxQO20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVg798%2FbtsLILV5R2W%2FrGkkCUJdPQ95t9k4FxQO20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;852&quot; height=&quot;626&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;develop브랜치는 뭐 룰셋 안만든 브랜치라 처음부터 초록불&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m8Ks2/btsLGP7fmxo/2eOKPFppKjWQGWQfuUvdRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m8Ks2/btsLGP7fmxo/2eOKPFppKjWQGWQfuUvdRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m8Ks2/btsLGP7fmxo/2eOKPFppKjWQGWQfuUvdRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm8Ks2%2FbtsLGP7fmxo%2F2eOKPFppKjWQGWQfuUvdRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;592&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main브랜치는 룰셋 만든 브랜치라 빨간박스로 리뷰쓰라고 나옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(사실 충돌났는데 당연히 한 파일에 주석추가해서 수정된거니..암튼 대충 해결하고 계속 진행 ㄱㄱ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JpyBQ/btsLIEQkyt4/IdGUVtU6lFB973FlSngJqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JpyBQ/btsLIEQkyt4/IdGUVtU6lFB973FlSngJqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JpyBQ/btsLIEQkyt4/IdGUVtU6lFB973FlSngJqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJpyBQ%2FbtsLIEQkyt4%2FIdGUVtU6lFB973FlSngJqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;279&quot; height=&quot;105&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘다 머지 잘해줬음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blyNeD/btsLGYJvk7p/6LbBChzoJ5H0HaF6MBPXE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blyNeD/btsLGYJvk7p/6LbBChzoJ5H0HaF6MBPXE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blyNeD/btsLGYJvk7p/6LbBChzoJ5H0HaF6MBPXE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblyNeD%2FbtsLGYJvk7p%2F6LbBChzoJ5H0HaF6MBPXE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;465&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 이렇게 급한불을 끄는 hotfix브랜치를 만들어서 버그를 수정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-type=&quot;image&quot; data-ke-style=&quot;style1&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;최종 git flow 아키텍쳐&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yskNc/btsLGMWXoau/5k5T5iwHMfiiwVK1fufVDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yskNc/btsLGMWXoau/5k5T5iwHMfiiwVK1fufVDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yskNc/btsLGMWXoau/5k5T5iwHMfiiwVK1fufVDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyskNc%2FbtsLGMWXoau%2F5k5T5iwHMfiiwVK1fufVDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1224&quot; height=&quot;638&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 puppy project 1.0.1버전이 완성되었따..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: center;&quot;&gt;Conclusion&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;깃 포스팅 시리즈는 참 설정할게 많았다..&lt;br /&gt;뭔가 단순한거 같으면서도 협업이 필요하니까 막상 그림이 잘 안그려저서 직접 해보자고&lt;br /&gt;vm파고.. 각자 계정 따로만들고.. 솔까 개고생이었음..&lt;br /&gt;같은 전화번호로 계정 여러개만든다고 블럭먹기도 했음 ㅠㅠ&lt;br /&gt;그림작업도 많아야하니까..참&lt;br /&gt;&lt;br /&gt;암튼 fork와 collaborator로 협업하는 시나리오로 포스팅을 했는데,&lt;br /&gt;딱 어떤 방법만 써야한다 이런게 아니라, 두가지 기능을 적제적소에 갖다넣어서 혼용하는게 중요할것같다.&lt;br /&gt;팀장이 이런 협업설계를 하는것이 중요할것같음. 팀원이 알아먹는것보다도..&lt;br /&gt;&lt;br /&gt;사실 뭐 내가 쓴 포스팅이 틀린점도 많을거다. 실제로 깃으로 제대로된 개발 협업을 해본경험이 없으니까말이다.&lt;br /&gt;실제로 취업후에 직접 맞닥뜨리고 배우는게 가장 최선일것같음.&lt;br /&gt;암튼 ㅅㄱ&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>git/git</category>
      <author>부엉이사장</author>
      <guid isPermaLink="true">https://jacobowl.tistory.com/350</guid>
      <comments>https://jacobowl.tistory.com/350#entry350comment</comments>
      <pubDate>Wed, 8 Jan 2025 00:01:55 +0900</pubDate>
    </item>
  </channel>
</rss>