<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>sinequanon</title>
    <link>https://sinequanon.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 7 Jul 2026 16:15:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>sinequanon</managingEditor>
    <image>
      <title>sinequanon</title>
      <url>https://tistory1.daumcdn.net/tistory/7322939/attach/331ebe13c5794f87b81ee4ee146f4feb</url>
      <link>https://sinequanon.tistory.com</link>
    </image>
    <item>
      <title>[우아한테크코스] 8기 BE 최종 합격 후기(+자소서)</title>
      <link>https://sinequanon.tistory.com/9</link>
      <description>&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;레벨2가 끝나고 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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 우테코 준비 시작&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 우아한테크코스가 어떤 곳인지 몰랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학생 시절 막연하게 내가 어떤 개발자가 되고 싶은지 고민없이 1학년부터 학부 연구생 활동과 학교 공부만 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 4학년 됐고 늦게, 개발자로 취업하고 싶은데 뭘 해야는지 고민하기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 방향이 있겠지만 그 당시 백엔드 개발자를 해야겠다는 걸 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운 좋게 지인 중에 우아한테크 캠프 출신 개발자셨는데 내가 백엔드 개발자가 너무 되고 싶다고 하니 우아한테크코스에 지원하라고 추천해주셨다. 그렇게 우테코 준비를 시작했다. 그 때가 접수 마감 3주 전이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;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;a href=&quot;https://naver.github.io/hackday-conventions-java/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://naver.github.io/hackday-conventions-java/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;오브젝트 책 읽기(객체지향 공부하기)&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://www.youtube.com/watch?v=dJ5C4qRqAgA&quot;&gt;https://www.youtube.com/watch?v=dJ5C4qRqAgA&lt;/a&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt; 영상 보기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;자동차 경주, 로또, 숫자 야구 풀어보기&lt;/li&gt;
&lt;li&gt;마크다운 사용법 공부: &lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://gist.github.com/ihoneymon/652be052a0727ad59601&quot;&gt;https://gist.github.com/ihoneymon/652be052a0727ad59601&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;깃 커밋 컨벤션 공부&lt;/li&gt;
&lt;li&gt;참고 했던 블로그 중 : &lt;a href=&quot;https://velog.io/@pengoose_dev/%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-%EA%B8%80%EC%93%B0%EA%B8%B0-1-%EA%B8%B0%EB%8A%A5%EB%AA%85%EC%84%B8%EC%84%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@pengoose_dev/%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-%EA%B8%80%EC%93%B0%EA%B8%B0-1-%EA%B8%B0%EB%8A%A5%EB%AA%85%EC%84%B8%EC%84%9C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(준비하면서 적었던 것 중에 이런 게 있네...;;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1390&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX7s2X/dJMcajv45gH/QSZHULIvsQKCdjxIbnczA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX7s2X/dJMcajv45gH/QSZHULIvsQKCdjxIbnczA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX7s2X/dJMcajv45gH/QSZHULIvsQKCdjxIbnczA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX7s2X%2FdJMcajv45gH%2FQSZHULIvsQKCdjxIbnczA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;168&quot; data-origin-width=&quot;1390&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 자소서 작성하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올해 자소서 양식은 작년과 많이 달랐다. 자소서 문항은 1개(10,000자)였다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;가장 깊이 몰입했던 도전 경험이 무엇인가?&lt;br /&gt;왜 그걸 했고, 어떤 어려움이 있었고, 어떤 실패와 좌절이 있었고, 어떻게 극복했고, 나를 어떻게 변화시켰는가?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자소서가 매우 중요하다는 소문??을 듣고 엄청 공들여서 작성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 생각해봐도 자소서가 매우 중요한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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 data-ke-size=&quot;size16&quot;&gt;나의 몰입 경험은 &quot;&lt;b&gt;1년간 영어 공부 몰입&lt;/b&gt;&quot;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 몰입했던 경험을 하나의 스토리로 만들면 좋을 것 같아서 노션을 켜고 도전을 시작했을 때부터 끝날때까지 모든 과정, 그 당시 감정들을 모두 작성했다. 그러고나니깐 4개의 큰 틀을 만들 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공백 포함해서 5000자 정도 나왔는데, 주변 크루들 자소서 들어보면 글자 수는 상관없고, 자신의 경험을 얼마나 진실되게 쓰는지가 중요한 것 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[ 공허함 속에서 시작한 첫 번째 도전 ]&lt;br /&gt;어떤 마음에 그 도전을 했는지...&lt;br /&gt;&lt;br /&gt;[ 나를 변화시킨 1년의 기록 ]&lt;br /&gt;어떤 어려움이 있고, 어떤 실패 좌절이 있고, 어떻게 극복했는지..&lt;br /&gt;&lt;br /&gt;[ 성장 후의 팀프로젝트 ]&lt;br /&gt;극복 후 어떤 일을 했는지...&lt;br /&gt;&lt;br /&gt;[ 긍정적 사고와 배우는 마음 ]&lt;br /&gt;나를 어떻게 변화시켰고, 어떤 마음 가짐을 살아가는 지 등등&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;증빙 자료는 노션 페이지를 만들어서 제출했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zcZrU/dJMcaftExjM/Quq818KHFLxEWA2an8uiL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zcZrU/dJMcaftExjM/Quq818KHFLxEWA2an8uiL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zcZrU/dJMcaftExjM/Quq818KHFLxEWA2an8uiL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzcZrU%2FdJMcaftExjM%2FQuq818KHFLxEWA2an8uiL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;651&quot; height=&quot;340&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;718&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;2242&quot; data-origin-height=&quot;1114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB3ez7/dJMcacKxysF/TUlKs3VVvCHQUeK44uv3kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB3ez7/dJMcacKxysF/TUlKs3VVvCHQUeK44uv3kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB3ez7/dJMcacKxysF/TUlKs3VVvCHQUeK44uv3kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB3ez7%2FdJMcacKxysF%2FTUlKs3VVvCHQUeK44uv3kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;319&quot; data-origin-width=&quot;2242&quot; data-origin-height=&quot;1114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt;3. 프&lt;/b&gt;&lt;b&gt;리코스&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1주차: &lt;a href=&quot;https://sinequanon.tistory.com/5&quot;&gt;https://sinequanon.tistory.com/5&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1783148246744&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[BE 8기] 우테코 프리코스 1주차 회고&quot; data-og-description=&quot;1주차 미션문자열 덧셈 계산기 구현이다 이번 회차의 목표1. 객체 지향적으로 코드 작성하기 2. 코드 컨벤션과 커밋 컨벤션 익숙해지기 3. **AI 툴 사용하지 않고, 문제 해결하기요구사항을 분석하&quot; data-og-host=&quot;sinequanon.tistory.com&quot; data-og-source-url=&quot;https://sinequanon.tistory.com/5&quot; data-og-url=&quot;https://sinequanon.tistory.com/5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bt7bzV/dJMb8VNGYMN/lfkDW2E3Cnq8ZZTVL5nvJK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bZWlSx/dJMb84qjNIk/begXA8DSuE7FBA3SxwbA5k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/PQgt1/dJMb84qjNIj/vKIg2cfgBZkvaJUtbSFKE0/img.png?width=655&amp;amp;height=496&amp;amp;face=0_0_655_496&quot;&gt;&lt;a href=&quot;https://sinequanon.tistory.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sinequanon.tistory.com/5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bt7bzV/dJMb8VNGYMN/lfkDW2E3Cnq8ZZTVL5nvJK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bZWlSx/dJMb84qjNIk/begXA8DSuE7FBA3SxwbA5k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/PQgt1/dJMb84qjNIj/vKIg2cfgBZkvaJUtbSFKE0/img.png?width=655&amp;amp;height=496&amp;amp;face=0_0_655_496');&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;[BE 8기] 우테코 프리코스 1주차 회고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1주차 미션문자열 덧셈 계산기 구현이다 이번 회차의 목표1. 객체 지향적으로 코드 작성하기 2. 코드 컨벤션과 커밋 컨벤션 익숙해지기 3. **AI 툴 사용하지 않고, 문제 해결하기요구사항을 분석하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sinequanon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주차: &lt;a href=&quot;https://sinequanon.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sinequanon.tistory.com/6&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1783148244865&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[BE 8기] 우테코 프리코스 2주차 회고&quot; data-og-description=&quot;디스코스에서 포비님의 글을 보고 많은 생각을 하게 되었다.잘할 수 있을까? 잘 모르는 데 어떡하지?라는 걱정만 가득했다. 스스로 잘해야 된다는 생각에만 빠져있었고, 잘하는 사람들과 비교하&quot; data-og-host=&quot;sinequanon.tistory.com&quot; data-og-source-url=&quot;https://sinequanon.tistory.com/6&quot; data-og-url=&quot;https://sinequanon.tistory.com/6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1BJqp/dJMb87N729s/ttlTkvLMubsRMfwgSLQcGk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cACNPe/dJMb8PGHsm7/Y5ywkuIf5MAZlDEQkrWzqk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/d7X87A/dJMb8Z3CJFO/UKPyaon7HfCkpJOUehnSWK/img.png?width=1280&amp;amp;height=1060&amp;amp;face=0_0_1280_1060&quot;&gt;&lt;a href=&quot;https://sinequanon.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sinequanon.tistory.com/6&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1BJqp/dJMb87N729s/ttlTkvLMubsRMfwgSLQcGk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cACNPe/dJMb8PGHsm7/Y5ywkuIf5MAZlDEQkrWzqk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/d7X87A/dJMb8Z3CJFO/UKPyaon7HfCkpJOUehnSWK/img.png?width=1280&amp;amp;height=1060&amp;amp;face=0_0_1280_1060');&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;[BE 8기] 우테코 프리코스 2주차 회고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;디스코스에서 포비님의 글을 보고 많은 생각을 하게 되었다.잘할 수 있을까? 잘 모르는 데 어떡하지?라는 걱정만 가득했다. 스스로 잘해야 된다는 생각에만 빠져있었고, 잘하는 사람들과 비교하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sinequanon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3주차: &lt;a href=&quot;https://sinequanon.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sinequanon.tistory.com/7&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1783148244939&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[BE 8기] 우테코 프리코스 3주차 회고&quot; data-og-description=&quot;벌써 3주차 미션이 끝났다. 4,5주차는 새로운 형태로 미션이 진행된다고 하는데 벌써 기대가 된다.3주차 미션: 로또 발매기미션을 시작하기 전,이번 주부터 프로그래밍 요구 사항이 많아지기 시&quot; data-og-host=&quot;sinequanon.tistory.com&quot; data-og-source-url=&quot;https://sinequanon.tistory.com/7&quot; data-og-url=&quot;https://sinequanon.tistory.com/7&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/v8wni/dJMb9ia2gf8/Rwa1j4YDIoyKpF0zAnlRhk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dkoszs/dJMb9fZGtdc/UuKFEkh4uQtRIiNT8obg4K/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/jHBB0/dJMb9aKQdpn/P2pSXwKitotft3byBLWjik/img.png?width=1280&amp;amp;height=927&amp;amp;face=0_0_1280_927&quot;&gt;&lt;a href=&quot;https://sinequanon.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sinequanon.tistory.com/7&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/v8wni/dJMb9ia2gf8/Rwa1j4YDIoyKpF0zAnlRhk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dkoszs/dJMb9fZGtdc/UuKFEkh4uQtRIiNT8obg4K/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/jHBB0/dJMb9aKQdpn/P2pSXwKitotft3byBLWjik/img.png?width=1280&amp;amp;height=927&amp;amp;face=0_0_1280_927');&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;[BE 8기] 우테코 프리코스 3주차 회고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;벌써 3주차 미션이 끝났다. 4,5주차는 새로운 형태로 미션이 진행된다고 하는데 벌써 기대가 된다.3주차 미션: 로또 발매기미션을 시작하기 전,이번 주부터 프로그래밍 요구 사항이 많아지기 시&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sinequanon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈미션: &lt;a href=&quot;https://sinequanon.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sinequanon.tistory.com/8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1783148239930&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[BE 8기] 우테코 프리코스 오픈미션 회고&quot; data-og-description=&quot;1. 목표 정하기저는 오픈미션 목표를 크게 두 가지 세웠습니다.첫째, 동물병원 환자 관리 시스템 개발하기둘째, 환자 관리 시스템 기반으로 진료 소견서 자동 생성 기능 개발하기Q. 어떻게 이 주&quot; data-og-host=&quot;sinequanon.tistory.com&quot; data-og-source-url=&quot;https://sinequanon.tistory.com/8&quot; data-og-url=&quot;https://sinequanon.tistory.com/8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wQPM3/dJMb8TCk69S/iEH3HAOblCckYNm1jfZSt1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bkAJYM/dJMb88fbYA5/Qznsi1c3XsGV2bM0l15a50/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/q0W7n/dJMb8RR3b2Q/L3UihLeAHCYM5x5tofmjMk/img.png?width=956&amp;amp;height=736&amp;amp;face=0_0_956_736&quot;&gt;&lt;a href=&quot;https://sinequanon.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sinequanon.tistory.com/8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wQPM3/dJMb8TCk69S/iEH3HAOblCckYNm1jfZSt1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bkAJYM/dJMb88fbYA5/Qznsi1c3XsGV2bM0l15a50/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/q0W7n/dJMb8RR3b2Q/L3UihLeAHCYM5x5tofmjMk/img.png?width=956&amp;amp;height=736&amp;amp;face=0_0_956_736');&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;[BE 8기] 우테코 프리코스 오픈미션 회고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 목표 정하기저는 오픈미션 목표를 크게 두 가지 세웠습니다.첫째, 동물병원 환자 관리 시스템 개발하기둘째, 환자 관리 시스템 기반으로 진료 소견서 자동 생성 기능 개발하기Q. 어떻게 이 주&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sinequanon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&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;4. 최종 코테 준비&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리코스 마치고, 잊혀질 때쯤 이메일이 왔다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OHrk2/dJMcabLEDqF/0Jyr7AtKzzwCXHpz6muJa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OHrk2/dJMcabLEDqF/0Jyr7AtKzzwCXHpz6muJa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OHrk2/dJMcabLEDqF/0Jyr7AtKzzwCXHpz6muJa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOHrk2%2FdJMcabLEDqF%2F0Jyr7AtKzzwCXHpz6muJa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;408&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;910&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;최종 코테 준비는 합격 문자를 받고 나서 시작했다. 약 2주 남았었는데, 모든 일정을 취소하고 최종 코테에만 몰두했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;/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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;1404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/92XzM/dJMcafN2LLy/HcpdHjnxTEKYqaiWEPE5c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/92XzM/dJMcafN2LLy/HcpdHjnxTEKYqaiWEPE5c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/92XzM/dJMcafN2LLy/HcpdHjnxTEKYqaiWEPE5c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F92XzM%2FdJMcafN2LLy%2FHcpdHjnxTEKYqaiWEPE5c0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;487&quot; height=&quot;699&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;1404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 최종 합격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 코테 끝나고 2주 뒤 합격 발표였는데, 군대 시절보다 느리게 갔다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 합격 이메일 받고 너무 행복했다ㅠㅠ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;1036&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIS1zO/dJMcagszsCF/3nBCWvtndXk8FQjyuVcKBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIS1zO/dJMcagszsCF/3nBCWvtndXk8FQjyuVcKBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIS1zO/dJMcagszsCF/3nBCWvtndXk8FQjyuVcKBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIS1zO%2FdJMcagszsCF%2F3nBCWvtndXk8FQjyuVcKBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;473&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;1036&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 잡담&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우테코 준비하면서 이런 생각을 많이했다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;객체지향 아무것도 모르는데 어떡하지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;TDD가 뭔지 모르는데 어떡하지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;요구사항 정의 어떻게 하고 코딩 컨벤션 어떻게 지키고, 회고는 어떻게 하며, 코드 리뷰는 할 줄 모르는데 어떡하지&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;나는 너무 못하고, 다른 사람들은 다 잘하는 것 같았다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아이러니한 게 우테코에 들어와서 보니 모든 사람들이 그렇게 생각했다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;음.. 모두가 스스로 못한다고 생각하면... 잘하는 사람은 어디있지?? &lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; text-align: left;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;포비가 이런 말씀을 하셨다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;이미 잘한다면 더 좋은 곳에 가있지 않을까요? 우테코에 올 이유가 없잖아요&quot;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우테코는 잘하는 사람을 원하는 게 아니라 발전 가능성이 있는 사람을 원하는 게 아닐까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>우아한테크코스</category>
      <category>8기</category>
      <category>백엔드</category>
      <category>우아한테크코스</category>
      <category>우테코 8기</category>
      <category>최종합격</category>
      <author>sinequanon</author>
      <guid isPermaLink="true">https://sinequanon.tistory.com/9</guid>
      <comments>https://sinequanon.tistory.com/9#entry9comment</comments>
      <pubDate>Sat, 4 Jul 2026 15:54:11 +0900</pubDate>
    </item>
    <item>
      <title>[BE 8기] 우테코 프리코스 오픈미션 회고</title>
      <link>https://sinequanon.tistory.com/8</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 목표 정하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 오픈미션 목표를 크게 두 가지 세웠습니다.&lt;br /&gt;첫째, 동물병원 환자 관리 시스템 개발하기&lt;br /&gt;둘째, 환자 관리 시스템 기반으로 진료 소견서 자동 생성 기능 개발하기&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Q. 어떻게 이 주제를 선정하게 되었는가?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동물병원와 함께하는 프로젝트에서 &lt;code&gt;진료 소견서 자동 생성 시스템&lt;/code&gt;을 개발한 경험이 있습니다. 본 프로그램은 수의시가 진료를 마친 환자에 대한 상태를 작성하는 &amp;ldquo;진료 소견서&amp;rdquo;를 자동으로 만들어줍니다. 프로그램을 요약하자면 아래와 같이 동작을 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;PDF 형식인 환자 진료 차트에서 카테고리별로 데이터를 추출&lt;/li&gt;
