6-keem
Gallery
About
© Powered by 6-keem
All
25 posts
  • All
  • 캡스톤디자인
  • 일상
  • Chrome-extension
  • Frontend
  • Backend
  • thumbnail for 넌 못 지나간다

    넌 못 지나간다

    해당 블로그는 Vercel 통해 배포되고 있다. 그래서 도메인도 Vercel에서 기본으로 제공해주는 vercel.app 도메인을 사용하고 있었는데 문득 다른 도메인을 구매하고 싶다는 생각이 들었다. 해당 글은 도메인을 구매하여 적용하는 과정에서 생긴 일에 대해서 정리한 글이다. 어떤 업체가 좋을까? 먼저 도메인 분야에서 대표적인 세 업체를 선정하고 세부적으로 비교하였다. 가격은 3년 기준으로 결과는 다음과 같다. Cloudflare Squarespace 가비아 가격 $31.32 $59.40 ~ $51 서비스 👍🏻 🤔 👎🏻 `Squarespace`는 google domains를 인수하여 구글과의 연동성이 매우 좋은 것이 장점인 것 같았다. 다만 가격이 저렴한 업체에 비해 2배 정도 비싼 것이 큰 단점이었다. `가비아`는 앞선 업체에 비해 저렴하지만 다소 기본적인 기능조차 돈을 지불해야 하는 점이 많이 아쉬웠다. 그에 비해 `Cloudflare`는 가장 저렴한 가격에 도메인을 구매할 수 있고, `가비아`에서는 유료인 등록 정보 숨김 기능을 무료로 지원한다. 또 다양한 보안 솔루션을 제공하기 때문에 `Cloudflare`를 선택하지 않을 이유가 없었다. Cloudflare 구매 구매는 원활하게 진행되었고, 한화로 대략 45,000₩ 정도가 빠져 나갔다. 무료 도메인 업체인 `duckdns`를 사용했을 때는 여러 설정을 수동으로 했었지만, `Cloudflare`의 경우 Vercel에 구매한 도메인을 입력하면 자동으로 필요한 설정을 등록해주는 것이 편했다. 이렇게 글이 마무리 되었으면 좋겠지만, 문제가 발생했다. !무수히 많은 악수의 요청이... 🫱🏻‍🫲🏽 whois에 새로 도메인이 등록되면 크롤링을 시작하는 건지, 도메인을 등록하자마자 무수한 GET 요청이 날라오는 것 아니겠나... 일단 Vercel 설정 > 방화벽에 가서 `Attack Challenge Mode`를 활성화 시키고 `Bot Filter`를 통해 걸러내고자 하였으나, 전혀 효과가 없었다. 어떻게 해결할까? Proxy 해결 방법을 찾던 도중 `Cloudflare`의 보안 서비스를 이용하면 된다는 것을 깨달았다. Vercel에 도메인을 등록하면 Cloudflare에 다음과 설정이 추가된다. Vercel 주소는 여기로 가면 돼 따라서 클라이언트는 내가 구매한 도메인의 IP 주소를 Cloudflare의 DNS 서버(DNS Only)를 통해 조회하게 된다. 이 경우 클라이언트는 Cloudflare DNS에 등록된 Vercel의 IP 또는 CNAME 정보를 받게 되며, 실제 요청은 Vercel로 직접 전송된다. 다만, 이 방식에서는 Cloudflare가 트래픽을 직접 다루지 않기 때문에, 보안 기능 (DDoS 방어, WAF, SSL 인증서 등)이 적용되지 않는다. 따라서 Proxy 설정을 켜주는 것이 필요하다. !DNS Records 먼저 Cloudflare Dashboard에서 DNS Records 탭을 클릭하면 현재 설정된 레코드를 볼 수 있다. 여기서 Edit 버튼을 눌러 Proxy 상태를 ON으로 바꾸면, 다음과 같은 일이 일어난다. Vercel? 갖다줄게, 잠깐 여기서 기다려봐 이제 Cloudflare가 클라이언트와 Vercel 사이에 중계자 역할을 하게 되며, 보안, 캐싱, 속도 최적화 기능들을 자유롭게 사용할 수 있다. _※ proxy를 켜면 domain configuration이 필요하다고 하는데 무시하면 된다._ Security 나의 블로그는 수익을 목적으로 한 블로그도 아니고 특정 분야의 전문적인 지식을 제공하는 블로그도 아니다. 블로그를 운영하는 목적은 일기 같은 느낌으로 오로지 배운 것을 정리해두는 목적이 크다. !사이버 수문장 내가 정리한 지식이 공유되는 것은 좋은 일이라고 생각하지만, Vercel의 무료 플랜은 대역폭에 제한이 있고 자동화 크롤러 때문에 과금을 하고 싶지는 않았다. 따라서 나만의 사이버 수문장을 만들고 자동화 크롤링이든 LLM에 의한 크롤링이든 사람이 아닌 클라이언트의 모든 요청을 막고자 했다. 나의 설정은 다음과 같다. !Setting 봇 탐지 관련(자동화 혹은 AI)은 모두 활성화 해주었다. 내 블로그는 `robots.txt`를 작성하지 않았기에 설정하지 않았고, 봇 탐지 정확도 향상 옵션과 링크 뺑뺑이 옵션도 활성화 시켰다. !Security Rules Security Rules 탭에는 다양한 조건들을 설정할 수 있다. 내 블로그는 한국, 일본 IP만 자유롭게 접속을 허용하고 그 외 국가는 Challenge를 거치도록 설정하였다. 이 탭에서는 10초에 몇 번이상 GET 요청을 받으면 차단 시키는 등의 Rate Limitation 설정도 가능하다. 마무리 보안 설정을 끝내니 그 많던 벌레들이 사라지는 것을 볼 수 있다. Cloudflare에서 접속을 잘 막아주는 듯 하다. 오른쪽 사진을 보면 알겠지만, 크롤러들이 사이트를 돌며 잘못 배포된 RSA Key, API Key를 찾으려고 혈안이 되어 있다. 다시 한 번 배포의 중요성을 깨닫게 된 순간이었다. 이런 일을 겪는다면 다들 사이버 수문장을 만들어보자
    2025년 04월 29일
    일상
  • thumbnail for 넌 못 지나간다

    넌 못 지나간다

    해당 블로그는 Vercel 통해 배포되고 있다. 그래서 도메인도 Vercel에서 기본으로 제공해주는 vercel.app 도메인을 사용하고 있었는데 문득 다른 도메인을 구매하고 싶다는 생각이 들었다. 해당 글은 도메인을 구매하여 적용하는 과정에서 생긴 일에 대해서 정리한 글이다. 어떤 업체가 좋을까? 먼저 도메인 분야에서 대표적인 세 업체를 선정하고 세부적으로 비교하였다. 가격은 3년 기준으로 결과는 다음과 같다. Cloudflare Squarespace 가비아 가격 $31.32 $59.40 ~ $51 서비스 👍🏻 🤔 👎🏻 `Squarespace`는 google domains를 인수하여 구글과의 연동성이 매우 좋은 것이 장점인 것 같았다. 다만 가격이 저렴한 업체에 비해 2배 정도 비싼 것이 큰 단점이었다. `가비아`는 앞선 업체에 비해 저렴하지만 다소 기본적인 기능조차 돈을 지불해야 하는 점이 많이 아쉬웠다. 그에 비해 `Cloudflare`는 가장 저렴한 가격에 도메인을 구매할 수 있고, `가비아`에서는 유료인 등록 정보 숨김 기능을 무료로 지원한다. 또 다양한 보안 솔루션을 제공하기 때문에 `Cloudflare`를 선택하지 않을 이유가 없었다. Cloudflare 구매 구매는 원활하게 진행되었고, 한화로 대략 45,000₩ 정도가 빠져 나갔다. 무료 도메인 업체인 `duckdns`를 사용했을 때는 여러 설정을 수동으로 했었지만, `Cloudflare`의 경우 Vercel에 구매한 도메인을 입력하면 자동으로 필요한 설정을 등록해주는 것이 편했다. 이렇게 글이 마무리 되었으면 좋겠지만, 문제가 발생했다. !무수히 많은 악수의 요청이... 🫱🏻‍🫲🏽 whois에 새로 도메인이 등록되면 크롤링을 시작하는 건지, 도메인을 등록하자마자 무수한 GET 요청이 날라오는 것 아니겠나... 일단 Vercel 설정 > 방화벽에 가서 `Attack Challenge Mode`를 활성화 시키고 `Bot Filter`를 통해 걸러내고자 하였으나, 전혀 효과가 없었다. 어떻게 해결할까? Proxy 해결 방법을 찾던 도중 `Cloudflare`의 보안 서비스를 이용하면 된다는 것을 깨달았다. Vercel에 도메인을 등록하면 Cloudflare에 다음과 설정이 추가된다. Vercel 주소는 여기로 가면 돼 따라서 클라이언트는 내가 구매한 도메인의 IP 주소를 Cloudflare의 DNS 서버(DNS Only)를 통해 조회하게 된다. 이 경우 클라이언트는 Cloudflare DNS에 등록된 Vercel의 IP 또는 CNAME 정보를 받게 되며, 실제 요청은 Vercel로 직접 전송된다. 다만, 이 방식에서는 Cloudflare가 트래픽을 직접 다루지 않기 때문에, 보안 기능 (DDoS 방어, WAF, SSL 인증서 등)이 적용되지 않는다. 따라서 Proxy 설정을 켜주는 것이 필요하다. !DNS Records 먼저 Cloudflare Dashboard에서 DNS Records 탭을 클릭하면 현재 설정된 레코드를 볼 수 있다. 여기서 Edit 버튼을 눌러 Proxy 상태를 ON으로 바꾸면, 다음과 같은 일이 일어난다. Vercel? 갖다줄게, 잠깐 여기서 기다려봐 이제 Cloudflare가 클라이언트와 Vercel 사이에 중계자 역할을 하게 되며, 보안, 캐싱, 속도 최적화 기능들을 자유롭게 사용할 수 있다. _※ proxy를 켜면 domain configuration이 필요하다고 하는데 무시하면 된다._ Security 나의 블로그는 수익을 목적으로 한 블로그도 아니고 특정 분야의 전문적인 지식을 제공하는 블로그도 아니다. 블로그를 운영하는 목적은 일기 같은 느낌으로 오로지 배운 것을 정리해두는 목적이 크다. !사이버 수문장 내가 정리한 지식이 공유되는 것은 좋은 일이라고 생각하지만, Vercel의 무료 플랜은 대역폭에 제한이 있고 자동화 크롤러 때문에 과금을 하고 싶지는 않았다. 따라서 나만의 사이버 수문장을 만들고 자동화 크롤링이든 LLM에 의한 크롤링이든 사람이 아닌 클라이언트의 모든 요청을 막고자 했다. 나의 설정은 다음과 같다. !Setting 봇 탐지 관련(자동화 혹은 AI)은 모두 활성화 해주었다. 내 블로그는 `robots.txt`를 작성하지 않았기에 설정하지 않았고, 봇 탐지 정확도 향상 옵션과 링크 뺑뺑이 옵션도 활성화 시켰다. !Security Rules Security Rules 탭에는 다양한 조건들을 설정할 수 있다. 내 블로그는 한국, 일본 IP만 자유롭게 접속을 허용하고 그 외 국가는 Challenge를 거치도록 설정하였다. 이 탭에서는 10초에 몇 번이상 GET 요청을 받으면 차단 시키는 등의 Rate Limitation 설정도 가능하다. 마무리 보안 설정을 끝내니 그 많던 벌레들이 사라지는 것을 볼 수 있다. Cloudflare에서 접속을 잘 막아주는 듯 하다. 오른쪽 사진을 보면 알겠지만, 크롤러들이 사이트를 돌며 잘못 배포된 RSA Key, API Key를 찾으려고 혈안이 되어 있다. 다시 한 번 배포의 중요성을 깨닫게 된 순간이었다. 이런 일을 겪는다면 다들 사이버 수문장을 만들어보자

    2025년 04월 29일
    일상

  • thumbnail for 살짝은 늦어버린 새해 다짐이랄까

    살짝은 늦어버린 새해 다짐이랄까

    새해가 밝은지 어느덧 4개월이 지났고 이제서야 목표를 세운다는 것은 내가 생각해도 조금 웃기긴 하다. 기대를 가지고 도전 했던 것들의 실패로 착잡한 상태지만 지금과 같은 노력이 언젠가 성공 내지는 행운을 불러 오지 않을까라는 생각으로 올해의 스케줄과 목표를 다시 정리해 보려고 한다. 일본 취업 이대로 괜찮은가? 일본행을 결정한 지 어느덧 일년, 원래 26년 3월 졸업 예정이었지만 이런저런 고민 끝에 교환학생에 지원하게 되었다. 교환학생은 정규 학기로서 파견 되는 것이기에 학기 인정이 되지만 4학년 2학기 파견은 반드시 추가 학기 등록이 필요하단다 😱 어차피 내년 하반기 졸업이니까 신졸 채용 준비해도 되는거 아니야? 엔트리 시트를 끄적이며 이곳저곳 살펴보니 어느정도 규모가 있는 기업은 4월 입사를 전제로 채용을 하는 것이 아니겠나? 나의 원대한 계획이 물거품이 되어 교환학생을 포기할까 잠시 고민도 했다. 하지만 이미 일본 내정률이 50%가 넘어간 시점, 준비도 안된 언어 실력과 스펙을 가지고 취업 전선에 뛰어 든다면 분명 나중에 후회할 것이 뻔했다. 그렇게 이번 년도에 칼을 갈아 내년 현지에서 더 많은 기업에 도전 해보는 것으로 마음을 굳혔다. 다만 현지에서 취업을 한다는 것은 일본인들과 싸워서 이겨야 한다는 뜻이다. 한국에서 한국인들과 싸워 일본에 취업하는 것과는 상상할 수 없을 만큼 어려울 것이고, 내가 그들보다 뛰어난 것을 보여줄 수 없다면 참패를 당할 것이 뻔하다. 그래서 도대체 목표가 뭔데? 내년 해금 전까지 많은 분야에서 성장을 이루어내야 한다. 그중에서 일본어 능력이 가장 우선이라고 생각했다. 한국인들과 경쟁해서 입사한다고 하면 일본어를 잘하는 것이 어느정도 어드벤티지로 작용할 수 있으나, 현지에서 일본어를 잘한다는 것은 당연한 일이고 토익이나 오픽 같은 영어 자격증이 없는 나는 더욱 열심히 해야한다고 느끼었다. 그래서 단기간에 어떻게 하면 효과적으로 올릴 수 있을까에 대해 생각해 본 결과 교환학생 기간 전과 후로 나누어 보았다. 현재 나에게 가장 부족하다고 생각하는 부분은 어휘력이다. 일본어 발음, 인토네이션 등은 네이티브는 아니지만 자연스러운 반면 어휘력이 부족하다는 평가를 받았다. 따라서 교환 학생 파견 이전에는 JLPT N1 시험을 준비하며 어휘력을 늘리는 연습을 할 것이다. 세부 방법은 다음과 같다 N1 단어 암기 및 쓰기 대화에서 배웠던 단어 사용하기 물론 N1 자격증을 가지고 있다고 일본어를 잘한다고 할 수는 없다. 그렇지만 교환 학생 기간동안 어차피 일본어 공부를 해야하고 지금 N2를 가지고 있기 때문에 겸사겸사 업그레이드를 하려고 한다. 이렇게 하면 지금보다는 어휘력이 늘 것이다. 그거 가지고 되겠어? 아마 턱 없이 부족할 것이다. 아무리 일본어 책이라고 해도 현지에서는 쓰이지 않는 단어도 많을 것이고 암기했던 단어를 바로 자유자재로 사용하기란 참 어려운 일이다. 언어 능력을 가장 빠르게 늘리기 위해서 가장 중요한 것은 실제로 쓰고 말해야한다. 다만 내 전공 특성상 파견 이후에도 대화가 많을 것이라고 생각이 들지 않았고 일본어를 많이 사용할 수 있는 환경에 놓이는 것이 중요하다고 생각하였다. 그리하여 생각한 것이 아르바이트와 봉사활동이다. 아르바이트에서는 필연적으로 직원 혹은 손님과 대화를 해야한다. 다양한 상황에 부딪히고 이를 해결하는 과정에서 일본어 뿐만 아니라 상황 대처 능력도 키울 수 있을 것이라 생각했다. 아르바이트는 이자카야를 생각하고 있는데 확정은 아니다. 다만 봉사활동은 꼭 보육원에서 해보고 싶다. 조금 오그라들 수 있는 이유인데, 내가 가진 것을 미래 세대에 나누며 사회에 공헌하고 싶다는 이유이다. 간단한 수학, 영어 과목이나 한국에 흥미를 가지는 학생에게 한국어를 가르쳐주며 내 일본어 능력도 늘릴 수 있는 공생 관계랄까 근데 일본어 공부만 하게? 당연히 아니다 하지만 지금 제일 중요하다고 생각하는 것이 일본어 능력 향상이기 때문에 먼저 말했다. 한국에서 하는 일본 취업에서는 많이 생략하지만 현지에서는 적성 검사(SPI) 대비를 위한 공부도 따로 해야하니 상황이 좋지만은 않다. 교환 학생 파견에서 서클 활동 등 다양한 계획이 있지만 이제는 전공과 관련된 이야기를 해야할 것 같다. 먼저 나는 저학년 시절 데이터분석가를 희망하다가 대학원 진학은 하고 싶지 않아 백앤드 개발자로 진로를 바꾸었다. 다만 최근 AI의 발전으로 단순히 코드를 짤 수 있는 개발자는 10년 이내에 대체될 것이라 생각하는 사람 중 한명으로 다른 능력을 더 키워야할 필요성을 최근에 절실히 느끼고 있다. 물론 중요한 비즈니스 로직을 AI로 설계하거나 구축하는건 쓸데없는 걱정이라고 생각하지만, 언젠가는 트랜드가 변할 것이고 나는 그것이 온디바이스 AI와 관련이 깊다고 생각한다. 그리하여 백앤드 개발자는 AI 기술에 대해 어느정도 지식을 가지고 서비스에 잘 적용할 수 있는 능력이 중요해질 것으로, 단순한 프론트 디자인은 다른 직무에 비해 빠르게 대체될 것이라 생각한다. 앞으로 어떻게 할거냐? 많은 고민이 있었고 내 길이 틀릴 수도 있다. 하지만 나는 풀스택 개발자로 방향을 정했다. 이유는 다음과 같은데 개발을 해보았다면 공감을 하겠지만, 비즈니스 로직은 그 역할에 따라 프론트에 있을 때도 있고, 백앤드에 있을 수도 있다. 따라서 프론트 능력만 갖춘다면 전체적인 비즈니스 로직을 처리할 수 있다. 프론트도 백앤드 모두 깊게 들어가면 쉽지 않은 기술들이지만, AI의 발전이 거듭된다면 프론트 디자인 쪽은 AI의 어시스턴트를 받아 더욱 높은 업무 효율을 낼 수 있을 것이라 생각했다. !나는야 이도류가 될테야 웹 개발 vs 앱 개발 앞서 언급한 것처럼 미래 온디바이스 AI의 큰 발전을 기대하기 때문에 앱 개발으로 도전할 것이고, 프레임워크는 크로스 플랫폼인 Flutter로 정하였다. 일본에서도 많은 기업들이 Flutter를 사용해서 사내 어플리케이션, 제품 어플리케이션을 개발하고 있다. 분명히 성능, 특정 기능 같은 크로스 플랫폼 프레임워크의 한계도 존재할 것이나, 차차 해결될 문제라고 생각한다. !아무튼 해결될 것임... Dart는 요즘 언어 다운 느낌이고 Kotlin과 React와 중간 어딘가라는 느낌을 받았다. Flutter 기본 개발 경험은 있기 때문에 인프런에 올라온 강의를 위주로, 실습 및 클론 코딩으로 전체적인 프레임워크에 대한 이해도를 상승시키고, MVVM 아키텍쳐와 Flutter 상태 관리에 대해 더 깊게 공부해볼 생각이다. 백앤드 프레임워크는 많은 고민을 했고 아직도 고민중인 부분이다. 한국은 Spring Boot가 널리 쓰이고 전세계적으로도 인기가 있는 프레임워크인 것은 확실하다. 하지만 최근 전세계적으로 Django가 유행을 타고 있고 일본에서는 Ruby on Rails가 많이 쓰이는 분위기라 어떤 프레임워크를 메인으로 가져갈까 많은 고민을 했으나 아직도 결론을 내지는 못한 상태이다. 다만, Django 혹은 Spring Boot에서 선택을 할 생각이고, Rails는 메인으로 가져가지는 않기로 했다. 이유는 성능은 꽤나 중요한데 Rails의 퍼포먼스가 앞선 두 프레임워크에 비해 떨어지기 때문에 언젠가는 한계에 부딪힐 수 있다고 생각 했기 때문이고 입문이 그렇게 어렵지 않은 프레임워크라고 알려져 있어 만약 회사에서 해당 프레임워크를 사용한다면 그때 배워도 늦지 않을 것 같았기 때문이다. 근데 일본에서 신입한테 개발 실력 기대 안하잖아 개인적으로 나도 걱정이 되는 부분이다. 일본 사회 특성상 신입을 뽑아서 키우는 분위기이기 때문에 특출난 능력을 요구하지 않는다는 느낌을 받았다. 학점도 많이 신경을 쓰지 않는 느낌이라, 고학점인 나로서는 장점을 하나 잃어버린 느낌이기도 했다. 그래서 직접적인 어필보다는 엔트리 시트에 성실함을 뒷받침하는 내용 정도로 하려고 한다. 또 엔트리 시트에 GitHub 주소를 넣을 순 없으니 아마 엔트리 시트에 가쿠치카에 적을 것 같다... 일단 이번년도 안에 정보처리기사를 따는 것이 목표이다. 원래는 딸 생각이 없었는데 일본의 응용정보기술자와 같은 자격으로 인정해준다고 한다. 다만 2차시 필기ᐧ실기에 합격하지 못하면 교환학생 도중에 실기를 보러 돌아와야하는 불상사가 생긴다. 🤯 신입에게 실력을 기대하지 않지만 잠재력 혹은 열정으로 평가되는 부분이 많기에 이번 여름 방학 때는 인턴쉽 혹은 일체험을 해보려고 한다. 물론 아직 일본어가 완벽하지 않은 한국인을 뽑아줄지는 모르겠으나 원하는 기업의 인턴쉽을 할 수 있으면 조기선고나 추후 면접에서 좋은 평가를 받을 수 있기에 한 번 도전해보려고 한다. 마무리 !대략적인 로드맵 쉽지 않은 도전이지만 화이팅 하자
    2025년 04월 25일
    일상
  • thumbnail for 살짝은 늦어버린 새해 다짐이랄까

    살짝은 늦어버린 새해 다짐이랄까

    새해가 밝은지 어느덧 4개월이 지났고 이제서야 목표를 세운다는 것은 내가 생각해도 조금 웃기긴 하다. 기대를 가지고 도전 했던 것들의 실패로 착잡한 상태지만 지금과 같은 노력이 언젠가 성공 내지는 행운을 불러 오지 않을까라는 생각으로 올해의 스케줄과 목표를 다시 정리해 보려고 한다. 일본 취업 이대로 괜찮은가? 일본행을 결정한 지 어느덧 일년, 원래 26년 3월 졸업 예정이었지만 이런저런 고민 끝에 교환학생에 지원하게 되었다. 교환학생은 정규 학기로서 파견 되는 것이기에 학기 인정이 되지만 4학년 2학기 파견은 반드시 추가 학기 등록이 필요하단다 😱 어차피 내년 하반기 졸업이니까 신졸 채용 준비해도 되는거 아니야? 엔트리 시트를 끄적이며 이곳저곳 살펴보니 어느정도 규모가 있는 기업은 4월 입사를 전제로 채용을 하는 것이 아니겠나? 나의 원대한 계획이 물거품이 되어 교환학생을 포기할까 잠시 고민도 했다. 하지만 이미 일본 내정률이 50%가 넘어간 시점, 준비도 안된 언어 실력과 스펙을 가지고 취업 전선에 뛰어 든다면 분명 나중에 후회할 것이 뻔했다. 그렇게 이번 년도에 칼을 갈아 내년 현지에서 더 많은 기업에 도전 해보는 것으로 마음을 굳혔다. 다만 현지에서 취업을 한다는 것은 일본인들과 싸워서 이겨야 한다는 뜻이다. 한국에서 한국인들과 싸워 일본에 취업하는 것과는 상상할 수 없을 만큼 어려울 것이고, 내가 그들보다 뛰어난 것을 보여줄 수 없다면 참패를 당할 것이 뻔하다. 그래서 도대체 목표가 뭔데? 내년 해금 전까지 많은 분야에서 성장을 이루어내야 한다. 그중에서 일본어 능력이 가장 우선이라고 생각했다. 한국인들과 경쟁해서 입사한다고 하면 일본어를 잘하는 것이 어느정도 어드벤티지로 작용할 수 있으나, 현지에서 일본어를 잘한다는 것은 당연한 일이고 토익이나 오픽 같은 영어 자격증이 없는 나는 더욱 열심히 해야한다고 느끼었다. 그래서 단기간에 어떻게 하면 효과적으로 올릴 수 있을까에 대해 생각해 본 결과 교환학생 기간 전과 후로 나누어 보았다. 현재 나에게 가장 부족하다고 생각하는 부분은 어휘력이다. 일본어 발음, 인토네이션 등은 네이티브는 아니지만 자연스러운 반면 어휘력이 부족하다는 평가를 받았다. 따라서 교환 학생 파견 이전에는 JLPT N1 시험을 준비하며 어휘력을 늘리는 연습을 할 것이다. 세부 방법은 다음과 같다 N1 단어 암기 및 쓰기 대화에서 배웠던 단어 사용하기 물론 N1 자격증을 가지고 있다고 일본어를 잘한다고 할 수는 없다. 그렇지만 교환 학생 기간동안 어차피 일본어 공부를 해야하고 지금 N2를 가지고 있기 때문에 겸사겸사 업그레이드를 하려고 한다. 이렇게 하면 지금보다는 어휘력이 늘 것이다. 그거 가지고 되겠어? 아마 턱 없이 부족할 것이다. 아무리 일본어 책이라고 해도 현지에서는 쓰이지 않는 단어도 많을 것이고 암기했던 단어를 바로 자유자재로 사용하기란 참 어려운 일이다. 언어 능력을 가장 빠르게 늘리기 위해서 가장 중요한 것은 실제로 쓰고 말해야한다. 다만 내 전공 특성상 파견 이후에도 대화가 많을 것이라고 생각이 들지 않았고 일본어를 많이 사용할 수 있는 환경에 놓이는 것이 중요하다고 생각하였다. 그리하여 생각한 것이 아르바이트와 봉사활동이다. 아르바이트에서는 필연적으로 직원 혹은 손님과 대화를 해야한다. 다양한 상황에 부딪히고 이를 해결하는 과정에서 일본어 뿐만 아니라 상황 대처 능력도 키울 수 있을 것이라 생각했다. 아르바이트는 이자카야를 생각하고 있는데 확정은 아니다. 다만 봉사활동은 꼭 보육원에서 해보고 싶다. 조금 오그라들 수 있는 이유인데, 내가 가진 것을 미래 세대에 나누며 사회에 공헌하고 싶다는 이유이다. 간단한 수학, 영어 과목이나 한국에 흥미를 가지는 학생에게 한국어를 가르쳐주며 내 일본어 능력도 늘릴 수 있는 공생 관계랄까 근데 일본어 공부만 하게? 당연히 아니다 하지만 지금 제일 중요하다고 생각하는 것이 일본어 능력 향상이기 때문에 먼저 말했다. 한국에서 하는 일본 취업에서는 많이 생략하지만 현지에서는 적성 검사(SPI) 대비를 위한 공부도 따로 해야하니 상황이 좋지만은 않다. 교환 학생 파견에서 서클 활동 등 다양한 계획이 있지만 이제는 전공과 관련된 이야기를 해야할 것 같다. 먼저 나는 저학년 시절 데이터분석가를 희망하다가 대학원 진학은 하고 싶지 않아 백앤드 개발자로 진로를 바꾸었다. 다만 최근 AI의 발전으로 단순히 코드를 짤 수 있는 개발자는 10년 이내에 대체될 것이라 생각하는 사람 중 한명으로 다른 능력을 더 키워야할 필요성을 최근에 절실히 느끼고 있다. 물론 중요한 비즈니스 로직을 AI로 설계하거나 구축하는건 쓸데없는 걱정이라고 생각하지만, 언젠가는 트랜드가 변할 것이고 나는 그것이 온디바이스 AI와 관련이 깊다고 생각한다. 그리하여 백앤드 개발자는 AI 기술에 대해 어느정도 지식을 가지고 서비스에 잘 적용할 수 있는 능력이 중요해질 것으로, 단순한 프론트 디자인은 다른 직무에 비해 빠르게 대체될 것이라 생각한다. 앞으로 어떻게 할거냐? 많은 고민이 있었고 내 길이 틀릴 수도 있다. 하지만 나는 풀스택 개발자로 방향을 정했다. 이유는 다음과 같은데 개발을 해보았다면 공감을 하겠지만, 비즈니스 로직은 그 역할에 따라 프론트에 있을 때도 있고, 백앤드에 있을 수도 있다. 따라서 프론트 능력만 갖춘다면 전체적인 비즈니스 로직을 처리할 수 있다. 프론트도 백앤드 모두 깊게 들어가면 쉽지 않은 기술들이지만, AI의 발전이 거듭된다면 프론트 디자인 쪽은 AI의 어시스턴트를 받아 더욱 높은 업무 효율을 낼 수 있을 것이라 생각했다. !나는야 이도류가 될테야 웹 개발 vs 앱 개발 앞서 언급한 것처럼 미래 온디바이스 AI의 큰 발전을 기대하기 때문에 앱 개발으로 도전할 것이고, 프레임워크는 크로스 플랫폼인 Flutter로 정하였다. 일본에서도 많은 기업들이 Flutter를 사용해서 사내 어플리케이션, 제품 어플리케이션을 개발하고 있다. 분명히 성능, 특정 기능 같은 크로스 플랫폼 프레임워크의 한계도 존재할 것이나, 차차 해결될 문제라고 생각한다. !아무튼 해결될 것임... Dart는 요즘 언어 다운 느낌이고 Kotlin과 React와 중간 어딘가라는 느낌을 받았다. Flutter 기본 개발 경험은 있기 때문에 인프런에 올라온 강의를 위주로, 실습 및 클론 코딩으로 전체적인 프레임워크에 대한 이해도를 상승시키고, MVVM 아키텍쳐와 Flutter 상태 관리에 대해 더 깊게 공부해볼 생각이다. 백앤드 프레임워크는 많은 고민을 했고 아직도 고민중인 부분이다. 한국은 Spring Boot가 널리 쓰이고 전세계적으로도 인기가 있는 프레임워크인 것은 확실하다. 하지만 최근 전세계적으로 Django가 유행을 타고 있고 일본에서는 Ruby on Rails가 많이 쓰이는 분위기라 어떤 프레임워크를 메인으로 가져갈까 많은 고민을 했으나 아직도 결론을 내지는 못한 상태이다. 다만, Django 혹은 Spring Boot에서 선택을 할 생각이고, Rails는 메인으로 가져가지는 않기로 했다. 이유는 성능은 꽤나 중요한데 Rails의 퍼포먼스가 앞선 두 프레임워크에 비해 떨어지기 때문에 언젠가는 한계에 부딪힐 수 있다고 생각 했기 때문이고 입문이 그렇게 어렵지 않은 프레임워크라고 알려져 있어 만약 회사에서 해당 프레임워크를 사용한다면 그때 배워도 늦지 않을 것 같았기 때문이다. 근데 일본에서 신입한테 개발 실력 기대 안하잖아 개인적으로 나도 걱정이 되는 부분이다. 일본 사회 특성상 신입을 뽑아서 키우는 분위기이기 때문에 특출난 능력을 요구하지 않는다는 느낌을 받았다. 학점도 많이 신경을 쓰지 않는 느낌이라, 고학점인 나로서는 장점을 하나 잃어버린 느낌이기도 했다. 그래서 직접적인 어필보다는 엔트리 시트에 성실함을 뒷받침하는 내용 정도로 하려고 한다. 또 엔트리 시트에 GitHub 주소를 넣을 순 없으니 아마 엔트리 시트에 가쿠치카에 적을 것 같다... 일단 이번년도 안에 정보처리기사를 따는 것이 목표이다. 원래는 딸 생각이 없었는데 일본의 응용정보기술자와 같은 자격으로 인정해준다고 한다. 다만 2차시 필기ᐧ실기에 합격하지 못하면 교환학생 도중에 실기를 보러 돌아와야하는 불상사가 생긴다. 🤯 신입에게 실력을 기대하지 않지만 잠재력 혹은 열정으로 평가되는 부분이 많기에 이번 여름 방학 때는 인턴쉽 혹은 일체험을 해보려고 한다. 물론 아직 일본어가 완벽하지 않은 한국인을 뽑아줄지는 모르겠으나 원하는 기업의 인턴쉽을 할 수 있으면 조기선고나 추후 면접에서 좋은 평가를 받을 수 있기에 한 번 도전해보려고 한다. 마무리 !대략적인 로드맵 쉽지 않은 도전이지만 화이팅 하자

    2025년 04월 25일
    일상

  • thumbnail for Logging with SLF4J and Logback

    Logging with SLF4J and Logback

    들어가며 > 왜 간단하게 System.out.print()으로 로그를 출력하지 않을까? 유연성을 위해서 선택 가능한 우선순위(`DEBUG`, `INFO`...) 수준 이상의 출력 메시지를 표시할 수 있음 모든 모듈이나 특정 모듈/클래스에 대해서만 메시지를 출력할 수 있음 이러한 메시지들의 형식을 어떻게 지정할지 제어할 수 있음 어디로 보낼지 결정할 수 있음 Logging Framework 네이티브인 `java.util.logging`은 잘 사용하지 않음 `Log4J` 몇 년간 사실상 표준(de facto)이었음 `Logback` Log4J의 개발자가 만든 후속작으로 현재 많은 프로젝트에서 사용됨 `SLF4J` (Simple Logging Facade for Java) Facade 패턴을 사용하는 인터페이스로 Log4J, Logback 등 실제 로깅 프레임워크의 공통된 인터페이스 역할 Facade Pattern (퍼사드 패턴) !Facade Pattern 클라이언트는 퍼사드(Facade)에 요청을 보내는 방식으로 서브시스템과 소통하며, 퍼사드는 해당 요청을 적절한 서브시스템 객체로 전달함 실제 작업은 서브시스템 객체들이 수행하지만, 퍼사드는 자신의 인터페이스를 서브시스템 인터페이스로 변환하기 위한 작업을 수행해야 할 수 있음 클라이언트가 서브 시스템에 직접 접근하지 않아도 됨 ※ 캡슐화(정보 은닉)와 목적이 다름 SLF4J (Simple Logging Facade for Java) !SLF4J `java.util.logging`, `Log4j`, `Logback` 등 다양한 로깅 프레임워크에 대해 간단한 퍼사드(혹은 추상화 레이어) 역할 slf4japi2.0.12.jar 하나를 의존성에 추가해야 함 클래스패스에 로깅 프레임워크와 연결(binding)되는 구현체가 없다면, SLF4J는 아무 동작도 하지 않는(nooperation) 상태로 동작 Logback > log4j의 후속작으로 더 빠르고 가벼움 !Logback logbackclassic 모듈을 사용하려면, 클래스패스에 다음 JAR 파일들이 반드시 포함되어야 한다. slf4japi.jar logbackcore.jar logbackclassic.jar ※ 스프링부트에서 `springbootstarterlogging`은 로킹 프레임 워크를 포함함 위 예제는 logback 관련 클래스는 전혀 사용하지 않았다는 점에 주목 오직 SLF4J의 클래스만 import 하면 됨 따라서, 코드는 SLF4J API만 사용하고, Logback이 존재한다는 사실을 몰라도 됨 Logger Logger는 이름을 가진 엔티티(객체)로 이름을 대소문자를 구분하며 계층적인 이름 규칙을 따름 `kr.ac.hansung` 이름의 Logger는 `kr.ac.hansung.cse` Logger의 부모 root logger는 계층 구조의 최상위 Logging Level > Logger에 레벨을 지정할 수 있다 로그 레벨은 `TRACE` → `DEBUG` → `INFO` → `WARN` → `ERROR` 순으로 중요도(심각도)가 점점 높아짐 명시적으로 레벨이 지정되어 있지 않다면 가장 가까운 상위 로거의 레벨을 상속 받음 root logger는 항상 레벨이 지정되어 있으며, 기본값은 `INFO`임 예시 Logger name Assigned level Effective level root `DEBUG` `DEBUG` X `INFO` `INFO` X.Y `none` `INFO` X.Y.Z `ERROR` `ERROR` Printing method 어떤 출력 메서드를 사용하는지에 따라 로그 요청의 레벨이 결정됨 → `logger.warn("hello");`는 `WARN` 레벨의 로그 요청 !Logback 로그 요청의 레벨이 해당 로거의 유효 레벨(effective level)보다 크거나 같으면, 그 로그 요청은 활성화(enabled)되었다고 한다. 그렇지 않으면, 즉 로깅 요청의 레벨이 더 낮으면, 그 로그 요청은 비활성화(disabled)되었다고 한다. 로그 요청 허용 여부 (`YES` = 출력됨, `NO` = 무시됨) Logging Request `p` ↓ \ Logger Effective Level `q` → TRACE DEBUG INFO WARN ERROR OFF TRACE YES NO NO NO NO NO DEBUG YES YES NO NO NO NO INFO YES YES YES NO NO NO WARN YES YES YES YES NO NO ERROR YES YES YES YES YES NO Appenders 로그 요청은 하나 이상의 출력 대상(destination)으로 출력될 수 있음 각 출력 대상은 appender(출력기)로 표현되며, 다음과 같은 종류 가능 → `console`, `files` (plain text, HTML...), `remote socket servers`, `databases` !Appenders > 특정 로거의 활성화된 로그 요청은, 해당 로거에 설정된 모든 appender뿐 아니라 상위 계층의 appender들에게도 전달된다. 즉, appender는 로거 계층에서 누적적으로 상속된다.이를 Appender Additivity이라고 부른다. 예를 들어, root 로거에 `console appender`가 추가되어 있다면 모든 활성 로그는 최소한 콘솔에 출력된다. 여기에 추가로 어떤 로거 L에 `file appender`를 설정하면, 및 그 하위 로거의 로그는 파일과 콘솔에 모두 출력된다. 하지만 이러한 기본 동작은 설정을 통해 변경할 수 있다. 즉, additivity 플래그를 `false`로 설정하면 상위 appender 상속을 막을 수 있다. Logger Name Attached Appenders Additivity Flag Output Targets Comment `root` A1 not applicable A1 Since the root logger stands at the top of the logger hierarchy, the additivity flag does not apply to it. `x` Ax1, Ax2 true A1, Ax1, Ax2 Appenders of "x" and of root. `x.y` none true A1, Ax1, Ax2 Appenders of "x" and of root. `x.y.z` Axyz1 true A1, Ax1, Ax2, Axyz1 Appenders of "x.y.z", "x" and of root. `security` Asec false Asec No appender accumulation since the additivity flag is set to false. Only appender Asec will be used. `security.access` none true Asec Only appenders of "security" because the additivity flag in "security" is set to false. ConsoleAppender 패턴 의미 `%d{pattern}` 로그 발생 시각 `%thread` 스레드 이름 `%5level` 로그 레벨 (5자 너비로 좌측 정렬) `%logger{length}` 로거 이름 (최대 길이 지정 가능) `%msg` 로그 메시지 FileAppender > 로그는 콘솔과 파일(test.dat)에 동시에 출력 RollingFileAppender 롤오버 파일(Rollover files): 로그를 하나의 파일에 기록하다가, 특정 조건이 되면 새로운 출력 파일로 전환하는 방식 이러한 조건은 롤링 정책(rolling policies)으로 지정하며, 가장 많이 사용되는 것은 TimeBasedRollingPolicy로, → 매달, 매주, 매일, 매시간마다 새 로그 파일로 전환됩니다. Logback Configuration classpath에 위치한 `logback.xml` 파일 !Logback Configuration
    2025년 04월 15일
    Backend
  • thumbnail for Logging with SLF4J and Logback

    Logging with SLF4J and Logback

    들어가며 > 왜 간단하게 System.out.print()으로 로그를 출력하지 않을까? 유연성을 위해서 선택 가능한 우선순위(`DEBUG`, `INFO`...) 수준 이상의 출력 메시지를 표시할 수 있음 모든 모듈이나 특정 모듈/클래스에 대해서만 메시지를 출력할 수 있음 이러한 메시지들의 형식을 어떻게 지정할지 제어할 수 있음 어디로 보낼지 결정할 수 있음 Logging Framework 네이티브인 `java.util.logging`은 잘 사용하지 않음 `Log4J` 몇 년간 사실상 표준(de facto)이었음 `Logback` Log4J의 개발자가 만든 후속작으로 현재 많은 프로젝트에서 사용됨 `SLF4J` (Simple Logging Facade for Java) Facade 패턴을 사용하는 인터페이스로 Log4J, Logback 등 실제 로깅 프레임워크의 공통된 인터페이스 역할 Facade Pattern (퍼사드 패턴) !Facade Pattern 클라이언트는 퍼사드(Facade)에 요청을 보내는 방식으로 서브시스템과 소통하며, 퍼사드는 해당 요청을 적절한 서브시스템 객체로 전달함 실제 작업은 서브시스템 객체들이 수행하지만, 퍼사드는 자신의 인터페이스를 서브시스템 인터페이스로 변환하기 위한 작업을 수행해야 할 수 있음 클라이언트가 서브 시스템에 직접 접근하지 않아도 됨 ※ 캡슐화(정보 은닉)와 목적이 다름 SLF4J (Simple Logging Facade for Java) !SLF4J `java.util.logging`, `Log4j`, `Logback` 등 다양한 로깅 프레임워크에 대해 간단한 퍼사드(혹은 추상화 레이어) 역할 slf4japi2.0.12.jar 하나를 의존성에 추가해야 함 클래스패스에 로깅 프레임워크와 연결(binding)되는 구현체가 없다면, SLF4J는 아무 동작도 하지 않는(nooperation) 상태로 동작 Logback > log4j의 후속작으로 더 빠르고 가벼움 !Logback logbackclassic 모듈을 사용하려면, 클래스패스에 다음 JAR 파일들이 반드시 포함되어야 한다. slf4japi.jar logbackcore.jar logbackclassic.jar ※ 스프링부트에서 `springbootstarterlogging`은 로킹 프레임 워크를 포함함 위 예제는 logback 관련 클래스는 전혀 사용하지 않았다는 점에 주목 오직 SLF4J의 클래스만 import 하면 됨 따라서, 코드는 SLF4J API만 사용하고, Logback이 존재한다는 사실을 몰라도 됨 Logger Logger는 이름을 가진 엔티티(객체)로 이름을 대소문자를 구분하며 계층적인 이름 규칙을 따름 `kr.ac.hansung` 이름의 Logger는 `kr.ac.hansung.cse` Logger의 부모 root logger는 계층 구조의 최상위 Logging Level > Logger에 레벨을 지정할 수 있다 로그 레벨은 `TRACE` → `DEBUG` → `INFO` → `WARN` → `ERROR` 순으로 중요도(심각도)가 점점 높아짐 명시적으로 레벨이 지정되어 있지 않다면 가장 가까운 상위 로거의 레벨을 상속 받음 root logger는 항상 레벨이 지정되어 있으며, 기본값은 `INFO`임 예시 Logger name Assigned level Effective level root `DEBUG` `DEBUG` X `INFO` `INFO` X.Y `none` `INFO` X.Y.Z `ERROR` `ERROR` Printing method 어떤 출력 메서드를 사용하는지에 따라 로그 요청의 레벨이 결정됨 → `logger.warn("hello");`는 `WARN` 레벨의 로그 요청 !Logback 로그 요청의 레벨이 해당 로거의 유효 레벨(effective level)보다 크거나 같으면, 그 로그 요청은 활성화(enabled)되었다고 한다. 그렇지 않으면, 즉 로깅 요청의 레벨이 더 낮으면, 그 로그 요청은 비활성화(disabled)되었다고 한다. 로그 요청 허용 여부 (`YES` = 출력됨, `NO` = 무시됨) Logging Request `p` ↓ \ Logger Effective Level `q` → TRACE DEBUG INFO WARN ERROR OFF TRACE YES NO NO NO NO NO DEBUG YES YES NO NO NO NO INFO YES YES YES NO NO NO WARN YES YES YES YES NO NO ERROR YES YES YES YES YES NO Appenders 로그 요청은 하나 이상의 출력 대상(destination)으로 출력될 수 있음 각 출력 대상은 appender(출력기)로 표현되며, 다음과 같은 종류 가능 → `console`, `files` (plain text, HTML...), `remote socket servers`, `databases` !Appenders > 특정 로거의 활성화된 로그 요청은, 해당 로거에 설정된 모든 appender뿐 아니라 상위 계층의 appender들에게도 전달된다. 즉, appender는 로거 계층에서 누적적으로 상속된다.이를 Appender Additivity이라고 부른다. 예를 들어, root 로거에 `console appender`가 추가되어 있다면 모든 활성 로그는 최소한 콘솔에 출력된다. 여기에 추가로 어떤 로거 L에 `file appender`를 설정하면, 및 그 하위 로거의 로그는 파일과 콘솔에 모두 출력된다. 하지만 이러한 기본 동작은 설정을 통해 변경할 수 있다. 즉, additivity 플래그를 `false`로 설정하면 상위 appender 상속을 막을 수 있다. Logger Name Attached Appenders Additivity Flag Output Targets Comment `root` A1 not applicable A1 Since the root logger stands at the top of the logger hierarchy, the additivity flag does not apply to it. `x` Ax1, Ax2 true A1, Ax1, Ax2 Appenders of "x" and of root. `x.y` none true A1, Ax1, Ax2 Appenders of "x" and of root. `x.y.z` Axyz1 true A1, Ax1, Ax2, Axyz1 Appenders of "x.y.z", "x" and of root. `security` Asec false Asec No appender accumulation since the additivity flag is set to false. Only appender Asec will be used. `security.access` none true Asec Only appenders of "security" because the additivity flag in "security" is set to false. ConsoleAppender 패턴 의미 `%d{pattern}` 로그 발생 시각 `%thread` 스레드 이름 `%5level` 로그 레벨 (5자 너비로 좌측 정렬) `%logger{length}` 로거 이름 (최대 길이 지정 가능) `%msg` 로그 메시지 FileAppender > 로그는 콘솔과 파일(test.dat)에 동시에 출력 RollingFileAppender 롤오버 파일(Rollover files): 로그를 하나의 파일에 기록하다가, 특정 조건이 되면 새로운 출력 파일로 전환하는 방식 이러한 조건은 롤링 정책(rolling policies)으로 지정하며, 가장 많이 사용되는 것은 TimeBasedRollingPolicy로, → 매달, 매주, 매일, 매시간마다 새 로그 파일로 전환됩니다. Logback Configuration classpath에 위치한 `logback.xml` 파일 !Logback Configuration

    2025년 04월 15일
    Backend

  • thumbnail for Spring Entity Mapping

    Spring Entity Mapping

    Entity Relationships > 데이터베이스에는 많은 테이블, 테이블간 여러 관계를 가짐 이것을 JPA/Hibernate로 설계 해야함 관계의 다중성에는 네 가지 유형이 있음 `@OneToOne` `@OneToMany`, `@ManyToOne` `@ManyToMany` 관계의 방향은 다음과 같을 수 있음 양방향(bidirectional) : 주인 쪽(owning side)과 반대 쪽(inverse side)이 존재함 단방향(unidirectional) : 주인 쪽(owning side)만 존재함 주인 쪽(owning side)은 참조를 테이블에 실제로 저장하는 엔터티 즉 외래 키(foreign key)를 가진 테이블 Entity Relation Attributes Cascading 업데이트/삭제 연관된 엔터티에 동일한 작업을 적용함 CascadeType: `ALL`, `PERSIST`, `MERGE`, `REMOVE`, `REFRESH` Cascade Type 설명 적용되는 작업 ALL 모든 작업(저장, 업데이트, 삭제 등)이 자식 엔티티에 전파됨. 부모의 `persist`, `merge`, `remove`, `refresh`, `detach` 작업 모두 자식 엔티티에 전파 (영속성 컨텍스트에서만 적용) PERSIST 부모 엔티티가 영속화(persist)될 때 자식 엔티티도 영속화됨. 부모의 `persist` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) MERGE 부모 엔티티가 병합(merge)될 때 자식 엔티티도 병합됨. 부모의 `merge` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) REMOVE 부모 엔티티가 삭제(remove)될 때 자식 엔티티도 삭제됨. 부모의 `remove` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) REFRESH 부모 엔티티가 새로 고침(refresh)될 때 자식 엔티티도 새로 고침됨. 부모의 `refresh` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) DETACH 부모 엔티티가 분리(detach)될 때 자식 엔티티도 분리됨. 부모의 `detach` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) ※ 기본적으로는 어떠한 작업도 연쇄되지 않음 연관된 엔터티를 가져오는 전략(Fetching strategy) FetchType: `LAZY`, `EAGER` EAGER는 모든 것을 한 번에 가져옵니다. 성능 문제로 이어질 수 있음 LAZY는 요청 시에만 데이터를 가져옵니다. ※ 즉, 프로퍼티에 접근할 때까지 해당 행(row)을 로드하지 않음 Mapping Default Fetch Type `@OneToOne` FetchType.EAGER `@OneToMany` FetchType.LAZY `@ManyToOne` FetchType.EAGER `@ManyToMany` FetchType.LAZY > Many가 포함되면 FetchType.LAZY가 Default OneToMany Unidirectional 한 강사는 여러 강의를 가질 수 있다. 일대다(OnetoMany) 관계에서는 외래 키(Foreign Key)가 항상 “Many” 쪽에 존재 `@ManyToOne` 애너테이션을 사용하여 JPA/Hibernate에게 어떤 객체가 자식 객체인지 알려줄 수 있습니다. `@OneToMany` 애너테이션을 사용하여 JPA/Hibernate에게 어떤 객체가 부모 객체인지 알려줄 수 있습니다. `@JoinColumn` 애너테이션을 사용하면, 어떤 컬럼을 조인에 사용할지 명시할 수 있으며, 해당 컬럼의 이름도 지정할 수 있습니다. ※ 즉, 부모 테이블(instructor), 자식 테이블(course) 중에서, 자식 테이블이 외래 키를 가짐 OneToMany Bidirectional 객체 간에 양방향(bidirectional) 관계가 있을 때, 두 객체는 서로 접근할 수 있다. 양방향 관계를 사용하려면, 기존의 데이터베이스 스키마를 그대로 유지할 수 있음 ※ 데이터베이스 변경 X, 단지 Java 코드만 업데이트 > 이 연관관계의 주인은 Course 쪽의 instructor 필드 모든 객체를 올바르게 유지하는 방법 부모 객체를 생성 자식 객체들을 생성 자식 객체들에 부모 객체를 설정 부모 객체에 자식 객체들의 모음을 설정 부모 객체를 저장 OneToOne Unidirectional ManyToMany Unidirectional 학생은 많은 수업을 가질 수 있고 수업도 많은 학생을 가질 수 있다. !Many To Many > Join Table을 두고 관계를 유지하는 것이 효율적 조인 테이블 (Join Table) !Many To Many 다대다(ManytoMany) 관계를 위한 좋은 설계는 조인 테이블을 사용하는 것 조인 테이블이라는 용어는 두 테이블의 기본 키(primary key)만 저장하는 세 번째 SQL 테이블을 설명하는 방법 관례상, 이 조인 테이블의 이름은 일반적으로 다대다 관계를 맺는 두 테이블의 이름을 결합한 형태 ex) course_student 이 조인 테이블은 course 테이블과 student 테이블에서 기본 키만 포함 전체 구조 !Architecture
    2025년 04월 09일
    Backend
  • thumbnail for Spring Entity Mapping

    Spring Entity Mapping

    Entity Relationships > 데이터베이스에는 많은 테이블, 테이블간 여러 관계를 가짐 이것을 JPA/Hibernate로 설계 해야함 관계의 다중성에는 네 가지 유형이 있음 `@OneToOne` `@OneToMany`, `@ManyToOne` `@ManyToMany` 관계의 방향은 다음과 같을 수 있음 양방향(bidirectional) : 주인 쪽(owning side)과 반대 쪽(inverse side)이 존재함 단방향(unidirectional) : 주인 쪽(owning side)만 존재함 주인 쪽(owning side)은 참조를 테이블에 실제로 저장하는 엔터티 즉 외래 키(foreign key)를 가진 테이블 Entity Relation Attributes Cascading 업데이트/삭제 연관된 엔터티에 동일한 작업을 적용함 CascadeType: `ALL`, `PERSIST`, `MERGE`, `REMOVE`, `REFRESH` Cascade Type 설명 적용되는 작업 ALL 모든 작업(저장, 업데이트, 삭제 등)이 자식 엔티티에 전파됨. 부모의 `persist`, `merge`, `remove`, `refresh`, `detach` 작업 모두 자식 엔티티에 전파 (영속성 컨텍스트에서만 적용) PERSIST 부모 엔티티가 영속화(persist)될 때 자식 엔티티도 영속화됨. 부모의 `persist` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) MERGE 부모 엔티티가 병합(merge)될 때 자식 엔티티도 병합됨. 부모의 `merge` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) REMOVE 부모 엔티티가 삭제(remove)될 때 자식 엔티티도 삭제됨. 부모의 `remove` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) REFRESH 부모 엔티티가 새로 고침(refresh)될 때 자식 엔티티도 새로 고침됨. 부모의 `refresh` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) DETACH 부모 엔티티가 분리(detach)될 때 자식 엔티티도 분리됨. 부모의 `detach` 작업이 자식 엔티티에 전파됨 (영속성 컨텍스트에서만 적용) ※ 기본적으로는 어떠한 작업도 연쇄되지 않음 연관된 엔터티를 가져오는 전략(Fetching strategy) FetchType: `LAZY`, `EAGER` EAGER는 모든 것을 한 번에 가져옵니다. 성능 문제로 이어질 수 있음 LAZY는 요청 시에만 데이터를 가져옵니다. ※ 즉, 프로퍼티에 접근할 때까지 해당 행(row)을 로드하지 않음 Mapping Default Fetch Type `@OneToOne` FetchType.EAGER `@OneToMany` FetchType.LAZY `@ManyToOne` FetchType.EAGER `@ManyToMany` FetchType.LAZY > Many가 포함되면 FetchType.LAZY가 Default OneToMany Unidirectional 한 강사는 여러 강의를 가질 수 있다. 일대다(OnetoMany) 관계에서는 외래 키(Foreign Key)가 항상 “Many” 쪽에 존재 `@ManyToOne` 애너테이션을 사용하여 JPA/Hibernate에게 어떤 객체가 자식 객체인지 알려줄 수 있습니다. `@OneToMany` 애너테이션을 사용하여 JPA/Hibernate에게 어떤 객체가 부모 객체인지 알려줄 수 있습니다. `@JoinColumn` 애너테이션을 사용하면, 어떤 컬럼을 조인에 사용할지 명시할 수 있으며, 해당 컬럼의 이름도 지정할 수 있습니다. ※ 즉, 부모 테이블(instructor), 자식 테이블(course) 중에서, 자식 테이블이 외래 키를 가짐 OneToMany Bidirectional 객체 간에 양방향(bidirectional) 관계가 있을 때, 두 객체는 서로 접근할 수 있다. 양방향 관계를 사용하려면, 기존의 데이터베이스 스키마를 그대로 유지할 수 있음 ※ 데이터베이스 변경 X, 단지 Java 코드만 업데이트 > 이 연관관계의 주인은 Course 쪽의 instructor 필드 모든 객체를 올바르게 유지하는 방법 부모 객체를 생성 자식 객체들을 생성 자식 객체들에 부모 객체를 설정 부모 객체에 자식 객체들의 모음을 설정 부모 객체를 저장 OneToOne Unidirectional ManyToMany Unidirectional 학생은 많은 수업을 가질 수 있고 수업도 많은 학생을 가질 수 있다. !Many To Many > Join Table을 두고 관계를 유지하는 것이 효율적 조인 테이블 (Join Table) !Many To Many 다대다(ManytoMany) 관계를 위한 좋은 설계는 조인 테이블을 사용하는 것 조인 테이블이라는 용어는 두 테이블의 기본 키(primary key)만 저장하는 세 번째 SQL 테이블을 설명하는 방법 관례상, 이 조인 테이블의 이름은 일반적으로 다대다 관계를 맺는 두 테이블의 이름을 결합한 형태 ex) course_student 이 조인 테이블은 course 테이블과 student 테이블에서 기본 키만 포함 전체 구조 !Architecture

    2025년 04월 09일
    Backend

  • thumbnail for Spring JPA (Java Persistence API)

    Spring JPA (Java Persistence API)

    JPA란? > Standard API for ObjecttoRelational Mapping (ORM) 모든 저수준(lowlevel) SQL 처리 개발자들이 객체 모델을 사용하여 프로그래밍에 집중할 수 있도록 도움 !ObjectToRelational Mapping (ORM) 단순 명세 인터페이스 집합을 정의함 사용하기 위해서 구현이 필요함 표준 API를 사용함으로써, 공급자의 구현에 얽매이지 않음 ※ JPA는 구현이 없는 명세나 인터페이스임 ※ Hibernate는 JPA의 구현체임 JDBC vs JPA(Hibernate) vs Spring Data JPA !JPA JDBC: LowLevel Database Access JPA: Java Persistence API를 나타내는 기술적 명세, 관계형 데이터베이스를 위한 인터페이스로 정의됨 Hibernate: JPA의 구현체 Spring Data JPA: JPA를 쉽게 하용하도록 만든 모듈 !JPA Entity Class > 데이터베이스 테이블에 매핑되는 자바 클래스 !Entity Class 최소 조건 @Entity 주석 필수 public 혹은 protected 기본 생성자 필수 (다른 생성자도 가질 수 있음) Java Annotations 1단계: 클래스를 데이터베이스 테이블에 매핑하기 2단계: 필드를 데이터베이스 컬럼에 매핑하기 @Table !Map class to database table 선택사항으로 없으면 클래스 이름으로 자동 설정됨 @Column !Map fields to database columns 선택사항으로 없으면 필드 이름으로 자동 설정됨 @Id, @GeneratedValue Primary Key !Primary Key 각 행을 고유하게 실벽 반드시 고유한 값으로 NULL일 수 없음 ID Generation Strategies 타입 설명 GenerationType.Auto 특정 데이터베이스를 위한 적절한 전략을 선택 GenerationType.IDENTITY 데이터베이스 ID 열을 사용하여 Primary Key 할당 GenerationType.SEQUENCE 데이터베이스 시퀀스로 Primary Key 할당 GenerationType.TABLE 기본 키의 고유성을 보장하기 위해 기본 데이터베이스 테이블을 사용하여 할당 Entity Manager !Entity Manager EntityManagerFactory : EntityManager의 객체 제공 JPA EntityManager (interface) : 특정 애플리케이션에서 데이터베이스를 접근하기 위해 사용 > EntityManager API는 영속적인 엔티티 인스턴스를 생성 및 제거하고, 기본 키로 엔티티를 찾으며, 엔티티를 대상으로 쿼리를 수행하는 데 사용됩니다. Action JPA Methods Hibernate Methods Create/Save new Entity entityManager.persist(...) session.save(...) Retrieve Entity by ID entityManager.find(...) session.get(...)/load(...) Retrieve list of Entities entityManager.createQuery(...) session.createQuery(...) Save or Update Entity entityManager.merge(...) session.saveOrUpdate(...) Delete Entity entityManager.remove(...) session.delete(...) Persistence Contetxt !Persistence Contetxt EntityManager 객체는 Persistence Context와 연관된다. Persistence Context는 Entity 객체들의 집합으로 데이터베이스에서 엔티티를 가져오거나 데이터베이스에 저장할 때 사용되는 1차 캐시 Entity Lifecycle !Entity Lifecycle 상태 Persistence Context에 있음? 설명 New / Transient ❌ 아님 아직 저장되지 않은 순수 객체 Persistent / Managed ✅ 있음 Persistence Context가 관리 중 Detached ❌ 아님 한 번 저장됐지만 지금은 관리되지 않음 Removed ✅ 있음 (삭제 대기 상태) 삭제 예약된 상태. flush/commit 시 실제 삭제 EntityManager API > CRUD (Create, Read, Update, Delete) ※ EntityClass와 Primary Key 전달 > 복잡한 연산은 어떻게 할까? JPA Query Language (JPQL) 객체들을 조회하기 위한 Query Language SQL과 비슷하지만 JPQL은 entity name과 entity fields에 기반함 ※ Class 이름과 Return 타입 전달 ※ 엔티티 이름 필드 이름에 주의가 필요함 ※ Query에 변수 사용 시 parameter를 설정해주어야 함 DAO (Data Access Object) 데이터베이스를 규격화 함 JPA Entity Manager가 필요함 (조회, 저장을 위한 기본 컴포넌트) !Data Access Object JPA Entity Manager JPA Entity Manager는 데이터 소스가 필요함 데이터 소스는 데이터베이스 연결 정보를 정의함 JPA Entity Manager를 Student DAO에 자동 주입하거나 주입할 수 있음 Spring @Transactional 자동으로 JPA 코드에 대한 트랜잭션을 시작하고 종료함 코드를 명시적으로 작성할 필요가 없음 사용자 모르게 처리됨
    2025년 04월 01일
    Backend
  • thumbnail for Spring JPA (Java Persistence API)

    Spring JPA (Java Persistence API)

    JPA란? > Standard API for ObjecttoRelational Mapping (ORM) 모든 저수준(lowlevel) SQL 처리 개발자들이 객체 모델을 사용하여 프로그래밍에 집중할 수 있도록 도움 !ObjectToRelational Mapping (ORM) 단순 명세 인터페이스 집합을 정의함 사용하기 위해서 구현이 필요함 표준 API를 사용함으로써, 공급자의 구현에 얽매이지 않음 ※ JPA는 구현이 없는 명세나 인터페이스임 ※ Hibernate는 JPA의 구현체임 JDBC vs JPA(Hibernate) vs Spring Data JPA !JPA JDBC: LowLevel Database Access JPA: Java Persistence API를 나타내는 기술적 명세, 관계형 데이터베이스를 위한 인터페이스로 정의됨 Hibernate: JPA의 구현체 Spring Data JPA: JPA를 쉽게 하용하도록 만든 모듈 !JPA Entity Class > 데이터베이스 테이블에 매핑되는 자바 클래스 !Entity Class 최소 조건 @Entity 주석 필수 public 혹은 protected 기본 생성자 필수 (다른 생성자도 가질 수 있음) Java Annotations 1단계: 클래스를 데이터베이스 테이블에 매핑하기 2단계: 필드를 데이터베이스 컬럼에 매핑하기 @Table !Map class to database table 선택사항으로 없으면 클래스 이름으로 자동 설정됨 @Column !Map fields to database columns 선택사항으로 없으면 필드 이름으로 자동 설정됨 @Id, @GeneratedValue Primary Key !Primary Key 각 행을 고유하게 실벽 반드시 고유한 값으로 NULL일 수 없음 ID Generation Strategies 타입 설명 GenerationType.Auto 특정 데이터베이스를 위한 적절한 전략을 선택 GenerationType.IDENTITY 데이터베이스 ID 열을 사용하여 Primary Key 할당 GenerationType.SEQUENCE 데이터베이스 시퀀스로 Primary Key 할당 GenerationType.TABLE 기본 키의 고유성을 보장하기 위해 기본 데이터베이스 테이블을 사용하여 할당 Entity Manager !Entity Manager EntityManagerFactory : EntityManager의 객체 제공 JPA EntityManager (interface) : 특정 애플리케이션에서 데이터베이스를 접근하기 위해 사용 > EntityManager API는 영속적인 엔티티 인스턴스를 생성 및 제거하고, 기본 키로 엔티티를 찾으며, 엔티티를 대상으로 쿼리를 수행하는 데 사용됩니다. Action JPA Methods Hibernate Methods Create/Save new Entity entityManager.persist(...) session.save(...) Retrieve Entity by ID entityManager.find(...) session.get(...)/load(...) Retrieve list of Entities entityManager.createQuery(...) session.createQuery(...) Save or Update Entity entityManager.merge(...) session.saveOrUpdate(...) Delete Entity entityManager.remove(...) session.delete(...) Persistence Contetxt !Persistence Contetxt EntityManager 객체는 Persistence Context와 연관된다. Persistence Context는 Entity 객체들의 집합으로 데이터베이스에서 엔티티를 가져오거나 데이터베이스에 저장할 때 사용되는 1차 캐시 Entity Lifecycle !Entity Lifecycle 상태 Persistence Context에 있음? 설명 New / Transient ❌ 아님 아직 저장되지 않은 순수 객체 Persistent / Managed ✅ 있음 Persistence Context가 관리 중 Detached ❌ 아님 한 번 저장됐지만 지금은 관리되지 않음 Removed ✅ 있음 (삭제 대기 상태) 삭제 예약된 상태. flush/commit 시 실제 삭제 EntityManager API > CRUD (Create, Read, Update, Delete) ※ EntityClass와 Primary Key 전달 > 복잡한 연산은 어떻게 할까? JPA Query Language (JPQL) 객체들을 조회하기 위한 Query Language SQL과 비슷하지만 JPQL은 entity name과 entity fields에 기반함 ※ Class 이름과 Return 타입 전달 ※ 엔티티 이름 필드 이름에 주의가 필요함 ※ Query에 변수 사용 시 parameter를 설정해주어야 함 DAO (Data Access Object) 데이터베이스를 규격화 함 JPA Entity Manager가 필요함 (조회, 저장을 위한 기본 컴포넌트) !Data Access Object JPA Entity Manager JPA Entity Manager는 데이터 소스가 필요함 데이터 소스는 데이터베이스 연결 정보를 정의함 JPA Entity Manager를 Student DAO에 자동 주입하거나 주입할 수 있음 Spring @Transactional 자동으로 JPA 코드에 대한 트랜잭션을 시작하고 종료함 코드를 명시적으로 작성할 필요가 없음 사용자 모르게 처리됨

    2025년 04월 01일
    Backend

  • thumbnail for Spring MVC Web Form

    Spring MVC Web Form

    Web Basics Request Parameter란 사용자가 발행한 HTTP 요청 메시지의 일부분으로 전송됨 두가지 전송 방식이 있음 Query string (GET Method) HTTP entity body (POST Method) !GET !POST Data Binding > 요청 파라미터에서 해당하는 객체로 어떻게 이동할 것인가? Naive solution @RequestParam annotation을 사용하여 requset parameter와 method parameter를 바인딩 할 수 있다. Spring Data Binding 요청 파라미터를 form bean에 바인딩하는 과정으로, form에서 오는 데이터는 자동으로 객체에 바인딩 될 수 있음 > 함수 파라미터에 객체를 선언하기만 하면 됨 다음과 같은 작업들이 발생함 새로운 form bean 인스턴스화됨 form bean은 요청 파라미터로부터 채워짐 form bean은 모델에 추가됨 !Data Binding offer form bean은 모델에 자동적으로 추가됨 form bean은 모델 속성 !Data Binding 뷰에서도 접근, form bean을 랜더링할 수 있다. Data Validation > 유저는 실수를 할 수 있다 그렇기에 에러를 설명하거나 유저가 이를 해결할 수 있도록 하고 싶다. Hibernate Validator 사용자의 에러를 검출하기 위해, 폼 빈에 캡슐화된 폼 데이터를 검증해야함 Bean Validation API (JSR303)는 JavaBean 검증을 위한 API를 정의하는 명세입니다. 폼 빈 속성에 선언적 검증 제약 조건을 주석으로 달 수 있습니다. (`@NotNull`, `@Pattern`, `@Size`) Hibernate Validator는 몇가지 커스텀 annotation을 제공 (`@Email`) Message Interpolation > 위반된 Bean Validation 제약 조건에 대해 오류 메시지를 생성하는 것 !Message Interpolation > 각 속성의 message descriptor를 메시지 속성을 통해 정의할 수 있습니다 Validating Object 검증은 @Valid 어노테이션을 통해 이루어짐 @Valid 어노테이션은 객체가 먼저 검증된 후 모델에 추가되도록 함 핸들러 메서드는 검증 과정의 결과를 나타내는 BindingResult 객체 요청 가능 가능한 검증 오류를 확인하기 위해 BindingResult 객체 검사 가능 Data Buffering > 사용자가 필수 입력 사항을 잊었을 때 처음부터 다시 입력해야하는가? Spring form tag library 해당 내용을 웹 폼에 바인딩해야 함 Spring은 미리 채워진 폼 빈을 처리하기 위해 데이터 바인딩을 지원하는 태그 세트를 제공함 !Spring form tag library 해당 라이브러리 사용을 위해 JSP 페이지 최상단에 아래를 추가해야함 Spring form tag lib HTML `` `` `` `` `` `` `` `` Revised JSP 다음은 앞선 라이브러리를 사용한 코드이다 Revised Controller !initial Web Form !Web Form on Error Error Messages > 사용자에게 데이터가 거부된 이유를 알려주어야 함수 !Error Messages 이를 위해, BindingResult 객체는 자동으로 모델에 삽입되어 뷰로 다시 전송함 Spring MVC는 Spring의 폼 태그 라이브러리의 일환으로 `` 태그 제공. `` 태그는 BindingResult 객체에서 가져온 HTML 오류 메시지를 렌더링합니다. Summary 폼 빈(Form beans)은 여러 역할을 동시에 수행할 수 있는 다재다능한 객체 데이터 바인더(Data binder): 폼 데이터를 Java 객체에 바인딩하는 역할 데이터 검증기(Data validator): 폼 데이터의 유효성을 검사하고 검증하는 역할 데이터 버퍼(Data buffer): 폼 데이터가 임시로 저장되거나 관리되는 역할
    2025년 03월 30일
    Backend
  • thumbnail for Spring MVC Web Form

    Spring MVC Web Form

    Web Basics Request Parameter란 사용자가 발행한 HTTP 요청 메시지의 일부분으로 전송됨 두가지 전송 방식이 있음 Query string (GET Method) HTTP entity body (POST Method) !GET !POST Data Binding > 요청 파라미터에서 해당하는 객체로 어떻게 이동할 것인가? Naive solution @RequestParam annotation을 사용하여 requset parameter와 method parameter를 바인딩 할 수 있다. Spring Data Binding 요청 파라미터를 form bean에 바인딩하는 과정으로, form에서 오는 데이터는 자동으로 객체에 바인딩 될 수 있음 > 함수 파라미터에 객체를 선언하기만 하면 됨 다음과 같은 작업들이 발생함 새로운 form bean 인스턴스화됨 form bean은 요청 파라미터로부터 채워짐 form bean은 모델에 추가됨 !Data Binding offer form bean은 모델에 자동적으로 추가됨 form bean은 모델 속성 !Data Binding 뷰에서도 접근, form bean을 랜더링할 수 있다. Data Validation > 유저는 실수를 할 수 있다 그렇기에 에러를 설명하거나 유저가 이를 해결할 수 있도록 하고 싶다. Hibernate Validator 사용자의 에러를 검출하기 위해, 폼 빈에 캡슐화된 폼 데이터를 검증해야함 Bean Validation API (JSR303)는 JavaBean 검증을 위한 API를 정의하는 명세입니다. 폼 빈 속성에 선언적 검증 제약 조건을 주석으로 달 수 있습니다. (`@NotNull`, `@Pattern`, `@Size`) Hibernate Validator는 몇가지 커스텀 annotation을 제공 (`@Email`) Message Interpolation > 위반된 Bean Validation 제약 조건에 대해 오류 메시지를 생성하는 것 !Message Interpolation > 각 속성의 message descriptor를 메시지 속성을 통해 정의할 수 있습니다 Validating Object 검증은 @Valid 어노테이션을 통해 이루어짐 @Valid 어노테이션은 객체가 먼저 검증된 후 모델에 추가되도록 함 핸들러 메서드는 검증 과정의 결과를 나타내는 BindingResult 객체 요청 가능 가능한 검증 오류를 확인하기 위해 BindingResult 객체 검사 가능 Data Buffering > 사용자가 필수 입력 사항을 잊었을 때 처음부터 다시 입력해야하는가? Spring form tag library 해당 내용을 웹 폼에 바인딩해야 함 Spring은 미리 채워진 폼 빈을 처리하기 위해 데이터 바인딩을 지원하는 태그 세트를 제공함 !Spring form tag library 해당 라이브러리 사용을 위해 JSP 페이지 최상단에 아래를 추가해야함 Spring form tag lib HTML `` `` `` `` `` `` `` `` Revised JSP 다음은 앞선 라이브러리를 사용한 코드이다 Revised Controller !initial Web Form !Web Form on Error Error Messages > 사용자에게 데이터가 거부된 이유를 알려주어야 함수 !Error Messages 이를 위해, BindingResult 객체는 자동으로 모델에 삽입되어 뷰로 다시 전송함 Spring MVC는 Spring의 폼 태그 라이브러리의 일환으로 `` 태그 제공. `` 태그는 BindingResult 객체에서 가져온 HTML 오류 메시지를 렌더링합니다. Summary 폼 빈(Form beans)은 여러 역할을 동시에 수행할 수 있는 다재다능한 객체 데이터 바인더(Data binder): 폼 데이터를 Java 객체에 바인딩하는 역할 데이터 검증기(Data validator): 폼 데이터의 유효성을 검사하고 검증하는 역할 데이터 버퍼(Data buffer): 폼 데이터가 임시로 저장되거나 관리되는 역할

    2025년 03월 30일
    Backend

  • thumbnail for Spring MVC 패턴

    Spring MVC 패턴

    MVC Pattern 스프링은 프레임워크는 MVC 아키텍쳐를 제공한다 Model 데이터 캡슐화, POJO로 구성됨 View model 데이터를 랜더링, 대체로 HTML 형식 Controller 사용자 요청 처리, 적절한 모델을 만들고 view 랜더링을 위해 넘겨줌 !MVC 패턴 Dispatcher Servlet 프론트 컨트롤러 역할 모든 요청을 가로채고 핸들러(컨트롤러)로 전달 요청을 처리할 컨트롤러를 호출하기 위해 핸들러 매핑을 참조 Handler Mapping 특정 요청을 처리할 적합한 컨트롤러를 찾는 역할 요청 URL과 컨트롤러 클래스 간의 매핑은 XML 설정, 애노테이션을 통해 수행 Controller 요청을 처리하며 비즈니스 로직 호출 출력은 모델 객체에 첨부되어 뷰로 전달 View Resolver 논리적 이름으로부터 실제 뷰 파일을 찾는 역할 View JSP, HTML ... 같은 실제 뷰 파일을 의미 Required Configuration Maven Configuration POM.xml Web deployment descriptor Web.xml Spring MVC Configuration `rootcontext.xml`, `servletcontext.xml`, `daocontext.xml`, `servicecontext.xml` Maven Configuration > 각종 라이브러리의 의존성 선언 !POM.xml Web deployment descriptor DispatcherServlet Spring 컨테이너(WebApplicationContext) 인스턴스화 다른 DI 컨테이너와 마찬가지로, WebApplicationContext는 일부 구성 메타데이터를 제공받아야 함 !DispatcherServlet ContextLoadListener 공유 Beans가 포함된 Spring Container 인스턴스화 DispatcherServlet에 의해 생성된 Beans은 ContextLoaderListener에 의해 생성된 Beans를 참조할 수 있음 (DispatcherServlet's Beans → ContextLoaderListener's Beans) Spring MVC Configuration `rootcontext.xml` 파일이 Spring 애플리케이션의 루트 컨테이너 설정을 담당하며, 기본적으로 비어 있지만 애플리케이션 시작 시 자동(`ContextLoaderListener`) 으로 로드된다 `servletcontext.xml` `DispatcherServlet에 의해 로딩됨 `` 프레임워크에 패키지 내 파일 스캔을 annotation based로 수행할 것임을 알림 `` 정적 메소드는 GET 요청으로 바로 접근할 수 있도록 매핑 Bean `InternalResourceViewResolver` 물리 JSP 파일들을 논리 이름으로 어떻게 찾을 수 있는지 알려줌 `` Spring Container에게 annotation based 사용시 어떤 패키지가 스캔될지 알려줌 Model 모델은 결과의 일부를 포함하며 객체를 컨트롤로에서 뷰로 전달할 때 사용된다. 이는 명명된 객체의 모음이다. Key(name) Value key1 value1 key2 value2 key3 value3 > 각 행은 named object 혹은 model attributes 로 불림 !Model 모델 구현 방법은 세 가지로 나눌 수 있다. Map java.util.Map Model Spring 에서 제공하는 Model interface 구현하여 사용된다 Model에서는 key 값을 지정해줄 필요가 없음 모델을 채우기 위한 편리한 방법 제공됨 (addAttribute()) key 값을 자동 혹은 수동으로 지정할 수 있음 ModelMap Spring에서 제공되는 객체로 더 편리함을 제공 (chained calls) Controller > @Controller 어노테이션이 붙은 빈(bean) @Controller 어노테이션 컨트롤러 역할을 한다는 것을 나타냄 @RequestMapping 어노테이션 URL ↔︎ 전체 클리스, 특정 핸들러 메소드 매핑 Class level mapping Handler level mapping Example Add attributes to the model Retrieve request parameters as regular parameters > http://localhost:8080/spring/login?username=scott&password=tiger JSTL JSP는 Java Server Pages의 약자로, 동적인 웹 페이지를 생성하는 데 사용되는 기술 prefix “c” can be used for core language prefix “fn” for using JSTL functions
    2025년 03월 29일
    Backend
  • thumbnail for Spring MVC 패턴

    Spring MVC 패턴

    MVC Pattern 스프링은 프레임워크는 MVC 아키텍쳐를 제공한다 Model 데이터 캡슐화, POJO로 구성됨 View model 데이터를 랜더링, 대체로 HTML 형식 Controller 사용자 요청 처리, 적절한 모델을 만들고 view 랜더링을 위해 넘겨줌 !MVC 패턴 Dispatcher Servlet 프론트 컨트롤러 역할 모든 요청을 가로채고 핸들러(컨트롤러)로 전달 요청을 처리할 컨트롤러를 호출하기 위해 핸들러 매핑을 참조 Handler Mapping 특정 요청을 처리할 적합한 컨트롤러를 찾는 역할 요청 URL과 컨트롤러 클래스 간의 매핑은 XML 설정, 애노테이션을 통해 수행 Controller 요청을 처리하며 비즈니스 로직 호출 출력은 모델 객체에 첨부되어 뷰로 전달 View Resolver 논리적 이름으로부터 실제 뷰 파일을 찾는 역할 View JSP, HTML ... 같은 실제 뷰 파일을 의미 Required Configuration Maven Configuration POM.xml Web deployment descriptor Web.xml Spring MVC Configuration `rootcontext.xml`, `servletcontext.xml`, `daocontext.xml`, `servicecontext.xml` Maven Configuration > 각종 라이브러리의 의존성 선언 !POM.xml Web deployment descriptor DispatcherServlet Spring 컨테이너(WebApplicationContext) 인스턴스화 다른 DI 컨테이너와 마찬가지로, WebApplicationContext는 일부 구성 메타데이터를 제공받아야 함 !DispatcherServlet ContextLoadListener 공유 Beans가 포함된 Spring Container 인스턴스화 DispatcherServlet에 의해 생성된 Beans은 ContextLoaderListener에 의해 생성된 Beans를 참조할 수 있음 (DispatcherServlet's Beans → ContextLoaderListener's Beans) Spring MVC Configuration `rootcontext.xml` 파일이 Spring 애플리케이션의 루트 컨테이너 설정을 담당하며, 기본적으로 비어 있지만 애플리케이션 시작 시 자동(`ContextLoaderListener`) 으로 로드된다 `servletcontext.xml` `DispatcherServlet에 의해 로딩됨 `` 프레임워크에 패키지 내 파일 스캔을 annotation based로 수행할 것임을 알림 `` 정적 메소드는 GET 요청으로 바로 접근할 수 있도록 매핑 Bean `InternalResourceViewResolver` 물리 JSP 파일들을 논리 이름으로 어떻게 찾을 수 있는지 알려줌 `` Spring Container에게 annotation based 사용시 어떤 패키지가 스캔될지 알려줌 Model 모델은 결과의 일부를 포함하며 객체를 컨트롤로에서 뷰로 전달할 때 사용된다. 이는 명명된 객체의 모음이다. Key(name) Value key1 value1 key2 value2 key3 value3 > 각 행은 named object 혹은 model attributes 로 불림 !Model 모델 구현 방법은 세 가지로 나눌 수 있다. Map java.util.Map Model Spring 에서 제공하는 Model interface 구현하여 사용된다 Model에서는 key 값을 지정해줄 필요가 없음 모델을 채우기 위한 편리한 방법 제공됨 (addAttribute()) key 값을 자동 혹은 수동으로 지정할 수 있음 ModelMap Spring에서 제공되는 객체로 더 편리함을 제공 (chained calls) Controller > @Controller 어노테이션이 붙은 빈(bean) @Controller 어노테이션 컨트롤러 역할을 한다는 것을 나타냄 @RequestMapping 어노테이션 URL ↔︎ 전체 클리스, 특정 핸들러 메소드 매핑 Class level mapping Handler level mapping Example Add attributes to the model Retrieve request parameters as regular parameters > http://localhost:8080/spring/login?username=scott&password=tiger JSTL JSP는 Java Server Pages의 약자로, 동적인 웹 페이지를 생성하는 데 사용되는 기술 prefix “c” can be used for core language prefix “fn” for using JSTL functions

    2025년 03월 29일
    Backend

  • thumbnail for Spring 의존성 주입

    Spring 의존성 주입

    의존성이란? 이러한 경우 PetOwner는 AnimalType에 의존하게 된다. 하지만 이러한 구조에는 문제가 있는데 다음과 같다. PetOwner 객체가 AnimalType 객체 생성을 관리하기 때문에 두 객체 사이의 Tight Coupling이 발생한다. > 따라서 AnimalType 객체의 변경은 PetOwner의 변경을 야기한다 의존성 주입 (Dependency Injection) 앞선 문제점은 DI를 통해 해결할 수 있다. !DI Bean Container는 Bean을 생성하고, 의존성 주입을 수행한다. 의존성 주입도 제어의 역전(IoC)의 한 종류이다. 따라서 코드는 다음과 같이 변화할 수 있다. > 따라서 의존성 주입(DI)는 객체가 자신의 의존성을 직접 처리하는 것이 아니라, 프레임워크에 의해 의존성이 주입되는 디자인 패턴이다. 이 패턴은 프레임워크에 의해 동적으로 주입되기 때문에 여러 객체 간의 결합도를 줄여준다. Spring (IoC) Container 스프링 프레임워크의 코어 컴포넌트로 객체 생성 관리, 객체 의존성 주입의 주요 기능을 갖고 있다. Spring Container의 구성하는 방법 세 가지 xml Java annotation Javabased Configuration Spring Container의 종류 두 가지 BeanFactory ApplicationContext BeanFactory ApplicationContext 매우 간단, 주로 DI를 위함 더 확장, 고급 기능 제공 리소스가 제한된 경우 사용 (모바일...) 아래 특징을 가진 어느곳애서든 사용 1. 엔터프라이즈 인식 기능2. 애플리케이션 이벤트를 리스너에 게시3. 요청 시 빈을 연결하고 폐기 org.springframework.beans.factory.BeanFactory org.springframework.context.ApplicationContext XMLBeanFactory ClassPathXmlApplicationContext 전체 플로우 !Spring Container and DI main 함수에서 ApplicationContext 객체 생성 Spring Container가 Bean 생성 의존성 주입 수행 Advantages of DI 의존성을 낮추어 코드 변경 줄어듦 코드 재사용성 증가 테스트 용이 (mock implements를 주입시키면 되기 때문에) 코드 가독성 증가 Bean이란? 스프링에서 POJO 클래스를 Bean이라고 부름 Configuration metadata를 통해 Spring Container에 의해 생성되고 관리됨 getBean() 메서드로 객체에 접근할 수 있음 Spring Bean Definition Key 역할 class (required) 클래스 네임 구분 id bean을 구분하는 식별자 scope 객체의 범위 (singletone, prototype) constructorarg 객체 생성 시 넘겨줄 매개변수 property 생성 시 setter에 넘겨줄 매개변수 init, destory 함수 Spring Annotation Based Configuration Spring 2.5 이후에 개발되어 유명해짐 XML의 구성은 방대해질 수 있음 Default가 아니기에 설정이 필요 빈 설정에서 XML이 어노테이션을 덮어쓴다 (XML이 우선순위가 더 높음) @Required Setter 메소드에서만 가능 @Autowired ⭐️ xml 방식 Annotation 방식 @Qualifier > @Autowired가 타입 모호성을 가질 때 사용 @Resource @Resource는 xml의 id(name)로 구분 @Autowired는 클래스로 구분 다만 작동 방식은 동일함 결론 POJO는 "Plain Old Java Object"로, 복잡한 구조나 규약 없이 간단한 Java 객체를 의미 빈(Bean)은 Spring에서 관리하는 객체로, Spring 컨테이너가 생성하고 관리 제어의 역전(Inversion of Control)은 객체의 생성과 생명 주기를 Spring 컨테이너가 관리하게 하는 디자인 패턴 의존성 주입(Dependency Injection, DI)은 객체 간의 의존성을 외부에서 주입하여, 객체들이 서로 독립적으로 동작(의존성을 낮춤)할 수 있도록 도와줍니다.
    2025년 03월 28일
    Backend
  • thumbnail for Spring 의존성 주입

    Spring 의존성 주입

    의존성이란? 이러한 경우 PetOwner는 AnimalType에 의존하게 된다. 하지만 이러한 구조에는 문제가 있는데 다음과 같다. PetOwner 객체가 AnimalType 객체 생성을 관리하기 때문에 두 객체 사이의 Tight Coupling이 발생한다. > 따라서 AnimalType 객체의 변경은 PetOwner의 변경을 야기한다 의존성 주입 (Dependency Injection) 앞선 문제점은 DI를 통해 해결할 수 있다. !DI Bean Container는 Bean을 생성하고, 의존성 주입을 수행한다. 의존성 주입도 제어의 역전(IoC)의 한 종류이다. 따라서 코드는 다음과 같이 변화할 수 있다. > 따라서 의존성 주입(DI)는 객체가 자신의 의존성을 직접 처리하는 것이 아니라, 프레임워크에 의해 의존성이 주입되는 디자인 패턴이다. 이 패턴은 프레임워크에 의해 동적으로 주입되기 때문에 여러 객체 간의 결합도를 줄여준다. Spring (IoC) Container 스프링 프레임워크의 코어 컴포넌트로 객체 생성 관리, 객체 의존성 주입의 주요 기능을 갖고 있다. Spring Container의 구성하는 방법 세 가지 xml Java annotation Javabased Configuration Spring Container의 종류 두 가지 BeanFactory ApplicationContext BeanFactory ApplicationContext 매우 간단, 주로 DI를 위함 더 확장, 고급 기능 제공 리소스가 제한된 경우 사용 (모바일...) 아래 특징을 가진 어느곳애서든 사용 1. 엔터프라이즈 인식 기능2. 애플리케이션 이벤트를 리스너에 게시3. 요청 시 빈을 연결하고 폐기 org.springframework.beans.factory.BeanFactory org.springframework.context.ApplicationContext XMLBeanFactory ClassPathXmlApplicationContext 전체 플로우 !Spring Container and DI main 함수에서 ApplicationContext 객체 생성 Spring Container가 Bean 생성 의존성 주입 수행 Advantages of DI 의존성을 낮추어 코드 변경 줄어듦 코드 재사용성 증가 테스트 용이 (mock implements를 주입시키면 되기 때문에) 코드 가독성 증가 Bean이란? 스프링에서 POJO 클래스를 Bean이라고 부름 Configuration metadata를 통해 Spring Container에 의해 생성되고 관리됨 getBean() 메서드로 객체에 접근할 수 있음 Spring Bean Definition Key 역할 class (required) 클래스 네임 구분 id bean을 구분하는 식별자 scope 객체의 범위 (singletone, prototype) constructorarg 객체 생성 시 넘겨줄 매개변수 property 생성 시 setter에 넘겨줄 매개변수 init, destory 함수 Spring Annotation Based Configuration Spring 2.5 이후에 개발되어 유명해짐 XML의 구성은 방대해질 수 있음 Default가 아니기에 설정이 필요 빈 설정에서 XML이 어노테이션을 덮어쓴다 (XML이 우선순위가 더 높음) @Required Setter 메소드에서만 가능 @Autowired ⭐️ xml 방식 Annotation 방식 @Qualifier > @Autowired가 타입 모호성을 가질 때 사용 @Resource @Resource는 xml의 id(name)로 구분 @Autowired는 클래스로 구분 다만 작동 방식은 동일함 결론 POJO는 "Plain Old Java Object"로, 복잡한 구조나 규약 없이 간단한 Java 객체를 의미 빈(Bean)은 Spring에서 관리하는 객체로, Spring 컨테이너가 생성하고 관리 제어의 역전(Inversion of Control)은 객체의 생성과 생명 주기를 Spring 컨테이너가 관리하게 하는 디자인 패턴 의존성 주입(Dependency Injection, DI)은 객체 간의 의존성을 외부에서 주입하여, 객체들이 서로 독립적으로 동작(의존성을 낮춤)할 수 있도록 도와줍니다.

    2025년 03월 28일
    Backend

  • thumbnail for Spring 개요

    Spring 개요

    사전지식 웹 시스템 웹에서 서로 다른 호스트의 상호 작용을 위한 소프트웨어 시스템 클라이언트서버 기반 HTTP, 메시지 지향적(xml,json) 플랫폼 중립적, 독립적 프레임워크 소프트웨어 품질에는 기능 품질, 구조 품질이 있다. 프레임워크란 구조 품질을 보장한다. 프레임워크는 반제품으로 애플리케이션 구조 및 코드의 상당 부분을 제공, 개발자는 핵심 로직 개발에 집중 가능하다. 이를 통해 높은 생산성과 코드 품질이 보장된다. 라이브러리 ↔ 프레임워크 중요한 차이점은 제어의 역전 (Inversion of Controll)이다. 라이브러리 프레임워크 차이 제어의 주체: 개발자(호출)클래스의 집합: 코드 재사용 ↑ 제어의 주체 : 프레임워크 (IoC) 프레임워크의 구조에 따라 코드 작성하면 프레임워크에서 호출 스프링이란? > Light weight JavaApplication Framework POJO 기반의 앤터프라이즈 애플리케이션 개발을 쉽고 편하게 함 자바 애플리케이션을 개발하는데 필요한 하부구조 (infrastructure)를 포괄적으로 제공 스프링이 하부 구조를 처리하므로 개발자는 애플리케이션 개발에 집중 스프링의 주요 특징 의존 관계 주입 (Dependency Injection) 관점 중심 프로그래밍 (Aspect Oriented Programming) 이식 가능한 서비스 추상화 (Portable Service Abstraction) DI 객체간의 의존성을 낮추기 위함 객체와 그 의존성을 직접 생성하는 대신, 외부 엔티티(즉, Spring IoC Container)에 의해 객체가 생성 및 구성된다 PersonService는 Person에 의존한다 Spring Container에 의해 생성된 Person 객체는 생성자를 통해 주입된다. AOP 애플리케이션의 핵심 비즈니스 로직과 공통적으로 필요한 부가 기능(예: 로깅, 보안, 트랜잭션 관리 등)을 분리하여 모듈화하는 프로그래밍 패러다임 관심사의 분리: 비즈니스 로직과 부가 기능을 분리하여 각각의 역할을 명확히 함 재사용성 증가, 유지보수 용이 > 비즈니스 로직과 로깅 로직 혼재 > Aspect (LoggingAspect) 로깅 기능을 별도의 클래스로 분리하여 관리 PSA 애플리케이션 코드가 다양한 서비스 제공자와 상호작용할 수 있도록 공통 인터페이스를 제공하는 추상화 계층 공통 인터페이스 제공: PSA 계층은 여러 서비스 제공자(구체적인 서비스 구현체)와 애플리케이션 코드 사이에 일관된 인터페이스를 제공. 애플리케이션 코드는 이 공통 인터페이스를 통해 서비스와 상호작용하므로, 개별 서비스 제공자의 세부 구현에 신경 쓸 필요가 없음 유연한 서비스 전환: PSA를 사용하면 서비스 제공자를 변경할 때 애플리케이션 코드를 수정할 필요 없이 PSA 계층이 제공하는 인터페이스만 준수하면 됩니다. 이로 인해 서로 다른 서비스 제공자 간의 전환이 매우 용이해짐. Spring과의 통합: Spring 환경에서 PSA를 도입하면, 의존성 주입 등과 같은 Spring의 기능을 활용하여 PSA 계층을 관리할 수 있고, 이를 통해 보다 모듈화된 설계와 유지보수가 용이한 코드를 작성 가능. 결론 스프링을 통해 Java Enterprise 시스템 개발이 용이 비즈니스 로직에 집중 가능하여 생산성 증대 재사용 및 유지 보수 용이, 확장성을 가진 코드 설계
    2025년 03월 27일
    Backend
  • thumbnail for Spring 개요

    Spring 개요

    사전지식 웹 시스템 웹에서 서로 다른 호스트의 상호 작용을 위한 소프트웨어 시스템 클라이언트서버 기반 HTTP, 메시지 지향적(xml,json) 플랫폼 중립적, 독립적 프레임워크 소프트웨어 품질에는 기능 품질, 구조 품질이 있다. 프레임워크란 구조 품질을 보장한다. 프레임워크는 반제품으로 애플리케이션 구조 및 코드의 상당 부분을 제공, 개발자는 핵심 로직 개발에 집중 가능하다. 이를 통해 높은 생산성과 코드 품질이 보장된다. 라이브러리 ↔ 프레임워크 중요한 차이점은 제어의 역전 (Inversion of Controll)이다. 라이브러리 프레임워크 차이 제어의 주체: 개발자(호출)클래스의 집합: 코드 재사용 ↑ 제어의 주체 : 프레임워크 (IoC) 프레임워크의 구조에 따라 코드 작성하면 프레임워크에서 호출 스프링이란? > Light weight JavaApplication Framework POJO 기반의 앤터프라이즈 애플리케이션 개발을 쉽고 편하게 함 자바 애플리케이션을 개발하는데 필요한 하부구조 (infrastructure)를 포괄적으로 제공 스프링이 하부 구조를 처리하므로 개발자는 애플리케이션 개발에 집중 스프링의 주요 특징 의존 관계 주입 (Dependency Injection) 관점 중심 프로그래밍 (Aspect Oriented Programming) 이식 가능한 서비스 추상화 (Portable Service Abstraction) DI 객체간의 의존성을 낮추기 위함 객체와 그 의존성을 직접 생성하는 대신, 외부 엔티티(즉, Spring IoC Container)에 의해 객체가 생성 및 구성된다 PersonService는 Person에 의존한다 Spring Container에 의해 생성된 Person 객체는 생성자를 통해 주입된다. AOP 애플리케이션의 핵심 비즈니스 로직과 공통적으로 필요한 부가 기능(예: 로깅, 보안, 트랜잭션 관리 등)을 분리하여 모듈화하는 프로그래밍 패러다임 관심사의 분리: 비즈니스 로직과 부가 기능을 분리하여 각각의 역할을 명확히 함 재사용성 증가, 유지보수 용이 > 비즈니스 로직과 로깅 로직 혼재 > Aspect (LoggingAspect) 로깅 기능을 별도의 클래스로 분리하여 관리 PSA 애플리케이션 코드가 다양한 서비스 제공자와 상호작용할 수 있도록 공통 인터페이스를 제공하는 추상화 계층 공통 인터페이스 제공: PSA 계층은 여러 서비스 제공자(구체적인 서비스 구현체)와 애플리케이션 코드 사이에 일관된 인터페이스를 제공. 애플리케이션 코드는 이 공통 인터페이스를 통해 서비스와 상호작용하므로, 개별 서비스 제공자의 세부 구현에 신경 쓸 필요가 없음 유연한 서비스 전환: PSA를 사용하면 서비스 제공자를 변경할 때 애플리케이션 코드를 수정할 필요 없이 PSA 계층이 제공하는 인터페이스만 준수하면 됩니다. 이로 인해 서로 다른 서비스 제공자 간의 전환이 매우 용이해짐. Spring과의 통합: Spring 환경에서 PSA를 도입하면, 의존성 주입 등과 같은 Spring의 기능을 활용하여 PSA 계층을 관리할 수 있고, 이를 통해 보다 모듈화된 설계와 유지보수가 용이한 코드를 작성 가능. 결론 스프링을 통해 Java Enterprise 시스템 개발이 용이 비즈니스 로직에 집중 가능하여 생산성 증대 재사용 및 유지 보수 용이, 확장성을 가진 코드 설계

    2025년 03월 27일
    Backend

  • thumbnail for GitHub Rule

    GitHub Rule

    브랜치 전략 (Branch Strategy) 1.1 주요 브랜치 master: 프로덕션(배포)용으로 사용되는 최종 안정 브랜치 (주 1회) develop: 개발이 완료된 기능들을 합치고, QA를 거친 뒤 최종적으로 `master` 브랜치로 병합되는 브랜치 1.2 보조 브랜치 feature/: 새로운 기능 개발이나 개선 작업에 사용 예) `feature/cmyk32`, `feature/cmyk24` hotfix/: 프로덕션에서 발견된 긴급 버그 수정에 사용 예) `hotfix/issue32`, `hotfix/issue24` 1.3 브랜치 생성 및 종료 작업 전 `develop` 브랜치에서 새로운 `feature/` 브랜치를 생성 작업 완료 후 PR(Pull Request)을 열고 reviewer를 지정 reviwer는 code reivew가 완료된 브랜치를 `develop` 브랜치로 머지 긴급 수정 사항 발생 시, `master`에서 `hotfix/` 브랜치를 생성 후 수정 완료 시 `master`과 `develop` 두 브랜치에 모두 병합 커밋 규칙 (Commit Convention) 2.1 Commit message 구조 ``은 커밋 유형을 나타내며 아래 중 하나여야 한다. 2.2 Commit message 규칙 제목 Header 제목과 본문을 빈 행으로 구분한다. 제목은 50글자 이내로 제한 제목의 첫 글자는 대문자로 작성 제목 끝에 마침표 넣지 않기 제목은 명령문으로 사용하며 과거형을 사용하지 않는다 본문 Body 선택 사항 본문의 각 행은 72글자 내로 제한 본문은 어떻게보다 무엇을, 왜에 맞춰 작성하기 바닥글 footer 선택사항 이슈를 추적하기 위한 ID를 추가할 때 사용 `해결` 해결한 이슈 ID `관련` 해당 커밋에 관련된 이슈 ID `참고` 참고할만한 이슈 ID 커밋 예시 Pull Request 규칙 3.1 리뷰어 지정 (Reviewer Assignment) > `junni01kim` > `6keem` > `KJH0506` > `HSJNYLee` 지정된 코드 리뷰어가 리뷰 진행 기능 개발 시, 해당 코드에 관계가 있는 사람 혹은 해당 모듈(화면/UI/비즈니스 로직)에 대한 이해도가 높은 사람 리뷰어로 지정 긴급 수정(`hotfix/` 등)의 경우, 리뷰가 지연되지 않도록 가능한 한 빨리 리뷰어를 배정하고 리뷰가 완료되는 대로 머지 리뷰어가 제안하는 수정 사항이 있으면, PR 작성자는 반드시 검토 후 반영 여부를 결정하고, 필요한 경우 재리뷰 요청 3.2 PR 양식 (Pull Request Template) PR을 생성할 때, 반드시 PR 템플릿을 사용하여 아래 항목을 명시 예시 템플릿
    2025년 02월 13일
    캡스톤디자인
  • thumbnail for GitHub Rule

    GitHub Rule

    브랜치 전략 (Branch Strategy) 1.1 주요 브랜치 master: 프로덕션(배포)용으로 사용되는 최종 안정 브랜치 (주 1회) develop: 개발이 완료된 기능들을 합치고, QA를 거친 뒤 최종적으로 `master` 브랜치로 병합되는 브랜치 1.2 보조 브랜치 feature/: 새로운 기능 개발이나 개선 작업에 사용 예) `feature/cmyk32`, `feature/cmyk24` hotfix/: 프로덕션에서 발견된 긴급 버그 수정에 사용 예) `hotfix/issue32`, `hotfix/issue24` 1.3 브랜치 생성 및 종료 작업 전 `develop` 브랜치에서 새로운 `feature/` 브랜치를 생성 작업 완료 후 PR(Pull Request)을 열고 reviewer를 지정 reviwer는 code reivew가 완료된 브랜치를 `develop` 브랜치로 머지 긴급 수정 사항 발생 시, `master`에서 `hotfix/` 브랜치를 생성 후 수정 완료 시 `master`과 `develop` 두 브랜치에 모두 병합 커밋 규칙 (Commit Convention) 2.1 Commit message 구조 ``은 커밋 유형을 나타내며 아래 중 하나여야 한다. 2.2 Commit message 규칙 제목 Header 제목과 본문을 빈 행으로 구분한다. 제목은 50글자 이내로 제한 제목의 첫 글자는 대문자로 작성 제목 끝에 마침표 넣지 않기 제목은 명령문으로 사용하며 과거형을 사용하지 않는다 본문 Body 선택 사항 본문의 각 행은 72글자 내로 제한 본문은 어떻게보다 무엇을, 왜에 맞춰 작성하기 바닥글 footer 선택사항 이슈를 추적하기 위한 ID를 추가할 때 사용 `해결` 해결한 이슈 ID `관련` 해당 커밋에 관련된 이슈 ID `참고` 참고할만한 이슈 ID 커밋 예시 Pull Request 규칙 3.1 리뷰어 지정 (Reviewer Assignment) > `junni01kim` > `6keem` > `KJH0506` > `HSJNYLee` 지정된 코드 리뷰어가 리뷰 진행 기능 개발 시, 해당 코드에 관계가 있는 사람 혹은 해당 모듈(화면/UI/비즈니스 로직)에 대한 이해도가 높은 사람 리뷰어로 지정 긴급 수정(`hotfix/` 등)의 경우, 리뷰가 지연되지 않도록 가능한 한 빨리 리뷰어를 배정하고 리뷰가 완료되는 대로 머지 리뷰어가 제안하는 수정 사항이 있으면, PR 작성자는 반드시 검토 후 반영 여부를 결정하고, 필요한 경우 재리뷰 요청 3.2 PR 양식 (Pull Request Template) PR을 생성할 때, 반드시 PR 템플릿을 사용하여 아래 항목을 명시 예시 템플릿

    2025년 02월 13일
    캡스톤디자인

  • thumbnail for Flutter Architecture Guide

    Flutter Architecture Guide

    에셋 폴더 assets/ 앱에서 사용하는 모든 에셋 파일을 정리합니다. 예: 폰트, 이미지, 아이콘, JSON 파일 등 `font/` : 커스텀 폰트 파일(ttf, otf 등) `icon/` : 앱에서 사용하는 아이콘 파일(svg, png 등) `image/` : 일반 이미지 리소스(jpg, png 등) 주의: `pubspec.yaml` 파일의 `flutter:` 섹션에서 `assets/`에 대한 경로를 선언해주어야 앱에서 정상적으로 사용 가능합니다. 코어 폴더: lib/ `main.dart` Flutter 앱의 진입점(Entry Point)입니다. `runApp(MyApp())`을 호출하여 앱을 실행합니다. `MultiProvider` 설정이 필요 없으며, `ProviderScope`로 Riverpod 상태를 감쌉니다. `models/` 데이터 모델을 정의하는 폴더입니다. 예: `UserModel`, `ProductModel` 등 주로 JSON 직렬화/역직렬화, 데이터 클래스, 엔티티를 정의합니다. `providers/` Riverpod 패턴을 활용해 상태 관리 로직을 담당합니다. `ChangeNotifier` 대신 `StateNotifier` + `StateNotifierProvider를` 사용해 상태를 관리합니다. 예: `UserProvider`, `AuthProvider`, `ThemeProvider` 등 `screens/` 앱의 UI 화면(Page, Screen)을 담당합니다. 예: `HomeScreen`, `LoginScreen`, `ProfileScreen` 등 각 스크린에서 `ConsumerWidget` 또는 `Consumer`를 사용해 Riverpod 상태를 구독하고 UI를 업데이트합니다. `services/` 비즈니스 로직, API 통신, 데이터베이스 접근 등 핵심 로직을 처리합니다. 예: `ApiService`, `AuthService`, `LocalStorageService` 등 Riverpod의 ref.read(...)를 사용해 서비스 로직과 상호작용할 수 있습니다. `utils/` 재사용 가능한 유틸리티 코드(함수, 상수, 포맷터 등)를 보관합니다. 예: `constants.dart`(상수), `validators.dart`(입력값 검증), `date_formatter.dart`(날짜 포맷) 등 특정 화면이나 로직에 국한되지 않고, 전역적으로 사용할 수 있는 헬퍼 코드가 들어갑니다.
    2025년 02월 12일
    캡스톤디자인
  • thumbnail for Flutter Architecture Guide

    Flutter Architecture Guide

    에셋 폴더 assets/ 앱에서 사용하는 모든 에셋 파일을 정리합니다. 예: 폰트, 이미지, 아이콘, JSON 파일 등 `font/` : 커스텀 폰트 파일(ttf, otf 등) `icon/` : 앱에서 사용하는 아이콘 파일(svg, png 등) `image/` : 일반 이미지 리소스(jpg, png 등) 주의: `pubspec.yaml` 파일의 `flutter:` 섹션에서 `assets/`에 대한 경로를 선언해주어야 앱에서 정상적으로 사용 가능합니다. 코어 폴더: lib/ `main.dart` Flutter 앱의 진입점(Entry Point)입니다. `runApp(MyApp())`을 호출하여 앱을 실행합니다. `MultiProvider` 설정이 필요 없으며, `ProviderScope`로 Riverpod 상태를 감쌉니다. `models/` 데이터 모델을 정의하는 폴더입니다. 예: `UserModel`, `ProductModel` 등 주로 JSON 직렬화/역직렬화, 데이터 클래스, 엔티티를 정의합니다. `providers/` Riverpod 패턴을 활용해 상태 관리 로직을 담당합니다. `ChangeNotifier` 대신 `StateNotifier` + `StateNotifierProvider를` 사용해 상태를 관리합니다. 예: `UserProvider`, `AuthProvider`, `ThemeProvider` 등 `screens/` 앱의 UI 화면(Page, Screen)을 담당합니다. 예: `HomeScreen`, `LoginScreen`, `ProfileScreen` 등 각 스크린에서 `ConsumerWidget` 또는 `Consumer`를 사용해 Riverpod 상태를 구독하고 UI를 업데이트합니다. `services/` 비즈니스 로직, API 통신, 데이터베이스 접근 등 핵심 로직을 처리합니다. 예: `ApiService`, `AuthService`, `LocalStorageService` 등 Riverpod의 ref.read(...)를 사용해 서비스 로직과 상호작용할 수 있습니다. `utils/` 재사용 가능한 유틸리티 코드(함수, 상수, 포맷터 등)를 보관합니다. 예: `constants.dart`(상수), `validators.dart`(입력값 검증), `date_formatter.dart`(날짜 포맷) 등 특정 화면이나 로직에 국한되지 않고, 전역적으로 사용할 수 있는 헬퍼 코드가 들어갑니다.

    2025년 02월 12일
    캡스톤디자인

  • thumbnail for Jenkins로 CI/CD 구축하기 (2)

    Jenkins로 CI/CD 구축하기 (2)

    들어가며 내가 설계한 기본적인 프로세스는 다음과 같다 `메인 브랜치로 머지` → `Webhook 전달` → `Docker 이미지 빌드` → `Docker Hub에 푸시` → `결과 알림` 본 글에서 Discord 알림을 제외한 모든 프로세스를 다룰 것이다. Jenkins 접속 브라우저에서 ec2 public ip에 8080 포트로 jenkins 서버에 접속한다. > 예시) http://0.0.0.0:8080 > 명령어를 통해 출력된 admin 비밀번호로 로그인이 가능하다. Install suggeseted plugins 설치 로그인 계정을 생성하고 젠킨스 접근 URL을 입력한다 Credentials 생성 GitHub Credentails GitHub Access Token 발급 `Settings` > `Developer Settings` > `Personal access tokens (classic)` > `Generate new token (classic)` repo 관련 권한과 hook 권한을 체크해준다. GitHub Credentails 등록 `jenkins 관리` > `Credentials` > `System` > `Glabal credentials` > `Add Credentials` Kind: Username with password Scope: Global Username: GitHub username Password: GitHub access token ID: Identifier used in pipeline code (e.g., githubcredentials) Docker Credentails Kind: Username with password Scope: Global Username: Docker Email Password: Docker Password ID: Identifier used in pipeline code (e.g., githubcredentials) plugins 다운로드 > GitHub API Plugin > Generic Integration > Generic Webhook Trigger > SSH Agent Plugin > Docker > Docker Pipeline GitHub Webhook 설정 `Settings` > `Webhooks` > `Add webhook` > Payload URL 예시 http://0.0.0.0:8080/githubwebhook/ (jenkins 주소) Pipeline 구축 `new items` > `pipeline` > 사진과 같이 선택하고 GitHub 레포지토리 URL을 넣으면 된다. 결과 확인 > main 브랜치에 머지되면 이미지 빌드를 수행하고 Docker Hub에 업로드 되는 것을 볼 수 있다.
    2025년 02월 10일
    Backend
  • thumbnail for Jenkins로 CI/CD 구축하기 (2)

    Jenkins로 CI/CD 구축하기 (2)

    들어가며 내가 설계한 기본적인 프로세스는 다음과 같다 `메인 브랜치로 머지` → `Webhook 전달` → `Docker 이미지 빌드` → `Docker Hub에 푸시` → `결과 알림` 본 글에서 Discord 알림을 제외한 모든 프로세스를 다룰 것이다. Jenkins 접속 브라우저에서 ec2 public ip에 8080 포트로 jenkins 서버에 접속한다. > 예시) http://0.0.0.0:8080 > 명령어를 통해 출력된 admin 비밀번호로 로그인이 가능하다. Install suggeseted plugins 설치 로그인 계정을 생성하고 젠킨스 접근 URL을 입력한다 Credentials 생성 GitHub Credentails GitHub Access Token 발급 `Settings` > `Developer Settings` > `Personal access tokens (classic)` > `Generate new token (classic)` repo 관련 권한과 hook 권한을 체크해준다. GitHub Credentails 등록 `jenkins 관리` > `Credentials` > `System` > `Glabal credentials` > `Add Credentials` Kind: Username with password Scope: Global Username: GitHub username Password: GitHub access token ID: Identifier used in pipeline code (e.g., githubcredentials) Docker Credentails Kind: Username with password Scope: Global Username: Docker Email Password: Docker Password ID: Identifier used in pipeline code (e.g., githubcredentials) plugins 다운로드 > GitHub API Plugin > Generic Integration > Generic Webhook Trigger > SSH Agent Plugin > Docker > Docker Pipeline GitHub Webhook 설정 `Settings` > `Webhooks` > `Add webhook` > Payload URL 예시 http://0.0.0.0:8080/githubwebhook/ (jenkins 주소) Pipeline 구축 `new items` > `pipeline` > 사진과 같이 선택하고 GitHub 레포지토리 URL을 넣으면 된다. 결과 확인 > main 브랜치에 머지되면 이미지 빌드를 수행하고 Docker Hub에 업로드 되는 것을 볼 수 있다.

    2025년 02월 10일
    Backend

  • thumbnail for Jenkins로 CI/CD 구축하기 (1)

    Jenkins로 CI/CD 구축하기 (1)

    들어가며 캡스톤 디자인 기획, 설걔 단계에서 아키텍쳐 설계 부분을 담당하게 됐다. 지난 2학기에 진행했던 프리캡스톤의 기억을 더듬어보니 EC2 서버에 볼륨이 부족하여 자주 Docker 빌드가 실패하던 악몽이 떠올랐다. 그래서 이번 캡스톤 디자인에서는 Docker 이미지를 운영 서버에서 Build하지 않도록 설계하고자 하였다. !아키텍쳐 내가 설계한 기본적인 프로세스는 다음과 같다 `메인 브랜치로 머지` → `Webhook 전달` → `Docker 이미지 빌드` → `Docker Hub에 푸시` → `결과 알림` EC2 인스턴스 정보 os: Amazon Linux 2023 AMI instance: t2.micro volumn: 30GB Jenkins 설치 Jenkins 저장소 등록 wget 명령어를 사용하여 Jenkins의 yum 저장소 파일을 다운로드합니다. 이를 통해 yum이나 dnf 패키지 관리자가 Jenkins 패키지를 찾을 수 있게 됩니다. Jenkins GPG 키 가져오기 Jenkins 저장소에서 제공하는 GPG 키를 가져와 시스템에 등록합니다. 이 키는 패키지의 무결성과 신뢰성을 확인하기 위해 사용됩니다. Amazon Corretto JDK 17 설치 Jenkins 설치 Jenkins 서비스 부팅 시 자동 시작 설정 Jenkins 서비스 시작 Jenkins 서비스 상태 확인 Git 설치 설치 및 버전 확인 Docker 설치 도커 설치 도커 실행 및 활성화 jenkins 사용자를 도커 그룹에 추가 jenkins 재시작 jenkins 접속 확인 브라우저에서 ec2 public ip에 8080 포트로 jenkins 서버에 접속한다. > 예시) http://0.0.0.0:8080 !접속 성공 🦄
    2025년 02월 09일
    Backend
  • thumbnail for Jenkins로 CI/CD 구축하기 (1)

    Jenkins로 CI/CD 구축하기 (1)

    들어가며 캡스톤 디자인 기획, 설걔 단계에서 아키텍쳐 설계 부분을 담당하게 됐다. 지난 2학기에 진행했던 프리캡스톤의 기억을 더듬어보니 EC2 서버에 볼륨이 부족하여 자주 Docker 빌드가 실패하던 악몽이 떠올랐다. 그래서 이번 캡스톤 디자인에서는 Docker 이미지를 운영 서버에서 Build하지 않도록 설계하고자 하였다. !아키텍쳐 내가 설계한 기본적인 프로세스는 다음과 같다 `메인 브랜치로 머지` → `Webhook 전달` → `Docker 이미지 빌드` → `Docker Hub에 푸시` → `결과 알림` EC2 인스턴스 정보 os: Amazon Linux 2023 AMI instance: t2.micro volumn: 30GB Jenkins 설치 Jenkins 저장소 등록 wget 명령어를 사용하여 Jenkins의 yum 저장소 파일을 다운로드합니다. 이를 통해 yum이나 dnf 패키지 관리자가 Jenkins 패키지를 찾을 수 있게 됩니다. Jenkins GPG 키 가져오기 Jenkins 저장소에서 제공하는 GPG 키를 가져와 시스템에 등록합니다. 이 키는 패키지의 무결성과 신뢰성을 확인하기 위해 사용됩니다. Amazon Corretto JDK 17 설치 Jenkins 설치 Jenkins 서비스 부팅 시 자동 시작 설정 Jenkins 서비스 시작 Jenkins 서비스 상태 확인 Git 설치 설치 및 버전 확인 Docker 설치 도커 설치 도커 실행 및 활성화 jenkins 사용자를 도커 그룹에 추가 jenkins 재시작 jenkins 접속 확인 브라우저에서 ec2 public ip에 8080 포트로 jenkins 서버에 접속한다. > 예시) http://0.0.0.0:8080 !접속 성공 🦄

    2025년 02월 09일
    Backend

  • thumbnail for HSU 돋부기 개인정보 처리 방침

    HSU 돋부기 개인정보 처리 방침

    돋부기 개인정보처리방침 / Dotbugi Privacy Policy 개인정보처리방침 (Korean) 시행일: [2025/03/08] 소개 한성대학교 LMS 정보 통합 확장 프로그램은 한성대학교의 LMS 시스템에서 제공하는 강의, 과제, 퀴즈 정보를 한 곳에 모아 사용자에게 제공함으로써 출석 및 과제/퀴즈 제출 여부를 쉽게 확인할 수 있도록 설계되었습니다. 본 개인정보처리방침은 프로그램이 수집하는 정보와 그 사용 및 저장 방법을 설명합니다. 정보 수집 웹사이트 콘텐츠 이 확장 프로그램은 한성대학교 LMS의 웹페이지에서 강의, 과제, 퀴즈 정보와 함께 사용자의 출석 및 과제/퀴즈 제출 상태와 같은 웹 콘텐츠를 수집합니다. 구체적인 데이터 특히, 다음과 같은 데이터를 수집합니다: 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 사용자의 강의 출석 여부와 과제/퀴즈 제출 상태 구글 캘린더 연동용 인증정보: 구글 캘린더와 연동하기 위해 필요한 인증 토큰 및 자격 증명 데이터 저장 및 보안 로컬 저장 수집된 모든 데이터는 사용자의 브라우저 또는 로컬 저장소에만 저장되며, 외부 서버나 제3자에게 전송되지 않습니다. 이는 구글 캘린더 연동을 위한 인증정보 또한 포함됩니다. 개인정보 및 민감 정보 미수집 확장 프로그램의 기능 수행에 필요한 한성대학교 LMS 웹 콘텐츠와 구글 캘린더 연동을 위한 인증정보 외에 추가적인 개인정보나 민감한 정보는 수집하지 않습니다. Google 사용자 데이터 보관/삭제 관련 본 확장 프로그램은 Google OAuth2를 통해, 사용자가 ‘캘린더 연동’ 기능을 직접 요청한 경우에만 구글 캘린더에 접근하여 이벤트 정보를 가져옵니다. 이때 사용자의 캘린더 이벤트는 중복 여부 확인을 위해 일시적으로만 로드되며, 확인 후 별도로 저장하거나 외부에 전송되지 않고 즉시 폐기됩니다. 즉, 어떠한 구글 사용자 데이터도 프로그램 내부·외부 서버에 보관하거나 공유하지 않으므로 별도의 삭제 절차가 필요하지 않습니다. 수집된 데이터의 사용 수집된 데이터는 오직 다음의 목적을 위해 사용됩니다: 한성대학교 LMS 내 강의, 과제, 퀴즈 정보를 한 곳에 통합하여 표시 출석 및 과제/퀴즈 제출 상태를 사용자에게 편리하게 제공 사용자가 원하는 경우, 구글 캘린더와 과제·퀴즈 일정을 동기화 수집된 데이터는 추적, 분석 또는 기타 외부 용도로 사용되지 않으며, 인증정보 또한 사용자의 로컬 환경에서만 구글 캘린더 연동을 위해 활용됩니다. 사용자 동의 한성대학교 LMS 정보 통합 확장 프로그램을 설치 및 사용함으로써, 본 개인정보처리방침에 따라 웹사이트 콘텐츠와 구글 캘린더 연동용 인증정보를 수집하고 이를 사용자 브라우저 내에 저장하는 것에 동의하는 것으로 간주됩니다. 명시적인 사용자 동의 없이 어떠한 데이터도 외부에 공유되지 않습니다. 방침 변경 본 개인정보처리방침은 수시로 업데이트될 수 있으며, 중요한 변경 사항은 적절한 방법으로 안내될 것입니다. 변경 사항을 확인하기 위해 주기적으로 본 방침을 검토하시길 권장합니다. 문의처 본 개인정보처리방침에 관한 문의 사항은 아래의 연락처로 문의해 주시기 바랍니다: 이메일: [6ukeem@gmail.com] Privacy Policy (English) Effective Date: [2025/03/08] Introduction The Hansung University LMS Consolidation Extension is designed to aggregate lectures, assignments, and quizzes from the Hansung University LMS into a single view, enabling users to easily check their attendance and submission statuses. This Privacy Policy explains what information is collected, how it is used, and how it is stored. Information Collection Website Content This extension collects web content from the Hansung University LMS, including information about lectures, assignments, quizzes, as well as attendance and submission statuses. Specific Data In particular, the extension gathers: Lecture Information: Course names, schedules, instructor details, etc. Assignment Information: Assignment titles, due dates, detailed descriptions, etc. Quiz Information: Quiz titles, schedules, questions, and answer details. Attendance and Submission Status: Information on user attendance for lectures and submission statuses for assignments/quizzes. Google Calendar Integration Credentials: Authentication tokens and credentials required to synchronize with Google Calendar. Data Storage and Security Local Storage All collected data—including Google Calendar integration credentials—is stored solely on your browser or local storage. No data is transmitted to external servers or third parties. No Personal/Sensitive Data Beyond the necessary LMS web content and the credentials needed for Google Calendar integration, no additional personal or sensitive data is collected. Regarding Storage/Deletion of Google User Data When you choose to enable calendar synchronization, this extension accesses your Google Calendar via Google OAuth2 only to retrieve events in order to check for duplicates and add new events if no duplicates are found. No Google Calendar event information is stored or shared; data is loaded temporarily to perform duplication checks and then discarded immediately. Use of Collected Data The collected data is used exclusively to: Aggregate and display lecture, assignment, and quiz information from the Hansung University LMS in a unified interface Provide convenient access to attendance and submission statuses for the user (If desired by the user) Synchronize assignment and quiz schedules with Google Calendar The data is not used for tracking, analytics, or any other external purposes. Google Calendar integration credentials are used only within your local environment for synchronization purposes. User Consent By installing and using the Hansung University LMS Consolidation Extension, you consent to the collection and local storage of the LMS web content and Google Calendar integration credentials as described in this Privacy Policy. No data will be shared without your explicit consent. Changes to This Policy This Privacy Policy may be updated from time to time. Any significant changes will be communicated through appropriate channels. We encourage you to review this policy periodically for any modifications. Contact Information For questions or concerns regarding this Privacy Policy, please contact us at: Email: [6ukeem@gmail.com]
    2025년 02월 06일
    Chrome-extension
  • thumbnail for HSU 돋부기 개인정보 처리 방침

    HSU 돋부기 개인정보 처리 방침

    돋부기 개인정보처리방침 / Dotbugi Privacy Policy 개인정보처리방침 (Korean) 시행일: [2025/03/08] 소개 한성대학교 LMS 정보 통합 확장 프로그램은 한성대학교의 LMS 시스템에서 제공하는 강의, 과제, 퀴즈 정보를 한 곳에 모아 사용자에게 제공함으로써 출석 및 과제/퀴즈 제출 여부를 쉽게 확인할 수 있도록 설계되었습니다. 본 개인정보처리방침은 프로그램이 수집하는 정보와 그 사용 및 저장 방법을 설명합니다. 정보 수집 웹사이트 콘텐츠 이 확장 프로그램은 한성대학교 LMS의 웹페이지에서 강의, 과제, 퀴즈 정보와 함께 사용자의 출석 및 과제/퀴즈 제출 상태와 같은 웹 콘텐츠를 수집합니다. 구체적인 데이터 특히, 다음과 같은 데이터를 수집합니다: 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 사용자의 강의 출석 여부와 과제/퀴즈 제출 상태 구글 캘린더 연동용 인증정보: 구글 캘린더와 연동하기 위해 필요한 인증 토큰 및 자격 증명 데이터 저장 및 보안 로컬 저장 수집된 모든 데이터는 사용자의 브라우저 또는 로컬 저장소에만 저장되며, 외부 서버나 제3자에게 전송되지 않습니다. 이는 구글 캘린더 연동을 위한 인증정보 또한 포함됩니다. 개인정보 및 민감 정보 미수집 확장 프로그램의 기능 수행에 필요한 한성대학교 LMS 웹 콘텐츠와 구글 캘린더 연동을 위한 인증정보 외에 추가적인 개인정보나 민감한 정보는 수집하지 않습니다. Google 사용자 데이터 보관/삭제 관련 본 확장 프로그램은 Google OAuth2를 통해, 사용자가 ‘캘린더 연동’ 기능을 직접 요청한 경우에만 구글 캘린더에 접근하여 이벤트 정보를 가져옵니다. 이때 사용자의 캘린더 이벤트는 중복 여부 확인을 위해 일시적으로만 로드되며, 확인 후 별도로 저장하거나 외부에 전송되지 않고 즉시 폐기됩니다. 즉, 어떠한 구글 사용자 데이터도 프로그램 내부·외부 서버에 보관하거나 공유하지 않으므로 별도의 삭제 절차가 필요하지 않습니다. 수집된 데이터의 사용 수집된 데이터는 오직 다음의 목적을 위해 사용됩니다: 한성대학교 LMS 내 강의, 과제, 퀴즈 정보를 한 곳에 통합하여 표시 출석 및 과제/퀴즈 제출 상태를 사용자에게 편리하게 제공 사용자가 원하는 경우, 구글 캘린더와 과제·퀴즈 일정을 동기화 수집된 데이터는 추적, 분석 또는 기타 외부 용도로 사용되지 않으며, 인증정보 또한 사용자의 로컬 환경에서만 구글 캘린더 연동을 위해 활용됩니다. 사용자 동의 한성대학교 LMS 정보 통합 확장 프로그램을 설치 및 사용함으로써, 본 개인정보처리방침에 따라 웹사이트 콘텐츠와 구글 캘린더 연동용 인증정보를 수집하고 이를 사용자 브라우저 내에 저장하는 것에 동의하는 것으로 간주됩니다. 명시적인 사용자 동의 없이 어떠한 데이터도 외부에 공유되지 않습니다. 방침 변경 본 개인정보처리방침은 수시로 업데이트될 수 있으며, 중요한 변경 사항은 적절한 방법으로 안내될 것입니다. 변경 사항을 확인하기 위해 주기적으로 본 방침을 검토하시길 권장합니다. 문의처 본 개인정보처리방침에 관한 문의 사항은 아래의 연락처로 문의해 주시기 바랍니다: 이메일: [6ukeem@gmail.com] Privacy Policy (English) Effective Date: [2025/03/08] Introduction The Hansung University LMS Consolidation Extension is designed to aggregate lectures, assignments, and quizzes from the Hansung University LMS into a single view, enabling users to easily check their attendance and submission statuses. This Privacy Policy explains what information is collected, how it is used, and how it is stored. Information Collection Website Content This extension collects web content from the Hansung University LMS, including information about lectures, assignments, quizzes, as well as attendance and submission statuses. Specific Data In particular, the extension gathers: Lecture Information: Course names, schedules, instructor details, etc. Assignment Information: Assignment titles, due dates, detailed descriptions, etc. Quiz Information: Quiz titles, schedules, questions, and answer details. Attendance and Submission Status: Information on user attendance for lectures and submission statuses for assignments/quizzes. Google Calendar Integration Credentials: Authentication tokens and credentials required to synchronize with Google Calendar. Data Storage and Security Local Storage All collected data—including Google Calendar integration credentials—is stored solely on your browser or local storage. No data is transmitted to external servers or third parties. No Personal/Sensitive Data Beyond the necessary LMS web content and the credentials needed for Google Calendar integration, no additional personal or sensitive data is collected. Regarding Storage/Deletion of Google User Data When you choose to enable calendar synchronization, this extension accesses your Google Calendar via Google OAuth2 only to retrieve events in order to check for duplicates and add new events if no duplicates are found. No Google Calendar event information is stored or shared; data is loaded temporarily to perform duplication checks and then discarded immediately. Use of Collected Data The collected data is used exclusively to: Aggregate and display lecture, assignment, and quiz information from the Hansung University LMS in a unified interface Provide convenient access to attendance and submission statuses for the user (If desired by the user) Synchronize assignment and quiz schedules with Google Calendar The data is not used for tracking, analytics, or any other external purposes. Google Calendar integration credentials are used only within your local environment for synchronization purposes. User Consent By installing and using the Hansung University LMS Consolidation Extension, you consent to the collection and local storage of the LMS web content and Google Calendar integration credentials as described in this Privacy Policy. No data will be shared without your explicit consent. Changes to This Policy This Privacy Policy may be updated from time to time. Any significant changes will be communicated through appropriate channels. We encourage you to review this policy periodically for any modifications. Contact Information For questions or concerns regarding this Privacy Policy, please contact us at: Email: [6ukeem@gmail.com]

    2025년 02월 06일
    Chrome-extension

  • thumbnail for Flutter Code Convention

    Flutter Code Convention

    공식문서를 참고하여 작성 하였습니다. 식별자 (Identifiers) Dart에서는 식별자를 세 가지 방식으로 사용합니다. 1.1. UpperCamelCase 설명: 각 단어의 첫 글자를 대문자로 작성합니다. 용도: 클래스, enum, typedef, 타입 매개변수 등 예시 (Good): 1.2. lowerCamelCase 설명: 첫 단어는 소문자, 이후 단어는 첫 글자만 대문자로 작성합니다. 용도: 메서드명, 변수명, 상수 (상수도 lowerCamelCase를 선호) 예시 (Good) : 1.3. lowercase_with_underscores 설명: 모든 글자를 소문자로 작성하고, 단어 사이에 언더스코어(\_)를 사용합니다. 용도: 패키지, 디렉토리, 파일명, import 접두어 예시 (Good): 예시 (Bad): 1.4. 약어와 두문어 처리 긴 약어 (2글자 이상): 일반 단어처럼 취급하여 첫 글자를 대문자로 작성 예: Http (Hypertext Transfer Protocol), Nasa (National Aeronautics and Space Administration) 두 글자 약어: 영어에서 모두 대문자로 쓰이면 그대로 사용 예: ID, TV lowerCamelCase에서 약어가 앞에 올 경우: 모두 소문자로 작성 예: 순서 (Ordering) 2.1. 임포트 순서 규칙: dart: 임포트 package: 임포트 상대 경로 임포트 예시 (Good): 예시 (Bad): 2.2. Export 순서 규칙: 임포트 이후 별도의 섹션에 배치하며, 각 섹션은 빈 줄로 구분합니다. 예시 (Good): 예시 (Bad): 포맷팅 (Formatting) 3.1. 자동 포맷터 사용 설명: dart format 명령어를 사용하면 일관된 포맷팅을 유지할 수 있습니다. 예시 3.2. 한 줄 120자 제한 설명: 가독성을 위해 한 줄의 길이를 120자로 제한합니다. (특별한 경우 제외) 주의: 긴 URI, 파일 경로, 또는 멀티라인 문자열은 예외가 될 수 있습니다. 3.3. 중괄호 사용 설명: 모든 제어문(조건문, 반복문 등)에서 중괄호를 사용합니다. 예시 (Good): 예시 (예외): else가 없는 간단한 if 문은 한 줄로 작성할 수 있습니다 예시 (Bad):
    2025년 02월 05일
    캡스톤디자인
  • thumbnail for Flutter Code Convention

    Flutter Code Convention

    공식문서를 참고하여 작성 하였습니다. 식별자 (Identifiers) Dart에서는 식별자를 세 가지 방식으로 사용합니다. 1.1. UpperCamelCase 설명: 각 단어의 첫 글자를 대문자로 작성합니다. 용도: 클래스, enum, typedef, 타입 매개변수 등 예시 (Good): 1.2. lowerCamelCase 설명: 첫 단어는 소문자, 이후 단어는 첫 글자만 대문자로 작성합니다. 용도: 메서드명, 변수명, 상수 (상수도 lowerCamelCase를 선호) 예시 (Good) : 1.3. lowercase_with_underscores 설명: 모든 글자를 소문자로 작성하고, 단어 사이에 언더스코어(\_)를 사용합니다. 용도: 패키지, 디렉토리, 파일명, import 접두어 예시 (Good): 예시 (Bad): 1.4. 약어와 두문어 처리 긴 약어 (2글자 이상): 일반 단어처럼 취급하여 첫 글자를 대문자로 작성 예: Http (Hypertext Transfer Protocol), Nasa (National Aeronautics and Space Administration) 두 글자 약어: 영어에서 모두 대문자로 쓰이면 그대로 사용 예: ID, TV lowerCamelCase에서 약어가 앞에 올 경우: 모두 소문자로 작성 예: 순서 (Ordering) 2.1. 임포트 순서 규칙: dart: 임포트 package: 임포트 상대 경로 임포트 예시 (Good): 예시 (Bad): 2.2. Export 순서 규칙: 임포트 이후 별도의 섹션에 배치하며, 각 섹션은 빈 줄로 구분합니다. 예시 (Good): 예시 (Bad): 포맷팅 (Formatting) 3.1. 자동 포맷터 사용 설명: dart format 명령어를 사용하면 일관된 포맷팅을 유지할 수 있습니다. 예시 3.2. 한 줄 120자 제한 설명: 가독성을 위해 한 줄의 길이를 120자로 제한합니다. (특별한 경우 제외) 주의: 긴 URI, 파일 경로, 또는 멀티라인 문자열은 예외가 될 수 있습니다. 3.3. 중괄호 사용 설명: 모든 제어문(조건문, 반복문 등)에서 중괄호를 사용합니다. 예시 (Good): 예시 (예외): else가 없는 간단한 if 문은 한 줄로 작성할 수 있습니다 예시 (Bad):

    2025년 02월 05일
    캡스톤디자인

  • thumbnail for SpringBoot Code Convention

    SpringBoot Code Convention

    NAVER의 java 코딩 컨벤션을 따라 작성되었습니다. Spring Boot 코드 컨벤션 프로젝트 구조 패키지 구조 도메인 별로 패키지를 분리하여 관리합니다. 예시: 네이밍 컨벤션 클래스/인터페이스 PascalCase (첫 글자 대문자) 예: `UserService`, `OrderController`, `ProductRepository` 메소드 camelCase (첫 글자 소문자) 예: `createUser()`, `findAllProducts()` 변수 camelCase 예: `userName`, `orderList` 상수 모두 대문자, 언더스코어로 단어 구분 예: `MAX_CONNECTIONS`, `DEFAULT_PAGE_SIZE` 코드 포맷팅 들여쓰기 Tab 또는 스페이스 4칸 사용 줄바꿈 및 공백 각 클래스, 메소드, 필드 사이에 적절한 공백을 두어 가독성을 높입니다. 긴 줄은 100~120자 이내로 작성합니다. 예시: 주석 작성 모든 주석은 한글 로 작성하여 팀원이 이해하기 쉽도록 합니다. 클래스/메소드 설명 Javadoc 스타일 주석을 사용하여 클래스, 메소드의 역할과 사용법을 설명합니다. 인라인 주석 코드의 복잡한 로직이나 주의사항이 있을 때 한 줄 주석(//)을 사용합니다. TODO 주석 앞으로 개선하거나 추가할 사항이 있을 때 // TODO: 형식으로 남깁니다. 예시: 예외 처리 전역 예외 처리 @ControllerAdvice를 활용하여 전역 예외 처리 로직을 작성합니다. 커스텀 예외 비즈니스 로직에 맞는 커스텀 예외를 정의하여 사용합니다.
    2025년 02월 05일
    캡스톤디자인
  • thumbnail for SpringBoot Code Convention

    SpringBoot Code Convention

    NAVER의 java 코딩 컨벤션을 따라 작성되었습니다. Spring Boot 코드 컨벤션 프로젝트 구조 패키지 구조 도메인 별로 패키지를 분리하여 관리합니다. 예시: 네이밍 컨벤션 클래스/인터페이스 PascalCase (첫 글자 대문자) 예: `UserService`, `OrderController`, `ProductRepository` 메소드 camelCase (첫 글자 소문자) 예: `createUser()`, `findAllProducts()` 변수 camelCase 예: `userName`, `orderList` 상수 모두 대문자, 언더스코어로 단어 구분 예: `MAX_CONNECTIONS`, `DEFAULT_PAGE_SIZE` 코드 포맷팅 들여쓰기 Tab 또는 스페이스 4칸 사용 줄바꿈 및 공백 각 클래스, 메소드, 필드 사이에 적절한 공백을 두어 가독성을 높입니다. 긴 줄은 100~120자 이내로 작성합니다. 예시: 주석 작성 모든 주석은 한글 로 작성하여 팀원이 이해하기 쉽도록 합니다. 클래스/메소드 설명 Javadoc 스타일 주석을 사용하여 클래스, 메소드의 역할과 사용법을 설명합니다. 인라인 주석 코드의 복잡한 로직이나 주의사항이 있을 때 한 줄 주석(//)을 사용합니다. TODO 주석 앞으로 개선하거나 추가할 사항이 있을 때 // TODO: 형식으로 남깁니다. 예시: 예외 처리 전역 예외 처리 @ControllerAdvice를 활용하여 전역 예외 처리 로직을 작성합니다. 커스텀 예외 비즈니스 로직에 맞는 커스텀 예외를 정의하여 사용합니다.

    2025년 02월 05일
    캡스톤디자인

  • thumbnail for HSU 돋부기 서비스 개요

    HSU 돋부기 서비스 개요

    서비스 개요 개인정보방침 한성대학교 LMS 강의, 과제, 퀴즈 한 눈에 보기 이 프로그램은 한성대학교 LMS에서 제공하는 강의, 과제, 퀴즈 정보를 한 번에 모아서 보여줍니다. 이를 통해 학생들은 각 강의의 출석 현황과 과제 및 퀴즈의 제출 여부를 쉽게 확인할 수 있으며, 제출 마감 시간이 다가오면 알림 기능을 통해 기한을 놓치지 않도록 도와줍니다. 주요 기능 통합 정보 제공 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 각 강의의 출석 현황과 과제/퀴즈 제출 여부 제출 마감 알림 실시간 알림: 제출 마감 시간이 임박한 과제 및 퀴즈에 대해 사용자에게 알림 제공 일정 관리: 중요한 일정 및 마감 기한을 놓치지 않도록 지원 구글 캘린더 연동 인증 정보 관리: 구글 캘린더와의 연동을 위한 인증 토큰 및 자격 증명을 안전하게 저장 일정 동기화: 강의, 과제, 퀴즈 일정 정보를 구글 캘린더와 연동하여 통합 관리 정보 수집 웹사이트 콘텐츠 수집 이 확장 프로그램은 한성대학교 LMS 웹페이지에서 다음과 같은 정보를 수집합니다: 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 사용자의 강의 출석 여부와 과제/퀴즈 제출 상태 구체적인 데이터 항목 강의 정보 강의명 강의 일정 및 시간표 담당 교수 및 강의 소개 과제 정보 과제 제목 제출 기한 과제 세부 내용 및 요구 사항 퀴즈 정보 퀴즈 제목 진행 일정 및 제한 시간 문제 및 답안 정보 출석 및 제출 상태 강의 출석 여부 과제 및 퀴즈 제출 여부 데이터 저장 및 보안 로컬 저장 방식 데이터 저장 위치: 수집된 모든 데이터는 사용자의 브라우저 또는 로컬 저장소에만 저장됩니다. 외부 전송 금지: 데이터는 외부 서버나 제3자에게 전송되지 않습니다. (구글 캘린더 연동용 인증정보 포함) 개인정보 보호 및 민감 정보 미수집 필요 최소 정보만 수집: 한성대학교 LMS 웹 콘텐츠와 구글 캘린더 연동을 위한 인증정보 외에는 추가적인 개인정보나 민감한 정보를 수집하지 않습니다. 보안 강화: 사용자 정보 보호를 최우선으로 하여 데이터 수집 및 저장 과정에서 철저한 보안 정책을 준수합니다. 결론 이 서비스는 학생들이 한성대학교 LMS의 다양한 정보를 한 곳에서 확인하고, 제출 기한 및 강의 출석 상태를 쉽게 관리할 수 있도록 돕습니다. 강의, 과제, 퀴즈 정보의 통합 관리와 구글 캘린더 연동을 통해 사용자 편의성을 극대화하며, 데이터는 로컬 저장소에 안전하게 보관되어 개인정보 보호에 만전을 기하고 있습니다.
    2025년 02월 05일
    Chrome-extension
  • thumbnail for HSU 돋부기 서비스 개요

    HSU 돋부기 서비스 개요

    서비스 개요 개인정보방침 한성대학교 LMS 강의, 과제, 퀴즈 한 눈에 보기 이 프로그램은 한성대학교 LMS에서 제공하는 강의, 과제, 퀴즈 정보를 한 번에 모아서 보여줍니다. 이를 통해 학생들은 각 강의의 출석 현황과 과제 및 퀴즈의 제출 여부를 쉽게 확인할 수 있으며, 제출 마감 시간이 다가오면 알림 기능을 통해 기한을 놓치지 않도록 도와줍니다. 주요 기능 통합 정보 제공 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 각 강의의 출석 현황과 과제/퀴즈 제출 여부 제출 마감 알림 실시간 알림: 제출 마감 시간이 임박한 과제 및 퀴즈에 대해 사용자에게 알림 제공 일정 관리: 중요한 일정 및 마감 기한을 놓치지 않도록 지원 구글 캘린더 연동 인증 정보 관리: 구글 캘린더와의 연동을 위한 인증 토큰 및 자격 증명을 안전하게 저장 일정 동기화: 강의, 과제, 퀴즈 일정 정보를 구글 캘린더와 연동하여 통합 관리 정보 수집 웹사이트 콘텐츠 수집 이 확장 프로그램은 한성대학교 LMS 웹페이지에서 다음과 같은 정보를 수집합니다: 강의 정보: 강의명, 강의 일정, 교수 정보 등 과제 정보: 과제 제목, 제출 기한, 과제 세부 내용 등 퀴즈 정보: 퀴즈 제목, 진행 일정, 문제 및 답안 정보 등 출석 및 제출 상태: 사용자의 강의 출석 여부와 과제/퀴즈 제출 상태 구체적인 데이터 항목 강의 정보 강의명 강의 일정 및 시간표 담당 교수 및 강의 소개 과제 정보 과제 제목 제출 기한 과제 세부 내용 및 요구 사항 퀴즈 정보 퀴즈 제목 진행 일정 및 제한 시간 문제 및 답안 정보 출석 및 제출 상태 강의 출석 여부 과제 및 퀴즈 제출 여부 데이터 저장 및 보안 로컬 저장 방식 데이터 저장 위치: 수집된 모든 데이터는 사용자의 브라우저 또는 로컬 저장소에만 저장됩니다. 외부 전송 금지: 데이터는 외부 서버나 제3자에게 전송되지 않습니다. (구글 캘린더 연동용 인증정보 포함) 개인정보 보호 및 민감 정보 미수집 필요 최소 정보만 수집: 한성대학교 LMS 웹 콘텐츠와 구글 캘린더 연동을 위한 인증정보 외에는 추가적인 개인정보나 민감한 정보를 수집하지 않습니다. 보안 강화: 사용자 정보 보호를 최우선으로 하여 데이터 수집 및 저장 과정에서 철저한 보안 정책을 준수합니다. 결론 이 서비스는 학생들이 한성대학교 LMS의 다양한 정보를 한 곳에서 확인하고, 제출 기한 및 강의 출석 상태를 쉽게 관리할 수 있도록 돕습니다. 강의, 과제, 퀴즈 정보의 통합 관리와 구글 캘린더 연동을 통해 사용자 편의성을 극대화하며, 데이터는 로컬 저장소에 안전하게 보관되어 개인정보 보호에 만전을 기하고 있습니다.

    2025년 02월 05일
    Chrome-extension

  • thumbnail for HSU 시간표 마슐사 개인정보 처리 방침

    HSU 시간표 마슐사 개인정보 처리 방침

    시간표 마슐사 개인정보처리방침 / Mashlebugi Privacy Policy 개인정보처리방침 (Korean) 시행일: [2025/02/01] 소개 시간표 마슐사 Chrome 확장 프로그램은 시간표 디자인을 개선하여 사용자 경험을 향상시키기 위해 설계되었습니다. 본 개인정보처리방침은 어떤 정보가 수집되며, 어떻게 사용되고 저장되는지를 설명합니다. 정보 수집 웹사이트 콘텐츠 이 확장 프로그램은 사용자가 방문하는 웹페이지의 텍스트, 이미지, 소리, 동영상, 하이퍼링크 등 웹사이트 콘텐츠를 수집합니다. 구체적인 데이터 특히, 다음과 같은 데이터를 수집합니다: 링크: 현재 방문한 페이지에서 확장 프로그램 실행 여부를 판단하기 위한 링크 텍스트 정보: 시간표 테이블을 구성하는 텍스트 정보 (예: 학과, 수업 시간 등) 데이터 저장 및 보안 로컬 저장 수집된 모든 데이터는 사용자 브라우저 내에만 저장되며, 외부 서버나 제3자에게 전송되지 않습니다. 개인정보 및 민감 정보 미수집 확장 프로그램의 기능 수행에 필요한 웹사이트 콘텐츠 외에 어떠한 개인정보나 민감한 정보도 수집하지 않습니다. 수집된 데이터의 사용 수집된 데이터는 오직 다음의 목적을 위해 사용됩니다: 확장 프로그램의 실행 여부 판단 시간표 정보의 구성 및 표시 수집된 데이터는 추적, 분석 또는 기타 외부 용도로 사용되지 않습니다. 사용자 동의 시간표 마슐사 Chrome 확장 프로그램을 설치 및 사용함으로써, 본 개인정보처리방침에 따라 웹사이트 콘텐츠의 수집 및 사용자 브라우저 내 저장에 동의하는 것으로 간주됩니다. 명시적인 사용자 동의 없이 어떠한 데이터도 외부에 공유되지 않습니다. 방침 변경 본 개인정보처리방침은 수시로 업데이트될 수 있으며, 중요한 변경 사항은 적절한 방법으로 안내될 것입니다. 변경 사항을 확인하기 위해 주기적으로 본 방침을 검토하시길 권장합니다. 문의처 본 개인정보처리방침에 관한 문의 사항은 아래의 연락처로 문의해 주시기 바랍니다: 이메일: [6ukeem@gmail.com] Privacy Policy (English) Effective Date: [2025/02/01] Introduction The Mashlebugi Chrome Extension is designed to enhance the user experience by modernizing timetable displays. This Privacy Policy explains what information is collected, how it is used, and how it is stored. Information Collection Website Content The extension collects website content such as text, images, audio, video, and hyperlinks from the webpages you visit. Specific Data In particular, the extension gathers: Links: From the current page to determine whether the Chrome extension should be activated. Text Information: That forms the timetable table (e.g., department names, class times). Data Storage and Security Local Storage All collected data is stored solely on your browser. No data is transmitted to external servers or third parties. No Personal/Sensitive Data Beyond the website content required for the extension’s functionality, no personal or sensitive information is collected. Use of Collected Data The collected data is used exclusively to: Determine the operational context (i.e., whether the extension should run on the current page). Construct and display the timetable information. The data is not used for tracking, analytics, or any other external purposes. User Consent By installing and using the Mashlebugi Chrome Extension, you consent to the collection and local storage of the website content as described in this Privacy Policy. No data will be shared without your explicit consent. Changes to This Policy This Privacy Policy may be updated from time to time. Any significant changes will be communicated through appropriate channels. We encourage you to review this policy periodically for any modifications. Contact Information For questions or concerns regarding this Privacy Policy, please contact us at: Email: [6ukeem@gmail.com]
    2025년 02월 01일
    Chrome-extension
  • thumbnail for HSU 시간표 마슐사 개인정보 처리 방침

    HSU 시간표 마슐사 개인정보 처리 방침

    시간표 마슐사 개인정보처리방침 / Mashlebugi Privacy Policy 개인정보처리방침 (Korean) 시행일: [2025/02/01] 소개 시간표 마슐사 Chrome 확장 프로그램은 시간표 디자인을 개선하여 사용자 경험을 향상시키기 위해 설계되었습니다. 본 개인정보처리방침은 어떤 정보가 수집되며, 어떻게 사용되고 저장되는지를 설명합니다. 정보 수집 웹사이트 콘텐츠 이 확장 프로그램은 사용자가 방문하는 웹페이지의 텍스트, 이미지, 소리, 동영상, 하이퍼링크 등 웹사이트 콘텐츠를 수집합니다. 구체적인 데이터 특히, 다음과 같은 데이터를 수집합니다: 링크: 현재 방문한 페이지에서 확장 프로그램 실행 여부를 판단하기 위한 링크 텍스트 정보: 시간표 테이블을 구성하는 텍스트 정보 (예: 학과, 수업 시간 등) 데이터 저장 및 보안 로컬 저장 수집된 모든 데이터는 사용자 브라우저 내에만 저장되며, 외부 서버나 제3자에게 전송되지 않습니다. 개인정보 및 민감 정보 미수집 확장 프로그램의 기능 수행에 필요한 웹사이트 콘텐츠 외에 어떠한 개인정보나 민감한 정보도 수집하지 않습니다. 수집된 데이터의 사용 수집된 데이터는 오직 다음의 목적을 위해 사용됩니다: 확장 프로그램의 실행 여부 판단 시간표 정보의 구성 및 표시 수집된 데이터는 추적, 분석 또는 기타 외부 용도로 사용되지 않습니다. 사용자 동의 시간표 마슐사 Chrome 확장 프로그램을 설치 및 사용함으로써, 본 개인정보처리방침에 따라 웹사이트 콘텐츠의 수집 및 사용자 브라우저 내 저장에 동의하는 것으로 간주됩니다. 명시적인 사용자 동의 없이 어떠한 데이터도 외부에 공유되지 않습니다. 방침 변경 본 개인정보처리방침은 수시로 업데이트될 수 있으며, 중요한 변경 사항은 적절한 방법으로 안내될 것입니다. 변경 사항을 확인하기 위해 주기적으로 본 방침을 검토하시길 권장합니다. 문의처 본 개인정보처리방침에 관한 문의 사항은 아래의 연락처로 문의해 주시기 바랍니다: 이메일: [6ukeem@gmail.com] Privacy Policy (English) Effective Date: [2025/02/01] Introduction The Mashlebugi Chrome Extension is designed to enhance the user experience by modernizing timetable displays. This Privacy Policy explains what information is collected, how it is used, and how it is stored. Information Collection Website Content The extension collects website content such as text, images, audio, video, and hyperlinks from the webpages you visit. Specific Data In particular, the extension gathers: Links: From the current page to determine whether the Chrome extension should be activated. Text Information: That forms the timetable table (e.g., department names, class times). Data Storage and Security Local Storage All collected data is stored solely on your browser. No data is transmitted to external servers or third parties. No Personal/Sensitive Data Beyond the website content required for the extension’s functionality, no personal or sensitive information is collected. Use of Collected Data The collected data is used exclusively to: Determine the operational context (i.e., whether the extension should run on the current page). Construct and display the timetable information. The data is not used for tracking, analytics, or any other external purposes. User Consent By installing and using the Mashlebugi Chrome Extension, you consent to the collection and local storage of the website content as described in this Privacy Policy. No data will be shared without your explicit consent. Changes to This Policy This Privacy Policy may be updated from time to time. Any significant changes will be communicated through appropriate channels. We encourage you to review this policy periodically for any modifications. Contact Information For questions or concerns regarding this Privacy Policy, please contact us at: Email: [6ukeem@gmail.com]

    2025년 02월 01일
    Chrome-extension

  • thumbnail for Auth.js(NextAuth) OAuth 로그인 구현 및 세션 관리

    Auth.js(NextAuth) OAuth 로그인 구현 및 세션 관리

    들어가며 최근 본인의 일상을 업로드하는 블로그를 취미로 운영하는 사람이 많아진 것 같다. 개발 블로그는 티스토리나 벨로그를 많이 사용하는 반면 일상은 네이버 블로그를 사용하는 사람이 많다. 개인 일상만 네이버 블로그에 업로드 하는 것은 굉장히 귀찮기 때문에 내가 깃허브에서 팔로우하고 있는 사람만 열람이 가능한 게시글을 따로 만들기로 결정하였다. 이를 위해서 로그인 기능이 필요해졌다. 일반 개발 관련 게시글에 접속할 때는 로그인이 필요하지 않지만, 개인 일상과 관련된 게시글은 로그인하지 않으면 열람할 수 없도록 개발할 것이다. 이전에 로그인 기능 개발 시 Spring Security로 JWT 토큰을 발행하고 관리 했었지만 이번에는 Auth.js라는 간단하게 인증 처리를 할 수 있는 라이브러리가 있어서 사용해보기로 하였다. 초기 설정 Auth.js 설치 환경 설정 auth.ts 파일 생성 route.ts 파일 생성 GitHub APP 설정 (OAuth 설정) 새로운 GitHub App 등록 !GitHub App 등록 > 하단 Webhook은 해제하고 등록 하여준다 등록한 GitHub App 설정 !GitHub App 설정 Client ID와 Secret Key를 복사해서 .env.local 파일에 넣어준다. 예시는 다음과 같다 로그인 테스트 로그인 테스트를 위한 간단한 컴포넌트 !정상적으로 기능하는 것을 볼 수 있다. 세션 관리 Auth.js를 사용하면 아주 간단하게 세션을 관리할 수 있다. 세션 설정 로그인 확인도 매우 쉽게 가능하다 로그인 확인 > 이렇게하면 로그인 여부를 확인할 수 있을 것이다.
    2025년 01월 13일
    Frontend
  • thumbnail for Auth.js(NextAuth) OAuth 로그인 구현 및 세션 관리

    Auth.js(NextAuth) OAuth 로그인 구현 및 세션 관리

    들어가며 최근 본인의 일상을 업로드하는 블로그를 취미로 운영하는 사람이 많아진 것 같다. 개발 블로그는 티스토리나 벨로그를 많이 사용하는 반면 일상은 네이버 블로그를 사용하는 사람이 많다. 개인 일상만 네이버 블로그에 업로드 하는 것은 굉장히 귀찮기 때문에 내가 깃허브에서 팔로우하고 있는 사람만 열람이 가능한 게시글을 따로 만들기로 결정하였다. 이를 위해서 로그인 기능이 필요해졌다. 일반 개발 관련 게시글에 접속할 때는 로그인이 필요하지 않지만, 개인 일상과 관련된 게시글은 로그인하지 않으면 열람할 수 없도록 개발할 것이다. 이전에 로그인 기능 개발 시 Spring Security로 JWT 토큰을 발행하고 관리 했었지만 이번에는 Auth.js라는 간단하게 인증 처리를 할 수 있는 라이브러리가 있어서 사용해보기로 하였다. 초기 설정 Auth.js 설치 환경 설정 auth.ts 파일 생성 route.ts 파일 생성 GitHub APP 설정 (OAuth 설정) 새로운 GitHub App 등록 !GitHub App 등록 > 하단 Webhook은 해제하고 등록 하여준다 등록한 GitHub App 설정 !GitHub App 설정 Client ID와 Secret Key를 복사해서 .env.local 파일에 넣어준다. 예시는 다음과 같다 로그인 테스트 로그인 테스트를 위한 간단한 컴포넌트 !정상적으로 기능하는 것을 볼 수 있다. 세션 관리 Auth.js를 사용하면 아주 간단하게 세션을 관리할 수 있다. 세션 설정 로그인 확인도 매우 쉽게 가능하다 로그인 확인 > 이렇게하면 로그인 여부를 확인할 수 있을 것이다.

    2025년 01월 13일
    Frontend

  • thumbnail for Next.js Type error: Type '*' does not satisfy the constraint '**'. Types of property 'params' are incompatible.

    Next.js Type error: Type '*' does not satisfy the constraint '**'. Types of property 'params' are incompatible.

    해결 방법 바로 궁금하신 분들은 여기를 클릭해주세요. 들어가며 운영중인 정적 블로그는 커스터 마이징에 제약이 있어 블로그를 새로 만들기로 하였다. 요즘 공부하고 있는 Next.js 프레임워크를 활용하여 개발을 시작하였는데 빌드 시에 기존 코드의 매개변수 문법에서 오류가 발생하여 해결 방법을 공유하고자 한다. 에러 메시지 > 오류 메시지를 통해 에러가 발생한 부분을 보아도 이상한 점을 찾지 못했다. 해결방법 !PageProps Type Errors in Next.js #142577 공식 래퍼런스가 궁금하신 분들은 여기를 클릭해주세요. > Next.js 15 업데이트에서 Promise 매개변수를 사용하는 방법이 달라진 것이 문제였다. 해결 방법은 총 두 가지이다. Next.js 버전 다운 그레이드 아래와 같은 방법으로 수정하기 > 다음과 같이 수정하면 정상적으로 빌드가 가능하다
    2024년 12월 23일
    Frontend
  • thumbnail for Next.js Type error: Type '*' does not satisfy the constraint '**'. Types of property 'params' are incompatible.

    Next.js Type error: Type '*' does not satisfy the constraint '**'. Types of property 'params' are incompatible.

    해결 방법 바로 궁금하신 분들은 여기를 클릭해주세요. 들어가며 운영중인 정적 블로그는 커스터 마이징에 제약이 있어 블로그를 새로 만들기로 하였다. 요즘 공부하고 있는 Next.js 프레임워크를 활용하여 개발을 시작하였는데 빌드 시에 기존 코드의 매개변수 문법에서 오류가 발생하여 해결 방법을 공유하고자 한다. 에러 메시지 > 오류 메시지를 통해 에러가 발생한 부분을 보아도 이상한 점을 찾지 못했다. 해결방법 !PageProps Type Errors in Next.js #142577 공식 래퍼런스가 궁금하신 분들은 여기를 클릭해주세요. > Next.js 15 업데이트에서 Promise 매개변수를 사용하는 방법이 달라진 것이 문제였다. 해결 방법은 총 두 가지이다. Next.js 버전 다운 그레이드 아래와 같은 방법으로 수정하기 > 다음과 같이 수정하면 정상적으로 빌드가 가능하다

    2024년 12월 23일
    Frontend

  • thumbnail for Github Readme 배지 만들기 🪪

    Github Readme 배지 만들기 🪪

    들어가며 3학년 2학기가 끝나고 나니, 그동안 진행했던 프로젝트들을 정리하고 싶다는 생각이 들었다. 우연히 다른 사람들의 GitHub Readme를 보게 되었는데, 내 Readme와 비교되어 초라하게 느껴졌다. 특히, Medium, Velog 등 블로그의 최신 글을 표시하는 이미지를 활용한 Readme가 눈에 띄었다. 나도 비슷한 기능을 구현하고 싶어졌다. 나의 미적 감각은 처참하기에 다음의 디자인을 적극 참고하였다. > Velog포스트로Github를꾸며보자 제작 과정 디렉터리 구조 및 역할 각 파일의 역할은 다음과 같다. route.ts : endpoint (컨트롤러의 역할) Badge.tsx : 블로그 최신글의 정보가 담긴 이미지(svg) 파일 반환 코드 구조 route.ts > ContentType 을 설정하지 않으면 이미지가 출력되지 않으니 주의 Badge.tsx > 디자인은 자세히 다루지 않겠지만 여기에서 전체 코드를 볼 수 있다. 배포 및 확인 \/api/badge?width=360&height=130으로 접속하면 이미지가 잘 반환되는 것을 볼 수 있다. > 이로써 게시글 업로드 시 Github Readme에 최신글이 표시될 것이다. 🤩
    2024년 12월 22일
    Frontend
  • thumbnail for Github Readme 배지 만들기 🪪

    Github Readme 배지 만들기 🪪

    들어가며 3학년 2학기가 끝나고 나니, 그동안 진행했던 프로젝트들을 정리하고 싶다는 생각이 들었다. 우연히 다른 사람들의 GitHub Readme를 보게 되었는데, 내 Readme와 비교되어 초라하게 느껴졌다. 특히, Medium, Velog 등 블로그의 최신 글을 표시하는 이미지를 활용한 Readme가 눈에 띄었다. 나도 비슷한 기능을 구현하고 싶어졌다. 나의 미적 감각은 처참하기에 다음의 디자인을 적극 참고하였다. > Velog포스트로Github를꾸며보자 제작 과정 디렉터리 구조 및 역할 각 파일의 역할은 다음과 같다. route.ts : endpoint (컨트롤러의 역할) Badge.tsx : 블로그 최신글의 정보가 담긴 이미지(svg) 파일 반환 코드 구조 route.ts > ContentType 을 설정하지 않으면 이미지가 출력되지 않으니 주의 Badge.tsx > 디자인은 자세히 다루지 않겠지만 여기에서 전체 코드를 볼 수 있다. 배포 및 확인 \/api/badge?width=360&height=130으로 접속하면 이미지가 잘 반환되는 것을 볼 수 있다. > 이로써 게시글 업로드 시 Github Readme에 최신글이 표시될 것이다. 🤩

    2024년 12월 22일
    Frontend

  • thumbnail for AWS 스프링부트, Swagger-ui 연동

    AWS 스프링부트, Swagger-ui 연동

    build.gradle 의존성 추가 application.yml 파일 수정 하단에 해당 부분을 추가하여준다. SwaggerConfig 클래스 생성 !접속 성공
    2024년 10월 18일
    Backend
  • thumbnail for AWS 스프링부트, Swagger-ui 연동

    AWS 스프링부트, Swagger-ui 연동

    build.gradle 의존성 추가 application.yml 파일 수정 하단에 해당 부분을 추가하여준다. SwaggerConfig 클래스 생성 !접속 성공

    2024년 10월 18일
    Backend

  • thumbnail for AWS SpringBoot, MariaDB 연결하기

    AWS SpringBoot, MariaDB 연결하기

    패키지 설치 설치 가능한 mariadb 패키지 검색 Mariadb 설치 Mariadb 실행 Mariadb root 비밀번호 설정 로그인 확인 그 외 설정 Docker 이미지 다운로드 DB 생성 및 사용자 설정 SpringBoot 프로젝트 설정 build.gradle 의존성 추가 application.yml, applicationlocal.yml 파일 생성 src/main/resources/application.yml src/main/resources/applicationlocal.yml dockercompose.yml 수정 !🔥 dbeaver 접속 성공
    2024년 10월 15일
    Backend
  • thumbnail for AWS SpringBoot, MariaDB 연결하기

    AWS SpringBoot, MariaDB 연결하기

    패키지 설치 설치 가능한 mariadb 패키지 검색 Mariadb 설치 Mariadb 실행 Mariadb root 비밀번호 설정 로그인 확인 그 외 설정 Docker 이미지 다운로드 DB 생성 및 사용자 설정 SpringBoot 프로젝트 설정 build.gradle 의존성 추가 application.yml, applicationlocal.yml 파일 생성 src/main/resources/application.yml src/main/resources/applicationlocal.yml dockercompose.yml 수정 !🔥 dbeaver 접속 성공

    2024년 10월 15일
    Backend

  • thumbnail for AWS EC2 docker, docker-compose 설치

    AWS EC2 docker, docker-compose 설치

    Docker란? Docker는 애플리케이션을 실행할 수 있는 가벼운 가상화 환경인 컨테이너를 생성하는 도구이다. 컨테이너는 시스템의 전체 운영체제를 복제하는 대신, 필요한 부분만 분리하여 애플리케이션을 격리된 환경에서 실행할 수 있게 한다. 이를 통해 개발 환경과 배포 환경의 일관성을 유지하고, 리소스를 효율적으로 사용할 수 있다. Docker는 개별 컨테이너를 만들고 실행하는 데 사용되며, 주로 하나의 애플리케이션 또는 서비스를 컨테이너화할 때 활용된다. 반면에 Docker Compose는 여러 컨테이너를 정의하고 관리할 수 있는 도구로, 복잡한 애플리케이션에서 여러 서비스(예: 웹 서버, 데이터베이스 등)를 한 번에 설정하고 실행할 수 있도록 도와준다. Docker Compose를 사용하면 dockercompose.yml 파일에서 설정을 정의하고, 한 명령어로 여러 컨테이너를 일괄적으로 관리할 수 있다. Docker 설치 방법 yum update install docker service docker grant permission to ec2user Docker service start and enable automatic startup Dockercompose 설치 방법 yum에는 기본적으로 Docker Compose 패키지가 없기 때문에, 직접 바이너리를 다운로드하여 설치해야 한다. Dockercompose 바이너리 파일 다운로드 실행 권한 부여 설치 확인 !설치 성공 ✨
    2024년 10월 09일
    Backend
  • thumbnail for AWS EC2 docker, docker-compose 설치

    AWS EC2 docker, docker-compose 설치

    Docker란? Docker는 애플리케이션을 실행할 수 있는 가벼운 가상화 환경인 컨테이너를 생성하는 도구이다. 컨테이너는 시스템의 전체 운영체제를 복제하는 대신, 필요한 부분만 분리하여 애플리케이션을 격리된 환경에서 실행할 수 있게 한다. 이를 통해 개발 환경과 배포 환경의 일관성을 유지하고, 리소스를 효율적으로 사용할 수 있다. Docker는 개별 컨테이너를 만들고 실행하는 데 사용되며, 주로 하나의 애플리케이션 또는 서비스를 컨테이너화할 때 활용된다. 반면에 Docker Compose는 여러 컨테이너를 정의하고 관리할 수 있는 도구로, 복잡한 애플리케이션에서 여러 서비스(예: 웹 서버, 데이터베이스 등)를 한 번에 설정하고 실행할 수 있도록 도와준다. Docker Compose를 사용하면 dockercompose.yml 파일에서 설정을 정의하고, 한 명령어로 여러 컨테이너를 일괄적으로 관리할 수 있다. Docker 설치 방법 yum update install docker service docker grant permission to ec2user Docker service start and enable automatic startup Dockercompose 설치 방법 yum에는 기본적으로 Docker Compose 패키지가 없기 때문에, 직접 바이너리를 다운로드하여 설치해야 한다. Dockercompose 바이너리 파일 다운로드 실행 권한 부여 설치 확인 !설치 성공 ✨

    2024년 10월 09일
    Backend

  • thumbnail for AWS EC2 생성 및 접속

    AWS EC2 생성 및 접속

    들어가며 교내 팀 프로젝트를 통해 백엔드 개발 다수 존재하지만, 환경 구축이나 배포 경험은 부족하다. 이번 학기에는 "다우기술"의 사내 문제를 해결하는 해커톤 형태의 과목을 수강하게 되었고, 팀원들과 역할을 분담하여 초기 백엔드 환경 구축 및 배포를 맡게 되었다. AWS란? AWS(Amazon Web Services)는 클라우드 컴퓨팅을 통해 다양한 서비스를 제공하는 플랫폼으로, 전 세계적으로 사용되는 안전하고 확장 가능한 인프라를 제공한다. 이를 통해 사용자는 서버 자원을 유연하게 조정하고 관리할 수 있으며, 초기 비용 없이 필요한 만큼만 비용을 지불할 수 있다. 본 글에서는 EC2를 사용하여 진행할 것이다. EC2 인스턴스 생성 및 설정 보안 규칙은 다음과 같이 설정해둔다 !보안 규칙 EC2 Instance Console에 접속 인스턴스 생성 시 발급 받은 pem 키가 있을 것이다. 해당 명령어로 권한을 변경하여 준다. !접속 성공 🤩
    2024년 10월 08일
    Backend
  • thumbnail for AWS EC2 생성 및 접속

    AWS EC2 생성 및 접속

    들어가며 교내 팀 프로젝트를 통해 백엔드 개발 다수 존재하지만, 환경 구축이나 배포 경험은 부족하다. 이번 학기에는 "다우기술"의 사내 문제를 해결하는 해커톤 형태의 과목을 수강하게 되었고, 팀원들과 역할을 분담하여 초기 백엔드 환경 구축 및 배포를 맡게 되었다. AWS란? AWS(Amazon Web Services)는 클라우드 컴퓨팅을 통해 다양한 서비스를 제공하는 플랫폼으로, 전 세계적으로 사용되는 안전하고 확장 가능한 인프라를 제공한다. 이를 통해 사용자는 서버 자원을 유연하게 조정하고 관리할 수 있으며, 초기 비용 없이 필요한 만큼만 비용을 지불할 수 있다. 본 글에서는 EC2를 사용하여 진행할 것이다. EC2 인스턴스 생성 및 설정 보안 규칙은 다음과 같이 설정해둔다 !보안 규칙 EC2 Instance Console에 접속 인스턴스 생성 시 발급 받은 pem 키가 있을 것이다. 해당 명령어로 권한을 변경하여 준다. !접속 성공 🤩

    2024년 10월 08일
    Backend