<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>LEFT ON</title>
    <link>https://lefton.tistory.com/</link>
    <description>Let's Enjoy Free Time (LEFT)</description>
    <language>ko</language>
    <pubDate>Sat, 1 Aug 2026 01:37:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>LEFT</managingEditor>
    <image>
      <title>LEFT ON</title>
      <url>https://tistory1.daumcdn.net/tistory/4649967/attach/c725ddb29edc48bba20efb4cb61a4fd6</url>
      <link>https://lefton.tistory.com</link>
    </image>
    <item>
      <title>Flask와 Django, PostgreSQL에 대하여</title>
      <link>https://lefton.tistory.com/302</link>
      <description>&lt;h1 style=&quot;text-align: center;&quot;&gt;&lt;b&gt;인턴십 프로젝트 &lt;/b&gt;&lt;/h1&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;[25.08.06-25.09.05]&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Flask&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Python으로 구동되는 웹 어플리케이션 프레임워크&lt;/li&gt;
&lt;li&gt;Django 프레임워크보다 가볍고 스케일이 작은 서버 &amp;rarr; 큰 서버까지 만들 수 있음&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓Flask vs Django&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/11LqJ/dJMcafL2rUF/TqTAlrPsAhtQIDerLKFAy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/11LqJ/dJMcafL2rUF/TqTAlrPsAhtQIDerLKFAy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/11LqJ/dJMcafL2rUF/TqTAlrPsAhtQIDerLKFAy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F11LqJ%2FdJMcafL2rUF%2FTqTAlrPsAhtQIDerLKFAy0%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;1007&quot; height=&quot;424&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Django&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;장고는 모델이라는 개념을 사용&lt;/li&gt;
&lt;li&gt;모델 : 우리가 처리하고자하는 데이터들이 어떤 정보를 가지고 있는지를 정의한 것 (=스키마)&lt;/li&gt;
&lt;li&gt;이 모델의 규칙을 따라서 생성된 데이터들이 실제로 저장되는 공간이 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;ldquo;데이터베이스&amp;rdquo;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;따라서 모델은 추상적 개념이고, 데이터베이스는 구체적 개념&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;처음 서비스 설계시&lt;br /&gt;ex)&lt;br /&gt;- 종류 (정보) : 맛집, 평가, 회원&lt;br /&gt;- 속성 :&lt;br /&gt;➡️맛집의 세부적인 속성으로 (주소, 명칭, 전화)&lt;br /&gt;➡️평가의 세부적인 속성으로 (별점, 회원, 코멘트)&lt;br /&gt;➡️회원의 세부적인 속성으로 (이메일, 닉네임)&lt;br /&gt;&lt;br /&gt;- 자료형 결정 : 주소, 명칭, 전화 = str, 별점 = int, &lt;b&gt;회원 = str&lt;/b&gt; &lt;br /&gt;(하지만 다른데이터를 참조하고있는 relationship (=참조형 레퍼런스)는 장고에서 relation (릴레이션) 이라고함)&lt;br /&gt;▶️즉 &lt;b&gt;회원은 릴레이션 타입&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Django 설치&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;파이썬이 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767539168830&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install django&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;br /&gt;(즉 개인, 회사, 토이플젝용)으로 나누어서 환경설정을 세팅해야하기때문에 virtualenv 이 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnWel0/dJMcabizJwE/1Sedzk7Wtd0dSG7UWcDDP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnWel0/dJMcabizJwE/1Sedzk7Wtd0dSG7UWcDDP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnWel0/dJMcabizJwE/1Sedzk7Wtd0dSG7UWcDDP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnWel0%2FdJMcabizJwE%2F1Sedzk7Wtd0dSG7UWcDDP0%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;1119&quot; height=&quot;567&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이처럼 myenv 가상환경 안에 pip install Django 로 장고를 설치할 수 있음&lt;/li&gt;
&lt;li&gt;myenv 가상환경 안에서 python &amp;rarr; import django 를 입력했을때 아무 반응이 없어야 제대로 설치가 완료된 것&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&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;1239&quot; data-origin-height=&quot;517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8Zfso/dJMcabpkseo/kvZWDlt9K2sYYtuQ8rKJ60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8Zfso/dJMcabpkseo/kvZWDlt9K2sYYtuQ8rKJ60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8Zfso/dJMcabpkseo/kvZWDlt9K2sYYtuQ8rKJ60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8Zfso%2FdJMcabpkseo%2FkvZWDlt9K2sYYtuQ8rKJ60%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;1239&quot; height=&quot;517&quot; data-origin-width=&quot;1239&quot; data-origin-height=&quot;517&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&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;1245&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfDOpv/dJMcafedcfT/L3GTcCBlPkR5PctdXVZbAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfDOpv/dJMcafedcfT/L3GTcCBlPkR5PctdXVZbAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfDOpv/dJMcafedcfT/L3GTcCBlPkR5PctdXVZbAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfDOpv%2FdJMcafedcfT%2FL3GTcCBlPkR5PctdXVZbAk%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;1245&quot; height=&quot;269&quot; data-origin-width=&quot;1245&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령프롬프트에서는 dir로 myenv 디렉토리를 확인한 후&lt;/li&gt;
&lt;li&gt;cd myenv &amp;rarr; cd Scripts &amp;rarr; activate.bat 을 실행하면 가상 환경이 만들어짐&lt;/li&gt;
&lt;li&gt;이를 통해 이 안에 설치되는 패키지들은 전역(글로벌)로 설치되는 것이 아닌 가상으로 설치할 수 있어 &lt;br /&gt;여러개의 가상서버에 각기 다른 패키지들을 환경으로 구성할 수 있다는 장점&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;데이터베이스를 읽기위해서 DBeaver 사용&lt;/li&gt;
&lt;li&gt;데이터베이스 모델링은 pgAdmin 4를 통해 구조 보기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4Dqdc/dJMcafrJZAz/5Z7LT3gIZ3BXOQM0yVaYpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4Dqdc/dJMcafrJZAz/5Z7LT3gIZ3BXOQM0yVaYpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4Dqdc/dJMcafrJZAz/5Z7LT3gIZ3BXOQM0yVaYpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4Dqdc%2FdJMcafrJZAz%2F5Z7LT3gIZ3BXOQM0yVaYpK%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;1364&quot; height=&quot;865&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyyYue/dJMcadUWddM/JX9K7uNn9bAFNSXoySr5Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyyYue/dJMcadUWddM/JX9K7uNn9bAFNSXoySr5Qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyyYue/dJMcadUWddM/JX9K7uNn9bAFNSXoySr5Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyyYue%2FdJMcadUWddM%2FJX9K7uNn9bAFNSXoySr5Qk%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;970&quot; height=&quot;472&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&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;b&gt;테이블 구조 보기&lt;/b&gt;&lt;br /&gt;- pgAdmin 4의 좌측 &lt;b&gt;Object Explorer&lt;/b&gt;에서 &lt;br /&gt;&lt;b&gt;Databases &amp;gt; [데이터베이스 이름] &amp;gt; Schemas &amp;gt; public &amp;gt; Tables&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;- product 테이블을 클릭하여 테이블의 속성들 확인&lt;br /&gt;- product 테이블 아래의 Columns 폴더를 열면 id, name, brand, price 등 &lt;b&gt;테이블의 컬럼 구조&lt;/b&gt;를 확인 가능&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ERD(ER Diagram) 보기&lt;br /&gt;&lt;/b&gt;- pgAdmin 4의 ERD 기능은 DBeaver처럼 ER Diagram이라는 별도 탭으로 바로 제공되진 않음&lt;br /&gt;- Tools 메뉴에서 Schema Diff나 Query Tool을 사용하여 스키마를 비교하거나, &lt;br /&gt;SQL 쿼리를 직접 실행하여 스키마 정보를 추출&lt;br /&gt;&lt;br /&gt;- 하지만 DBeaver처럼 시각적인 ERD 기능을 기본으로 제공하지는 않기 때문에, &lt;b&gt;ERD 확인은 DBeaver가 더 편리&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWf0fW/dJMcadgljt0/fatlFpdDUm419QgOWusM6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWf0fW/dJMcadgljt0/fatlFpdDUm419QgOWusM6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWf0fW/dJMcadgljt0/fatlFpdDUm419QgOWusM6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWf0fW%2FdJMcadgljt0%2FfatlFpdDUm419QgOWusM6K%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;944&quot; height=&quot;500&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pgAdmin4의 첫 사용으로 샘플DB를 만들어 테스트해보는 것 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 인턴십</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/302</guid>
      <comments>https://lefton.tistory.com/302#entry302comment</comments>
      <pubDate>Mon, 5 Jan 2026 00:09:23 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_113일차_&amp;quot;2차 팀 프로젝트 마무리&amp;quot;</title>
      <link>https://lefton.tistory.com/299</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [113]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 113&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 프로젝트의 최종 마무리를 위해 개발된 기능들을 테스트하고 수정 및 기능추가를 진행하였다. (2025.05.27)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이메일 인증 및 게스트 회원가입 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0fMRc/dJMcac2C95Q/klF8tZKYVJuBejxdBbKrKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0fMRc/dJMcac2C95Q/klF8tZKYVJuBejxdBbKrKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0fMRc/dJMcac2C95Q/klF8tZKYVJuBejxdBbKrKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0fMRc%2FdJMcac2C95Q%2FklF8tZKYVJuBejxdBbKrKK%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;446&quot; height=&quot;841&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&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-filename=&quot;blob&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;1246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DkzT8/dJMcaacImF8/K6G8DE11xnXGjue10x9fS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DkzT8/dJMcaacImF8/K6G8DE11xnXGjue10x9fS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DkzT8/dJMcaacImF8/K6G8DE11xnXGjue10x9fS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDkzT8%2FdJMcaacImF8%2FK6G8DE11xnXGjue10x9fS1%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;445&quot; height=&quot;1246&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;1246&quot;/&gt;&lt;/span&gt;&lt;/figure&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;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;pre id=&quot;code_1765010445785&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAIL_USERNAME: 이메일 주소