&lt;li&gt;LLM과 이미지 모델을 활용해서 데이터를 요약&lt;/li&gt;
&lt;li&gt;요약된 데이터를 pptx 형식의 진료 소견서 템플릿에 삽입&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템을 개발할 당시에 동물병원 내의 환자 정보 시스템에 접근할 수 없었고 백엔드 지식이 전무했습니다. 그래서 웹이나 애플리케이션으로 제작하지 못했고, CLI 프로그램으로 제작을 했습니다. 로컬 파일 경로에 PDF가 들어오는 지 모니터링하고, 새로운 환자 차트 PDF가 디렉토리에 들어왔을 때 CLI 프로그램을 실행해 진료소견서(pptx)를 만들어주도록 제작했습니다. &lt;code&gt;python monitory.py&lt;/code&gt;로 실행하는 콘솔 프로그램이다 보니 많은 아쉬움이 있었습니다. PDF에서 데이터를 추출해서 사용하는 것이 아니라 환자 정보 시스템에 저장된 데이터를 바로 사용하는 것은 어떨까?, 단순 콘솔 프로그램이 아니라 진료 소견 요약 시스템을 웹 서비스로 제작하면 어떨까?라는 호기심으로 해당 주제를 선정하게 되었습니다. 그리고 아직 웹 서버 개발 경험이 아예 없었기 때문에 이번 기회를 통해 경험하면서 배우는 시간으로 만들 수 있겠다고 생각했습니다.&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;&lt;a href=&quot;https://github.com/SineQunNon/PerfectS&quot;&gt;https://github.com/SineQunNon/PerfectS&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769331247020&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 - SineQunNon/PerfectS: 진료 소견서 자동생성 프로그램&quot; data-og-description=&quot;진료 소견서 자동생성 프로그램. Contribute to SineQunNon/PerfectS development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/SineQunNon/PerfectS&quot; data-og-url=&quot;https://github.com/SineQunNon/PerfectS&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UsBgx/dJMb85vJcvj/W9IkIZyayiGRPGKvkqpbA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Waz4J/dJMb9g45uXt/B6K8BcdwhfSIxv4DIx81Wk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/SineQunNon/PerfectS&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/SineQunNon/PerfectS&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UsBgx/dJMb85vJcvj/W9IkIZyayiGRPGKvkqpbA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Waz4J/dJMb9g45uXt/B6K8BcdwhfSIxv4DIx81Wk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - SineQunNon/PerfectS: 진료 소견서 자동생성 프로그램&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;진료 소견서 자동생성 프로그램. Contribute to SineQunNon/PerfectS development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 계획 세우기 - 11월 5일(수)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목표를 세웠으니, 구체적으로 어떤 과정으로 목표를 달성하지에 대한 일정을 세웠습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/sinequanonn/post/94581cb4-2e0d-4136-a498-862715051660/image.png&quot; alt=&quot;&quot; width=&quot;528&quot; height=&quot;332&quot; /&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;수의사 도메인 정리하기&lt;/li&gt;
&lt;li&gt;요구사항 분석하기&lt;/li&gt;
&lt;li&gt;DB 테이블 정의서 작성하기&lt;/li&gt;
&lt;li&gt;기능 명세서 작성하기&lt;/li&gt;
&lt;li&gt;에러 코드 정의하기&lt;/li&gt;
&lt;li&gt;API 명세서 작성하기&lt;/li&gt;
&lt;li&gt;1차 기능 구현하기(MVP) &amp;rarr; 기본적인 CRUD 연산 구현하기&lt;/li&gt;
&lt;li&gt;중간 점검하기(리팩토링)&lt;/li&gt;
&lt;li&gt;2차 기능 구현하기 &amp;rarr; AI 기능 추가하기!&lt;/li&gt;
&lt;li&gt;회고 작성하기&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 수의사 도메인 정리하기 - 11월 5일(수)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 진료 차트 데이터에는 엄청나게 많은 종류의 데이터를 포함합니다. 실제 동물병원에서 사용하는 데이터를 모두 시스템에 적용하고 싶지만 일정상 모두 적용한다면 2주간 설계만 하다고 끝날 것 같다고 판단했습니다. 그래서 최대한 구체적인 내용은 빼고, 기본적인 내용만 간추려서 환자 정보 시스템을 제작하기로 했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 요구사항 분석하기 - 11월 5일(수)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유비쿼터스 언어라는 개념을 접했습니다. 환자 정보 시스템을 개발할 때 도메인 전문가 관점으로 작성하고, 개발자 관점에서도 작성하면서 두 개의 개념을 점차 맞춰지는 과정을 만들어보고 싶었습니다. 하지만 이미 제 머릿속은 개발자 입장이어서 그런지 도메인 전문가 관점으로 요구사항을 만드는 데는 한계가 있었습니다. 그래도 &amp;ldquo;~한 기능들이 있어야 해!&amp;rdquo; 느낌으로 작성을 했고, 그 다음에는 &amp;ldquo;만약에 이런 기능이 동작 안했을 때는 어떻게 해야 하지?&amp;rdquo;라는 접근 방식으로 요구사항 명세서를 작성해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://curiousjinan.tistory.com/entry/ddd-ubiquitous-language-importance-and-development#3.%20%EC%9C%A0%EB%B9%84%EC%BF%BC%ED%84%B0%EC%8A%A4%20%EC%96%B8%EC%96%B4%EC%9D%98%20%ED%8A%B9%EC%A7%95%EC%9D%84%20%EC%9D%B4%ED%95%B4%ED%95%B4%20%EB%B4%85%EC%8B%9C%EB%8B%A4.-1&quot;&gt;[DDD] 유비쿼터스 언어(Ubiquitous Language)의 중요성&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[수의사 관리]&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;수의사 등록
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;수의사 정보를 등록할 수 있다.&lt;/li&gt;
&lt;li&gt;수의사명을 입력받는다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;수의사 조희
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;등록된 수의사 목록을 조회할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[환자(동물) 정보 관리]&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;환자 등록
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;환자 정보를 등록할 수 있다.&lt;/li&gt;
&lt;li&gt;환자는 고유한 동물 번호를 가진다.&lt;/li&gt;
&lt;li&gt;동물 이름, 보호자명, 품종, 체중, 생일을 입력 받는다.&lt;/li&gt;
&lt;li&gt;환자 정보는 모두 포함되어야 한다&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;환자 조회
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;등록된 전체 환자 목록을 조회할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;환자 정보 수정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;동물 번호로 환자를 찾아서 정보를 수정할 수 있다.&lt;/li&gt;
&lt;li&gt;동물 번호는 수정할 수 없다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;환자 정보 삭제
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;환자 정보를 삭제할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[진료 기록 관리]&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;진료 기록 작성
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;수의사는 환자에 대한 진료 기록을 작성할 수 있다.&lt;/li&gt;
&lt;li&gt;진료 기록에는 날짜를 입력한다.&lt;/li&gt;
&lt;li&gt;SOAP 형식으로 진료 내용을 기록한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;S(Subjective): 주관적 판단&lt;/li&gt;
&lt;li&gt;O(Objective): 객관적 판단&lt;/li&gt;
&lt;li&gt;A(Assessment): 확정 진단명&lt;/li&gt;
&lt;li&gt;P(Plan): 추후 계획(치료 계획, 처방)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;진료 기록 조회
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특정 환자의 모든 진료 기록을 조회할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;진료 기록 수정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;작성된 진료 기록의 내용을 수정할 수 있다.&lt;/li&gt;
&lt;li&gt;진료 날짜도 수정 가능하다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;진료 기록 삭제
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특정 진료 기록을 삭제할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[진료 소견서 작성]&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;진료 소견서 작성
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;수의사는 특정 환자에 대한 진료 소견서를 작성할 수 있다.&lt;/li&gt;
&lt;li&gt;환자 정보가 있는 환자에 대해서 작성이 가능하다.&lt;/li&gt;
&lt;li&gt;다음 항목을 입력한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Cheif Complaint(주요 증상)&lt;/li&gt;
&lt;li&gt;Assessment(확정 진단)&lt;/li&gt;
&lt;li&gt;Plan(치료 계획)&lt;/li&gt;
&lt;li&gt;Postoperative Care(추후 관리)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;진료 소견서 조회
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특정 환자의 진료 소견서를 조회할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;진료 소견서 수정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;작성된 진료 소견서의 내용을 수정할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. DB 테이블 정의서 작성하기 - 11월 5일(수)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학부생 수업 이후로 오랜만에 DB 테이블을 정의하려다보니 많이 어색했습니다. DB 테이블 정의 방법을 여러 블로그를 활용해서 복습한 뒤에 정의서를 작성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[참고 링크]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rhgustmfrh.tistory.com/220&quot;&gt;테이블 정의서 작성 가이드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/moneycake-/223660129598&quot;&gt;개발자인데? 테이블 정의서 작성법 모르신다구요?&lt;/a&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;vet(수의사)&lt;/b&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;필드명&lt;/th&gt;
&lt;th&gt;데이터 타입&lt;/th&gt;
&lt;th&gt;길이&lt;/th&gt;
&lt;th&gt;제약 조건&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;null여부&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vet_id&lt;/td&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;PK,AUTO_INCREMENT&lt;/td&gt;
&lt;td&gt;기본 키&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vet_name&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;수의사명&lt;/td&gt;
&lt;td&gt;NOT NULL&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;pet(환자)&lt;/b&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;필드명&lt;/th&gt;
&lt;th&gt;데이터 타입&lt;/th&gt;
&lt;th&gt;길이&lt;/th&gt;
&lt;th&gt;제약 조건&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;null여부&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;pet_id&lt;/td&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;PK,AUTO_INCREMENT&lt;/td&gt;
&lt;td&gt;환자 번호(기본 키)&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pet_name&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;환자 이름&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ower_name&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;반려인명&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;breed&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;품종&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;weight&lt;/td&gt;
&lt;td&gt;DECIMAL&lt;/td&gt;
&lt;td&gt;(5, 2)&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;체중&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;birthdate&lt;/td&gt;
&lt;td&gt;DATE&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;생일&lt;/td&gt;
&lt;td&gt;NOT NULL&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;medical_record(진료 기록)&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;height: 172px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;필드명&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;데이터 타입&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;길이&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;제약 조건&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;설명&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;null여부&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;record_id&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;INT&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;PK,AUTO_INCREMENT&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;기본 키&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;pet_id&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;INT&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;FK&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;환자 번호&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;vet_id&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;INT&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;FK&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;수의사 ID&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;record_date&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;DATE&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;진료 날짜&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;subjective&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;500&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;주관적 판단&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;objective&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;500&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;객관적 판단&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;assessment&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;확정 진단명&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;plan&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;VARCHAR&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;500&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;추후 계획&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;NOT NULL&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;medical_report(진료 소견서)&lt;/b&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;필드명&lt;/th&gt;
&lt;th&gt;데이터 타입&lt;/th&gt;
&lt;th&gt;길이&lt;/th&gt;
&lt;th&gt;제약 조건&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;null여부&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;report_id&lt;/td&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;PK,AUTO_INCREMENT&lt;/td&gt;
&lt;td&gt;기본 키&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pet_id&lt;/td&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;FK&lt;/td&gt;
&lt;td&gt;수의사 ID&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vet_id&lt;/td&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;FK&lt;/td&gt;
&lt;td&gt;환자 번호&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;report_date&lt;/td&gt;
&lt;td&gt;DATE&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;작성 날짜&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;chief_complaint&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;주요 증상&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;assessment&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;확정 진단&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;plan&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;치료 계획&lt;/td&gt;
&lt;td&gt;NOT NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;postoperative_care&lt;/td&gt;
&lt;td&gt;VARCHAR&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;추후 관리&lt;/td&gt;
&lt;td&gt;NOT NULL&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;수의사, 환자, 진료 기록, 진료 소견서가 있다.&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;b&gt;[ERD 다이어그램]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/sinequanonn/post/bb7e0181-d533-48ea-a2f9-855ff49d2fe9/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. 기능 명세서 작성하기 - 11월 5일(수)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환자 정보 시스템이 가지는 주요 기능이랑 상세 동작들을 구체적으로 작성해보았습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 에러 코드 정의하기 - 11월 5일(목)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 응답 형식&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
    &quot;errorCode&quot;: &quot;PET-001&quot;,
    &quot;message&quot;: &quot;환자 이름은 1자 이상 20자 이하여야 합니다.&quot;,
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/sinequanonn/post/e735f108-c4e4-48cd-a4e5-dc943506caa5/image.png&quot; alt=&quot;&quot; width=&quot;634&quot; height=&quot;605&quot; /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8. API 명세서 작성하기 - 11월 5일(수)~11월6일(목)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 명세서 작성법을 블로그와 유튜브를 찾아보면서 공부했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 명세서는 API의 기능, 동작, 사용법을 나타낸 문서입니다. 이름 및 설명, 기본 정보, 요청(request), 응답(respnose), 예시 정보가 포함됩니다. 기본 정보에서 Host 주소, endpoint, http method가 포함됩니다. 요청(request)에는 header정보, parameter, body가 포함됩니다. 응답(response) 정보에는 Header, body가 있습니다. API 명세서를 작성할 때 가장 중요한 것은 API 명세서만 보고도 사용할 수 있도록 만드는 것입니다. API 명세서 도구는 swagger, postman, rest docs, Notion 등이 있는데 현재 단계에서는 Notion이 제일 편한 것 같아 Notion으로 작성하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=r03ObslCNlo&quot;&gt;[10분 테코톡] 체인저의 API 명세서와 협업&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/2b08273095b180e2a07efa61b2783437?pvs=21&quot;&gt;API 명세서&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9. 1차 기능 개발하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 정리부터 API 명세서 작성까지 마쳤습니다. 이제 스프링으로 구현을 시작하려 했지만, 어디서부터 손을 대야 할지 막막했습니다. 올해 초 3월에 스프링과 JPA 강의를 들었지만, 실제로 프로젝트를 만들어 본 경험이 없어서 시작점을 찾기가 어려웠습니다. 게다가 스프링과 JPA 개념도 시간이 많이 지나서 많이 흐릿해진 상태였습니다. 그래서 금요일부터 일요일까지 3일간 개념을 복습하는 시간을 가졌습니다. 더불어 일정을 조정했습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/sinequanonn/post/f9d0157f-8f1f-4524-a928-ed91003e1d2d/image.png&quot; alt=&quot;&quot; width=&quot;493&quot; height=&quot;331&quot; /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;11월 10일(월) - 도메인 구현하기&lt;/h4&gt;
&lt;h5&gt;Q. 왜 스프링으로 구현하는 것을 선택했나요&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링을 조금이나마 공부한 경험은 있지만, 실제로 제 손으로 서비스를 처음부터 끝까지 만들어 본적이 없었습니다. 이번 기회에 작은 프로젝트라도 전체 개발 과정을 경험해보고 싶었습니다. 또한 이전 진료 소견서 생성 시스템에서는 LangChain을 사용했는데, 이번에는 SpringAI를 활용해 구현해보고 싶은 생각도 들었습니다. 이러한 이유로 스프링을 선택하게 되었습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈 미션 진행 방식 중에서 &lt;code&gt;프리코스 경험을 기반으로 관련된 분야의 미션 설계하고 구현한다&lt;/code&gt;는 조건이 있었기 때문에, 내가 프리코스를 하면서 배운 내용을 적용해보고자 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, READMD.md를 상세히 작성하려고 했습니다. 구현해야 할 기능 목록을 중심으로 먼저 작성했고, 예외 상황도 함께 정리했습니다. 그리고 기능을 구현하면서 꾸준히 READMD.md를 업데이트하기로 했습니다.&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;code&gt;테스트 작성 &amp;rarr; 기능 구현 &amp;rarr; README.md 업데이트 &amp;rarr; 커밋&lt;/code&gt; 과정을 반복했습니다. (지금 생각해보면 과할 정도로 많은 커밋을 한 것 같다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어디서부터 테스트 코드 작성을 시작해야 할 지 고민을 했습니다. API 명세서 한 개 당 하나씩 기능을 구현해야 하나..? 그렇다기엔 하나의 API 안에는 여러 개의 도메인이 섞여있는 경우가 있어서 작은 테스트를 수행하기는 무리가 있는 것 같았습니다. 여기서 가장 작은 단위는 도메인이니깐, 도메인 하나에 대한 테스트를 작성하고 도메인 하나를 구현하기로 했습니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h5&gt;&lt;b&gt;[ 익힌 개념 ]&lt;/b&gt;&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@Entity&lt;/code&gt; 애노테이션을 사용했을 때, protected 생성자와 public 생성자를 동시에 선언해야 했다. 이를 통해 의미 없는 객체를 만들어 버그가 발생하는 것을 방지할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Entity
public class Vet {
        protected Vet() {}

        public Vet(String vetName) {
                this.vetName = vetName;
        }
}

//또는

@Entity
@NoArgsConstructor(access = AccessLevel.protected)
public class Vet {
        public Vet(String vetName) {
                this.vetName = vetName;
        }
}&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;code&gt;@GeneratedValue&lt;/code&gt; 애노테이션은 기본 키 값을 자동으로 생성하도록 도와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성전략&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;IDENTITY: DB의 AUTO_INCREMENT 기능 사용&lt;/li&gt;
&lt;li&gt;AUTO: Hibernate가 알아서 선택하도록 함&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 일주일이 지났습니다...&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;11월 11일(화) - Repository 구현하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 구현을 마쳤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/1&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769331182300&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;도메인 구현 완료 by sinequanonn &amp;middot; Pull Request #1 &amp;middot; sinequanonn/veterinary-clinic&quot; data-og-description=&quot;도메인 Vet 엔티티 구현 수의사명 유효성 검증 Pet 엔티티 구현 환자명 유효성 검증 보호자명 유효성 검증 품종 유효성 검증 체중 유효성 검증 생년월일 유효성 검증 MedicalRecord 엔티티 구현 진료 &quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/1&quot; data-og-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kyh5F/dJMb8RRMhQV/ZrUW41LlhCgktMigXsXl1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xsoYi/dJMb8ZvvKWw/qmPAdW3hylomE2DbmgB5Vk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kyh5F/dJMb8RRMhQV/ZrUW41LlhCgktMigXsXl1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xsoYi/dJMb8ZvvKWw/qmPAdW3hylomE2DbmgB5Vk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;도메인 구현 완료 by sinequanonn &amp;middot; Pull Request #1 &amp;middot; sinequanonn/veterinary-clinic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;도메인 Vet 엔티티 구현 수의사명 유효성 검증 Pet 엔티티 구현 환자명 유효성 검증 보호자명 유효성 검증 품종 유효성 검증 체중 유효성 검증 생년월일 유효성 검증 MedicalRecord 엔티티 구현 진료&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현을 마친 뒤 다시 돌아보면서 느낀 점은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, 도메인 계층에서 할 필요 없는 테스트를 작성했다는 생각이 들었습니다. 예를 들어 &amp;ldquo;수의사명이 20자를 초과하면 예외가 발생한다&amp;rdquo;는 책임은 도메인 계층에서 담당하는 것이 아니라, 서비스 계층에서 수행돼야 하는 게 적절해보였습니다. 그래서 전체적으로 대부분 테스트 코드가 서비스 쪽에서 테스트를 수행하는 것이 적절해보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째, 엔티티를 구현할 때 &lt;code&gt;@Entity&lt;/code&gt; 애노테이션을 사용했지만 JPA 테스트를 작성하지 않고, POJO 방식으로 테스트를 진행했습니다. 즉, POJO 클래스에 아직은 필요하지 않은 @Enttiy를 일단 붙이고 테스트를 진행했던 것이었습니다. 여기서 든 의문점이 &amp;ldquo;POJO 클래스에 &lt;code&gt;@Entity&lt;/code&gt;를 붙인다고 해서 왜 테스트가 깨지지 않을까?&amp;rdquo;였습니다. 더 나아가서 어떤 규칙을 가졌길래 테스트가 깨지지 않았을까? 그리고 만약 깨진다면 어떤 부분을 준수하지 않았기에 테스트가 깨지는 문제가 발생할까?라는 질문을 던지게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA 엔티티를 POJO 클래스처럼 테스트할 수 있는 이유는 POJO 클래스가 담당하는 로직이 JPA 영역에 침법하지 않기 때문이라고 생각했습니다. @Entity 애노테이션을 붙이기 전까지는 POJO 클래스에 아무런 영향이 없다가, @Entity를 붙이는 순간 부가 기능이 추가되는 것입니다. 사실상 위임자가 생기는 것이고, 그 위임자가 자신의 역할을 수행하는 데 그 범위를 벗어나지 않았기 때문에 오류가 나지 않은 것입니다. 즉, 관심사 분리 원칙을 잘 지키고 있었던 것입니다. 다르게 말하면 테스트 범위를 잘 제한했기 때문에 오류 없이 테스트할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 나아가서 만약, JPA에서 대포적인 오류 형태가 바로 Lazy 로딩인데, POJO 형태에서는 절대로 테스트가 불가능한 형태이다. 이렇게 테스트가 가능한 범위와 불가능한 범위를 생각하면서 코드를 구현하면, 각 계층의 책임을 분명히 이해하고 적절한 테스트를 할 수 있을 것이라 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 구현을 마치고 나서 h2 데이터베이스를 설치하고, 의존성도 추가하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Service 계층을 구현하면서 도메인 계층을 구현할 때처럼 단위테스트를 작성하려고 했습니다. 하지만 Service는 VetRepository에 직접 의존하고 있었고, 이 Repository는 JpaRepository를 상속받고 있었습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;public class VetService {
    private final VetRepository vetRepository;

    public VetService(VetRepository vetRepository) {
        this.vetRepository = vetRepository;
    }
}&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;ldquo;Repository에 직접 의존하고 있는 상태에서 단위 테스트를 작성하는 게 맞을까&amp;rdquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 &lt;code&gt;@SpringBootTest&lt;/code&gt;를 사용하면 이미 구현된 JpaRepository를 그대로 사용할 수 있어서 편하다고 생각했습니다. 하지만 아니었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조사해보니 &lt;code&gt;@SpringBootTest&lt;/code&gt;는 전체 애플리케이션을 띄우고 실제 DB연결하면서 외부 의존성이 포함되기 때문에 통합 테스트용 애노테이션이었습니다. 그렇기 때문에 단위 테스트를 작성하기 위해서 외부 의존성을 제거해야 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 알아보니 Mocking을 사용하면 실제 JpaRepository 구현체 없이 테스트가 가능하다는 것을 알게 되었습니다. 여기서 더 나아가 새로운 의문이 들었습니다. Repository 자체는 테스트 하지 않아도 되나?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 생각한 정답은 &amp;ldquo;해야 한다&amp;rdquo;였습니다. 그리고 여기서 중요한 점은 어디까지 테스트해야 하는가에 대한 기준이었습니다. 기준은 생각보다 쉽게 세울 수 있었습니다. 제가 프리코스 기간동안 도메인과 서비스에 대한 기준을 고민한 적이 있었습니다. &amp;ldquo;하나만 처리할 때는 도메인, 두 개 이상을 처리하면 서비스&amp;rdquo;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Repository는 도메인 계층에 포함된다고 생각했기에, Repository에 대한 테스트는 저장, 조회, 수정, 삭제를 하고, Service 계층에서는 두 개 이상의 도메인을 활용한 로직에 대한 테스트를 작성하면 되겠다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JpaRepository는 @DataJpaTest 애노테이션을 활용해 단위 테스트를 진행할 수 있다고 알게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/2&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769331205953&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;도메인 Repository 구현 완료 by sinequanonn &amp;middot; Pull Request #2 &amp;middot; sinequanonn/veterinary-clinic&quot; data-og-description=&quot;&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/2&quot; data-og-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rNVFK/dJMb8ZvvKWO/bB396RU2slV4M4fxRta2Fk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/chI2cZ/dJMb87NQFPx/kXSG1JkPWMC92Bjly8eMA1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rNVFK/dJMb8ZvvKWO/bB396RU2slV4M4fxRta2Fk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/chI2cZ/dJMb87NQFPx/kXSG1JkPWMC92Bjly8eMA1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;도메인 Repository 구현 완료 by sinequanonn &amp;middot; Pull Request #2 &amp;middot; sinequanonn/veterinary-clinic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;11월 12일(수) - Service 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Repository 계층 구현 및 테스트 작성이 끝나서 Service 계층 구현을 시작했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현을 시작하기 전에 Mock 사용법을 공부했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/Mock-2b08273095b1804b8d10cf213702889c?pvs=21&quot;&gt;Mock 사용법 익히기&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VetService를 작성하면서, 현재 서비스 기능 요구사항은 대부분 Repository 게층에서 수행하는 작은 단위이므로 서비스 계층에서 한 번 더 테스트할 필요가 없다고 판단했습니다. 즉, 하나의 도메인에 대한 기능 테스트 담당은 Repository에서 이미 하고 있기 때문에 서비스 계층에서 한 번 더 할 필요가 없다고 생각했습니다. 그렇기 때문에 Repository를 활용한 Service 게층 코드를 구현했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/3&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/3&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769331211405&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;251112 morning by sinequanonn &amp;middot; Pull Request #3 &amp;middot; sinequanonn/veterinary-clinic&quot; data-og-description=&quot;Mock 테스트 작성법 공부 VetServiceTest, VetService 작성&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/3&quot; data-og-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b6JRfj/dJMb8SpChr7/XMf0P213N7mu0dsfRxZQck/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/DrJwv/dJMb83SdaRD/D6k7DmyzzXogKBmndDoiX0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b6JRfj/dJMb8SpChr7/XMf0P213N7mu0dsfRxZQck/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/DrJwv/dJMb83SdaRD/D6k7DmyzzXogKBmndDoiX0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;251112 morning by sinequanonn &amp;middot; Pull Request #3 &amp;middot; sinequanonn/veterinary-clinic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mock 테스트 작성법 공부 VetServiceTest, VetService 작성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 계층까지 모두 구현을 마치고 컨트롤러를 구현할 차례가 되었습니다. 이 때 &amp;ldquo;컨트롤러를 단위테스트로 작성해야 할까, 통합 테스트로 작성해야 할까?&amp;rdquo;라는 고민이 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 상황은 이미 하위 계층들이 모두 구현되어 있고 테스트도 완료된 상태였습니다. 저는 이미 바텀업 방식으로 구현하고 있었기에 이미 테스트가 완료된 계층을 활용하는 것이 더 적합하다고 판단했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 탑다운 방식으로 개발했다면, 서비스가 아직 구현되지 않은 상태이므로 @WebMvcTest를 사용해서 컨트롤러에 대해서만 단위 테스트를 했을 것입니다. 하지만 현재 상황은 모든 계층이 준비되어 있기 때문에 &lt;code&gt;@SpringBootTest&lt;/code&gt;를 사용한 통합 테스트가 더 적합하다고 판단했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경험을 기반으로 통합 테스트를 선택하는 경우와 단위 테스트를 선택하는 기준을 세울 수 있었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;통합 테스트(&lt;code&gt;@SpringBootTest&lt;/code&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;/li&gt;
&lt;li&gt;단위 테스트(&lt;code&gt;@WebMvcTest&lt;/code&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;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;[ 익힌 개념 ]&lt;/h5&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@AutoConfigureMockMvc&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: MockMvc 빈을 자동으로 구성한다. 톰캣 같은 외부 서버를 띄우지 않고, HTTP 요청/응답을 시뮬레이션 할 수 있게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;mockMvc.perform(&amp;hellip;)&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 실제 컨트롤러에 요청을 하는 것과 동일한 흐름을 검증할 수 있게 해준다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;11월 13일(목) - Controller 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러를 구현할 때 브랜치를 안 만들고, 제 다른 계정으로 커밋하는 실수를 범했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/compare/ed28471...727bc8c&quot;&gt;Comparing ed28471...727bc8c &amp;middot; sinequanonn/veterinary-clinic&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 1차 기능 구현이었고, 기능 구현을 마친 뒤 제가 했던 과정에 대해 돌아보는 시간을 가졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 여기서 과제가 17일까지 제출인 줄 알고 17일까지로 계획을 세웠다가, 과제 제출 마감이 25일이라는 것을 알게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 저의 고민은 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;추가적인 요구사항을 나열해서, 기존 코드 위에서 복잡한 비즈니스 로직을 추가 개발해야 하는가
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스스로 왜 추가해야 하는가?라는 질문에 1차 기능 요구사항에는 단순 CRUD 연산만 포함했고, 복잡한 비즈니스 로직이 포함되지 않았습니다. 그래서 복잡한 비즈니스 로직을 다루는 서비스 계층을 구현해보고 싶은 생각이 들었습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;기존 코드에서 보완할 부분을 찾고 리팩토링을 진행하는가
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;코드를 구현하는 과정에서, 도메인 계층에서 서비스 계층의 책임을 담당하고 있었고, POJO 방식으로 구현했으며, JPA를 제대로 활용하지 못했다고 생각을 했습니다. 그리고 특히 엔티티에서 Getter를 사용하고 있는 것에 대한 찝찝함이 게속 있었습니다.&lt;/li&gt;
&lt;li&gt;예외 처리도 새롭게 정의해서 구현을 시작하기 전에 만들엇던 에러 코드를 사용하고 싶다는 생각을 했습니다.&lt;/li&gt;
&lt;li&gt;서버 구현한 경험이 없다보니, response body에 정확히 어떤 데이터가 들어있어야 하는지 판단하기 힘들었습니다. 다시 정확하게 공부하고 적용해보고 싶은 생각이 들었습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;지금 바로 SpringAI를 추가 해야 하는가?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 현재 코드가 깔끔하지 않다고 판단했고, 이 상태로 추가 기능을 구현한다면 마지막에 리팩토링 하는 과정이 더 부담된다고 판단했습니다. 그래서 리팩토링을 먼저 하기로 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩토링 대상&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검증을 API 앞에서 처리하는 로직 추가하기&lt;/li&gt;
&lt;li&gt;controller와 Service 계층에서 dto의 정적 팩토리 메서드 사용하도록 변경하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어 테스트 작성을 postman으로 해보기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 먼저 다음 일정을 조정했습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;날짜&lt;/th&gt;
&lt;th&gt;활동&lt;/th&gt;
&lt;th&gt;산출물&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;11/5(수) ~ 11/6(목)&lt;/td&gt;
&lt;td&gt;기존 도메인 정리요구사항 분석기능사항 정의DB 테이블 정의서 작성에러코드 정의API 명세서 작성&lt;/td&gt;
&lt;td&gt;요구사항명세기능명세서에러코드 정의서DB테이블 정의서API 명세서&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/7(금) ~ 11/9(일)&lt;/td&gt;
&lt;td&gt;스프링, JPA 복습&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/10(월)~11/12(수)&lt;/td&gt;
&lt;td&gt;1차 기능 개발&lt;/td&gt;
&lt;td&gt;핵심 기능 코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/13(목)&lt;/td&gt;
&lt;td&gt;중간 점검&lt;/td&gt;
&lt;td&gt;진행률 표?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/13(목)~11/15(토)&lt;/td&gt;
&lt;td&gt;리팩토링&lt;/td&gt;
&lt;td&gt;리팩토링 적용 코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/15(토)~11/16(일)&lt;/td&gt;
&lt;td&gt;에러 처리 로직 추가하기&lt;/td&gt;
&lt;td&gt;에러 처리 추가 코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/17(월)~11/18(화)&lt;/td&gt;
&lt;td&gt;Spring AI를 활용한 진료소견서 요약 기능 추가&lt;/td&gt;
&lt;td&gt;ai 추가 코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11/19(수)~11/24(월)&lt;/td&gt;
&lt;td&gt;회고 작성하기&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;제출&lt;/td&gt;
&lt;td&gt;회고글&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;최종 산출물(코드)&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;10. 리팩토링 - 11월 14일(금)~11월 15(토)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/4&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769331241794&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;리팩토링 by sinequanonn &amp;middot; Pull Request #4 &amp;middot; sinequanonn/veterinary-clinic&quot; data-og-description=&quot;DTO 계층 재구조화 DTO에 Bean Validation을 통한 검증 추가 정적 팩토리 메서드 및 Builder 패턴 적용 서비스/컨트롤러 책임 명확히 분배&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/4&quot; data-og-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIdrus/dJMb9g45uXm/pJ98z0F0rkjXWqUMXKWt3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cWcBzp/dJMb9iIBuWJ/zp7fqfKLMk7CB2l2vIbe3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIdrus/dJMb9g45uXm/pJ98z0F0rkjXWqUMXKWt3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cWcBzp/dJMb9iIBuWJ/zp7fqfKLMk7CB2l2vIbe3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리팩토링 by sinequanonn &amp;middot; Pull Request #4 &amp;middot; sinequanonn/veterinary-clinic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DTO 계층 재구조화 DTO에 Bean Validation을 통한 검증 추가 정적 팩토리 메서드 및 Builder 패턴 적용 서비스/컨트롤러 책임 명확히 분배&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;DTO 계층을 재구조화을 했고, 책임을 분리했습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 DTO를 용도별로 분리했습니다(예: &lt;code&gt;VetRequest&lt;/code&gt; &amp;rarr; &lt;code&gt;VetCreateRequest&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;생성, 수정, 조회와 같이 목적에 맞는 DTO를 각각 정의했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;직관적인 네이밍을 사용하도록 수정했습니다.&lt;/li&gt;
&lt;li&gt;Bean Validation을 통한 검증 로직을 추가했습니다.&lt;/li&gt;
&lt;li&gt;Builder 패턴을 적용했습니다.&lt;/li&gt;
&lt;li&gt;계층 간 책임을 명확하게 분배했습니다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;원래는 서비스 계층에서 엔티티를 직접 받고 반환했지만&lt;/li&gt;
&lt;li&gt;Request DTO를 받아 Response DTO를 반환하도록 수정했습니다.&lt;/li&gt;
&lt;li&gt;컨트롤러가 DTO를 엔티티로 직접 변환하던 로직을 서비스에게 위임했습니다.&lt;/li&gt;
&lt;li&gt;&amp;rarr; 이로써 컨트롤러는 HTTP 요청/응답 처리하는 책임에만 집중할 수 있게 했습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리팩토링을 마무리하고 나니, 그동안 무분별하게 사용했던 Lombok 애노테이션들에 의문이 생겼습니다. &lt;code&gt;@Builder&lt;/code&gt;, &lt;code&gt;@AllArgsConstructor&lt;/code&gt;, &lt;code&gt;@NoArgsConstructor&lt;/code&gt; 같은 애노테이션들을 명확한 기준 없이 &quot;일단 편하니까&quot; 사용하는 경향이 있었습니다. 이제는 &lt;b&gt;각 애노테이션을 언제, 왜 사용해야 하는지 기준을 명확히 하고 다시 적용&lt;/b&gt;해야겠다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/Lombok-2b08273095b1809c8de6cdfc4d33e821?pvs=21&quot;&gt;Lombok 애노테이션 사용 기준 정리&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 수정 기능을 구현하면서 JPA의 변경 감지를 사용했습니다. 그런데 update 로직을 어디에 위치시켜야 할지 고민이 되었습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;DTO 내부에서 엔티티의 update 메서드를 호출해야 하는가?&lt;/li&gt;
&lt;li&gt;Service 계층에서 udpate 메서드를 호출해야 하는가?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 고민은 빠르게 해결할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리코스를 진행할 때 &amp;ldquo;객체 생성을 컨트롤러에서 해야 하는가 아니면 서비스에서 생성해야 하는가&amp;rdquo;에 대한 고민을 한 적이 었었습니다. 그 때 제가 내린 결론은 &amp;ldquo;생성하는 것은 비즈니스 로직이므로 서비스 계층이 담당해야 한다&amp;rdquo;였습니다. &amp;ldquo;로또를 발행한다&amp;rdquo;가 비즈니스 로직이듯이 &amp;ldquo;이름을 변경한다&amp;rdquo;도 비즈니스 로직이므로 서비스 계층에 있는 것이 적절하다고 판단했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;11. 에러 로직 추가 - 11월 16일(일)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 정의했던 에러 코드를 적용하기로 했습니다. 그전에 스프링에서 에러 처리 동작 방식을 먼저 학습했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/API-2b08273095b180b88ce0cb2f091e6b94?pvs=21&quot;&gt;스프링에서 API 예외 처리 학습&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/5&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/5&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현 과정에서..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 기존에 정의했던 에러 코드를 모든 예외 상황에 적용하려고 했습니다. 하지만 구현하다 보니 너무 too much라는 것을 깨달았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 DTO 검증 로직에 에러 코드를 적용하는 것이 매우 부담스러웠습니다. 그래서 굳이 DTO 검증 로직에 대해서 에러 코드를 적용하는 건 오버 엔지니어링이라고 판단했습니다. Bean Validation의 기본 메시지만으로도 충분히 명확하게 어떤 오류인지 판단 가능하다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 비즈니스 로직에만 에러 코드를 적용하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 로직을 추가하고 postman으로 테스트도 진행했습니다.&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;12. Spring AI 추가 - 11월 17일(월)~11월 18일(화)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 Spring AI를 활용해서 환자 진료 데이터를 기반으로 진료 소견서를 자동으로 생성하는 기능을 추가하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 시스템은 PDF 파일에서 카테고리 별로 데이터를 추출하는 방식이었습니다. 하지만 현재는 환자 진료 기록이 환자 시스템에 저장돼 있는 상황입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 환자 정보, 동물병원 정보, 코드, 항목명, 수량, 일투, 일수, 총투, 확정 진단명, 구분, 코드, 과목, vital check, lab 표 데이터 등 어마어마하게 많은 데이터가 존재합니다. 하지만 현재는 축약된 데이터를 기반으로 진료 소견서에 들어갈 내용을 자동으로 생성하도록 구현하는 것이 목표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어 RAG 프로세스를 적용하고 싶었지만, 실제 동물 병원의 데이터를 기반으로 VectorDB를 구축하는 데 무리가 있다고 판단했습니다. 그렇기 때문에 에시 프롬프트를 주어서 진료 소견서를 생성하도록 구현하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 프로세스로 진행됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;petId와 recordId를 활용해서 진료 기록을 조회합니다.&lt;/li&gt;
&lt;li&gt;진료 기록을 LLM에 입력 가능한 컨텍스트로 변환합니다.&lt;/li&gt;
&lt;li&gt;컨텍스트 + 지시사항을 LLM에게 주입합니다.&lt;/li&gt;
&lt;li&gt;OutputConverter에 따라 진료 소견서 카테고리에 데이터를 자동으로 삽입합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain을 활용한 경험은 있지만 Spring AI를 활용한 경험이 없기 때문에 기본적인 Spring AI에 대해 학습했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/Spring-AI-2b08273095b18027a8e1f838d1f9a5ba?pvs=21&quot;&gt;Spring AI 학습하기&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/veterinary-clinic/pull/6&quot;&gt;https://github.com/sinequanonn/veterinary-clinic/pull/6&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프리코스를 마치면서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적으로 돌이켜보면, 이번 오픈 미션은 저에게 &amp;ldquo;시스템 구현 했다&amp;rdquo;라는 사실 그 이상이었던 것 같습니다. 도메인을 정의하는 과정, 테스트의 기준을 세우는 과정, 검증과 예외 처리를 분리하는 과정, 리팩토링을 통해 구조를 다듬는 과정, 그리고 AI 기능을 서비스와 연결하는 과정까지, 모든 과정이 배움이었습니다. 설계부터 개발, 테스트, 리팩토링까지 한 번의 사이클을 직접 온전하게 경험해본 것이 저에게 가장 큰 수확이었던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 5주 프리코스 기간 전체가 마무리되었을 때 정말 후련한 마음이 들었습니다. 동시에 정말 멋진 개발자가 되고 싶다는 마음이 들었습니다. 저는 원래 무언가를 배우고 나서 정리하는 성격이 아니었습니다. 그냥 이해하면 넘기고, 필요하면 다시 찾는 식이었습니다. 그런데 프리코스에서는 매주 제가 배운 것을 글로 남기고, 다른 사람의 생각도 보고 제 생각을 비교한 뒤에 다시 정리해서 공유해야 했습니다. 이 과정은 처음에는 정말 어색했고 시간도 많이 걸려서 힘들었습니다. 하지만 하루하루 하다 보니 많은 것을 깨닫게 되었습니다. 결국 개발자는 혼자 컴퓨터 앞에 앉아서 코드만 치는 사람이 아니라 문제를 해결해야 하는 사람인 것을 다시 느꼈습니다. 제 생각을 동료들에게 설명할 수 있어야 하고, 동료들의 생각을 이해하는 것이 중요하다는 사실을 배웠습니다. 이런 경험이 쌓이면서, 단순히 기술을 아는 개발자가 아니라 함께 일하고 함께 성정할 수 있는 개발자가 되고 싶다는 목표가 생겼습니다.&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;** 미션하면서 노션에 정리했던 거...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;&lt;a href=&quot;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372?source=copy_link&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372?source=copy_link&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769333258803&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;오픈 미션 | Notion&quot; data-og-description=&quot;동물병원 환자 시스템 with 진료 소견서 자동 생성&quot; data-og-host=&quot;www.notion.so&quot; data-og-source-url=&quot;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372?source=copy_link&quot; data-og-url=&quot;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/L9KeB/dJMb88eUXoJ/3Pzar2oUWS2RCL5CpZluIK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c6uPWn/dJMb9g45u5Z/FQHFtbWkAuOdPHkv3xz0A0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372?source=copy_link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.notion.so/2af8273095b180b1bac6c77f8d96c372?source=copy_link&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/L9KeB/dJMb88eUXoJ/3Pzar2oUWS2RCL5CpZluIK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c6uPWn/dJMb9g45u5Z/FQHFtbWkAuOdPHkv3xz0A0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;오픈 미션 | Notion&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;동물병원 환자 시스템 with 진료 소견서 자동 생성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.notion.so&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;**블로그 새로 만들어서 프리코스 기간 때 작성했던 내용을 다시 옮겨 적었습니다&lt;/span&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;&lt;a title=&quot;4주차&quot; href=&quot;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-4%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-4%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;5주차&quot; href=&quot;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-5%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-5%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>우아한테크코스</category>
      <category>8기</category>
      <category>우아한테크코스</category>
      <category>프리코스</category>
      <author>sinequanon</author>
      <guid isPermaLink="true">https://sinequanon.tistory.com/8</guid>
      <comments>https://sinequanon.tistory.com/8#entry8comment</comments>
      <pubDate>Sun, 25 Jan 2026 17:55:22 +0900</pubDate>
    </item>
    <item>
      <title>[BE 8기] 우테코 프리코스 3주차 회고</title>
      <link>https://sinequanon.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;벌써 3주차 미션이 끝났다. 4,5주차는 새로운 형태로 미션이 진행된다고 하는데 벌써 기대가 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3주차 미션: 로또 발매기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;927&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vaU8x/dJMcaiWox1D/RHHpNKkaLfb0k3GiGFFFt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vaU8x/dJMcaiWox1D/RHHpNKkaLfb0k3GiGFFFt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vaU8x/dJMcaiWox1D/RHHpNKkaLfb0k3GiGFFFt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvaU8x%2FdJMcaiWox1D%2FRHHpNKkaLfb0k3GiGFFFt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;406&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;927&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;h3 data-ke-size=&quot;size23&quot;&gt;미션을 시작하기 전,&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주부터 프로그래밍 요구 사항이 많아지기 시작했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능을 구현하기 전에 &lt;code&gt;README.md&lt;/code&gt;에 구현할 기능 목록을 정리해 추가하기&lt;/li&gt;
&lt;li&gt;indent depth 3 넘지 않기&lt;/li&gt;
&lt;li&gt;3항 연산자 쓰지 않기&lt;/li&gt;
&lt;li&gt;함수 최대한 작게 만들기&lt;/li&gt;
&lt;li&gt;함수의 길이가 15라인 넘지 않도록 구현&lt;/li&gt;
&lt;li&gt;else 예약어 쓰지 않기&lt;/li&gt;
&lt;li&gt;Enum 사용하기&lt;/li&gt;
&lt;li&gt;구현한 기능에 대한 단위 테스트 작성하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주차 미션을 얻은 피드백&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Controller에는 흐름 제어 코드만 작성하자&lt;/li&gt;
&lt;li&gt;네이밍을 명확하게 하자(테스트명, 상수명, 클래스명 등)&lt;/li&gt;
&lt;li&gt;에러 처리 할 때 메시지를 추가하자&lt;/li&gt;
&lt;li&gt;DRY 원칙을 준수하자&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;미션을 진행하면서,&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 작은 단위로 테스트하고 커밋하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 미션에서 작은 단위로 테스트 코드를 작성하고 기능을 구현한 뒤 바로 커밋하는 것이었다.&lt;br /&gt;먼저 READMD.md에 정리한 체크리스트를 따라가면서 하나씩 구현하니 무엇을 해야 할 지 명확했고, 진행 상황도 한 눈에 파악할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 문제는 리팩토링 단게였다. 첫 구현을 마치고 구조를 변경하거나, 새로운 도메인을 추가할 때 문서를 어떻게 업데이트해야 할지 막막했다. 그래서 리팩토링 할 때는 문서를 먼저 작성한 것이 아니라 먼저 리팩토링하고 다시 문서를 작성하는 방향으로 했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. MVC 패턴과 계층 분리 이해하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 주에 이어 이번 주도 MVC 패턴을 적용했다. 저번 주에는 Controller의 역할이 애매모호했고, mdoel의 domain과 service 계층에 대한 이해가 부족했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 고민했던 질문들:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Controller에서 도메인 객체를 생성해도 되는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 코드를 작성할 때 가장 큰 고민은 &lt;code&gt;new LottoCoin()&lt;/code&gt;, &lt;code&gt;new WinningLotto()&lt;/code&gt;처럼 도메인 객체를 직접 Controller에서 생성해도 되는가였다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 나는 도메인 객체를 생성하는 것도 비즈니스 로직의 일부라고 판단했다.&lt;br /&gt;왜냐면 Controller는 흐름 제어 역할만 담당해야 하고, &quot;무엇을 할지만 결정&quot;해야 한다고 판단했다. 그리고 &lt;b&gt;로또 코인을 구매한다&lt;/b&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;Service는 어떤 책임을 가져야 하는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 주에는 비즈니스 로직은 Servie가 책임을 가져야 한다는 사실만 알고 있었지, 구체적으로는 알지 못했다. 더불어 domain과 service의 경계도 애매모호했다. 이번 미션을 통해 다음과 같은 기준을 세울 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;domain은 하나의 객체 규칙을 정의하는 곳&lt;br /&gt;service는 이러한 객체들을 활용하는 곳&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리하면서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주에 공부하고 익힌 것들&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MVC 패턴 좀 더 명확하게&lt;/li&gt;
&lt;li&gt;enum 사용법&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;a href=&quot;https://github.com/sinequanonn/java-lotto-8/tree/sinequanonn&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/sinequanonn/java-lotto-8/tree/sinequanonn&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769330795328&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 - sinequanonn/java-lotto-8&quot; data-og-description=&quot;Contribute to sinequanonn/java-lotto-8 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/java-lotto-8/tree/sinequanonn&quot; data-og-url=&quot;https://github.com/sinequanonn/java-lotto-8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/udTtC/dJMb81GRvNx/8GJNnmTSUErsV3oCLKVIVK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/HrMy3/dJMb83SdaP7/srIuUL6w3r9jl1LnTnUKS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/java-lotto-8/tree/sinequanonn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/java-lotto-8/tree/sinequanonn&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/udTtC/dJMb81GRvNx/8GJNnmTSUErsV3oCLKVIVK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/HrMy3/dJMb83SdaP7/srIuUL6w3r9jl1LnTnUKS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - sinequanonn/java-lotto-8&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to sinequanonn/java-lotto-8 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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;**블로그 새로 만들어서 프리코스 기간 때 작성했던 내용을 다시 옮겨 적었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;&lt;a href=&quot;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-3%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-3%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>우아한테크코스</category>
      <category>8기</category>
      <category>우아한테크코스</category>
      <category>프리코스</category>
      <author>sinequanon</author>
      <guid isPermaLink="true">https://sinequanon.tistory.com/7</guid>
      <comments>https://sinequanon.tistory.com/7#entry7comment</comments>
      <pubDate>Sun, 25 Jan 2026 17:48:01 +0900</pubDate>
    </item>
    <item>
      <title>[BE 8기] 우테코 프리코스 2주차 회고</title>
      <link>https://sinequanon.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;디스코스에서 포비님의 글을 보고 많은 생각을 하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘할 수 있을까? 잘 모르는 데 어떡하지?라는 걱정만 가득했다. 스스로 잘해야 된다는 생각에만 빠져있었고, 잘하는 사람들과 비교하면서 나의 위치를 판단하고 좌절만 했다.&lt;br /&gt;피드백을 듣고나서 생각을 다시 정리했다. 지금 모르는 것이 당연하다. 내가 모르는 것을 인지하고, 하루하루 채워나가는 것이 &lt;code&gt;도전&lt;/code&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;h2 data-ke-size=&quot;size26&quot;&gt;2주차 미션: 자동차 경주&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lY6Hd/dJMcaiIQXiP/ShPnfwlKhYPu4HHp7wOHW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lY6Hd/dJMcaiIQXiP/ShPnfwlKhYPu4HHp7wOHW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lY6Hd/dJMcaiIQXiP/ShPnfwlKhYPu4HHp7wOHW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlY6Hd%2FdJMcaiIQXiP%2FShPnfwlKhYPu4HHp7wOHW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;229&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;548&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;1280&quot; data-origin-height=&quot;1060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wplt3/dJMcaiIQXiX/lIZN7H6b2MhBpHXqt4BaMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wplt3/dJMcaiIQXiX/lIZN7H6b2MhBpHXqt4BaMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wplt3/dJMcaiIQXiX/lIZN7H6b2MhBpHXqt4BaMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwplt3%2FdJMcaiIQXiX%2FlIZN7H6b2MhBpHXqt4BaMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;411&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1060&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2주차 미션을 시작하기 전,&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1주차 미션 코드 리뷰와 공통 피드백을 보면서 내가 공부해서 적용할 수 있는 내용을 정리해보았다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;큰 함수를 단일 역할을 수행하는 작은 함수로 분리(단일 책임 원칙 준수하기)&lt;/li&gt;
&lt;li&gt;테스트 도구 사용하는 방법 배우기&lt;/li&gt;
&lt;li&gt;커밋 메시지 의미있게 작성하기&lt;/li&gt;
&lt;li&gt;코드 포맷팅 사용하기&lt;/li&gt;
&lt;li&gt;MVC 패턴 적용하기&lt;/li&gt;
&lt;li&gt;상태가 없는 객체에 static 사용하기&lt;/li&gt;
&lt;li&gt;요구사항 분석 잘하기&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 리뷰를 하는 과정에서 많은 동료들이 MVC 패턴을 사용한 것을 파악할 수 있었다. 나의 코드와 비교했을 때 확실히 패키지가 분리되어 있어, 어디서 어떤 기능을 하는지 한 눈에 파악할 수 있어서 좋았다. 그래서 나도 2주차에는 MVC 패턴을 공부하고 적용하기로 마음 먹었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요구사항을 분석하면서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주에는 요구사항 분석을 잘해야지라는 마음으로 시작했지만 역시나 잘하는 것 자체가 쉽지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요구사항을 어떻게 하면 잘할 수 있을지 고민하다가 커뮤니티에서 &lt;code&gt;기능 요구사항을 기능 단위로 나누는 기준&lt;/code&gt;에 대해 토론 보았다. 그래서 나도 요구사항 분석에 대한 기준을 세우는 시간을 가졌다. 1,2주차 미션 과정을 돌아봤을 때 나는 &lt;code&gt;입력 -&amp;gt; 처리 -&amp;gt; 출력&lt;/code&gt;흐름 중심으로 기능을 쪼개고, 이후 책임에 따라 객체를 나누는 것이 편했 던 것 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;행동 중심으로 나누기&lt;/li&gt;
&lt;li&gt;구현 단계에서 '누가 이 일을 맡을까?' 고민하면서 책임 중심으로 전환&lt;/li&gt;
&lt;/ol&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;미션을 진행하면서&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;MVC 패턴 적용하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 리뷰를 하면서 많은 동료들이 MVC 패턴을 사용한 걸 알 수 있었다. 나의 코드와 비교했을 때 확실히 한 눈에 파악하기 좋았다. 그래서 나도 2주차에는 MVC 패턴을 공부하고 적용해보기로 마음 먹었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC패턴이 정리된 블로그들을 찾아보고, 우테코 제리 선배님의 영상을 참고했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ogaXW6KPc8I&amp;amp;t=331s&quot;&gt;https://www.youtube.com/watch?v=ogaXW6KPc8I&amp;amp;t=331s&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=ogaXW6KPc8I&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/tbXig/dJMb87f0HTs/YYBRIpdGJWYQLayW6ZJEEK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=734_168_814_256&quot; data-video-width=&quot;430&quot; data-video-height=&quot;242&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;[10분 테코톡]   제리의 MVC 패턴&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ogaXW6KPc8I&quot; width=&quot;430&quot; height=&quot;242&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념적으로 Model은 데이터를 처리를 담당하고, View는 화면 처리 담당, Controller는 View와 Model의 상호작용 담당이라는 사실을 쉽게 이해할 수 있었다. 해당 영상에서 제공하는 기준을 바탕으로 내 코드에 MVC 패턴이 적용되었는지 확인하면서 리팩토링을 반복했다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Model은 Controller와 View에 의존하지 않아야 함&lt;/li&gt;
&lt;li&gt;View는 Model에만 의존해야 하고, Controller에는 의존하면 안됨&lt;/li&gt;
&lt;li&gt;View가 Model로부터 데이터를 받을 때, 사용자에게 보여질 데이터에 대해서만 받아야 함&lt;/li&gt;
&lt;li&gt;Controller는 Model과 View에 의존해도 된다.&lt;/li&gt;
&lt;li&gt;View가 Model로부터 데이터를 받을 때, 반드시 Controller를 통해서만 받아야 함&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제로 코드에 적용하려다보니 어떤 코드를 어디에 넣어야 할지 선택하기가 힘들었다. 특히 Controller 영역에 들어갈지, Model에 들어갈지에 대한 기준을 세우기 힘들었다. 예를 들어 &quot;경주를 N번 진행한다&quot;는 반복 로직을 어디에 둬야 할지 애매했다. Controller가 직접 반복문을 돌면서 Model의 메서드를 호출해야 하는지, 아니면 Model에 &quot;N번 진행하라&quot;는 메서드를 만들어야 하는지 헷갈렸다. 이번 주 과제를 수행하면서 Controller는 '무엇을 할지만 결정하기'로 이해하고 적용했다. 즉, Controller는 '입력받기-&amp;gt;검증하기-&amp;gt;게임진행하기-&amp;gt;결과출력하기'와 같은 흐름만 제어하고, 실제로 어떻게 검증하고 어떻게 게임을 진행하는지는 Model이 담당해야 한다는 것을 깨달았다. 하지만 여전히 경계가 명확하지 않아 더 많은 연습이 필요하다고 느꼈다.&lt;br /&gt;그리고 동료들의 1주차 코드를 보면서 service라는 패키지를 보았다. Controller랑 뭐가 다르지?라는 궁금증이 생생겼고, &quot;비즈니스 로직을 담당한다&quot;는 설명을 봤지만 아직 개념을 완전히 이해하지 못해 미션에 적용하지 못했다.&lt;br /&gt;다음 주차에는 Service 계층의 역할과 필요성에 대해 더 공부하고, MVC 패턴 내에서 각 계층이 어떤 책임을 가져야 하는 지 더 명확하게 이해해야겠다고 느꼈다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Static 메서드 사용 기준&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 리뷰에서 상태를 가지지 않는 객체에 대해서 static 메서드를 사용하면 좋겠다는 의견이 있었다.&lt;br /&gt;그래서 util 클래스뿐만 아니라 InputView와 OutputView 클래스도 static으로 생성할까?라는 고민을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고민 끝에 나는 외부 의존성과 확장 가능성을 기준으로 판단하기로 했다. util 클래스처럼 외부 의존성 없이 순수하게 특정 기능 처리만 하는 메서드는 static으로 만드는 것이 적합하다고 생각했다.&lt;br /&gt;InputView와 OutputView는 Console이나 System.out같은 의존성을 가지고 있고, 콘솔 입력이 아닌 파일 입력으로 변경해야 할 수도 있다는 확장 가능성도 고려했다. 따라서 View와 같은 클래스는 인스턴스로 생성했다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;상태를 가지지 않음&lt;/li&gt;
&lt;li&gt;외부 의존성이 없음&lt;/li&gt;
&lt;li&gt;확장 가능성이 없음&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리하면서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;완벽하게 해내는 것&lt;/code&gt;보다 &lt;code&gt;새로운 시도를 멈추지 않는 것&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주 배우고 시도한 것&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;MVC 패턴 공부 및 적용&lt;/li&gt;
&lt;li&gt;일급 컬렉션 공부 및 적용&lt;/li&gt;
&lt;li&gt;private 생성자 + static 메서드 적용&lt;/li&gt;
&lt;li&gt;요구사항 분석 기준 세우기&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준 세우기&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;MVC에서 Controller의 기준&lt;/li&gt;
&lt;li&gt;정적 메서드 사용 기준&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 주에는 더 많은 동료들과 코드 리뷰를 해서 공부할 수 있는 부분을 찾아 볼 것이다. 그리고 MVC 패턴을 더 완벽하게 이해해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과제 제출 링크: &lt;a href=&quot;https://github.com/sinequanonn/java-racingcar-8/tree/sinequanonn&quot;&gt;https://github.com/sinequanonn/java-racingcar-8/tree/sinequanonn&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769330388990&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 - sinequanonn/java-racingcar-8&quot; data-og-description=&quot;Contribute to sinequanonn/java-racingcar-8 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/java-racingcar-8/tree/sinequanonn&quot; data-og-url=&quot;https://github.com/sinequanonn/java-racingcar-8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b2x9Zi/dJMb85WNAVl/dG7dxDLIaIHcNusFWE54lk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/TgafS/dJMb85vJcrq/dkEpGWPkf1S4wkGwQP3TjK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/java-racingcar-8/tree/sinequanonn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/java-racingcar-8/tree/sinequanonn&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b2x9Zi/dJMb85WNAVl/dG7dxDLIaIHcNusFWE54lk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/TgafS/dJMb85vJcrq/dkEpGWPkf1S4wkGwQP3TjK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - sinequanonn/java-racingcar-8&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to sinequanonn/java-racingcar-8 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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**블로그 새로 만들어서 프리코스 기간 때 작성했던 내용을 다시 옮겨 적었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;2주차회고&quot; href=&quot;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&quot;&gt;2주차 회고&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>우아한테크코스</category>
      <category>8기</category>
      <category>우아한테크코스</category>
      <category>프리코스</category>
      <author>sinequanon</author>
      <guid isPermaLink="true">https://sinequanon.tistory.com/6</guid>
      <comments>https://sinequanon.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 25 Jan 2026 17:43:25 +0900</pubDate>
    </item>
    <item>
      <title>[BE 8기] 우테코 프리코스 1주차 회고</title>
      <link>https://sinequanon.tistory.com/5</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1주차 미션&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;문자열 덧셈 계산기&lt;/code&gt; 구현이다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 회차의 목표&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 객체 지향적으로 코드 작성하기 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 코드 컨벤션과 커밋 컨벤션 익숙해지기 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. **AI 툴 사용하지 않고, 문제 해결하기&lt;/span&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;요구사항을 분석하면서&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PdfKN/dJMcadHydj1/j7Mi5BW1TaJQqesTGKmf2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PdfKN/dJMcadHydj1/j7Mi5BW1TaJQqesTGKmf2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PdfKN/dJMcadHydj1/j7Mi5BW1TaJQqesTGKmf2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPdfKN%2FdJMcadHydj1%2Fj7Mi5BW1TaJQqesTGKmf2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;295&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;295&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;776&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BO6Qy/dJMcagqLmao/v9inqc0zfe3gyvfUx6mvOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BO6Qy/dJMcagqLmao/v9inqc0zfe3gyvfUx6mvOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BO6Qy/dJMcagqLmao/v9inqc0zfe3gyvfUx6mvOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBO6Qy%2FdJMcagqLmao%2Fv9inqc0zfe3gyvfUx6mvOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;307&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;제시된 요구 사항을 바탕으로 나만의 언어로&amp;nbsp; README에 다시 작성을 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhcgIM/dJMcai28YPC/QYu53B4g8AeNT18XWsIsAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhcgIM/dJMcai28YPC/QYu53B4g8AeNT18XWsIsAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhcgIM/dJMcai28YPC/QYu53B4g8AeNT18XWsIsAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhcgIM%2FdJMcai28YPC%2FQYu53B4g8AeNT18XWsIsAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;496&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고&amp;nbsp;문자열&amp;nbsp;덧셈&amp;nbsp;계산기에는&amp;nbsp;어떤&amp;nbsp;책임들이&amp;nbsp;있을지&amp;nbsp;고민했다.&lt;br /&gt;1.&amp;nbsp;더하기&amp;nbsp;연산을&amp;nbsp;수행하는&amp;nbsp;책임&lt;br /&gt;2.&amp;nbsp;문자열에&amp;nbsp;포함된&amp;nbsp;양수를&amp;nbsp;얻어내는&amp;nbsp;책임&lt;br /&gt;3.&amp;nbsp;사용자로부터&amp;nbsp;문자열&amp;nbsp;입력받는&amp;nbsp;책임&lt;br /&gt;4.&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구현하면서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'객체&amp;nbsp;지향적으로&amp;nbsp;작성하자'는&amp;nbsp;마음으로&amp;nbsp;수행했다.&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;문자열로부터&amp;nbsp;양수를&amp;nbsp;추출하는&amp;nbsp;책임을&amp;nbsp;같도록&amp;nbsp;했다.&amp;nbsp;하지만&amp;nbsp;여러&amp;nbsp;의문점이&amp;nbsp;존재했다.&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;검증&amp;nbsp;로직은&amp;nbsp;어디서&amp;nbsp;하지?&lt;br /&gt;2.&amp;nbsp;예외&amp;nbsp;처리는&amp;nbsp;어디서&amp;nbsp;하지?&lt;br /&gt;3.&amp;nbsp;만약&amp;nbsp;요구사항이&amp;nbsp;바꼈을&amp;nbsp;때,&amp;nbsp;변경에&amp;nbsp;자유로운가?&lt;br /&gt;&lt;br /&gt;3번의&amp;nbsp;경우&amp;nbsp;구현하면서&amp;nbsp;문제가&amp;nbsp;발생했다.&amp;nbsp;요구&amp;nbsp;사항&amp;nbsp;분석을&amp;nbsp;할&amp;nbsp;때&amp;nbsp;양수를&amp;nbsp;'정수'로만&amp;nbsp;한정지어서&amp;nbsp;Integer&amp;nbsp;타입을&amp;nbsp;사용했다.&amp;nbsp;구현&amp;nbsp;도중&amp;nbsp;'실수'도&amp;nbsp;가능하다는&amp;nbsp;걸&amp;nbsp;깨닫고&amp;nbsp;코드&amp;nbsp;수정을&amp;nbsp;했는데,&amp;nbsp;`PositiveNumberExtractor`를&amp;nbsp;수정하니,&amp;nbsp;`Calculator`&amp;nbsp;클래스도&amp;nbsp;수정해야&amp;nbsp;했고,&amp;nbsp;`Computer`,&amp;nbsp;`OutputView`&amp;nbsp;모두&amp;nbsp;다&amp;nbsp;수정해야&amp;nbsp;했다.&amp;nbsp;객체지향적으로&amp;nbsp;작성한다는&amp;nbsp;것은&amp;nbsp;변경&amp;nbsp;시&amp;nbsp;코드&amp;nbsp;수정이&amp;nbsp;없어야하고,&amp;nbsp;즉&amp;nbsp;변경에&amp;nbsp;자유로워야&amp;nbsp;하는데&amp;nbsp;그렇지&amp;nbsp;않았다.&lt;br /&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;실패했다.&lt;br /&gt;OOP를&amp;nbsp;공부해서&amp;nbsp;변경에&amp;nbsp;용이한&amp;nbsp;코드를&amp;nbsp;작성하는지&amp;nbsp;공부해야겠다.&lt;br /&gt;그리고&amp;nbsp;다른&amp;nbsp;의문점들은&amp;nbsp;커뮤니티를&amp;nbsp;통해&amp;nbsp;생각을&amp;nbsp;나눠봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배운 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;요구사항&amp;nbsp;분석의&amp;nbsp;중요성&lt;br /&gt;2.&amp;nbsp;변경에&amp;nbsp;자유로운&amp;nbsp;코드&amp;nbsp;작성의&amp;nbsp;중요성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/java-calculator-8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/sinequanonn/java-calculator-8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769329772134&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 - sinequanonn/java-calculator-8: 1주차 미션&quot; data-og-description=&quot;1주차 미션. Contribute to sinequanonn/java-calculator-8 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sinequanonn/java-calculator-8&quot; data-og-url=&quot;https://github.com/sinequanonn/java-calculator-8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nhHgQ/dJMb88eUXaN/m5uqoX25g594hlkSjiv781/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Vd1QA/dJMb86nRSL6/51u41hBCOFlIYLdx2TapeK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sinequanonn/java-calculator-8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sinequanonn/java-calculator-8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nhHgQ/dJMb88eUXaN/m5uqoX25g594hlkSjiv781/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Vd1QA/dJMb86nRSL6/51u41hBCOFlIYLdx2TapeK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - sinequanonn/java-calculator-8: 1주차 미션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1주차 미션. Contribute to sinequanonn/java-calculator-8 development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;**블로그 새로 만들어서 프리코스 기간 때 작성했던 내용을 다시 옮겨 적었습니다.&lt;br /&gt;&lt;a href=&quot;https://velog.io/@sinequanonn/BE-8%EA%B8%B0-%EC%9A%B0%ED%85%8C%EC%BD%94-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1주차 회고&lt;/a&gt;&lt;/p&gt;</description>
      <category>우아한테크코스</category>
      <category>8기</category>
      <category>우아한테크코스</category>
      <category>프리코스</category>
      <author>sinequanon</author>
      <guid isPermaLink="true">https://sinequanon.tistory.com/5</guid>
      <comments>https://sinequanon.tistory.com/5#entry5comment</comments>
      <pubDate>Sun, 25 Jan 2026 17:31:14 +0900</pubDate>
    </item>
  </channel>
</rss>