MAIL_PASSWORD: 이메일 패스워드&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;API 명세 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;백엔드와 프론트엔드 간의 API 명세 공유의 중요성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발자가 작업을 시작하기 위해서는 백엔드 개발자(서버 로직 담당)가 만든 API의 명세(Specification)가 필요&lt;br /&gt;&lt;br /&gt;&lt;b&gt;- 백엔드 개발자 &lt;/b&gt;: 특정 URL(api/v1/auth/login), 요청 방식(POST), 필요한 데이터(email, password)를 정의하고 구현&lt;br /&gt;&lt;b&gt;- 프론트엔드 개발자 &lt;/b&gt;: 백엔드 개발자가 만든 명세에 따라 정확한 주소로 데이터를 전송하고, 서버가 보낸 응답 데이터를 받아 &lt;br /&gt;화면에 로그인 성공/실패 메시지를 표시&lt;/p&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정리 : &lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프론트엔드 파트 담당 : &lt;br /&gt;&lt;/b&gt;ex. API를 만들어서 달라는 요청 ➡️&amp;nbsp;백엔드 개발자에게 API 엔드포인트(auth/login)의 구현을 완료해달라는 것&lt;br /&gt;ex. Swagger를 만들어달라는 요청 ➡️ 백엔드 개발자가 API 명세를 Swagger 도구를 사용해 문서화해 달라는 요청&lt;/p&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Swagger&lt;/b&gt;는 API의 모든 엔드포인트, 필요한 입력 값, 예상되는 응답을 자동으로 시각화해주는 도구이므로&lt;br /&gt;프론트엔드 개발자는 이 Swagger 문서를 보고 curl 요청에 필요한 모든 정보를 바로 파악할 수 있게됨&lt;/p&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;따라서 curl 요청은 '백엔드 개발자가 만든 API 명세에 따라 요청을 테스트하는 행위'&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;회원가입된 정보로 로그인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1765010636470&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST &quot;http://localhost:8090/api/v1/auth/login&quot; \
-H &quot;Content-Type: application/json&quot; \
-d '{
&quot;email&quot;: &quot;xxx@xxx.com&quot;,
&quot;password&quot;: &quot;xxxxxx1!&quot;&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;curl 명령어를 통해 CLI 환경에서 호스트 로그인을 테스트 진행 (위의 회원가입에서 등록된 회원정보)&lt;/li&gt;
&lt;li&gt;이를 통해 토큰값이 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egh1zw/dJMcagqs5ys/w5nK1tky2HMhLXURdlXIG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egh1zw/dJMcagqs5ys/w5nK1tky2HMhLXURdlXIG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egh1zw/dJMcagqs5ys/w5nK1tky2HMhLXURdlXIG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fegh1zw%2FdJMcagqs5ys%2Fw5nK1tky2HMhLXURdlXIG0%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;643&quot; height=&quot;131&quot; data-origin-width=&quot;643&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;DB에서는 패스워드가 이처럼 암호화되어서 저장되어있는데 이는 BCrypt 방식을 사용하여 암호화한 것&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-path-to-node=&quot;1&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;BCrypt (비크립트)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li data-path-to-node=&quot;2&quot;&gt;비밀번호를 안전하게 저장하기 위해 사용되는 해시 함수&lt;/li&gt;
&lt;li data-path-to-node=&quot;2&quot;&gt;Spring Security를 사용하는 Spring Boot 백엔드에서 기본적으로 채택하는 암호화 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;BCrypt 구조 =&amp;nbsp;&lt;/b&gt;&lt;b&gt;(알고리즘 + 비용계수 + 솔트/해시된비밀번호)&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;ex. $2a$ + $10$ + lof.R4/Bq.....Fy&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;알고리즘&lt;/b&gt; : BCrypt 알고리즘을 사용했음을 나타냄 (ex. $2a$ 또는 $2b$, $2y$)&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;비용계수 (Cost Factor)&lt;/b&gt; : 해시를 생성하는 데 필요한 계산 횟수(강도), 숫자가 높을수록 더 안전하지만, 해시 생성 시간이 길어짐&lt;br /&gt;(ex. $10$)&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;솔트(Salt) + 해시된 비밀번호&lt;/b&gt; : 무작위로 생성된 솔트(22자리)와 최종 해시된 비밀번호가 Base64 인코딩되어 결합&lt;b&gt;&lt;br /&gt;&lt;/b&gt;(ex. lof.R4/Bq.z9PZnVinwEYukhhWe5mKp6h1/QKV6xXmbGpUFajhaFy)&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;최종 예시 비밀번호 문자열 : $2a$10$lof.R4/Bq.z9PZnVinwEYukhhWe5mKp6h1/QKV6xXmbGpUFajhaFy&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이미지 업로드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1765010800418&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST &quot;http://localhost:8090/api/v1/spaces/images/upload&quot; \
-H &quot;Authorization: Bearer 반환된토큰&quot; \
-F &quot;files=@/c/Workspace/Lion_Project/loco_project/test_image.jpg&quot; -v&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;이 curl 명령어를 통해 data의 이미지 URL을 반환받음&lt;br /&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;[&quot;global/data/image/534231e3-76a0-402b-9970-dec78db296b3.jpg&quot;]&lt;/span&gt;&lt;br /&gt;(내용 정리를 위해 임의로 작성된 이미지 URL)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공간 등록&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;curl -X POST &quot;&amp;lt;http://localhost:8090/api/v1/spaces&amp;gt;&quot; \\
-H &quot;Content-Type: application/json&quot; \\
-H &quot;Authorization: Bearer 반환된토큰&quot; \\
-d '{
  &quot;name&quot;: &quot;DB연동 테스트공간&quot;,
  &quot;description&quot;: &quot;curl 명령어로 등록한 테스트 공간입니다.&quot;,
  &quot;address&quot;: &quot;서울시 강남구&quot;,
  &quot;detailAddress&quot;: &quot;역삼동 123-45&quot;,
  &quot;zipCode&quot;: &quot;06130&quot;,
  &quot;latitude&quot;: 37.498095,
  &quot;longitude&quot;: 127.027610,
  &quot;price&quot;: 50000,
  &quot;openingHours&quot;: &quot;09:00&quot;,
  &quot;closingHours&quot;: &quot;18:00&quot;,
  &quot;phoneNumber&quot;: &quot;010-1234-5678&quot;,
  &quot;imageUrls&quot;: [&quot;global/data/image/534231e3-76a0-402b-9970-dcdasd296b3.jpg&quot;],
  &quot;type&quot;: &quot;PHOTO&quot;,
  &quot;maxCapacity&quot;: 10,
  &quot;parkingAvailable&quot;: true,
  &quot;petAvailable&quot;: false,
  &quot;smokingAvailable&quot;: false,
  &quot;hasKitchen&quot;: true,
  &quot;hasRestroom&quot;: true,
  &quot;facilities&quot;: [&quot;WIFI&quot;, &quot;PROJECTOR&quot;]
}' -v&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;b&gt;1) 백엔드 서버에서의 공간 등록 성공&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;703&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B65F7/dJMcag44VQ9/ZT4kVG0KpfTm1E4wWzUpzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B65F7/dJMcag44VQ9/ZT4kVG0KpfTm1E4wWzUpzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B65F7/dJMcag44VQ9/ZT4kVG0KpfTm1E4wWzUpzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB65F7%2FdJMcag44VQ9%2FZT4kVG0KpfTm1E4wWzUpzK%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;217&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;200 응답코드와 함께 공간 등록이 성공되었다는 로그메시지 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) Git Bash에서의 공간 등록 성공 로그&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ curl -X POST &quot;&amp;lt;http://localhost:8090/api/v1/spaces&amp;gt;&quot; \\
-H &quot;Content-Type: application/json&quot; \\
-H &quot;Authorization: Bearer 반환된토큰&quot; \\
-d '{
  &quot;name&quot;: &quot;DB연동 테스트공간&quot;,
  &quot;description&quot;: &quot;curl 명령어로 등록한 테스트 공간입니다.&quot;,
  &quot;address&quot;: &quot;서울시 강남구&quot;,
  &quot;detailAddress&quot;: &quot;역삼동 123-45&quot;,
  &quot;zipCode&quot;: &quot;06130&quot;,
  &quot;latitude&quot;: 37.498095,
  &quot;longitude&quot;: 127.027610,
  &quot;price&quot;: 50000,
  &quot;openingHours&quot;: &quot;09:00&quot;,
  &quot;closingHours&quot;: &quot;18:00&quot;,
  &quot;phoneNumber&quot;: &quot;010-1234-5678&quot;,
  &quot;imageUrls&quot;: [&quot;global/data/image/534231e3-76a0-402b-9970-dcasdasd96b3.jpg&quot;],
  &quot;type&quot;: &quot;PHOTO&quot;,
  &quot;capacity&quot;: 10,
  &quot;parkingAvailable&quot;: true,
  &quot;petAvailable&quot;: false,
  &quot;smokingAvailable&quot;: false,
  &quot;hasKitchen&quot;: true,
}' -vcilities&quot;: [&quot;WIFI&quot;, &quot;PROJECTOR&quot;]
Note: Unnecessary use of -X or --request, POST is already inferred.
* Host localhost:8090 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8090...
* Connected to localhost (::1) port 8090
* using HTTP/1.x
&amp;gt; POST /api/v1/spaces HTTP/1.1
&amp;gt; Host: localhost:8090
&amp;gt; User-Agent: curl/8.10.1
&amp;gt; Accept: */*
&amp;gt; Content-Type: application/json
&amp;gt; Authorization: Bearer 반환된토큰
&amp;gt; Content-Length: 653
&amp;gt;
* upload completely sent off: 653 bytes
&amp;lt; HTTP/1.1 200
&amp;lt; Vary: Origin
&amp;lt; Vary: Access-Control-Request-Method
&amp;lt; Vary: Access-Control-Request-Headers
&amp;lt; X-Content-Type-Options: nosniff
&amp;lt; X-XSS-Protection: 0
&amp;lt; Cache-Control: no-cache, no-store, max-age=0, must-revalidate
&amp;lt; Pragma: no-cache
&amp;lt; Expires: 0
&amp;lt; X-Frame-Options: SAMEORIGIN
&amp;lt; Content-Type: application/json
&amp;lt; Transfer-Encoding: chunked
&amp;lt; Date: Wed, 28 May 2025 04:46:34 GMT
&amp;lt;
{&quot;resultCode&quot;:&quot;S-1&quot;,&quot;msg&quot;:&quot;공간 등록 성공&quot;,&quot;data&quot;:{&quot;id&quot;:2,&quot;hostId&quot;:3,&quot;imageId&quot;:null,&quot;spaceName&quot;:&quot;DB연동 공간테스트1&quot;,&quot;description&quot;:&quot;curl 명령어로 등록한 테스트 공간입니다.&quot;,&quot;uploadDate&quot;:&quot;2025-05-28T13:46:34.8586441&quot;,&quot;spaceType&quot;:&quot;PHOTO&quot;,&quot;price&quot;:50000,&quot;address&quot;:&quot;서울시 강남구&quot;,&quot;latitude&quot;:37.5665,&quot;longitude&quot;:126.978,&quot;maxCapacity&quot;:10,&quot;isActive&quot;:true,&quot;spaceRating&quot;:0,&quot;isFavoritedByMe&quot;:null,&quot;imageUrl&quot;:&quot;global/data/image/534231e3-76a0-402b-9970-dce79db296b3.jpg&quot;,&quot;additionalImageUrls&quot;:[]},&quot;success&quot;:true,&quot;fail&quot;:false}* Connection #0 to host localhost left intact&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트 마무리&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C1szJ/dJMcahJGTKo/F5pAokqjdc6MQmwMOCvo31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C1szJ/dJMcahJGTKo/F5pAokqjdc6MQmwMOCvo31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C1szJ/dJMcahJGTKo/F5pAokqjdc6MQmwMOCvo31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC1szJ%2FdJMcahJGTKo%2FF5pAokqjdc6MQmwMOCvo31%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;git 통합의 경우에는 기능브랜치를 분기한 팀원들이 기능개발을 완료하면 부팀장 (개발팀장)으로써 Git 통합을 진행함&lt;br /&gt;➡️코드 리뷰 및 이 코드가 왜 쓰였는지 등등 (on Discord)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;815&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nhrMc/dJMb99Za79K/9ClJw4sQODizAcsZnkWHYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nhrMc/dJMb99Za79K/9ClJw4sQODizAcsZnkWHYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nhrMc/dJMb99Za79K/9ClJw4sQODizAcsZnkWHYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnhrMc%2FdJMb99Za79K%2F9ClJw4sQODizAcsZnkWHYk%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;461&quot; height=&quot;815&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;815&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ztk2y/dJMcafryXU8/pA5bkSMoAyKKL9Rk50XKj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ztk2y/dJMcafryXU8/pA5bkSMoAyKKL9Rk50XKj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ztk2y/dJMcafryXU8/pA5bkSMoAyKKL9Rk50XKj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fztk2y%2FdJMcafryXU8%2FpA5bkSMoAyKKL9Rk50XKj0%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최종적으로는 MySQL DB로의 마이그레이션에 성공했고, Amazon S3를 통해 이미지 업로드 구현 및 Spring 으로써 블로그 서비스의 전반적인 환경을 개발해낼 수 있었음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZIy72/dJMcaaDMxSG/0aHpQ10Mb6tMwnyFD7Jd70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZIy72/dJMcaaDMxSG/0aHpQ10Mb6tMwnyFD7Jd70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZIy72/dJMcaaDMxSG/0aHpQ10Mb6tMwnyFD7Jd70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZIy72%2FdJMcaaDMxSG%2F0aHpQ10Mb6tMwnyFD7Jd70%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;3000&quot; height=&quot;1545&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1545&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q339w/dJMcacInzUK/CvvBP0bUkQMUB4Rcv9DAs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q339w/dJMcacInzUK/CvvBP0bUkQMUB4Rcv9DAs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q339w/dJMcacInzUK/CvvBP0bUkQMUB4Rcv9DAs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ339w%2FdJMcacInzUK%2FCvvBP0bUkQMUB4Rcv9DAs1%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;3000&quot; height=&quot;1428&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJ9HKQ/dJMcacInzUM/miE6ZeC3SGAkgRaRctZwAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJ9HKQ/dJMcacInzUM/miE6ZeC3SGAkgRaRctZwAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJ9HKQ/dJMcacInzUM/miE6ZeC3SGAkgRaRctZwAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJ9HKQ%2FdJMcacInzUM%2FmiE6ZeC3SGAkgRaRctZwAK%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;3000&quot; height=&quot;486&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&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;br /&gt;서비스를 개발하면서 필요해진 기능까지 추가하며 업데이트했던 요구사항 정의서 시트지&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;팀원들과 각자 해낸 기능개발이 생기면 바로 체크해놓을 수 있도록함&lt;/li&gt;
&lt;li&gt;중요도 (MVP)를 나누어서 중요한 기능부터 개발해내는 과정에서 이러한 시각적인 자료가 필수적이었음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;⚠️요구사항 정의서에 정의된 기능을 꼭 개발해내야겠다는 생각을 하다보니 &lt;br /&gt;기능 하나하나의 안정성 및 테스트에는 신경을 쓰지 못했음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUqMt2/dJMcahbP7y4/fff2bBL1YruQpOpe7jjJn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUqMt2/dJMcahbP7y4/fff2bBL1YruQpOpe7jjJn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUqMt2/dJMcahbP7y4/fff2bBL1YruQpOpe7jjJn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUqMt2%2FdJMcahbP7y4%2Ffff2bBL1YruQpOpe7jjJn0%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 구조의 ERD는 중간 피드백과 팀원들간의 기능개발에 중점을 두어 최종적으로 완성할 수 있었음&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;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckBhRa/dJMcadf9YQQ/ViO8RqDSGsyBG7EEe6Lo80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckBhRa/dJMcadf9YQQ/ViO8RqDSGsyBG7EEe6Lo80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckBhRa/dJMcadf9YQQ/ViO8RqDSGsyBG7EEe6Lo80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckBhRa%2FdJMcadf9YQQ%2FViO8RqDSGsyBG7EEe6Lo80%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&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;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOCE6l/dJMcadf9YQR/9s5Q6LwkgUBpwM0IsVRlfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOCE6l/dJMcadf9YQR/9s5Q6LwkgUBpwM0IsVRlfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOCE6l/dJMcadf9YQR/9s5Q6LwkgUBpwM0IsVRlfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOCE6l%2FdJMcadf9YQR%2F9s5Q6LwkgUBpwM0IsVRlfK%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유저 및 채팅/공간 부분에 대한 ERD도 여러번의 개선 끝에 필요한 부분을 남기고 불필요한 부분은 제거해낼 수 있었음'&lt;/li&gt;
&lt;li&gt;중간 피드백 내용 중 유저가 어드민/게스트/호스트로 나눌지&lt;br /&gt;유저가 게스트/호스트로만 나누어지고 어드민은 따로 둘지 등을 고민하는 과정이 있었음&lt;br /&gt;✅최종적으로는 어드민은 분리하여 관리자페이지 (백오피스)에서 권한을 토대로 활용할 수 있도록 설계하였음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;트러블 슈팅&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v6cUl/dJMcahpn9cW/N11riFUPD0BF65StcTJ0xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v6cUl/dJMcahpn9cW/N11riFUPD0BF65StcTJ0xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v6cUl/dJMcahpn9cW/N11riFUPD0BF65StcTJ0xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv6cUl%2FdJMcahpn9cW%2FN11riFUPD0BF65StcTJ0xk%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&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;4000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddqqHB/dJMcabWZLYw/xkrVRjnVTNAHygYddYVok0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddqqHB/dJMcabWZLYw/xkrVRjnVTNAHygYddYVok0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddqqHB/dJMcabWZLYw/xkrVRjnVTNAHygYddYVok0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddqqHB%2FdJMcabWZLYw%2FxkrVRjnVTNAHygYddYVok0%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;4000&quot; height=&quot;2250&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2250&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LoCo 블로그 서비스 페이지&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;게스트 페이지&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 메인 페이지&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;1317&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1GPR5/dJMcahpn9zz/tGK4XBZK3neoDkSyiZknqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1GPR5/dJMcahpn9zz/tGK4XBZK3neoDkSyiZknqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1GPR5/dJMcahpn9zz/tGK4XBZK3neoDkSyiZknqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1GPR5%2FdJMcahpn9zz%2FtGK4XBZK3neoDkSyiZknqK%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;1317&quot; height=&quot;1292&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;공간을 카테고리 별로 분류하여 빠르게 필요한 공간을 찾을 수 있고 &lt;br /&gt;검색기능에서 필터 및 검색어를 통해 원하는 공간을 상세하게 찾을 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 로그인 페이지&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;462&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ii1TL/dJMcadAsx7X/Uzmm5xRk7itQTKPI7TqTW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ii1TL/dJMcadAsx7X/Uzmm5xRk7itQTKPI7TqTW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ii1TL/dJMcadAsx7X/Uzmm5xRk7itQTKPI7TqTW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIi1TL%2FdJMcadAsx7X%2FUzmm5xRk7itQTKPI7TqTW0%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;462&quot; height=&quot;559&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;회원가입이 되지 않은 상태이면 아래의 &quot;회원가입&quot;버튼을 눌러 회원가입을 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 회원가입 페이지&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;1329&quot; data-origin-height=&quot;1289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwYMJR/dJMcabvVGTf/ggJndcEjqrCGUyhYPk1KfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwYMJR/dJMcabvVGTf/ggJndcEjqrCGUyhYPk1KfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwYMJR/dJMcabvVGTf/ggJndcEjqrCGUyhYPk1KfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwYMJR%2FdJMcabvVGTf%2FggJndcEjqrCGUyhYPk1KfK%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;1329&quot; height=&quot;1289&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;1289&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;소셜로그인 기능 ➡️카카오 로그인 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 로그인된 메인페이지&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;1276&quot; data-origin-height=&quot;1302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7MS7c/dJMcaaDMyd6/kuGuLDvMVpY0E3epYk3X1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7MS7c/dJMcaaDMyd6/kuGuLDvMVpY0E3epYk3X1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7MS7c/dJMcaaDMyd6/kuGuLDvMVpY0E3epYk3X1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7MS7c%2FdJMcaaDMyd6%2FkuGuLDvMVpY0E3epYk3X1K%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;1276&quot; height=&quot;1302&quot; data-origin-width=&quot;1276&quot; data-origin-height=&quot;1302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우측 상단으로 로그인이 성공한 유저 정보를 확인할 수 있음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-1) 검색 페이지 (카테고리 : &quot;카페&quot;)&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;1792&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boQpKi/dJMcabJtrQn/vVkdOOYNiq2pzGz2K7kx60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boQpKi/dJMcabJtrQn/vVkdOOYNiq2pzGz2K7kx60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boQpKi/dJMcabJtrQn/vVkdOOYNiq2pzGz2K7kx60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboQpKi%2FdJMcabJtrQn%2FvVkdOOYNiq2pzGz2K7kx60%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;1792&quot; height=&quot;642&quot; data-origin-width=&quot;1792&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메인 페이지에서 &quot;카페&quot; 카테고리를 클릭하여 &quot;카페&quot; 카테고리로 등록된 공간을 확인할 수 있는 검색 페이지&lt;/li&gt;
&lt;li&gt;URL에서 &lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;/spaces/search?purpose=CAFE&lt;/b&gt;&lt;/span&gt; 로 API 요청 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-2) 검색 페이지 (검색어 : &quot;인천&quot;)&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;1772&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnjHps/dJMcagcWBOu/UcKlLSG7yiUZgElG4yGen1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnjHps/dJMcagcWBOu/UcKlLSG7yiUZgElG4yGen1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnjHps/dJMcagcWBOu/UcKlLSG7yiUZgElG4yGen1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnjHps%2FdJMcagcWBOu%2FUcKlLSG7yiUZgElG4yGen1%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;1772&quot; height=&quot;686&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;URL에서 &lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;/spaces/search?query=인천&lt;/b&gt;&lt;/span&gt; 으로 API 요청 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6) 사이드탭&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;967&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btEm0O/dJMcafSDyzI/CXUcjYo5RaXpkkgSjyAOZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btEm0O/dJMcafSDyzI/CXUcjYo5RaXpkkgSjyAOZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btEm0O/dJMcafSDyzI/CXUcjYo5RaXpkkgSjyAOZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtEm0O%2FdJMcafSDyzI%2FCXUcjYo5RaXpkkgSjyAOZk%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;967&quot; height=&quot;707&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;프로필 관리를 누르게되면 프로필 정보를 변경할 수 있는 마이페이지로 리다이렉트됨&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7) 마이페이지&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;1272&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4qCma/dJMcajtUAKS/nBmXUjpkQ2vUH3onCjkdD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4qCma/dJMcajtUAKS/nBmXUjpkQ2vUH3onCjkdD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4qCma/dJMcajtUAKS/nBmXUjpkQ2vUH3onCjkdD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4qCma%2FdJMcajtUAKS%2FnBmXUjpkQ2vUH3onCjkdD1%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;1272&quot; height=&quot;469&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;469&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;호스트 페이지&lt;/b&gt;&lt;/h3&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;1) 호스트센터 페이지&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;1242&quot; data-origin-height=&quot;1281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kUWOc/dJMb99SqaH0/uXx1pD9VxThnq9KZeTKk20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kUWOc/dJMb99SqaH0/uXx1pD9VxThnq9KZeTKk20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kUWOc/dJMb99SqaH0/uXx1pD9VxThnq9KZeTKk20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkUWOc%2FdJMb99SqaH0%2FuXx1pD9VxThnq9KZeTKk20%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;1242&quot; height=&quot;1281&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;1281&quot;/&gt;&lt;/span&gt;&lt;/figure&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;li&gt;호스트에 대한 접근은 &lt;br /&gt;1) 게스트로 회원가입 후 호스트로 전환할것인지, &lt;br /&gt;2) 호스트 자체 회원가입을 별도로 구분할지에 대한 고민들도 있었음 &lt;br /&gt;➡️현재는 &lt;b&gt;호스트 자체 회원가입&lt;/b&gt;을 별도로 두는 방향으로 설계&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;게스트와 호스트의 페이지를 분리한 이유는 각 유저의 역할 별로의 기능 구분이 명확히 필요함과 &lt;br /&gt;동시에 유지보수의 용이성을 고려했고 게스트와 호스트가 하는 역할이 다르다고 판단하여 이러한 설계로 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 호스트 로그인 페이지&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;839&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBnsEw/dJMcah3YOTm/eSMG2vvMmPU3bKMvrhR7H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBnsEw/dJMcah3YOTm/eSMG2vvMmPU3bKMvrhR7H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBnsEw/dJMcah3YOTm/eSMG2vvMmPU3bKMvrhR7H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBnsEw%2FdJMcah3YOTm%2FeSMG2vvMmPU3bKMvrhR7H1%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;1235&quot; height=&quot;839&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;839&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상단 메뉴의 공간작성을 클릭하면 &quot;로그인이 필요한 서비스입니다&quot; 문구를 통해 인증이 필요한 로직을 구현&lt;/li&gt;
&lt;/ul&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;1256&quot; data-origin-height=&quot;879&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SDdWW/dJMcai9BQ40/efmBU2RG7nUpI6rkKLnQY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SDdWW/dJMcai9BQ40/efmBU2RG7nUpI6rkKLnQY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SDdWW/dJMcai9BQ40/efmBU2RG7nUpI6rkKLnQY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSDdWW%2FdJMcai9BQ40%2FefmBU2RG7nUpI6rkKLnQY1%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;1256&quot; height=&quot;879&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;879&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 호스트 회원가입 페이지&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;1256&quot; data-origin-height=&quot;1027&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1pycA/dJMcabioJOk/u8I6dHfgun1zmCFjhgvG5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1pycA/dJMcabioJOk/u8I6dHfgun1zmCFjhgvG5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1pycA/dJMcabioJOk/u8I6dHfgun1zmCFjhgvG5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1pycA%2FdJMcabioJOk%2Fu8I6dHfgun1zmCFjhgvG5k%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;1256&quot; height=&quot;1027&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;1027&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게스트 회원가입 페이지와 마찬가지로 이메일 인증 로직과 전화번호, 비밀번호 유효성 검증 후 회원가입이 이루어짐&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4) 공간 등록 페이지&lt;/b&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;1493&quot; data-origin-height=&quot;957&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brIdD0/dJMcaacIn5U/zwb7CQzWq9lrMGkuyyj2k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brIdD0/dJMcaacIn5U/zwb7CQzWq9lrMGkuyyj2k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brIdD0/dJMcaacIn5U/zwb7CQzWq9lrMGkuyyj2k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrIdD0%2FdJMcaacIn5U%2Fzwb7CQzWq9lrMGkuyyj2k0%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;1493&quot; height=&quot;957&quot; data-origin-width=&quot;1493&quot; data-origin-height=&quot;957&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;745&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfspvh/dJMcagxewsf/ujBK7Kr4WtMaLNMDdckDl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfspvh/dJMcagxewsf/ujBK7Kr4WtMaLNMDdckDl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfspvh/dJMcagxewsf/ujBK7Kr4WtMaLNMDdckDl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdfspvh%2FdJMcagxewsf%2FujBK7Kr4WtMaLNMDdckDl0%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;745&quot; height=&quot;677&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;677&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;496&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cW7dwn/dJMcagRw8gK/Ie0yCQqeR0cDuGLvSXKm4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cW7dwn/dJMcagRw8gK/Ie0yCQqeR0cDuGLvSXKm4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cW7dwn/dJMcagRw8gK/Ie0yCQqeR0cDuGLvSXKm4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcW7dwn%2FdJMcagRw8gK%2FIe0yCQqeR0cDuGLvSXKm4K%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;496&quot; height=&quot;257&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765016462972&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kakao:
  map:
    javascript-key: API키값&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;application-secret.yml 부분에서 카카오맵 API 키를 발급 받아 사용하여 공간의 상세주소검색이 가능하도록 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wO9La/dJMcacO8snQ/aHtz2RI0wwGqXtZsMxip10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wO9La/dJMcacO8snQ/aHtz2RI0wwGqXtZsMxip10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wO9La/dJMcacO8snQ/aHtz2RI0wwGqXtZsMxip10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwO9La%2FdJMcacO8snQ%2FaHtz2RI0wwGqXtZsMxip10%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;632&quot; height=&quot;778&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;778&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;844&quot; data-origin-height=&quot;965&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUCBND/dJMcahbP8tL/UKjc7sob6tCIMwl0Cu9GEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUCBND/dJMcahbP8tL/UKjc7sob6tCIMwl0Cu9GEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUCBND/dJMcahbP8tL/UKjc7sob6tCIMwl0Cu9GEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUCBND%2FdJMcahbP8tL%2FUKjc7sob6tCIMwl0Cu9GEk%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;844&quot; height=&quot;965&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;965&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;1111&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/waton/dJMcabo9HHx/EX1nhV35DMto1D74zfkuvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/waton/dJMcabo9HHx/EX1nhV35DMto1D74zfkuvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/waton/dJMcabo9HHx/EX1nhV35DMto1D74zfkuvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwaton%2FdJMcabo9HHx%2FEX1nhV35DMto1D74zfkuvK%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;1111&quot; height=&quot;486&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1355&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3MJZQ/dJMcaiIxVTm/Uz9Igc2ciGduaaICoh1s61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3MJZQ/dJMcaiIxVTm/Uz9Igc2ciGduaaICoh1s61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3MJZQ/dJMcaiIxVTm/Uz9Igc2ciGduaaICoh1s61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3MJZQ%2FdJMcaiIxVTm%2FUz9Igc2ciGduaaICoh1s61%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;1355&quot; height=&quot;592&quot; data-origin-width=&quot;1355&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예약 페이지&lt;/b&gt;&lt;/h3&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;1) 메인 페이지 (등록된 공간들 확인)&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;967&quot; data-origin-height=&quot;831&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ch1UuR/dJMcadmVfMO/aZAH7HTvyi8ck2TY83sBy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ch1UuR/dJMcadmVfMO/aZAH7HTvyi8ck2TY83sBy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ch1UuR/dJMcadmVfMO/aZAH7HTvyi8ck2TY83sBy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fch1UuR%2FdJMcadmVfMO%2FaZAH7HTvyi8ck2TY83sBy1%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;967&quot; height=&quot;831&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;831&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 공간 상세 페이지&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;1165&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbfDbv/dJMcagcWCbT/N1CpXX6TiNpJLkP2oGXgt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbfDbv/dJMcagcWCbT/N1CpXX6TiNpJLkP2oGXgt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbfDbv/dJMcagcWCbT/N1CpXX6TiNpJLkP2oGXgt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbfDbv%2FdJMcagcWCbT%2FN1CpXX6TiNpJLkP2oGXgt0%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;1165&quot; height=&quot;564&quot; data-origin-width=&quot;1165&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-1) 공간 예약 확인 페이지&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;1153&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVConK/dJMcaaKyqZu/4l5SsGCYxOQUK6h095rKOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVConK/dJMcaaKyqZu/4l5SsGCYxOQUK6h095rKOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVConK/dJMcaaKyqZu/4l5SsGCYxOQUK6h095rKOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVConK%2FdJMcaaKyqZu%2F4l5SsGCYxOQUK6h095rKOK%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;1153&quot; height=&quot;319&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-2) 예약 확인 및 결제하기 버튼 활성화 페이지&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;1084&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/34Lfl/dJMcaaX5Msx/fYOc2aozCXqfX43HuXkspk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/34Lfl/dJMcaaX5Msx/fYOc2aozCXqfX43HuXkspk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/34Lfl/dJMcaaX5Msx/fYOc2aozCXqfX43HuXkspk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F34Lfl%2FdJMcaaX5Msx%2FfYOc2aozCXqfX43HuXkspk%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;1084&quot; height=&quot;305&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style1&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 결제 페이지&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;1085&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JMgUl/dJMcahQrK3Q/mIWiodKLhdTUKXb5nlroVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JMgUl/dJMcahQrK3Q/mIWiodKLhdTUKXb5nlroVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JMgUl/dJMcahQrK3Q/mIWiodKLhdTUKXb5nlroVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJMgUl%2FdJMcahQrK3Q%2FmIWiodKLhdTUKXb5nlroVK%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;1085&quot; height=&quot;691&quot; data-origin-width=&quot;1085&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765016904116&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;toss:                           # 토스페이먼츠 파트
  payments:
    secret-key: 테스트키 # LoCo 프로젝트 토스페이먼츠 시크릿키
    success-url: &quot;http://localhost:8090/api/v1/payments/success&quot;
    fail-url: &quot;http://localhost:8090/api/v1/payments/fail&quot;&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;토스페이먼츠 API 와 연동하여 시크릿키를 발급받아 application-secret.yml 에 적용&lt;/li&gt;
&lt;li&gt;그 결과 토스페이먼츠를 통해 다양한 은행을 통해 결제할 수 있도록 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnXfWP/dJMcaf6aiZt/BJ5s81f0YldsktKjbq7vcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnXfWP/dJMcaf6aiZt/BJ5s81f0YldsktKjbq7vcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnXfWP/dJMcaf6aiZt/BJ5s81f0YldsktKjbq7vcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnXfWP%2FdJMcaf6aiZt%2FBJ5s81f0YldsktKjbq7vcK%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;702&quot; height=&quot;673&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex. KB국민카드의 경우 KB Pay 앱을 실행하여 QR스캔 후 결제할 수 있도록 구현&lt;/li&gt;
&lt;li&gt;배포되기 전 서비스이기때문에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;실제 결제까지는 &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이루어지지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;관리자 페이지 (=어드민 페이지, 백오피스)&lt;/b&gt;&lt;/h3&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;1) 대시보드 페이지&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;1268&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmvbX1/dJMcacInAPz/VYfXr0H6d45HxjHzjaQKq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmvbX1/dJMcacInAPz/VYfXr0H6d45HxjHzjaQKq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmvbX1/dJMcacInAPz/VYfXr0H6d45HxjHzjaQKq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmvbX1%2FdJMcacInAPz%2FVYfXr0H6d45HxjHzjaQKq0%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;1268&quot; height=&quot;1058&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 사용자 관리 페이지&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1874&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SJ3Dm/dJMcaaKyq5A/NuQuhP3qjq5FqKlZVgk2MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SJ3Dm/dJMcaaKyq5A/NuQuhP3qjq5FqKlZVgk2MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SJ3Dm/dJMcaaKyq5A/NuQuhP3qjq5FqKlZVgk2MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSJ3Dm%2FdJMcaaKyq5A%2FNuQuhP3qjq5FqKlZVgk2MK%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;1874&quot; height=&quot;630&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1874&quot; data-origin-height=&quot;630&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;1677&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btE8ty/dJMb99SqbcA/JRgkwoJkwPMcf0Xc1Xpe0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btE8ty/dJMb99SqbcA/JRgkwoJkwPMcf0Xc1Xpe0K/img.png&quot; data-alt=&quot;토글 후 GUEST &amp;amp;gt; HOST 로 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btE8ty/dJMb99SqbcA/JRgkwoJkwPMcf0Xc1Xpe0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtE8ty%2FdJMb99SqbcA%2FJRgkwoJkwPMcf0Xc1Xpe0K%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;1677&quot; height=&quot;414&quot; data-origin-width=&quot;1677&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;토글 후 GUEST &amp;gt; HOST 로 변경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 관리페이지에서는 해당 사용자의 권한을 변경할 수 있는 토글 버튼 (GUEST ➡️ HOST 혹은 HOST ➡️ GUEST)과&lt;/li&gt;
&lt;li&gt;전체 유저 정보가 담겨있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 예약 결제 관리 페이지&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;1869&quot; data-origin-height=&quot;643&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wemC7/dJMcaiu0PvP/ALVa4eTHGvgRzaqn9HjqfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wemC7/dJMcaiu0PvP/ALVa4eTHGvgRzaqn9HjqfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wemC7/dJMcaiu0PvP/ALVa4eTHGvgRzaqn9HjqfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwemC7%2FdJMcaiu0PvP%2FALVa4eTHGvgRzaqn9HjqfK%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;1869&quot; height=&quot;643&quot; data-origin-width=&quot;1869&quot; data-origin-height=&quot;643&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기능 시연 영상 &lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;전체 발표 영상은 개인채널에 별도 업로드 완료&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=dQzQO2KjDYg&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=dQzQO2KjDYg&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=dQzQO2KjDYg&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/z1Kxp/hyZOXQtYia/qfA4hK9Rjj094EgKotN121/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/55EJd/hyZOXwc4q1/BhO9zfvOG3oMy61GtKsZWk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/UObqV/hyZOBy1Pxh/Crc32iMUSekx8CH0upvSmK/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;LoCo 최종 발표 시연 영상&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/dQzQO2KjDYg&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;팀원분이 업로드한 기능시연 영상&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 프로젝트를 마무리하며 :&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;팀 프로젝트를 진행해보며 Github Project에서의 협업 및 Git 명령어에 익숙해질 수 있었고&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데일리 스크럼을 통해 기능 개발 및 요구사항 정의를 기획해나가는 과정도 뜻깊었다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Git branch를 분기하여 팀원들이 각각 기능을 개발하고 추후 병합할때 충돌된 부분들을 함께 해결해나가는 부분도&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;도전의식과 함께 희열, 뿌듯함도 느낄 수 있었다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;어려움이 없던 프로젝트라고한다면 거짓말이겠지만 어려웠던 만큼 어떤 부분이 부족한지, 어떤 부분에 강점인지를 파악할 수 있어&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;개발 공부에 큰 원동력이 될 수 있었다. &lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>api 명세</category>
      <category>BCrypt</category>
      <category>CURL</category>
      <category>Til</category>
      <category>공유공간</category>
      <category>관리자 페이지</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 자바</category>
      <category>카카오맵 API</category>
      <category>토스페이먼츠 API</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/299</guid>
      <comments>https://lefton.tistory.com/299#entry299comment</comments>
      <pubDate>Mon, 8 Dec 2025 10:37:58 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_108일차_&amp;quot;DB 마이그레이션 및 중간 피드백&amp;quot;</title>
      <link>https://lefton.tistory.com/297</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [108]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 108&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 빠른 디버깅 및 테스트용으로 쓰던 H2 데이터베이스에서 MySQL 데이터베이스로 마이그레이션하는 작업과 application.yml 설정 수정, 관리자페이지 즉 백오피스의 개념 및 필요성에 대해서 팀원들과 회의 (2025.05.20)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;103%EC%9D%BC%EC%B0%A8%20%EA%B8%B0%EB%8A%A5%EA%B0%9C%EB%B0%9C%20Log-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;H2 DB ➡️ MySQL DB 마이그레이션 작업&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1qE4R/dJMcadtHw8Z/6KqIGKZOCkpfK7v877Ddk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1qE4R/dJMcadtHw8Z/6KqIGKZOCkpfK7v877Ddk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1qE4R/dJMcadtHw8Z/6KqIGKZOCkpfK7v877Ddk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1qE4R%2FdJMcadtHw8Z%2F6KqIGKZOCkpfK7v877Ddk0%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;780&quot; height=&quot;487&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Io8z4/dJMcaiIxS4X/V3VxJmZn6gfWedqbmGPbb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Io8z4/dJMcaiIxS4X/V3VxJmZn6gfWedqbmGPbb1/img.png&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;181&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;62.6&quot; data-filename=&quot;blob&quot; style=&quot;width: 61.8698%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Io8z4/dJMcaiIxS4X/V3VxJmZn6gfWedqbmGPbb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIo8z4%2FdJMcaiIxS4X%2FV3VxJmZn6gfWedqbmGPbb1%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;405&quot; height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lH7nt/dJMcagKLTir/pn4qLMak2eFJB70bzqGLCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lH7nt/dJMcagKLTir/pn4qLMak2eFJB70bzqGLCK/img.png&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;276&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;37.4&quot; data-filename=&quot;blob&quot; style=&quot;width: 36.9674%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lH7nt/dJMcagKLTir/pn4qLMak2eFJB70bzqGLCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlH7nt%2FdJMcagKLTir%2Fpn4qLMak2eFJB70bzqGLCK%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;369&quot; height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Jsvr/dJMcac9oPgB/DueQzq9R2ydaKfy97QJsc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Jsvr/dJMcac9oPgB/DueQzq9R2ydaKfy97QJsc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Jsvr/dJMcac9oPgB/DueQzq9R2ydaKfy97QJsc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Jsvr%2FdJMcac9oPgB%2FDueQzq9R2ydaKfy97QJsc1%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;591&quot; height=&quot;485&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;show tables; 로 마이그레이션된 테이블들 확인 완료&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;application.yml&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;  datasource:
    url: jdbc:mysql://localhost:0000/loco_db
    username: nenomdeul
    password: xxxx
    # url: jdbc:h2:./db_dev;MODE=MySQL
    # username: sa
    # password:
    # driver-class-name: org.h2.Driver&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;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;백오피스 Backoffice 필요성&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;관리자 결제 내역 조회, 환불 처리, 통계 관리 등 기능이 필요&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓LMS, PMS, 백오피스의 차이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) LMS &lt;/b&gt;: Learning Management System(학습 관리 시스템) &lt;br /&gt;- 교육/강의/수강생 관리 중심&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) PMS &lt;/b&gt;: Property Management System(부동산/공간 관리 시스템)&lt;br /&gt;- 호텔, 공간, 예약, 청소 등 자산 관리 중심&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 백오피스 &lt;/b&gt;: 서비스 운영자(관리자)가 전체 시스템을&amp;nbsp;관리하는 내부 시스템&lt;br /&gt;(ex. 회원, 예약, 결제, 통계, 신고, 환불 등)&lt;/p&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;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;LoCo 프로젝트&lt;/b&gt;&lt;/span&gt;는 공간 예약/결제/회원/호스트/게스트/통계/환불/신고 등 다양한&amp;nbsp;관리가 필요하므로&amp;nbsp;&lt;br /&gt;LMS, PMS라기보다는 &quot;백오피스&quot;가 포함된 공간 서비스로 개발이 필요&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;관리자 페이지 기능 개발 (LoCo 프로젝트)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;프로토타입&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J7sl7/dJMcac2C9JN/8OwsaS32tJLZ06VOxdRoi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J7sl7/dJMcac2C9JN/8OwsaS32tJLZ06VOxdRoi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J7sl7/dJMcac2C9JN/8OwsaS32tJLZ06VOxdRoi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ7sl7%2FdJMcac2C9JN%2F8OwsaS32tJLZ06VOxdRoi0%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;1268&quot; height=&quot;1058&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;중간 피드백&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 관리자 엔드포인트에는 반드시 관리자 권한 검증이 필요&lt;br /&gt;➡️Spring Security의 @PreAuthorize(&quot;hasRole('ADMIN')&quot;) 같은 어노테이션 사용 추천&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Swagger 문서화 정보가 보충될 필요 ➡️@Operation 관련 내용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 잘못된 ID나 이미 처리된 공간에 대한 예외 처리를 추가 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) PR에서 팀원 간 상세한 코드 리뷰의 필요성&lt;br /&gt;➡️Repository에 리뷰 과정이 기록되어있는 것이 좋음&lt;br /&gt;➡️구체적으로는 PR에서 File Changed 탭에서 코드에 대한 의견과 개선점과 같은 것들을 Comment로 첨언해서 기록하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) 주석 관련하여 메서드나 필드 자체를 설명하기 위한 Docs 주석은 좋았지만 일부 다른 구간에서 불필요 주석 및 업데이트 되지 않은 주석이 있는 부분 수정 필요&lt;br /&gt;➡️주석으로 구분하기보다 기능을 메서드로 분리하여 가독성을 향상시키는 것이 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6) 테스트 코드에 대한 내용 필요&lt;br /&gt;➡️테스트를 위한 개발을 하는 것은 좋지 않지만, 현재 개발되어있는 기능들에 대한 테스트와 명세를 남기는 것도 도움이 됨&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스의 마이그레이션에서 application.yml 설정파일들에 대한 공부를 진행할 수 있었음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;관리자페이지의 필요성에 대해 알고 백오피스 페이지 개발에 대해 팀원들과 상의할 수 있었음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;중간 피드백을 통해 프로젝트 개발 중간의 개선사항과 방향성에 대해 파악할 수 있었음 &lt;br /&gt;(특히 어노테이션의 부재 및 주석 관리 필요성)&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>h2 db</category>
      <category>LMS</category>
      <category>MYSQL DB</category>
      <category>Til</category>
      <category>관리자페이지</category>
      <category>데이터베이스 마이그레이션</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 자바</category>
      <category>백오피스</category>
      <category>블로그 개발</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/297</guid>
      <comments>https://lefton.tistory.com/297#entry297comment</comments>
      <pubDate>Sat, 6 Dec 2025 16:51:38 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_103일차_&amp;quot;Git Projects 이슈 관리 및 게시판 Board&amp;quot;</title>
      <link>https://lefton.tistory.com/296</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [103]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 103&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 각자 만든 기능 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: justify;&quot;&gt;브랜치들의 병합을 위해 &lt;/span&gt;Git Projects로 팀원들의 이슈를 관리할 수 있도록 구축해보았다. 또한 게시판 Board 담당으로 게시글 관련 엔티티 및 Repository, Service, Controller를 설계하였다. (2025.05.13)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;103일차 기능개발 Log&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;깃허브 - 프로젝트 - 이슈생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;867&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/liaZf/dJMcaaXYOOt/WAqWube4x8tgbhZCGWwsTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/liaZf/dJMcaaXYOOt/WAqWube4x8tgbhZCGWwsTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/liaZf/dJMcaaXYOOt/WAqWube4x8tgbhZCGWwsTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FliaZf%2FdJMcaaXYOOt%2FWAqWube4x8tgbhZCGWwsTk%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;943&quot; height=&quot;867&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;867&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;852&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzyO4y/dJMcahiuWTo/wk293aR3VZ5JqKbxNAKvuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzyO4y/dJMcahiuWTo/wk293aR3VZ5JqKbxNAKvuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzyO4y/dJMcahiuWTo/wk293aR3VZ5JqKbxNAKvuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzyO4y%2FdJMcahiuWTo%2Fwk293aR3VZ5JqKbxNAKvuk%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;414&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;414&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;797&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjUSzt/dJMcabJl4o6/9Fxqp4oGTv1Pi6R74W3DJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjUSzt/dJMcabJl4o6/9Fxqp4oGTv1Pi6R74W3DJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjUSzt/dJMcabJl4o6/9Fxqp4oGTv1Pi6R74W3DJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjUSzt%2FdJMcabJl4o6%2F9Fxqp4oGTv1Pi6R74W3DJk%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;797&quot; height=&quot;704&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;704&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;724&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWwNeT/dJMcab3EEvX/a2rvgzveiuPBwr7AV3WutK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWwNeT/dJMcab3EEvX/a2rvgzveiuPBwr7AV3WutK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWwNeT/dJMcab3EEvX/a2rvgzveiuPBwr7AV3WutK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWwNeT%2FdJMcab3EEvX%2Fa2rvgzveiuPBwr7AV3WutK%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;758&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이슈번호 #15 확인 (본인이 만든 이슈번호 확인)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763436940266&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git switch develop&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;현재 브랜치가 develop 브랜치인지 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763436970340&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git pull&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;원격의 develop 브랜치 작업내용 가져오기 - 팀원들이 병합한 코드 최신화&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763437000005&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b feature/#15&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;최신화된 develop 브랜치 내용을 기반으로 feature/#15브랜치가 분기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763437079072&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch&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;&amp;nbsp;(현재 어느 브랜치에 위치해있는지 확인&lt;/li&gt;
&lt;li&gt;[* feature/#15] 처럼 표시됨&lt;/li&gt;
&lt;li&gt;feature/#15 브랜치 확인 후 기능 개발 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1763437134191&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git status
git add .
git commit -m &amp;ldquo;feat: 댓글 엔티티 설계 (#15)&amp;rdquo;&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;기능 개발 진행 후 (#15)처럼 이슈번호를 적어야 이슈트래킹 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;git push --set-upstream origin main
&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;원격 저장소에 feature/#15 브랜치와 함께 feature/#15 브랜치 작업내용을 push&lt;/li&gt;
&lt;li&gt;기능 개발이 끝났으면 저장소에서 &lt;b&gt;Compare &amp;amp; Pull Request로&lt;/b&gt;&amp;nbsp;눌러 &lt;b&gt;PR&lt;/b&gt; 날리기&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Board 게시판 개발&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Board - Controller - 게시글 작성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;웹에서 사용자가 새 게시글을 작성할 때, 프론트엔드(웹 페이지나 앱)에서 백엔드 서버로 보내는 요청을 받아서 처리하는 부분&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@PostMapping // HTTP POST 요청 처리
public ResponseEntity&amp;lt;BoardResponseDto&amp;gt; createBoard(
        @Valid @RequestBody BoardRequestDto boardRequestDto, // 요청 본문을 BoardRequestDto 객체로 매핑하고 유효성 검사 수행
        @AuthenticationPrincipal UserDetails userDetails // 현재 인증된 사용자의 UserDetails 객체 주입
) {
    // 프로젝트의 UserDetails 구현체에서 사용자 ID(Long)를 String으로 반환한다고 가정합니다.
    Long userId = Long.parseLong(userDetails.getUsername()); // UserDetails에서 사용자 ID 가져와 Long으로 변환

    // BoardService의 createBoard 메소드 호출하여 게시글 생성 비즈니스 로직 수행
    BoardResponseDto createdBoard = boardService.createBoard(boardRequestDto, userId);

    // 생성된 게시글 정보(DTO)와 함께 HTTP 상태 코드 201 (Created) 반환
    return ResponseEntity.status(HttpStatus.CREATED).body(createdBoard);
}&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;게시글 작성 API : &lt;b&gt;POST /api/v1/boards&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@param boardRequestDto&lt;/b&gt; : 게시글 생성 요청 데이터 (JSON 형태)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@param userDetails&lt;/b&gt; : 인증된 사용자의 정보 (Spring Security 제공)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@return&lt;/b&gt; : 생성된 게시글 정보와 함께 HTTP 상태 코드 201 (Created) 반환&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@throws ResourceNotFoundException&lt;/b&gt; : Space (공간) 또는 Host (공간 공유자)를 찾을 수 없을 때 발생&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@throws AccessDeniedException :&lt;/b&gt;&amp;nbsp;사용자가 호스트가 아니거나 권한이 없을 때 발생&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;@PostMapping 클라이언트(ex. 웹 브라우저)가 &lt;b&gt;/api/v1/boards&lt;/b&gt; 라는 주소로 &lt;br /&gt;&lt;b&gt;새로운 데이터를 생성해달라&lt;/b&gt;는 요청을 보낼 때, 이 &lt;b&gt;createBoard 메소드&lt;/b&gt;가 실행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;public ResponseEntity&amp;lt;BoardResponseDto&amp;gt; createBoard(...)&amp;nbsp;&lt;br /&gt;&lt;/b&gt;: 반환 타입이 ResponseEntity&amp;lt;BoardResponseDto&amp;gt;인 객체로 &lt;br /&gt;Spring에서 HTTP 응답을 유연하게 다룰 수 있게 해주는 객체&lt;br /&gt;응답 본문(BoardResponseDto)과 HTTP 상태 코드(ex. 성공 201, 에러 400 등)을 함께 보낼 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;b&gt;BoardResponseDto&lt;/b&gt;&lt;br /&gt;: 게시글 생성 요청이 성공했을 때, 클라이언트에게 돌려줄 게시글 정보를 담는 데이터 형태(DTO)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@Valid&lt;/b&gt;&lt;br /&gt;: BoardRequestDto 객체에 설정된 유효성 검사 규칙(ex. 제목은 비어있으면 안됨)을 자동으로 실행해주는 어노테이션&lt;br /&gt;만약 유효성 검사에 실패하면 Spring이 에러 응답을 자동으로 보내 메소드 내부에서 별도로 검사할 필요가 없음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@RequestBody&lt;br /&gt;&lt;/b&gt;: 클라이언트가 HTTP 요청의 본문(body)에 담아 보낸 데이터를 BoardRequestDto 객체로 자동으로 변환(매핑) 후 boardRequestDto 변수에 넣음&lt;br /&gt;(ex. 클라이언트가 JSON 형태로 게시글 제목, 내용 등을 보내면 Spring이 BoardRequestDto 객체로 만들어줌)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@AuthenticationPrincipal UserDetails userDetails&lt;/b&gt;&lt;br /&gt;&lt;b&gt;- @AuthenticationPrincipal&lt;/b&gt; : Spring Security를 통해 &lt;b&gt;현재 로그인(인증)된 사용자&lt;/b&gt;의 정보를 가져와서 &lt;br /&gt;userDetails 변수에 넣어주는 어노테이션&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UserDetails&lt;br /&gt;&lt;/b&gt;: Spring Security에서 사용자 정보를 나타내는 표준 인터페이스&lt;br /&gt;객체 안에 로그인한 사용자의 아이디, 비밀번호, 권한 등의 정보가 담김&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Long userId = Long.parseLong(userDetails.getUsername());&lt;/b&gt;:&lt;br /&gt;- &lt;b&gt;userDetails.getUsername()&lt;/b&gt;: UserDetails 객체에서 사용자의 식별자(ex. 아이디 / 이메일)를 문자열(String) 형태로 가져옴&lt;br /&gt;- &lt;b&gt;Long.parseLong(...)&lt;/b&gt;: 가져온 문자열 형태의 사용자 ID를 숫자(Long) 타입으로 변환&lt;br /&gt;- 현재 게시글을 작성하려는 사용자의 ID를 userId 변수에 저장&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BoardResponseDto createdBoard = boardService.createBoard(boardRequestDto, userId);&lt;/b&gt;:&lt;br /&gt;실제로 게시글을 데이터베이스에 저장하고 비즈니스 로직을 처리하는 부분은 BoardService라는 다른 클래스에 위임&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;boardService.createBoard()&lt;/b&gt; &lt;b&gt;메소드 호출&lt;br /&gt;&lt;/b&gt;: 클라이언트로부터 받은 게시글 정보(boardRequestDto)와 현재 로그인한 사용자의 ID(userId)를 넘김&lt;br /&gt;&lt;br /&gt;- BoardService에서 게시글을 성공적으로 생성하면, 그 결과를 BoardResponseDto 형태로 받아 createdBoard 변수에 저장&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;return ResponseEntity.status(HttpStatus.CREATED).body(createdBoard);&lt;/b&gt;:&lt;br /&gt;- 게시글 생성 비즈니스 로직이 성공적으로 완료되면, 클라이언트에게 응답을 반환&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;ResponseEntity.status(HttpStatus.CREATED)&lt;/b&gt;: HTTP 상태 코드를 201 (Created, 생성됨)으로 설정&lt;br /&gt;(새 데이터가 성공적으로 생성되었음을 의미하는 표준 상태 코드)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;.body(createdBoard)&lt;/b&gt;: &lt;br /&gt;- 응답 본문에 BoardService로부터 받은 createdBoard 객체(생성된 게시글 정보)를 담아서 보냄&lt;/li&gt;
&lt;/ul&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;클라이언트로부터 새 게시글 작성 요청(POST)이 오면, 요청 본문에 담긴 게시글 정보와 현재 로그인한 사용자의 정보를 받아서, Service 계층에 게시글 생성을 요청하고, 서비스에서 성공적으로 게시글을 만들면 생성된 게시글 정보와 함께 '생성됨(201)' 상태 코드를 클라이언트에게 응답으로 돌려주는 역할을 하는 메소드&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;❓AWS S3에서의 이미지 업로드 방식 차이점&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2가지 방식 : Multipart vs Presigned URL&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Multipart 이미지 업로드&lt;/b&gt;&lt;b&gt; (클라이언트 ➡️ 서버 &lt;b&gt;➡️&lt;/b&gt; S3)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;동작 방식&lt;/b&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;1) 클라이언트(ex. 브라우저) 이미지 파일을 HTTP 요청의 본문(multipart/form-data)에 담아&lt;span&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;2) 애플리케이션 서버로 보냄&lt;br /&gt;3) 서버는 이 파일을 받아 S3 SDK를 사용하여 S3 버킷으로 업로드&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;br /&gt;&lt;/b&gt;- 구현이 간단함 (클라이언트 쪽에서는 일반적인 파일 업로드 요청만 보내면 되는 구조)&lt;br /&gt;- 서버에서 파일 내용을 직접 처리하므로 업로드 전 서버에서 추가적인 유효성 검사/가공(ex. 리사이징, 워터마크 추가)이 용이&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;br /&gt;&lt;/b&gt;- 대용량 파일이나 많은 수의 파일이 동시에 업로드될 경우, 서버가 파일 데이터를 직접 처리 및 S3로 전송하므로 서버 부하 증가&lt;br /&gt;➡️서버의 확장성(Scalability)에 병목 가능성&lt;br /&gt;&lt;br /&gt;- (클라이언트 ➡️ 서버, 서버 ➡️ S3) 처럼 두단계이므로 업로드 시간이 길어질 수 있음&lt;br /&gt;&lt;br /&gt;- 서버에 AWS 인증 정보가 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;Presigned S3 이미지 업로드 (클라이언트 ➡️ S3 직접)&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;&lt;b&gt;동작 방식&lt;br /&gt;&lt;/b&gt;1) 클라이언트가 파일 자체를 서버로 보내지 않고 (올릴 수 있는 권한이 담긴 임시 URL)을 요청&lt;br /&gt;2) 서버는 그 요청을 받아 S3 SDK를 사용하여 특정 버킷의 특정 경로에 파일을 업로드할 수 있는 Presigned URL을 생성&lt;br /&gt;3) 클라이언트는 응답받은 이 Presigned URL을 사용하여 S3 버킷에 파일을 직접 업로드&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;br /&gt;- &lt;/b&gt;서버가 파일 데이터를 직접 처리하지 않고 Presigned URL만 생성해주므로, 서버 부하없이 효율적&lt;br /&gt;- 대용량 파일 업로드나 트래픽이 많은 상황에서의 서버 확장성에 용이&lt;br /&gt;- 업로드 시간이 단축 (클라이언트 ➡️ S3 한 단계)&lt;br /&gt;- 클라이언트는 AWS 인증 정보 없이 서버로부터 받은 Presigned URL만으로 안전하게 S3에 접근 가능&lt;br /&gt;- 임시 URL에 제한된 권한과 유효 기간 설정이 가능해 보안성이 높음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;br /&gt;&lt;/b&gt;- 클라이언트 쪽에서 Presigned URL을 받아 S3에 직접 업로드하는 로직 구현이 필요&lt;br /&gt;- 업로드 전 서버에서 파일 내용을 기반으로 하는 유효성 검사나 가공이 어려움&lt;br /&gt;➡️가공을 위해서는 업로드 후 S3 이벤트 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;정리 : &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 큰 규모의 서비스 및 대용량 파일 업로드나 높은 트래픽이 예상된다면 Presigned S3 이미지 업로드 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 개발 초기 단계이거나 파일 크기가 작고 트래픽이 많지 않다면, 구현이 간단한 Multipart 이미지 업로드 방식으로 시작 후&lt;br /&gt;서비스 규모가 커지면 Presigned URL 방식으로 전환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 블로그 서비스처럼 사용자가 직접 이미지를 업로드하는 경우, Presigned URL 방식도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅만약 LoCo 프로젝트에 적용한다면 소규모의 회원이 이용하는 프로젝트이므로 &lt;br /&gt;호스트가 공간 정보 등록/수정 시에만 이미지를 업로드하게 됨&lt;br /&gt;&lt;br /&gt;✅이럴경우 구현이 더 간단한 Multipart 이미지 업로드 방식을 선택하는 것도 방법&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;LoCo 프로젝트 - S3 Multipart 기술 도입 테스트&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;호스트 게시판에 이미지 도입&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbJq0l/dJMcahCUfwB/qnkNKVQF0CoNqZNyVwHBB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbJq0l/dJMcahCUfwB/qnkNKVQF0CoNqZNyVwHBB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbJq0l/dJMcahCUfwB/qnkNKVQF0CoNqZNyVwHBB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbJq0l%2FdJMcahCUfwB%2FqnkNKVQF0CoNqZNyVwHBB0%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;770&quot; height=&quot;305&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버킷 이름이과 S3 객체 키 (data/image/abc-123.jpg)를 통해 이미지의 접근을 공개로 허용한 경우에는&lt;/li&gt;
&lt;li&gt;이미지 URL이 &lt;br /&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://my-loco-bucket.s3.ap-northeast-2.amazonaws.com/data/image/abc-123.jpg&quot;&gt;https://버킷이름.s3.ap-northeast-2.amazonaws.com/data/image/abc-123.jpg&lt;/a&gt; &lt;br /&gt;와 같은 형태&lt;/li&gt;
&lt;li&gt;클라이언트는 이 URL을 사용하여 이미지를 로드&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;액터 (Actor)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;웹 애플리케이션 개발에서 현재 요청을 수행하는 사용자(Actor)와 관련된 정보를 캡슐화하여 편리하게 사용하기 위한 패턴&lt;br /&gt;(ex. User Rq)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rq (Request):&lt;/b&gt; 웹 요청 자체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;User Rq:&lt;/b&gt; 현재 웹 요청을 보내고 있는 사용자(User)와 관련된 정보를 담고 있는 객체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;액터 (Actor):&lt;/b&gt; 시스템과 상호작용하는 주체 (ex. &lt;b&gt;현재 로그인하여 요청을 보내는 사용자)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;액터 패턴의 목적&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;컨트롤러나 서비스 메소드를 개발할 때, &lt;br /&gt;현재 요청을 보낸 사용자가 누구인지, 어떤 권한을 가지고 있는지, 해당 사용자의 ID는 무엇인지 등의 정보가 자주 필요&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;이러한 사용자 정보를 얻기 위해 매번 &lt;br /&gt;@AuthenticationPrincipal UserDetails userDetails를 메소드 인자로 받거나, SecurityContextHolder.getContext().getAuthentication().getPrincipal()와 같은 코드를 사용하는 것은 &lt;br /&gt;반복적이고 비효율적인 코드&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&quot;User Rq&quot; 또는 &quot;액터&quot; 객체 도입 시 이 객체 하나만 주입받거나 접근하여 현재 사용자의 모든 관련 정보를 쉽게 얻을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// 기존 방식 (UserDetails 사용)
public ResponseEntity&amp;lt;?&amp;gt; createBoard(@Valid @RequestBody BoardRequestDto boardRequestDto, @AuthenticationPrincipal UserDetails userDetails) {
    Long userId = Long.parseLong(userDetails.getUsername()); // UserDetails에서 ID 가져와 변환
    // ... 비즈니스 로직 ...
}

// User Rq / Actor 객체 사용 방식 (예시)
public ResponseEntity&amp;lt;?&amp;gt; createBoard(@Valid @RequestBody BoardRequestDto boardRequestDto, RqUser rqUser) { // RqUser 객체 주입
    Long userId = rqUser.getUserId(); // RqUser에서 사용자 ID 바로 가져옴
    boolean isHost = rqUser.isHost(); // RqUser에서 권한 확인
    User currentUser = rqUser.getUser(); // RqUser에서 User 엔티티 가져옴 (구현 방식에 따라 다름)
    // ... 비즈니스 로직 ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;액터 패턴의 장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 코드 간결화&lt;/b&gt; : 컨트롤러 및 서비스 메소드가 간결해짐, 사용자 정보를 얻는 코드가 반복되지 않아 효율적&lt;br /&gt;&lt;b&gt;- 정보 캡슐화 &lt;/b&gt;: 사용자 ID, 권한, 심지어 연관된 User 엔티티 객체까지 하나의 객체에 담아 관리 가능&lt;br /&gt;&lt;b&gt;- 유지보수 용이성:&lt;/b&gt; 사용자 정보를 가져오는 로직이 변경되어도 &quot;User Rq&quot; 객체 내부만 수정&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;액터 패턴의 단점&lt;/b&gt;&lt;/h3&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;b&gt; &quot;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;User Rq&quot; 객체를 정의하고, 요청 스코프 빈으로 등록하거나 &lt;br /&gt;Spring MVC의 Argument Resolver를 구현하여 컨트롤러 메소드 인자로 주입되도록 설정하는 초기 작업이 필요&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;- 추상화 레이어 추가 :&lt;/b&gt; 시스템에 새로운 객체가 추가되므로 낯선 구조가 될 수 있음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;액터 패턴의 도입 가능성 (LoCo 프로젝트)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;게시글 작성은 호스트만 가능&lt;/li&gt;
&lt;li&gt;공간 등록/수정은 해당 공간의 호스트만 가능&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;- 이처럼 사용자 역할과 권한에 기반한 로직이 많을 경우 &lt;br /&gt;현재 요청을 수행하는 사용자의 정보를 중앙에서 관리하고 쉽게 접근할 수 있는 &quot;User Rq&quot; 또는 &quot;액터&quot; 객체 패턴을 도입하여&lt;br /&gt;코드의 가독성과 유지보수성을 향상 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특히 @AuthenticationPrincipal UserDetails userDetails에서 &lt;br /&gt;userId를 Long.parseLong(userDetails.getUsername()) 형태로 변환하는 과정이 반복되는 것을 줄이고, &lt;br /&gt;사용자 역할(GUEST, HOST, ADMIN)을 확인하는 헬퍼 메소드(rqUser.isHost(), rqUser.isAdmin()) 등을 &lt;br /&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;아직 프로젝트 규모가 작고 사용자 역할 구분이 단순하다면 필수는 아닐 수 있지만 사용자 역할이 나뉘고 권한 관리가 필요한 서비스에서는 &quot;User Rq&quot; 또는 &quot;액터&quot; 객체 패턴 도입을 생각해볼 수는 있음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Github Project로 템플릿을 작성하여 개발일지 및 이슈사항에 대해 팀원들과 공유할 수 있는 환경을 만들 수 있었음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;게시판을 개발하기 위한 Board 엔티티에 관련해 Controller, Repository, Service 등 구현을 할 수 있었음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이미지 업로드를 위한 AWS S3 기술에 대해 공부해볼 수 있었음&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>Actor 패턴</category>
      <category>AWS S3</category>
      <category>GitHub Project</category>
      <category>Multipart</category>
      <category>Presigned S3</category>
      <category>Til</category>
      <category>게시판 개발</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 자바</category>
      <category>블로그 개발</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/296</guid>
      <comments>https://lefton.tistory.com/296#entry296comment</comments>
      <pubDate>Tue, 18 Nov 2025 13:03:51 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_102일차_&amp;quot;Git 협업 및 CI 구축&amp;quot;</title>
      <link>https://lefton.tistory.com/295</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [102]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 102&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 Git 협업과 관련해 히스토리를 남기는 것과 브랜치 관리에 대해 배움 (2025.05.09)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Git 추적 파일 지우기&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;git에 원치않게 추적되고 있는 파일 지우기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;git rm -r --cached .
git add .
git commit -m &quot;gitignore 적용&quot;
git push origin main
&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;팀원들이 이 상태에서 다시 pull을 받으면 사라진 상태에서 최신화가 되므로&amp;nbsp;사라진 상태가 원격 브랜치에 적용되어있을 것&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브랜치 생성 및 이동&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 브랜치를 만들면서 바로 이동하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762429214677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b enhancement/#1&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;2. 브랜치를 먼저 생성 후 checkout으로 이동하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1762429267962&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch enhancement/#1
git checkout enhancement/#1&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;git log&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;커밋 확인하는 방법의 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwm0ty/dJMcacBqaaO/DRwVvgTkcNguhYzUSBT6nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwm0ty/dJMcacBqaaO/DRwVvgTkcNguhYzUSBT6nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwm0ty/dJMcacBqaaO/DRwVvgTkcNguhYzUSBT6nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwm0ty%2FdJMcacBqaaO%2FDRwVvgTkcNguhYzUSBT6nk%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;953&quot; height=&quot;440&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 Log에서 표시된 &quot;HEAD &amp;rarr;&quot; 의 의미는 현재 가리키고 있는 브랜치를 의미&lt;/li&gt;
&lt;li&gt;그 뒤 &quot;develop&quot; 은 어느 원격 브랜치와 연결되어있는지를 표시&lt;/li&gt;
&lt;li&gt;⭐HEAD 부분이 중요 (현재 로컬에서 어딜 가리키는지 중요)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;협업에서의 코드 리뷰 및 Merge 과정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 개발:&lt;/b&gt; 팀원은 develop 브랜치에서 분기한 자신의 기능 브랜치(ex. feature/기능명 또는 feature/#이슈번호)를 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;b&gt;3) 푸시:&lt;/b&gt; 기능 개발이 완료된 후&lt;/p&gt;
&lt;pre id=&quot;code_1762429553087&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt; git push origin feature/기능명&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4) Pull Request 생성:&lt;/b&gt; GitHub에서 자신의 기능 브랜치(feature/기능명)를 develop 브랜치로 병합하겠다는 Pull Request 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5) 자동화된 확인 (CI/CD):&lt;/b&gt; PR이 생성되면 설정된 CI 워크플로우가 자동으로 코드 빌드, 테스트, 린트 검사 등 수행&lt;br /&gt;결과는 PR 페이지에 상태 체크(Status Checks) 로 표시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6) 코드 리뷰 (동료 검토):&lt;/b&gt; 팀원들이 해당 PR 페이지에서 코드 변경 내역을 확인하고 리뷰 댓글을 남기거나 수정 사항을 제안&lt;b&gt;&lt;br /&gt;&lt;/b&gt;필요한 경우 코드를 로컬로 가져와 테스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7) 수정 및 업데이트:&lt;/b&gt; 리뷰를 통해 수정 요청이 있으면, 개발자는 로컬 기능 브랜치에서 코드를 수정하고 커밋한 후 다시 푸시&lt;br /&gt;푸시하면 PR이 자동으로 업데이트되고, 자동화된 확인(CI)이 다시 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8) 승인 (Approval):&lt;/b&gt; 코드에 문제가 없고 리뷰어들의 요청 사항이 반영되었다면, 리뷰어들은 PR에 'Approve' 승인 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;9) 병합 조건 충족:&lt;/b&gt; Ruleset에 설정된 모든 병합 조건 (ex. 최소 승인 수 충족 (4명 이상), 모든 상태 체크 통과 등)이 충족&lt;br /&gt;⚠️팀장의 경우 Bypass 권한을 설정하여 승인 수와 상관없이 바로 병합 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;10) 병합 (Merge):&lt;/b&gt; 병합 조건을 만족하거나, Bypass 권한이 있는 사용자(ex. 팀장)가 'Merge pull request' 버튼을 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11) 브랜치 정리:&lt;/b&gt; 병합이 완료되면 기능 브랜치는 더 이상 필요 없으므로 삭제&lt;br /&gt;(GitHub 설정에서 PR 병합 시 자동으로 기능 브랜치 삭제 옵션을 켤 수도 있음&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;결론&lt;/b&gt; : [&lt;b&gt;기능 브랜치 푸시] -&amp;gt; [PR 생성] -&amp;gt; [자동 검증(CI)] + [동료 리뷰] -&amp;gt; [승인] -&amp;gt; [조건 충족 시 병합]&lt;/b&gt;&lt;/span&gt; 순으로 진행&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;로컬에서 직접 코드 리뷰&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;팀원의 기능개발 코드를 로컬로 가져와서 직접 테스트&lt;/li&gt;
&lt;li&gt;해당 팀원의 기능 브랜치를 가져옴&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762429938134&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기능 브랜치 : feature/#5

# 1. 원격의 최신 정보를 가져옴 (각자의 환경에서 생성되었던 브랜치가 가져와짐)
git fetch origin

# 2. 해당 팀원이 생성했던 기능 브랜치로 이동
git checkout feautre/#5&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;이렇게 checkout을 해보면 해당 팀원이 작성했던 코드의 브랜치로 이동하여 본인의 환경에서 로컬로 테스트할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CI 구축하기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MJYMN/dJMcahCJhv1/gOUePA73cvjz7DJ1s09uCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MJYMN/dJMcahCJhv1/gOUePA73cvjz7DJ1s09uCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MJYMN/dJMcahCJhv1/gOUePA73cvjz7DJ1s09uCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMJYMN%2FdJMcahCJhv1%2FgOUePA73cvjz7DJ1s09uCK%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;1273&quot; height=&quot;908&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&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;a href=&quot;https://aistudio.google.com/&quot;&gt;https://aistudio.google.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1762430047679&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;Google AI Studio&quot; data-og-description=&quot;The fastest path from prompt to production with Gemini&quot; data-og-host=&quot;aistudio.google.com&quot; data-og-source-url=&quot;https://aistudio.google.com/&quot; data-og-url=&quot;https://aistudio.google.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DheMT/hyZMZtxOFp/hDO9LrrxoPvGua1x4MoP60/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://aistudio.google.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aistudio.google.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DheMT/hyZMZtxOFp/hDO9LrrxoPvGua1x4MoP60/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&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;Google AI Studio&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The fastest path from prompt to production with Gemini&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aistudio.google.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;구글 AI 스튜디오 접속 후 에서 API Key 발급받기&lt;/li&gt;
&lt;/ul&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;499&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ymV8a/dJMcagKAvr6/RSbXNjNbFM0SltyqXfkFEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ymV8a/dJMcagKAvr6/RSbXNjNbFM0SltyqXfkFEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ymV8a/dJMcagKAvr6/RSbXNjNbFM0SltyqXfkFEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FymV8a%2FdJMcagKAvr6%2FRSbXNjNbFM0SltyqXfkFEk%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;499&quot; height=&quot;239&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;발급받은 Google AI Studio API Key를 기억해놓기 (⚠️클라우드 저장 금지)&lt;/li&gt;
&lt;li&gt;Settings&amp;nbsp;&amp;gt;&amp;nbsp;Secrets&amp;nbsp;and&amp;nbsp;variables&amp;nbsp;&amp;gt;&amp;nbsp;Actions&amp;nbsp;&amp;gt;&amp;nbsp;&quot;New&amp;nbsp;repository&amp;nbsp;secret&quot;&amp;nbsp;버튼&amp;nbsp;클릭&lt;/li&gt;
&lt;li&gt;이처럼 Github에 적절한 이름으로 API Key를 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;코드리뷰 CI 파일 등록&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;.github/workflows/gemini-code-review.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762430250606&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Gemini Code Review

on:
  push:
    branches: [ feature/gemini ]
    paths:
      - 'backend/**'
  pull_request:
    types: [opened, synchronize]

jobs:
  code-review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Node
        uses: actions/setup-node@v3

      - name: Install GoogleGenerativeAI
        run: |
          npm install @google/generative-ai

      # PR 이벤트에서의 변경사항 처리
      - name: Get git diff for PR
        if: github.event_name == 'pull_request'
        run: |
          git fetch origin &quot;${{ github.event.pull_request.base.ref }}&quot;
          git fetch origin &quot;${{ github.event.pull_request.head.ref }}&quot;
          git diff --unified=0 &quot;origin/${{ github.event.pull_request.base.ref }}&quot; &amp;gt; &quot;diff.txt&quot;
          echo &quot;EVENT_TYPE=pull_request&quot; &amp;gt;&amp;gt; $GITHUB_ENV

      # Push 이벤트에서의 변경사항 처리
      - name: Get git diff for Push
        if: github.event_name == 'push'
        run: |
          git diff --unified=0 HEAD^ HEAD &amp;gt; &quot;diff.txt&quot;
          echo &quot;EVENT_TYPE=push&quot; &amp;gt;&amp;gt; $GITHUB_ENV

      # Gemini를 사용한 코드 분석
      - name: Run Gemini-1.5-flash
        id: gemini_review
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require(&quot;fs&quot;);
            const diff_output = fs.readFileSync(&quot;diff.txt&quot;,'utf8');
            
            const { GoogleGenerativeAI } = require(&quot;@google/generative-ai&quot;);
            const genAI = new GoogleGenerativeAI(&quot;${{ secrets.GEMINI_API_KEY }}&quot;);
            const model = genAI.getGenerativeModel({ model: &quot;gemini-1.5-flash&quot;});
            
            // PR과 Push에 따라 다른 프롬프트 사용
            let prompt;
            if (process.env.EVENT_TYPE === 'pull_request') {
              prompt = `Explain in korean. You are a senior software engineer and need to perform a code review based on the results of a given git diff. Review the changed code from different perspectives and let us know if there are any changes that need to be made. If you see any code that needs to be fixed in the result of the git diff, you need to calculate the exact line number by referring to the &quot;@@ -0,0 +0,0 @@&quot; part. The output format is \[{&quot;path&quot;:&quot;{ filepath }&quot;, &quot;line&quot;: { line }, &quot;text&quot;: { review comment }, &quot;side&quot;: &quot;RIGHT&quot;}\] format must be respected.\n&amp;lt;git diff&amp;gt;${diff_output}&amp;lt;/git diff&amp;gt;`;
            } else {
              prompt = `Explain in korean. You are a senior software engineer and need to perform a code review based on the results of a given git diff. Provide a detailed review of the code changes, focusing on code quality, readability, performance, and security. Format your response in Markdown with clear headings for each file reviewed.\n&amp;lt;git diff&amp;gt;${diff_output}&amp;lt;/git diff&amp;gt;`;
            }
            
            const result = await model.generateContent(prompt);
            const response = await result.response;
            const text = response.text();
            
            fs.writeFileSync('review_result.txt', text);
            console.log('Review results saved!');

      # PR 이벤트: 라인별 리뷰 코멘트 추가
      - name: Format and add PR review comments
        if: env.EVENT_TYPE == 'pull_request'
        id: store
        run: |
          COMMENT=$(sed '/^```/d' review_result.txt | jq -c .)
          echo &quot;comment=$COMMENT&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT

      - name: Add Pull Request Review Comment
        if: env.EVENT_TYPE == 'pull_request'
        uses: nbaztec/add-pr-review-comment@v1.0.7
        with:
          comments: ${{ steps.store.outputs.comment }}
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          repo-token-user-login: 'github-actions[bot]'
          allow-repeats: false

      # Push 이벤트: 액션 로그에 리뷰 결과 출력 및 아티팩트 업로드
      - name: Display review results in workflow log
        if: env.EVENT_TYPE == 'push'
        run: |
          echo &quot;===== Gemini Code Review Results =====&quot;
          cat review_result.txt
          echo &quot;======================================&quot;

      - name: Upload review results as artifact
        if: env.EVENT_TYPE == 'push'
        uses: actions/upload-artifact@v4
        with:
          name: gemini-code-review
          path: review_result.txt&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드리뷰 과정을 협업을 통해 직접 경험해보고 팀원들과 적절한 규칙 및 기능 개발 분담을 수행해볼 수 있었음&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CI 구축에 대해 더 공부해봐야겠다는 생각을 함&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>CI 구축</category>
      <category>CI/CD</category>
      <category>git log</category>
      <category>git rm -r --cached .</category>
      <category>git 협업</category>
      <category>google ai studio</category>
      <category>Til</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 자바</category>
      <category>코드리뷰</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/295</guid>
      <comments>https://lefton.tistory.com/295#entry295comment</comments>
      <pubDate>Thu, 6 Nov 2025 21:03:50 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_101일차_&amp;quot;2차 팀 프로젝트 : 공유 공간 매칭&amp;quot;</title>
      <link>https://lefton.tistory.com/294</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [101]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 101&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 프로젝트의 방향성을 확정하고 그 프로젝트에 맞게 기획서 및 정의서, ERD 설계 방법을 배움 (2025.05.08)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 id=&quot;LMS%20(Learning%20Management%20System)-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt; 프로젝트명은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;LoCo&lt;/span&gt; 프로젝트 - Location (공간) + Connect (연결)로 확정.&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&quot;공간을&amp;nbsp;잇고,&amp;nbsp;가치를&amp;nbsp;나누다&quot;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;도심&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;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ERD 수정내역 (v1 -&amp;gt; v2)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dunih1/btsQamd0MsJ/7VKYj2SYPNvBcUf9EqKAR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dunih1/btsQamd0MsJ/7VKYj2SYPNvBcUf9EqKAR0/img.png&quot; data-alt=&quot;[기존] LoCo_ERD_v1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dunih1/btsQamd0MsJ/7VKYj2SYPNvBcUf9EqKAR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdunih1%2FbtsQamd0MsJ%2F7VKYj2SYPNvBcUf9EqKAR0%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;1940&quot; height=&quot;1122&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;1122&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[기존] LoCo_ERD_v1&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;1600&quot; data-origin-height=&quot;1774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpbbJu/btsP8khtGBQ/YjcpXDanfYgSxxw2psUvOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpbbJu/btsP8khtGBQ/YjcpXDanfYgSxxw2psUvOK/img.png&quot; data-alt=&quot;[개선] LoCo_ERD_v2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpbbJu/btsP8khtGBQ/YjcpXDanfYgSxxw2psUvOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpbbJu%2FbtsP8khtGBQ%2FYjcpXDanfYgSxxw2psUvOK%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;1600&quot; height=&quot;1774&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1774&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[개선] LoCo_ERD_v2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ERD 플랫폼 변경&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERDCloud.com ➡️ &lt;b&gt;dbdiagram.io&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;1467&quot; data-origin-height=&quot;1186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckjV7a/btsQa4qoJkU/SxAq0iA3RzF7VQhEuUWGFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckjV7a/btsQa4qoJkU/SxAq0iA3RzF7VQhEuUWGFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckjV7a/btsQa4qoJkU/SxAq0iA3RzF7VQhEuUWGFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckjV7a%2FbtsQa4qoJkU%2FSxAq0iA3RzF7VQhEuUWGFk%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;1467&quot; height=&quot;1186&quot; data-origin-width=&quot;1467&quot; data-origin-height=&quot;1186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서비스 배포에 사용되는 기술&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;주로 프론트엔드 Vercel&lt;/li&gt;
&lt;li&gt;백엔드 AWS EC2 등 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프론트엔드 배포 기술&lt;/b&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;b&gt;Vercel:&lt;/b&gt; Next.js 개발팀이 만든 서비스로, Next.js 프로젝트 배포에 최적화&lt;br /&gt;➡️서버리스 함수, 자동 스케일링 등을 편리하게 사용&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Netlify:&lt;/b&gt; Vercel과 유사하게 프론트엔드 배포에 특화된 서비스&lt;br /&gt;➡️정적 사이트, SPA, 서버리스 기능 등을 지원&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS S3 + CloudFront:&lt;/b&gt; 정적 웹사이트 호스팅에 적합&lt;br /&gt;➡️S3에 빌드된 파일을 올리고 CloudFront를 통해 CDN(Content Delivery Network)을 구성하여 빠르게 서비스&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Amplify:&lt;/b&gt; 프론트엔드 및 모바일 앱 개발/배포를 위한 통합 서비스&lt;br /&gt;➡️CI/CD, 백엔드 기능(인증, API 등) 연동까지 편리하게 지원&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS EC2 또는 컨테이너 서비스 (ECS, EKS):&lt;/b&gt; 전통적인 서버 방식&lt;br /&gt;➡️EC2 인스턴스에 직접 Node.js 환경을 설정하고 Next.js 앱을 실행하거나, Docker 컨테이너화하여 ECS나 EKS에 배포 ➡️Vercel이나 Netlify보다 설정 및 관리가 복잡하지만, 더 많은 제어권을 가짐&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;백엔드 배포 기술&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Spring Boot와 관련하여 백엔드 애플리케이션은 AWS EC2 외에도 다른 옵션들도 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;AWS EC2:&lt;/b&gt; 가장 기본적인 가상 서버 인스턴스&lt;br /&gt;➡️OS를 선택하고 직접 미들웨어(Java, Spring Boot 등)를 설치하여 애플리케이션을 실행&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Elastic Beanstalk:&lt;/b&gt; 웹 애플리케이션 배포 및 관리를 자동화해주는 서비스&lt;br /&gt;➡️코드만 올리면 환경 설정, 로드 밸런싱, 오토 스케일링 등을 자동으로 처리, EC2 위에 추상화된 형태&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS ECS (Elastic Container Service):&lt;/b&gt; 도커 컨테이너를 관리하고 배포하는 서비스&lt;br /&gt;➡️EC2 인스턴스 클러스터 위에서 도커 컨테이너를 실행&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS EKS (Elastic Kubernetes Service):&lt;/b&gt; AWS에서 제공하는 관리형 쿠버네티스 서비스&lt;br /&gt;➡️쿠버네티스 클러스터를 쉽게 구축하고 관리할 수 있으며, 대규모 컨테이너화된 애플리케이션 배포 및 관리에 용이&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Lambda:&lt;/b&gt; 서버리스 함수 서비스&lt;br /&gt;➡️짧게 실행되는 백엔드 로직을 함수 형태로 배포하고, 요청이 있을 때만 실행되어 비용이 효율적&lt;br /&gt;Spring Boot 애플리케이션 전체를 Lambda로 배포하기에는 구조 변경 필요&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓백엔드 AWS EC2 배포 시 도커/쿠버네티스(무중단배포) 사용은 필수적인지&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS EC2에 백엔드 애플리케이션을 배포할 때 도커나 쿠버네티스를 반드시 사용해야 하는 것은 아님&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 도커나 쿠버네티스를 사용하지 않을때는&lt;/b&gt;&amp;nbsp;EC2 인스턴스에 접속하여 직접 Java, Spring Boot 실행 환경을 설치하고, &lt;br /&gt;빌드된 Spring Boot JAR 또는 WAR 파일을 업로드하여 java -jar your-app.jar 와 같은 명령어로 직접 실행&lt;br /&gt;Nginx나 Apache와 같은 웹 서버를 앞에 두고 리버스 프록시 설정도 가능 ➡️기본적인 배포 형태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 도커나 쿠버네티스를 사용할때는&amp;nbsp;&lt;br /&gt;&lt;/b&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;자동화된 방식으로 배포, 스케일링, 관리&lt;/b&gt;해주는 오케스트레이션 플랫폼&lt;br /&gt;,여러 대의 서버(EC2 인스턴스 클러스터)에 걸쳐 애플리케이션을 효율적으로 분산시키고, 서비스 디스커버리, 로드 밸런싱, 자동 복구 등을 제공하여 &lt;b&gt;안정성과 확장성&lt;/b&gt;을 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;➡️소규모 프로젝트나 학습 목적으로는 EC2에 도커 없이 직접 배포하는 것도 가능하지만 &lt;b&gt;프로젝트 규모가 커지고, 여러 대의 서버를 사용하며, 안정적인 운영과 확장이 중요해진다면 도커와 쿠버네티스를 사용하는 것이 권장&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CI/CD (Continuous Integration / Continuous Deployment (or Delivery))&lt;/b&gt;&lt;/h4&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;소프트웨어 개발 및 제공 과정을 자동화하여, 변경된 코드를 신속하고 빈번하게 테스트하고 프로덕션 환경에 배포하는 DevOps 방법론&lt;/li&gt;
&lt;li&gt;'지속적 통합(CI)' : 여러 개발자의 코드를 자동으로 병합하고 검증&lt;/li&gt;
&lt;li&gt;'지속적 배포(CD)' : 테스트가 완료된 코드를 자동으로 운영 환경에 릴리스하는 과정을 포함&lt;br /&gt;때때로 '지속적인 제공'이라는 의미로 'Continuous Delivery' 라고 씀&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Tailwind CSS&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;미리 정의된 유틸리티(Utility) 클래스들을 사용하여 HTML 코드 내에서 직접 스타일을 적용할 수 있게 해주는&amp;nbsp;CSS 프레임워크&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1055&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPx27s/btsPVmzUHji/pK539dFBkQtilapOfFa2M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPx27s/btsPVmzUHji/pK539dFBkQtilapOfFa2M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPx27s/btsPVmzUHji/pK539dFBkQtilapOfFa2M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPx27s%2FbtsPVmzUHji%2FpK539dFBkQtilapOfFa2M1%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;1055&quot; height=&quot;432&quot; data-origin-width=&quot;1055&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이처럼 클래스명에 스타일을 정의하는 방법을 &amp;ldquo;테일윈드 tailwind&amp;rdquo; 기법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;ex. grid, grid-rows, items-center ...&lt;/i&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;br /&gt;- Tailwind는 특히 &lt;span data-token-index=&quot;1&quot;&gt;디자인 시스템을 빠르게 구축&lt;/span&gt;하거나, &lt;span data-token-index=&quot;3&quot;&gt;UI를 유연하게 커스터마이징&lt;/span&gt;해야 하는 프론트엔드 프로젝트에서 많이 사용&lt;br /&gt;- 복잡한 UI를 직접 구현해야 할 때나, 기존의 컴포넌트 라이브러리 디자인이 마음에 들지 않을 때 유용&lt;br /&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;- CSS 파일을 관리하는 대신, HTML 파일에서 직접 스타일을 제어하여 개발 속도와 생산성을 크게 향상&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CSS 프레임워크와 Tailwind CSS의 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;➡️일반적인 CSS 프레임워크(ex. Bootstrap)가 미리 만들어진 컴포넌트(버튼, 카드 등)를 제공하는 것과 달리,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;➡️ Tailwind CSS는 flex, pt-4, text-center, bg-blue-500과 같은 &lt;b&gt;원자 단위의 CSS 클래스&lt;/b&gt;를 제공&lt;br /&gt;또한 Tailwind CSS는 CSS 파일을 직접 작성하는 대신, HTML 클래스 속성 안에 유틸리티 클래스들을 나열하는 방식으로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. HTML + 일반 CSS 방식&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1755593447773&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;button class=&quot;my-button&quot;&amp;gt;버튼&amp;lt;/button&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1755593461729&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.my-button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 2rem;
  border-radius: 0.5rem;
  background-color: #3b82f6;
  color: #ffffff;
  font-size: 1rem;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Tailwind CSS 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1755593492643&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;script src=&quot;https://cdn.tailwindcss.com&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;button class=&quot;flex items-center justify-center p-4 rounded-lg bg-blue-500 text-white text-base&quot;&amp;gt;
        버튼
    &amp;lt;/button&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&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;button class = &quot;flex items-center...&quot; 처럼 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Git에서 일반 Merge와 Squash Merge의 차이점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ️일반 Merge의 Git Flow&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;933&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/comYz2/dJMcaajiNTz/JUBCrOlOIBvkRW6AvLpbJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/comYz2/dJMcaajiNTz/JUBCrOlOIBvkRW6AvLpbJk/img.png&quot; data-alt=&quot;Normal Merge&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/comYz2/dJMcaajiNTz/JUBCrOlOIBvkRW6AvLpbJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcomYz2%2FdJMcaajiNTz%2FJUBCrOlOIBvkRW6AvLpbJk%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;2160&quot; height=&quot;933&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;933&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Normal Merge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. main 브랜치의 흐름에서 기능을 개발할 feature/#1 브랜치를 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. feature/#1 의 커밋 내역들 F1, F2, F3, F3(수정) 등 이 각각 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-1) 예를들어&lt;br /&gt;feature/#1 브랜치에서 첫번째 기능을 개발 (F1) - 첫번째 커밋 : &quot;feat: add a button&quot; = 버튼 추가&lt;br /&gt;두번째 기능을 개발 (F2) - 두번째 커밋 : &quot;fix: fix button style&quot; = 버튼 스타일 수정&lt;br /&gt;세번째 기능을 개발 (F3) - 세번째 커밋 : &quot;refactor: modify button logic: = 버튼 로직 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이제 이 F1, F2, F3 기능 개발한 것들이 feature/#1 브랜치에서는 내역이 실려있는데 main 브랜치에는 반영이 되지 않은 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 이 경우 Pull Request를 통해 feature/#1 브랜치의 작업 내역을 main 브랜치에 병합해도되는지에 대한 요청&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이 PR (Pull Request)가 승인되면 일반 Merge가 실행되는데 이때 main 브랜치에 Merge Commmit (M4)가 새로 생성되는 흐름&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/span&gt; : 개발 과정의 &lt;b&gt;완전한 기록&lt;/b&gt;과 원본 브랜치 복원 용이 &lt;br /&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/span&gt; : 히스토리가 &lt;b&gt;복잡해지고&lt;/b&gt; 불필요한 커밋이 많아질 수 있음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ️SquashMerge의 Git Flow&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;feature/#1의 각각의 커밋내역들이 하나로 뭉쳐져서 병합되는 것이 Squash Merge&lt;/li&gt;
&lt;li&gt;Squash Merge의 장점은 깔끔해지는 것&lt;/li&gt;
&lt;li&gt;feature/#1 같은 브랜치는 &amp;ldquo;하나의 기능&amp;rdquo;을 커밋한 것이기때문에 하나로 합쳐서 병합하는 것이 좋다고 느낄때 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;1150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v3IQH/dJMcahCJgL1/ZvkB96b37XcqFtdCOhCnp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v3IQH/dJMcahCJgL1/ZvkB96b37XcqFtdCOhCnp0/img.png&quot; data-alt=&quot;Squash Merge&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v3IQH/dJMcahCJgL1/ZvkB96b37XcqFtdCOhCnp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv3IQH%2FdJMcahCJgL1%2FZvkB96b37XcqFtdCOhCnp0%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;2160&quot; height=&quot;1150&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;1150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Squash Merge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 브랜치 생성 및 작업:&lt;/b&gt; feature/#1 브랜치가 main 브랜치에서 생성되고, 그 위에서 &lt;span data-math=&quot;F1, F2, F3&quot;&gt;F1, F2, F3&lt;/span&gt; 커밋이 순차적으로 발생&lt;br /&gt;(&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;공통점&lt;/b&gt;&lt;/span&gt; : 일반 Merge와 동일한 브랜치 생성 및 작업)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Pull Request (PR):&lt;/b&gt; 작업 완료 후 PR을 생성하여 통합을 요청&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Squash Merge:&lt;/b&gt; PR이 승인되고 &lt;b&gt;Squash Merge&lt;/b&gt;가 실행&lt;br /&gt;- feature/#1의 모든 커밋 &lt;span data-math=&quot;F1, F2, F3&quot;&gt;F1, F2, F3&lt;/span&gt;이 하나의 새로운 커밋 &lt;span data-math=&quot;S1&quot;&gt;S1&lt;/span&gt;으로 통합&lt;br /&gt;- 이후 이 단일 커밋 &lt;span data-math=&quot;S1&quot;&gt;S1&lt;/span&gt;이 main 브랜치에 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 히스토리 결과:&lt;/b&gt; main 브랜치의 히스토리에는 &lt;span data-math=&quot;F1, F2, F3&quot;&gt;F1, F2, F3&lt;/span&gt;의 개별 흔적 없이, 오직 하나의 깔끔한 커밋 S&lt;span data-math=&quot;S1&quot;&gt;1&lt;/span&gt;만 남음&lt;br /&gt;(&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;차이점&lt;/b&gt;&lt;/span&gt; : &lt;b&gt;Merge Commit이 생성되지 않음.&lt;/b&gt; (단일 커밋으로 처리))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;장점&lt;/b&gt; :&lt;/span&gt; main 브랜치 히스토리가 깔끔하고 이해하기 쉬움 &lt;br /&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;단점&lt;/b&gt; :&lt;/span&gt; 세부 작업 과정을 잃어버리고 원본 브랜치 히스토리가 main 브랜치와 분리됨&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;❓일반 Merge vs Squash Merge 명령어 비교&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 105px;&quot; border=&quot;1&quot; data-sheets-baot=&quot;1&quot; data-sheets-root=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;일반 (Standard) Merge&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;Squash Merge&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;명령어&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;git merge &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;git merge --squash &amp;lt;브랜치명&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;Merge Commit 생성&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;변경 사항이 Staged 상태로 들어옴&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;커밋 필요 여부&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;자동으로 커밋됨 (별도 git commit 불필요)&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;수동으로 커밋해야 함 (필수)&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;히스토리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;feature 브랜치의 모든 커밋을 남기고 Merge Commit 추가&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;feature 브랜치 커밋들을 하나로 합쳐 새 커밋으로 추가&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;일반 Merge 로직&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762425490910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# main 브랜치로 이동
git checkout main

# feature 브랜치를 main에 병합 (Merge Commit 자동 생성)
git merge feature/#1&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;b&gt;Squash Merge 로직&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762425529990&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# main 브랜치로 이동
git checkout main

# feature 브랜치의 모든 변경사항을 하나의 작업으로 가져와 Staged 상태로 만듦
git merge --squash feature/#1

# 수동으로 커밋 (이 때 하나의 커밋이 생성됨)
git commit -m &quot;feat: feature/#1 커밋이 Squash Merge&quot;&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;main 브랜치의 히스토리는 '누가', '어떤 기능'을 넣었는지에 대한 '요약'만으로 충분&lt;/li&gt;
&lt;li&gt;복잡한 개발 과정의 세부 내용은 해당 PR 페이지나 feature 브랜치에 남겨두고,&lt;/li&gt;
&lt;li&gt;main 브랜치는 &lt;b&gt;오직 중요한 기능 단위&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;로만 깔끔하게 기록&lt;/span&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;&lt;b&gt;결론 :&lt;/b&gt; &lt;br /&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;오픈 소스 프로젝트, 라이브러리&lt;/span&gt;에서는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Squash Merge 또는 Rebase Merge&lt;/span&gt;가 선호&lt;br /&gt;&lt;/b&gt;&amp;gt;&amp;gt; main 브랜치의 히스토리를 깔끔하고 선형적으로 유지하여 추적에 용이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;규모가 크고 복잡한 엔터프라이즈 앱&lt;/span&gt;에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;일반 Merge (Merge Commit)&lt;/span&gt;&lt;/b&gt;가 선호&lt;br /&gt;&amp;gt;&amp;gt; 특정 릴리스 브랜치나 버그 픽스의 &lt;b&gt;병합 시점 자체&lt;/b&gt;를 중요하게 기록하고, 히스토리의 완전한 복원이 필수적일 때 사용&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Rebase Merge&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;GitHub에서 제공하는 'Rebase and Merge' 옵션을 사용하여 main 브랜치에 통합이 가능&lt;br /&gt;&lt;b&gt;(자동으로&amp;nbsp; Rebase를 처리하고 Fast-forward Merge를 수행)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;1620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ybcdj/dJMcagw3mKI/xJjMWVkv1h4BFk4cU5iRWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ybcdj/dJMcagw3mKI/xJjMWVkv1h4BFk4cU5iRWK/img.png&quot; data-alt=&quot;Rebase Merge&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ybcdj/dJMcagw3mKI/xJjMWVkv1h4BFk4cU5iRWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYbcdj%2FdJMcagw3mKI%2FxJjMWVkv1h4BFk4cU5iRWK%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;2160&quot; height=&quot;1620&quot; data-origin-width=&quot;2160&quot; data-origin-height=&quot;1620&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Rebase Merge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feature/#1 브랜치 커밋들 F1, F2, F3을 main 브랜치의 최신 커밋 M4 위에 재배치(Rebase)&lt;/li&gt;
&lt;li&gt;이 과정에서 새로운 커밋 ID를 가진 커밋들 F1', F2', F3'이 생성&lt;/li&gt;
&lt;li&gt;이후 main 브랜치는 Fast-forward 방식으로 통합되어 선형 히스토리를 만듦&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;Rebase Merge 로직&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762427606141&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. 브랜치 이동 후 Rebase
git checkout feature/#1

git rebase main

# 2. 병합 (Merge) - Fast-forward
git checkout main
git merge feature/#1&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;b&gt;결과&lt;br /&gt;&lt;/b&gt;- main 브랜치의 끝에 feature 브랜치의 모든 커밋(F1', F2', F3')이 합쳐짐&lt;br /&gt;- Merge 단계에서 자동으로 커밋 (Fast-forward)&lt;br /&gt;- Merge Commit 없이, feature의 모든 커밋이 선형적으로 이어진 히스토리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;장점&lt;/b&gt; &lt;/span&gt;: &lt;b&gt;선형 히스토리의 장점&lt;/b&gt;과 &lt;b&gt;세부 커밋 보존의 장점&lt;/b&gt;을 모두 갖추고 있어, &lt;b&gt;핵심 브랜치(main/master)&lt;/b&gt; 통합 전략으로 매우 선호&lt;br /&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/span&gt; : &lt;br /&gt;- Rebase 시 커밋 ID가 모두 바뀌어, 이미 원격 저장소에 푸시된 브랜치에 적용하면 협업자들에게 심각한 문제 야기&lt;br /&gt;- 충돌 해결의 어려움: 병합 시 발생할 충돌을 각 커밋이 Rebase될 때마다 해결해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;⚠️주의사항&lt;/b&gt; :&lt;br /&gt;- 이미 다른 사람이 작업하는 &lt;b&gt;공용 브랜치&lt;/b&gt;에 로컬 git rebase 명령 직접 사용하지 않기&lt;br /&gt;- PR단계에서 Github 플랫폼의 기능을 이용하는 방식 권장&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;❓Squash Merge vs Rebase Merge&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 105px;&quot; border=&quot;1&quot; data-sheets-baot=&quot;1&quot; data-sheets-root=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;Squash Merge&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;Rebase Merge&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;최종 커밋 개수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;단 하나의 커밋 (압축/요약)&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;원본 커밋 개수 (F1&amp;prime;,F2&amp;prime;,F3&amp;prime;)&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;히스토리 형태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;선형적 (하나의 커밋으로 인해)&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;선형적 (모든 커밋이 순차적으로 이어짐)&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;원본 커밋 보존&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;main 브랜치에서 사라짐 (단일 커밋으로 요약)&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;main 브랜치에서 보존됨 (새 ID로 재생성)&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;커밋 ID 변경&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;새로운 단일 커밋 ID 생성&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;
&lt;div&gt;
&lt;div&gt;Rebase 시 모든 커밋 ID가 변경됨&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;git fetch&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&amp;nbsp;로컬(IDE 환경)에서 원격 환경(GitHub 등)의 최신 변경 사항을 확인하고 비교하는 데 사용되는 핵심 명령어&lt;/li&gt;
&lt;li&gt;즉 로컬 저장소를 훼손하지 않고 원격 저장소(origin 등)의 최신 정보를 조회하고 다운로드하는 명령어 &lt;br /&gt;&lt;b&gt;(= 원격 저장소의 최신 브랜치, 커밋, 태그 등의 정보만 가져와서 로컬에 업데이트)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt; 병합(Merge)기능이 아니므로&lt;/b&gt; 로컬 작업 공간(Working Directory)이나 로컬 브랜치의 내용은 전혀 변경되지 않음&lt;/li&gt;
&lt;li&gt;git fetch를 실행하면, 로컬 저장소는 원격 저장소의 최신 상태를 알게되는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762428102433&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch origin&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;&amp;nbsp;명령어를 실행하게되면 로컬의 remotes/origin/main 브랜치가 GitHub의 main 브랜치 최신 커밋을 가리키게됨&lt;/li&gt;
&lt;li&gt;로컬 IDE나 CLI 명령(git log, git status)을 통해 현재 작업 중인 &lt;b&gt;로컬 브랜치&lt;/b&gt;와 원격의 최신 상태인 &lt;b&gt;원격 추적 브랜치&lt;/b&gt; 간의 &lt;br /&gt;차이점(ex. 몇 개의 커밋이 뒤처져 있는지)을 쉽게 비교 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&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;&lt;b&gt;fetch --prune 옵션&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762428536400&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch --prune&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;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓git fetch vs git pull&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;명령어&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;결과 (로컬 브랜치)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;git fetch&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;가져오기만&lt;/b&gt; 수행 (정보 다운로드)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;변경 없음 &lt;br /&gt;&lt;/b&gt;(origin/&amp;lt;branch&amp;gt;만 업데이트)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;git pull&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;가져오기 + 병합&lt;/b&gt; 수행 &lt;br /&gt;(정보 다운로드 후 로컬 브랜치에 통합)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;업데이트 및 변경&lt;br /&gt;&lt;/b&gt;(원격 내용이 로컬 브랜치에 병합됨)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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가지&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 최신 정보 확인만 수행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762428436154&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch&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;b&gt;2. 확인 후 로컬 브랜치에 병합&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762428457194&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (fetch + merge와 동일)
git pull&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;b&gt;3. fetch 후 수동으로 병합 (안전한 통합)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762428487267&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch
git merge origin/main # 또는 git rebase origin/main&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;git branch&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;브랜치 관련 역할을 수행할 수 있는 Git 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762428616814&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -D feature/#1&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;-D 옵션 : 브랜치 지우는 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;❓원격과 로컬의 브랜치를 맞춰주는 방법&lt;/b&gt;&lt;/h3&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;609&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sbzds/dJMcaeF0mwA/I6jGT1kLhaartA54ktEXg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sbzds/dJMcaeF0mwA/I6jGT1kLhaartA54ktEXg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sbzds/dJMcaeF0mwA/I6jGT1kLhaartA54ktEXg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSbzds%2FdJMcaeF0mwA%2FI6jGT1kLhaartA54ktEXg0%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;609&quot; height=&quot;337&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 원격 브랜치가 삭제되었을때 로컬에서도 삭제하려면 (⭐권장)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1762428702856&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; git fetch --prune&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;b&gt;2. 원격 브랜치는 삭제하지 않았지만&lt;/b&gt; 로컬에서 로컬 브랜치 삭제 후 원격 저장소에 push하게되면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 로컬 브랜치가 삭제된 것이 원격 저장소의 원격 브랜치에 반영&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Git 명령어에 대해 흐름에 따라 공부하여 협업 환경에서의 원활한 프로젝트 구현에 도움이 될 수 있도록 노력했다.&lt;br /&gt;git 명령어의 fetch, merge, pull, branch 등에 대해 개념을 제대로 이해하고 팀 프로젝트를 시작하는 것이 중요할 것 같았다.&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>CI/CD</category>
      <category>ERD</category>
      <category>git fetch</category>
      <category>git merge</category>
      <category>Rebase Merge</category>
      <category>Squash Merge</category>
      <category>tailwind</category>
      <category>Til</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 자바</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/294</guid>
      <comments>https://lefton.tistory.com/294#entry294comment</comments>
      <pubDate>Tue, 19 Aug 2025 17:55:37 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_100일차_&amp;quot;2차 팀 프로젝트 시작&amp;quot;</title>
      <link>https://lefton.tistory.com/293</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; 멋쟁이사자처럼 백엔드 부트캠프 13기&amp;nbsp; &lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [100]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 100&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 LMS 시스템이나 PMS 시스템, 혹은 백오피스가 있는 서비스 중 하나를 2차 팀 프로젝트로 기획하는 과정을 회고로 작성해보고자 한다. (2025.05.07)&lt;/span&gt;&lt;/span&gt;&lt;u&gt;&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LMS (Learning Management System)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&quot;학습 관리 시스템&quot;&lt;/li&gt;
&lt;li&gt;즉, 온라인 학습을 지원하고 관리하는 시스템을 가리킴&lt;/li&gt;
&lt;li&gt;1차 프로젝트에서의 블로그 서비스는 누구나 접근하는 범용적 소프트웨어이지만&lt;br /&gt;2차 프로젝트에서의 LMS는 시스템적이기때문에 기업적, 특정 그룹에서 사용하는 소프트웨어일 수 있다.&lt;br /&gt;➡️혹은 &lt;b&gt;[사용자 UI 부분 + &lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;b&gt;관리자 대시보드 부분]&lt;/b&gt;까지 개발&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;예를 들어보면&lt;br /&gt;&lt;b&gt;1) B2C (비즈니스 to 커스토머)&lt;/b&gt;&amp;nbsp;&lt;br /&gt;➡️ ex. 블로그 (&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;백오피스까지 구현&lt;/b&gt;&lt;/span&gt;해야함)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2) B2B (기업적인 것)&lt;/b&gt;&amp;nbsp;&lt;br /&gt;➡️ ex. 물류관리시스템 (사용자에게 노출된 영역이 아님, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;백오피스를 따로 만들필요없음, &lt;/b&gt;&lt;/span&gt;관리시스템 자체가 백오피스)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-size: 16px; letter-spacing: 0px;&quot;&gt;ex. &lt;b&gt;교육 콘텐츠를 관리하고 학습자를 관리하는 시스템 (대표적으로 '구글 클래스룸')&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;회원가입 / 로그인 (학생, 관리자, 강사 등 권한 분리)&lt;/li&gt;
&lt;li&gt;강의 등록 및 조회, 수강 신청&lt;/li&gt;
&lt;li&gt;과제 / 시험 제출 및 채점&lt;/li&gt;
&lt;li&gt;학습 이력 관리, 진도율 추적&lt;/li&gt;
&lt;li&gt;관리자 페이지 (강좌 관리, 사용자 관리)&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PMS (Project Management System)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;프로젝트를 계획하고 관리하는 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ex. 노션과 같은 일정 관리 시스템 (대표적으로 '&lt;span style=&quot;color: #666666; text-align: center;&quot;&gt;Jira, Trello, Asana, Notion 등')&lt;/span&gt;&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;팀원 등록 / 역할 설정&lt;/li&gt;
&lt;li&gt;프로젝트 생성 / 관리&lt;/li&gt;
&lt;li&gt;작업(Task) 등록, 상태 변경 (예: 할당, 진행 중, 완료)&lt;/li&gt;
&lt;li&gt;캘린더 / 간트 차트&lt;/li&gt;
&lt;li&gt;커뮤니케이션 로그 / 코멘트 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;백오피스(Back Office)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;사용자가 직접 보지 않는 &amp;lsquo;관리자용 시스템&amp;rsquo;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ex.&lt;/b&gt; &lt;br /&gt;- 사용자 관리&lt;br /&gt;- 게시글 / 상품 / 주문 등 DB CRUD 인터페이스&lt;br /&gt;- 통계 조회 (매출, 사용자 수, 클릭 수 등)&lt;br /&gt;- 권한 관리&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주로 Admin 페이지 형태로 구현되며&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, 서비스의 데이터를 내부적으로 운영하는 용도&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;✅ 주제 확정: 공유 로케이션 매칭 플랫폼&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;목적 : 공간이 필요한 사용자(게스트)와 공간을 제공하는 호스트를 매칭시켜주는 플랫폼&lt;/li&gt;
&lt;li&gt;ex. Airbnb for studios / rooms / creators&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;921&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8ZsQd/btsN4CjAVrL/q5pT5KzeqvxDxbkf2QEZx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8ZsQd/btsN4CjAVrL/q5pT5KzeqvxDxbkf2QEZx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8ZsQd/btsN4CjAVrL/q5pT5KzeqvxDxbkf2QEZx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8ZsQd%2FbtsN4CjAVrL%2Fq5pT5KzeqvxDxbkf2QEZx1%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;1920&quot; height=&quot;921&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;921&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;주요 기능 예상&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 사용자 (게스트) :&amp;nbsp;&lt;br /&gt;&lt;/b&gt;- &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;공간 검색 (지역, 시간, 타입 필터)&lt;br /&gt;- 공간 예약 및 결제&lt;br /&gt;- 리뷰 작성&lt;br /&gt;- 예약 취소 및 환불&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2. 공간 제공자 (호스트) :&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 공간 등록 (사진, 설명, 가격, 이용가능 시간)&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;br /&gt;- 예약 관리 (수락/거절)&lt;br /&gt;- 수익 정산 내역 조회 &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;사용자(게스트)&lt;/td&gt;
&lt;td&gt;- 공간 검색 (지역, 시간, 타입 필터)- 공간 예약 및 결제- 리뷰 작성- 예약 취소 및 환불&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공간 제공자(호스트)&lt;/td&gt;
&lt;td&gt;- 공간 등록 (사진, 설명, 가격, 이용가능 시간)- 예약 관리 (수락/거절)- 수익 정산 내역 조회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;관리자(Back Office)&lt;/td&gt;
&lt;td&gt;- 사용자/호스트 관리- 공간 검수 승인/반려- 통계 관리 (예약 수, 정산 등)- 신고 관리 (리뷰, 사용자, 공간 신고 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;추가할만한 기능 예상&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;카테고리 기반 공간 분류&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;연습실 / 촬영 / 회의실 / 파티룸 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;시간 단위 예약 (스케줄링 UI)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;캘린더 기반 시간 선택 기능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;결제 시스템 연동 (가상결제 or 모의)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;결제 흐름 연습 or TossPayments 연동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;찜 기능 / 즐겨찾기&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;자주 보는 공간을 따로 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;공간 리뷰 및 평점 시스템&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;후기 기반 추천 구조&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;정산 기능 (호스트 기준 수익 정리)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;호스트에게 월별 정산 내역 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 30.1163%; text-align: left;&quot;&gt;&lt;b&gt;알림 기능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 69.7674%; text-align: center;&quot;&gt;예약 확정/취소/정산 안내 알림&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관리자 기능은 status 속성들을 중심으로 구현 (승인/반려, 예약 상태, 리뷰 검토 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;UI 구성 예상&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;[사용자 화면]
  - 홈 / 검색 / 공간 상세 / 예약
  - 마이페이지 (예약 목록, 후기 작성, 찜한 공간)

[호스트 화면]
  - 공간 등록 / 수정 / 예약 현황 확인
  - 수익 정산 페이지

[관리자 화면 (BackOffice)]
  - 공간 목록 (승인/반려)
  - 사용자 관리
  - 통계 (월 예약 수, 수익)
  - 신고 관리&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트 관련 용어&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;용어 간단 설명 주로 누가 참여? 사용 빈도&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Daily (Stand-up)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;매일 15분 내외 진행 상황 공유 (어제, 오늘, 장애 여부)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Sprint Planning&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;이번 스프린트 동안 할 일 선정하고 분배&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Sprint Review&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;스프린트 종료 후 개발한 기능 시연&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Retrospective&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;회고. 잘한 점/개선점/다음 스프린트 개선 논의&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Tech Talk&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;기술 지식 공유 발표 (자율 주제)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%; text-align: center;&quot;&gt;&lt;b&gt;Demo&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.1395%;&quot;&gt;기능을 실제로 보여주는 시연. 내부 or 외부 대상&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&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;1차 팀프로젝트에서의 부족했던 점을 개선하여 2차 프로젝트에서도 기능 구현에 힘써야겠다고 생각했다.&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;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>LMS</category>
      <category>PMS</category>
      <category>개발자 팀 프로젝트</category>
      <category>공유 공간 매칭 서비스</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 부트캠프 13기</category>
      <category>백엔드 자바</category>
      <category>백오피스</category>
      <category>부트캠프 후기</category>
      <category>스프린트</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/293</guid>
      <comments>https://lefton.tistory.com/293#entry293comment</comments>
      <pubDate>Thu, 22 May 2025 19:53:51 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_99일차_&amp;quot;1차 블로그 프로젝트 마무리&amp;quot;</title>
      <link>https://lefton.tistory.com/292</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt; &lt;i&gt;&lt;b&gt;멋쟁이사자처럼 백엔드 부트캠프 13기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [99]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 99&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 1차 프로젝트로 블로그 프로젝트를 개발하면서 팀프로젝트의 중요성과 각자의 업무분담을 깃허브에서 관리하는 방법, Git Branch 생성 및 이슈 관리 등에 대해 회고해보고자 한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: justify;&quot;&gt;(2025.05.02)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&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;1078&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dI4r7q/btsN4RtHQBy/7Kw107jd4LwIKNyESfZ9Z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dI4r7q/btsN4RtHQBy/7Kw107jd4LwIKNyESfZ9Z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dI4r7q/btsN4RtHQBy/7Kw107jd4LwIKNyESfZ9Z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdI4r7q%2FbtsN4RtHQBy%2F7Kw107jd4LwIKNyESfZ9Z1%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;1078&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;1078&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;a style=&quot;background-color: #9feec3;&quot; title=&quot;pickipi 대체 저장소&quot; href=&quot;https://github.com/pickipi/momentree_blog&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;모먼트리 블로그 저장소&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;figure id=&quot;og_1747718117315&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 - pickipi/momentree_blog: 멋쟁이사자처럼 백엔드 부트캠프 13기 1차프로젝트 결과 저장소입니다.&quot; data-og-description=&quot;멋쟁이사자처럼 백엔드 부트캠프 13기 1차프로젝트 결과 저장소입니다. Contribute to pickipi/momentree_blog development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/pickipi/momentree_blog&quot; data-og-url=&quot;https://github.com/pickipi/momentree_blog&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://github.com/pickipi/momentree_blog&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/pickipi/momentree_blog&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;GitHub - pickipi/momentree_blog: 멋쟁이사자처럼 백엔드 부트캠프 13기 1차프로젝트 결과 저장소입니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;멋쟁이사자처럼 백엔드 부트캠프 13기 1차프로젝트 결과 저장소입니다. Contribute to pickipi/momentree_blog 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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시연 영상&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 회원가입&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nZAAZ/btsN4CQ7Hid/YWD1dRnPEvNlAAZ1dRBAL1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nZAAZ/btsN4CQ7Hid/YWD1dRnPEvNlAAZ1dRBAL1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nZAAZ/btsN4CQ7Hid/YWD1dRnPEvNlAAZ1dRBAL1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/nZAAZ/btsN4CQ7Hid/YWD1dRnPEvNlAAZ1dRBAL1/img.gif&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;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 로그인 및 좋아요&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HJQwO/btsN5xnLJxD/5RoRFXoKtWB5rbm7kZbAV0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HJQwO/btsN5xnLJxD/5RoRFXoKtWB5rbm7kZbAV0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HJQwO/btsN5xnLJxD/5RoRFXoKtWB5rbm7kZbAV0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/HJQwO/btsN5xnLJxD/5RoRFXoKtWB5rbm7kZbAV0/img.gif&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;1920&quot; height=&quot;1080&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) 검색 및 좋아요&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIPeAv/btsN31416X1/SNpV87n1zBUxJ2aBOz0KYK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIPeAv/btsN31416X1/SNpV87n1zBUxJ2aBOz0KYK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIPeAv/btsN31416X1/SNpV87n1zBUxJ2aBOz0KYK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cIPeAv/btsN31416X1/SNpV87n1zBUxJ2aBOz0KYK/img.gif&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;1920&quot; height=&quot;1080&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4) 마이페이지&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mDEfh/btsN27kjIBl/DukIXFNhPs4keqS7vbrke0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mDEfh/btsN27kjIBl/DukIXFNhPs4keqS7vbrke0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mDEfh/btsN27kjIBl/DukIXFNhPs4keqS7vbrke0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/mDEfh/btsN27kjIBl/DukIXFNhPs4keqS7vbrke0/img.gif&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;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5) 게시글 작성&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AGkfn/btsN4fIQTTZ/c8dO85nTEok99Qss8QC7sk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AGkfn/btsN4fIQTTZ/c8dO85nTEok99Qss8QC7sk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AGkfn/btsN4fIQTTZ/c8dO85nTEok99Qss8QC7sk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/AGkfn/btsN4fIQTTZ/c8dO85nTEok99Qss8QC7sk/img.gif&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;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6) 팔로우&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PEUgq/btsN3M8gLQI/hitgyaqv5FDD73CIFruW9k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PEUgq/btsN3M8gLQI/hitgyaqv5FDD73CIFruW9k/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PEUgq/btsN3M8gLQI/hitgyaqv5FDD73CIFruW9k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/PEUgq/btsN3M8gLQI/hitgyaqv5FDD73CIFruW9k/img.gif&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;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트 개선점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개인적으로 느낀 개선점&lt;/b&gt;&lt;/h3&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;✅개선 방안&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;프로젝트 시작 전, 각 팀원의 역할과 책임(R&amp;amp;R)을 문서화&lt;/li&gt;
&lt;li&gt;기능 단위로 작업을 나누고, 담당자와 마감 기한 지정&lt;/li&gt;
&lt;li&gt;GitHub Issue/Project 보드를 활용하여 작업 추적 및 리뷰 주기 설정&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;&lt;b&gt;2) 스프린트 및 일정 관리 부족&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매주 or 격주 단위의 스프린트를 계획&lt;/li&gt;
&lt;li&gt;매일 or 이틀에 한 번 미팅 (15분 이내)으로 진행 상황 공유&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;&lt;b&gt;3) 기능 위주의 개발로 인한 구조적 한계&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 초반에 DB 설계, API 명세, 주요 클래스 다이어그램 등 기본 설계 문서 작성은 완료했지만&lt;/li&gt;
&lt;li&gt;기초 구축 완료 후 기능 개발에 들어가는 &lt;b&gt;단계적 개발 전략이 부족했음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;PR 시 설계 방향과 일치 여부 확인하는 리뷰 기준 마련 (ex. Comment 작성 및 PR 승인 인원 수 제한)&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;&lt;b&gt;4) 시간 부족으로 인한 기능 미완성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅개선 방안 : &lt;/b&gt;&lt;b&gt;MVP 우선 개발 전략&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;꼭 필요한 기능부터 우선 구현하는 &lt;b&gt;MVP(Minimum Viable Product) 전략&lt;/b&gt; 적용&lt;br /&gt;➡️요구사항 정의서를 통해 MVP (상, 중, 하)로 나누고 개발을 진행했지만 핵심 기능들에서 오류가 발생했던 문제&lt;/li&gt;
&lt;li&gt;중간 점검을 위한 데모 일정 확보 &lt;br /&gt;➡️일정 초과 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;팀원들이 느낀 개선점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 이슈 사항들 (Issues)&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;게시글 저장 때 시간이 다른 시간대&lt;/li&gt;
&lt;li&gt;회원 수정 시에 수정이 되면 다시 입력란에 빈 칸이 되는 문제&lt;/li&gt;
&lt;li&gt;팔로우 하면 새로고침하기 전에는 언팔로우도 가능하지만, 새로고침하면 언팔로우 대신 팔로우로 되어있고 오류가 발생&lt;/li&gt;
&lt;li&gt;로그아웃 환경시에 인기 블로거 클릭하면 fetch 오류 발생&lt;/li&gt;
&lt;li&gt;이메일 형식을 지키지 않더라도 &quot;사용 가능한 이메일&quot; 문구 발생 문제&lt;/li&gt;
&lt;li&gt;시간이 다 돼서 로그아웃 되었을 때 다른 링크로 접근하면 fetch 오류 발생&lt;br /&gt;➡️메인화면으로 리다이렉팅 하도록 해야할 것 같음&lt;/li&gt;
&lt;li&gt;다크모드 UI 개선&lt;/li&gt;
&lt;li&gt;화면&amp;nbsp;여백&amp;nbsp;조정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 추가할 사항들 (Additional)&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;인기 블로거 정렬 : 인기 블로거 외에 다른 사람 블로그를 들어갈 수 있는 방법 부재&lt;/li&gt;
&lt;li&gt;상세 게시글에서 블로그로 들어갈 수 있게 개선 필요검색 기능: +블로거, 게시글 제목&lt;/li&gt;
&lt;li&gt;게시글 댓글, 조회수 표시(실시간 인기글 기준)&lt;/li&gt;
&lt;li&gt;최신 게시물 페이징 기술 적용해서 여러개 볼 수 있도록 구현 (ex. 스크롤 Left, Right 버튼)&lt;/li&gt;
&lt;li&gt;게시물 모아놓은 페이지 구성 필요&lt;/li&gt;
&lt;li&gt;댓글이나, 글 작성시, 프로필을 누르면 그 유저의 나의 나무( 또는 유저의 글 목록 페이지)로 가도록 하는 기능&lt;/li&gt;
&lt;li&gt;이메일 인증 강화 : 실제 사용하는 이메일을 사용하도록 하여 가짜 계정 생성제한&lt;/li&gt;
&lt;li&gt;홈 화면에서 댓글, 조회수 표시되도록 하기.&lt;/li&gt;
&lt;li&gt;비공개, 공개 설정 만들기.&lt;/li&gt;
&lt;li&gt;관리자 페이지&lt;/li&gt;
&lt;li&gt;신고하기 기능&lt;/li&gt;
&lt;li&gt;비밀번호 찾기 시에 이메일로 비밀번호를 보내어 임시 비밀번호를 받을 수 있도록 하는 기능&lt;/li&gt;
&lt;li&gt;태그&amp;nbsp;기능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1차 팀프로젝트가 마무리되었다. Readme를 통해 지금까지 만들어낸 프로젝트를 정리해보니&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모두가 고생했던 프로젝트임을 느낄 수 있었다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;부족한 기능들도 많고 도움을 받은 곳도 많지만 서비스 개발의 흐름을 이해하고 협업에 진지하게 임하는 것으로&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;팀프로젝트를 열심히 마무리할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot;&gt;서비스 유지보수가 필요할때 &lt;/span&gt;팀원들과도 종종 컨택해야겠다는 생각을 하게되었다.&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>mvp 개발 전략</category>
      <category>개발자 팀 프로젝트</category>
      <category>깃허브 협업</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 부트캠프 13기</category>
      <category>백엔드 자바</category>
      <category>부트캠프 후기</category>
      <category>블로그 프로젝트</category>
      <category>스프린트</category>
      <category>프로젝트 마무리 회고</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/292</guid>
      <comments>https://lefton.tistory.com/292#entry292comment</comments>
      <pubDate>Thu, 22 May 2025 19:01:21 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_96일차_&amp;quot;블로그 프로젝트의 에디터 도입&amp;quot;</title>
      <link>https://lefton.tistory.com/291</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt; &lt;i&gt;&lt;b&gt;멋쟁이사자처럼 백엔드 부트캠프 13기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [96]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 96&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에는 블로그 프로젝트를 개발하면서 필요했던 에디터 (Editor, 게시글을 작성할때 필요한 텍스트 박스 관련)에 대해 회고해보고자 한다. &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: justify;&quot;&gt;(2025.04.29)&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;❓블로그 프로젝트에서 에디터를 사용하는 이유&lt;/b&gt;&lt;/h2&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;기존에는 input 태그(textarea)를 사용해 글을 입력받음&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;텍스트 꾸미기 (굵게, 기울임, 색상) 지원 안 됨&lt;/li&gt;
&lt;li&gt;이미지 삽입 어려움&lt;/li&gt;
&lt;li&gt;코드 블록, 표 삽입 불가&lt;/li&gt;
&lt;li&gt;➡️이처럼 &lt;b&gt;기본 input/textarea&lt;/b&gt;는 한계가 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✅전문적인 블로그 기능을 위해서는 &quot;WYSIWYG 에디터&quot; 도입 필요&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;WYSIWYG&lt;/b&gt;: &quot;What You See Is What You Get&quot;&lt;br /&gt;➡️&lt;b&gt;작성하는 화면이 결과물과 똑같이 보이는 편집기&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대표적인 라이브러리 종류&lt;br /&gt;&lt;/b&gt;&lt;b&gt;- CKEditor&lt;br /&gt;- TinyMCE&lt;/b&gt;&lt;br /&gt;&lt;b&gt;- Toast UI Editor&amp;nbsp;&lt;/b&gt;&lt;br /&gt;- Quill 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;프론트엔드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;WYSIWYG 에디터(ex. CKEditor, TinyMCE)를 설치하고 게시글 작성 UI에 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;백엔드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;에디터가 생성한 HTML 포맷의 콘텐츠를 수신하여 데이터베이스에 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;실행결과&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;사용자는 직관적인 에디터로 텍스트, 이미지, 표, 링크 등을 삽입 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CKEditor vs TinyMCE 차이점&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 101px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;b&gt;CKEditor&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;b&gt;TinyMCE&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;라이선스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;무료/유료 버전 모두 존재&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;오픈소스/유료 기능 별도 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;배포 안정성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;매우 안정적 (많은 사례)&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;추가 설정 필요할 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;이미지 업로드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;자체 플러그인 제공&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;플러그인 설치 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;&lt;b&gt;커스터마이징&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;유연함 (플러그인 다양)&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;고급 설정 시 약간 복잡할 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CKEditor 설치 및 연동 (Next.js)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;패키지 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;npm install --save @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;연동 방법 (Next.js 컴포넌트) &amp;gt;&amp;gt; &lt;b&gt;components/MyEditor.tsx&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import React, { useState } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

const MyEditor = ({ onChange }: { onChange: (data: string) =&amp;gt; void }) =&amp;gt; {
  const [editorData, setEditorData] = useState('');

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;CKEditoreditor={ClassicEditor}
        data={editorData}
        onChange={(event, editor) =&amp;gt; {
          const data = editor.getData();
          setEditorData(data);
          onChange(data);
        }}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default MyEditor;&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;import로 CKEditor를 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;게시글 작성 페이지&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import React, { useState } from 'react';
import MyEditor from '@/components/MyEditor';

const PostCreatePage = () =&amp;gt; {
  const [content, setContent] = useState('');

  const handleSubmit = () =&amp;gt; {
    console.log('작성된 게시글 내용:', content);
    // 백엔드로 content 전송
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;게시글 작성&amp;lt;/h1&amp;gt;
      &amp;lt;MyEditor onChange={setContent} /&amp;gt;
      &amp;lt;button onClick={handleSubmit}&amp;gt;제출&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default PostCreatePage;&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;MyEditor로 받아와서 필요한 form 부분에 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CKEditor vs Toast UI Editor 차이점&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;마크다운 변환 필요시 Toast UI Editor 고려&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;CKEditor&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Toast UI Editor&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;렌더링 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;HTML 기반 (WYSIWYG)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Markdown 기반 (WYSIWYG + Markdown 동시지원)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;이미지 업로드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;자체 플러그인, S3 연동 등 가능&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;커스터마이징 필요 (직접 핸들러 작성)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Next.js 호환성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;SSR 미지원 &amp;rarr; dynamic import 필요&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;SSR 잘 작동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;사용 편의성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;워드같은 편리한 UI&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;개발자 친화적 UI (양방향 모드)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;출력 형태&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;HTML&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Markdown + HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;CKEditor&lt;/b&gt;&lt;br /&gt;개발 블로그, 기술문서, 마크다운 중심 ➡️&lt;b&gt;Toast UI Editor&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Toast UI Editor 설치 및 연동 (Next.js)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;npm install @toast-ui/react-editor&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import { Editor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';

export default function MyToastEditor() {
  return (
    &amp;lt;EditorinitialValue=&quot;내용을 입력하세요&quot;
      previewStyle=&quot;vertical&quot;
      height=&quot;500px&quot;
      initialEditType=&quot;markdown&quot;
      useCommandShortcut={true}
    /&amp;gt;
  );
}&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;Next.js에서는&amp;nbsp;Toast UI가 설정과 SSR 대응 측면에서 더 편리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot;&gt;회고를 통해&lt;/span&gt;&lt;span&gt;&lt;span&gt; 블로그 프로젝트의 게시글 작성 부분을 일반 input태그 등으로 처리하는 것이 아닌&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;외부 Editor를 설치하여서 사용하는 방법을 공부할 수 있었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각각의 Editor별로 스타일이 달라 기획하고자하는 서비스에 맞게 도입하는 것도 회고를 통해 알 수 있었다.&lt;/p&gt;</description>
      <category>Recording/멋쟁이사자처럼 BE 13기</category>
      <category>ckeditor</category>
      <category>TinyMCE</category>
      <category>TOAST UI Editor</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 부트캠프 13기</category>
      <category>백엔드 자바</category>
      <category>부트캠프 후기</category>
      <category>블로그 프로젝트</category>
      <category>프론트엔드 게시물 작성</category>
      <category>프론트엔드 에디터</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/291</guid>
      <comments>https://lefton.tistory.com/291#entry291comment</comments>
      <pubDate>Wed, 21 May 2025 19:36:28 +0900</pubDate>
    </item>
    <item>
      <title>[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_92일차_&amp;quot;프론트엔드 팔로우 기능 오류 해결 (2)&amp;quot;</title>
      <link>https://lefton.tistory.com/290</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt; &lt;i&gt;&lt;b&gt;멋쟁이사자처럼 백엔드 부트캠프 13기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;TIL 회고 - [92]일차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 92&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차에 발생했었던 오류해결과정 및 수정사항을 회고하고자한다. (2025.04.23)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;유저 생성 후 팔로우를 하여도 해당 유저의 팔로잉 목록은 비어있는 문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;%E2%9A%A0%EF%B8%8F%EC%98%A4%EB%A5%98%EC%9B%90%EC%9D%B8-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⚠️오류원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- userId와 Id 경로 문제&lt;br /&gt;- LazyInitializationException 오류 발생&lt;br /&gt;➡️JPA의 지연 로딩(Lazy Loading) 관련 문제로, 트랜잭션 범위 밖에서 지연 로딩된 엔티티에 접근하려고 할 때 발생&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 id=&quot;%E2%8C%9B%EC%A7%84%ED%96%89%EA%B3%BC%EC%A0%95-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⌛진행과정&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dA9K8C/btsN3g8XIlO/be1niUYBi2RLx9WtgZwyz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dA9K8C/btsN3g8XIlO/be1niUYBi2RLx9WtgZwyz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dA9K8C/btsN3g8XIlO/be1niUYBi2RLx9WtgZwyz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdA9K8C%2FbtsN3g8XIlO%2Fbe1niUYBi2RLx9WtgZwyz0%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;502&quot; height=&quot;133&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 새로운 유저 생성&lt;/b&gt; (기존에 가입된 유저가 &quot;팔로우할&quot; 유저를 새로 생성함)&lt;/p&gt;
&lt;pre id=&quot;code_1747708312161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST http://localhost:8090/api/v1/members/signup -H 'Content-Type: application/json' -d '{&quot;email&quot;:&quot;test3@test.com&quot;,&quot;password&quot;:&quot;Test123!@#&quot;,&quot;name&quot;:&quot;테스트3&quot;,&quot;blogName&quot;:&quot;테스트블로그3&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;&lt;b&gt;2. 기존 유저로 로그인&lt;/b&gt; (새로운 유저를 팔로우 하기 위함)&lt;/p&gt;
&lt;pre id=&quot;code_1747708340508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST http://localhost:8090/api/v1/members/login -H 'Content-Type: application/json' -d '{&quot;email&quot;:&quot;test2@test.com&quot;,&quot;password&quot;:&quot;Test123!@#&quot;}'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM0mM1/btsN4oEOT0j/vh7f9OeegTKevDRFhKLuT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM0mM1/btsN4oEOT0j/vh7f9OeegTKevDRFhKLuT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM0mM1/btsN4oEOT0j/vh7f9OeegTKevDRFhKLuT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM0mM1%2FbtsN4oEOT0j%2Fvh7f9OeegTKevDRFhKLuT1%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;514&quot; height=&quot;223&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;223&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;3. 기존 유저로 새로운 유저 팔로잉&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747708369563&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST 'http://localhost:8090/api/v1/follows/follow?followingid=2' -H 'Authorization: Bearer 키값'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWgPL9/btsN37DG0Cn/n4lDPHYthuO8wVLxnYbJj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWgPL9/btsN37DG0Cn/n4lDPHYthuO8wVLxnYbJj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWgPL9/btsN37DG0Cn/n4lDPHYthuO8wVLxnYbJj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWgPL9%2FbtsN37DG0Cn%2Fn4lDPHYthuO8wVLxnYbJj1%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;513&quot; height=&quot;141&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;141&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;4. 기존 유저의 팔로잉 상태 확인&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;564&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb2J2Y/btsN2JqcJka/EI6b7cF0hycUgr4yL63q6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb2J2Y/btsN2JqcJka/EI6b7cF0hycUgr4yL63q6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb2J2Y/btsN2JqcJka/EI6b7cF0hycUgr4yL63q6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb2J2Y%2FbtsN2JqcJka%2FEI6b7cF0hycUgr4yL63q6K%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;564&quot; height=&quot;460&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프론트엔드 UI에서는 팔로잉이 &quot;1&quot; 증가된 것을 확인 가능하지만&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AMjLj/btsN5hkL6Z5/ForpRLD7bpgH4PZ0u2woh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AMjLj/btsN5hkL6Z5/ForpRLD7bpgH4PZ0u2woh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AMjLj/btsN5hkL6Z5/ForpRLD7bpgH4PZ0u2woh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAMjLj%2FbtsN5hkL6Z5%2FForpRLD7bpgH4PZ0u2woh1%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;483&quot; height=&quot;473&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;%E2%9C%85%ED%95%B4%EA%B2%B0%20%EB%B0%A9%EB%B2%95-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅해결 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 새 토큰을 받고 새 토큰으로 다시 팔로우 요청&lt;/p&gt;
&lt;pre id=&quot;code_1747708867485&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X POST 'http://localhost:8090/api/v1/follows/follow?followingid=2' -H 'Authorization: Bearer 키값'&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;새 토큰을 사용하여 팔로우 요청을 보냈고, &quot;팔로우 성공&quot; 응답을 받음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 요약&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;팔로잉 목록 조회 테스트&amp;nbsp;&lt;br /&gt;&lt;/b&gt;- ID 2번 유저(&quot;유저입니다&quot;)가 팔로잉 목록에 정상적으로 표시됨&lt;br /&gt;- 상태는 &quot;ACTIVE&quot;로 정상&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;언팔로우 테스트&lt;br /&gt;&lt;/b&gt;- 언팔로우 요청 성공&lt;br /&gt;- 팔로잉 목록이 빈 배열 []로 변경되어 정상적으로 언팔로우됨&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다시 팔로우 테스트&lt;br /&gt;&lt;/b&gt;- 새 토큰으로 팔로우 요청 성공&lt;br /&gt;- 팔로잉 목록 재확인 시 ID 2번 유저가 다시 표시됨&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ID 2번 유저의 팔로워 목록 확인 - UI화면&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1747708751360&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl http://localhost:8090/api/v1/follows/members/2/followers -H 'Authorization: Bearer 키값'&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;b&gt;ID 2번 유저의 팔로워 목록을 확인한 결과&lt;br /&gt;&lt;/b&gt;- ID 1번 유저(&quot;테스트2&quot;)가 팔로워로 표시됨&lt;br /&gt;- 팔로워의 상태는 &quot;ACTIVE&quot;로 정상&lt;br /&gt;- 현재 프로필 사진은 없음(null)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;➡️팔로우 작업이 성공적으로 반영된 것&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;ID 1번 유저(테스트2)가 ID 2번 유저를 팔로우했기 때문에 팔로워 목록에 정상적으로 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;팔로워/팔로잉 목록이 반대로 표시되고 있는 문제&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 id=&quot;%E2%9A%A0%EF%B8%8F%EC%98%A4%EB%A5%98%EC%9B%90%EC%9D%B8-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⚠️오류원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 백엔드 API 응답은 정상적으로 오지만 프론트엔드에서 표시되는 방식이 잘못됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Nlmp/btsN31XGm3L/HGEFfNydYLGfmposrLZeTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Nlmp/btsN31XGm3L/HGEFfNydYLGfmposrLZeTK/img.png&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;498&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 32.9115%; margin-right: 10px;&quot; data-widthpercent=&quot;33.7&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Nlmp/btsN31XGm3L/HGEFfNydYLGfmposrLZeTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Nlmp%2FbtsN31XGm3L%2FHGEFfNydYLGfmposrLZeTK%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;568&quot; height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTqttH/btsN4ukUcHz/FXCbsWxdOieNMA1QXfTkiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTqttH/btsN4ukUcHz/FXCbsWxdOieNMA1QXfTkiK/img.png&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;401&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.3815%; margin-right: 10px;&quot; data-widthpercent=&quot;33.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTqttH/btsN4ukUcHz/FXCbsWxdOieNMA1QXfTkiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTqttH%2FbtsN4ukUcHz%2FFXCbsWxdOieNMA1QXfTkiK%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;450&quot; height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n80pZ/btsN4EOcySL/Bwj7yqRO7eI4LAQVmYxms0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n80pZ/btsN4EOcySL/Bwj7yqRO7eI4LAQVmYxms0/img.png&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;401&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.3815%;&quot; data-widthpercent=&quot;33.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n80pZ/btsN4EOcySL/Bwj7yqRO7eI4LAQVmYxms0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn80pZ%2FbtsN4EOcySL%2FBwj7yqRO7eI4LAQVmYxms0%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;450&quot; height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;%E2%9C%85%ED%95%B4%EA%B2%B0%20%EB%B0%A9%EB%B2%95-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅해결 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;user_follower_tsx (유저 팔로워 관련 스크립트)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1747708989772&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 팔로워와 팔로잉 목록을 가져오는 함수
const fetchFollowData = async () =&amp;gt; {
  setLoading(true);
  try {
    // 팔로워 목록 가져오기
    const followersResponse = await fetch(`http://localhost:8090/api/v1/follows/members/${userId}/followers`, {
      credentials: 'include'
    });
    
    // 팔로잉 목록 가져오기
    const followingResponse = await fetch(`http://localhost:8090/api/v1/follows/members/${userId}/followings`, {
      credentials: 'include'
    });

    if (followersResponse.ok) {
      const followersData = await followersResponse.json();
      setFollowers(followersData);  // 팔로워 데이터 설정
    } else {
      setFollowers([]);
    }

    if (followingResponse.ok) {
      const followingData = await followingResponse.json();
      setFollowing(followingData);  // 팔로잉 데이터 설정
    } else {
      setFollowing([]);
    }
  } catch (error) {
    ...
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1747709140358&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 현재 탭에 따른 사용자 목록
const currentUsers = activeTab === 'followers' ? followers : following;&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;1. API 호출과 상태 설정은 올바르게 되어있지만, 화면에 표시할 때 &lt;b&gt;followers와 following 배열을 반대로 사용중인 문제발견&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;2. 다른 문제로 백엔드의 FollowServiceImpl에서 팔로워/팔로잉 목록을 조회하는 로직이 반대로 되어있는 &lt;b&gt;문제발견&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;3. 또한 FollowRepository의 메소드와 FollowServiceImpl의 구현이 불일치하는 &lt;b&gt;문제발견&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FollowServiceImpl 에서&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;findAllByFollowerId(Long followerId)&lt;/b&gt;&amp;nbsp;- 내가 팔로우하는 사람들 목록&lt;/li&gt;
&lt;li&gt;&lt;b&gt;findAllByFollowingId(Long followingId)&lt;/b&gt;&amp;nbsp;- 나를 팔로우하는 사람들 목록&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메소드를 수정함으로써 &lt;b&gt;해결&lt;br /&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 회고 결과 :&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot;&gt;회고를 통해&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;팔로우 관련 기능에서 모달 팝업의 출력문제를 해결할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;백엔드 단에서의 호출과 프론트엔드 단에서의 처리에서 꼬여있는 것 같았다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;팔로우, 팔로워, 팔로잉 등에 대한 용어 개념 정리가 필요하여서&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;팔로우 기능이라는 전체 범주 안에 (팔로워, 팔로잉)을 포함시키는 것으로 개념을 정리할 수 있었다.&lt;/p&gt;</description>
      <category>Recording/에러 기록장</category>
      <category>LazyInitializationException</category>
      <category>멋쟁이사자처럼 후기</category>
      <category>백엔드 부트캠프 13기</category>
      <category>백엔드 자바</category>
      <category>부트캠프 후기</category>
      <category>블로그 프로젝트</category>
      <category>프론트엔드 모달팝업 문제</category>
      <category>프론트엔드 팔로우 기능</category>
      <category>프론트엔드 팔로우 팝업</category>
      <category>프론트엔드 팔로잉 기능</category>
      <author>LEFT</author>
      <guid isPermaLink="true">https://lefton.tistory.com/290</guid>
      <comments>https://lefton.tistory.com/290#entry290comment</comments>
      <pubDate>Tue, 20 May 2025 19:10:20 +0900</pubDate>
    </item>
  </channel>
</rss>