<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>애플자라</title>
    <link>https://applejara.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 1 Jun 2026 00:42:09 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>애플자라</managingEditor>
    <image>
      <title>애플자라</title>
      <url>https://tistory1.daumcdn.net/tistory/33508/attach/9ea5e9c4f3e542f8a082c18d189902f4</url>
      <link>https://applejara.tistory.com</link>
    </image>
    <item>
      <title>[Telegram]내 PC에서 돌리는 Telegram 알림 스케줄러 만들기 (Node.js + React + SQLite)</title>
      <link>https://applejara.tistory.com/693</link>
      <description>&lt;div style=&quot;background-color: #121314; color: #bbbebf;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;# 들어가며&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;&quot;매일 아침 9시에 팀원들에게 데일리 스크럼 알림 보내기&quot;, &quot;매주 금요일 주간보고 리마인더&quot; &amp;mdash; 이런 반복 알림, 어떻게 처리하고 계신가요?&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;별도 서버 없이, &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;**내 PC에서 직접 돌리는 Telegram 알림 스케줄러**&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;를 만들어 보았습니다. 클라우드 비용 0원, DB 서버 설치 0건. Node.js와 SQLite만으로 충분합니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 이런 걸 만들었습니다&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 기능 | 설명 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;|------|------|&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 알림 CRUD | 등록 / 수정 / 삭제 / 테스트 발송 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 반복 유형 | 1회, 매시, 매일, 매주, 매월, 매년 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 캘린더 뷰 | 주간 / 월간 / 연간 시각화 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 실행 로그 | 발송 성공/실패 이력 조회 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 자동 복원 | 앱 재시작 시 활성 스케줄 자동 등록 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 다수 수신자 | Chat ID 콤마 구분으로 다중 전송 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| 보안 헤더 | XSS, Clickjacking 등 기본 방어 적용 |&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 기술 스택&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;Frontend : React 19 + Vite&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;Backend &amp;nbsp;: Node.js + Express&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;Database : SQLite (better-sqlite3)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;Scheduler: node-cron&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;API 통신 &amp;nbsp;: axios&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7ee787;&quot;&gt; SQLite를 선택한 이유 &amp;mdash; MySQL이나 PostgreSQL 같은 외부 DB 없이 &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`.db`&lt;/span&gt;&lt;span style=&quot;color: #7ee787;&quot;&gt; 파일 하나로 끝. 로컬 용도에는 이게 최고입니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 프로젝트 구조&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;telegram-schedule/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;├── server/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── index.js &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 서버 진입점&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── controllers/ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 요청 처리 (유효성 검증)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── routes/ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # REST API 라우팅&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── services/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; ├── telegramReminderService.js &amp;nbsp;# DB CRUD&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; └── telegramService.js &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# Telegram API 연동&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── scheduler/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; └── telegramReminderScheduler.js # cron 기반 스케줄링&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── db/sqlite.js &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# SQLite 연결 &amp;amp; 테이블 초기화&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; └── lib/ &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;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;├── client/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; ├── src/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; ├── pages/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; │ &amp;nbsp; └── TelegramReminderAdminPage.jsx &amp;nbsp;# 메인 관리 화면&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; └── components/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── TelegramReminderForm.jsx &amp;nbsp; # 등록/수정 폼&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── TelegramReminderList.jsx &amp;nbsp; # 목록 테이블&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── CalendarView.jsx &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 캘린더 시각화&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── LogModal.jsx &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 실행 로그 모달&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; │ &amp;nbsp; &amp;nbsp; &amp;nbsp; └── Toast.jsx &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 알림 토스트&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;│ &amp;nbsp; └── dist/ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 프로덕션 빌드&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;├── db/telegram_reminders.db &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# SQLite DB 파일 (자동 생성)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;├── logs/ &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;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;└── .env &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;# Bot Token 설정&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 핵심 설계 포인트&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 1. Cron 표현식 자동 생성&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;반복 유형에 따라 cron 표현식을 동적으로 빌드합니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```javascript&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;buildCronExpression&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;reminder&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; reminder.time_value.&lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;':'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(Number);&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; (reminder.repeat_type) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'hourly'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;// 매시 정각 ~ 지정 시간대까지&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;startHour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;endHour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; * * *`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'daily'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; * * *`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'weekly'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; * * &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;weekday&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'monthly'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;day&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; * *`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'yearly'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;day&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;month&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; *`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'once'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;// 매일 체크하되, 날짜 일치 시에만 실행&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt; * * *`&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`once`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;(1회) 타입이 재미있는데요 &amp;mdash; cron 자체는 매일 해당 시각에 트리거되지만, 실행 시점에 날짜를 비교해서 해당일에만 발송하고 자동 비활성화합니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 2. 실패 시 지수 백오프 재시도&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;네트워크 불안정에 대비해 최대 3회 재시도하며, 대기 시간을 1초 &amp;rarr; 2초 &amp;rarr; 4초로 늘려갑니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```javascript&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;attempt&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;attempt&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &amp;lt;= &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;maxRetries&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;attempt&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++) &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;sendTelegramMessage&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(chatId, formattedMsg);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; (result.success) &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;// 지수 백오프: 2^(attempt-1) * 1000ms&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;delayMs&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; Math.&lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;, attempt &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Promise&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;setTimeout&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(resolve, delayMs));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 3. 중복 실행 방지&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`executingJobs`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; Set으로 동일 알림이 동시에 두 번 실행되는 것을 방지합니다. cron이 1분 간격이라 거의 발생하지 않지만, 전송 지연 시 다음 트리거와 겹칠 수 있어 방어 코드를 넣었습니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 4. 앱 재시작 시 자동 복원&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;서버가 시작되면 DB에서 활성 상태인 알림을 모두 읽어와 cron job을 재등록합니다. 만료된 1회성 알림은 자동으로 비활성화 처리합니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```javascript&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;restoreAllJobs&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;activeReminders&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; reminderService.&lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;getActiveReminders&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #ff7b72;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;reminder&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; activeReminders) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; (reminder.repeat_type &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;'once'&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; reminder.date_value &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt; today) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; reminderService.&lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;deactivateReminder&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(reminder.id);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;continue&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #d2a8ff;&quot;&gt;registerJob&lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;(reminder);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## API 설계&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;RESTful하게 구성했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| Method | Endpoint | 설명 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;|--------|----------|------|&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| GET | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 전체 목록 조회 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| POST | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 알림 등록 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| GET | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/:id`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 단건 조회 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| PUT | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/:id`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 수정 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| DELETE | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/:id`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 삭제 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| PATCH | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/:id/active`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 활성/비활성 토글 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| POST | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/test-send`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 테스트 발송 |&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;| GET | &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`/api/telegram-reminders/:id/logs`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; | 실행 로그 조회 |&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 실행 방법&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 사전 준비&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;**Node.js 18+**&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; 설치&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; Telegram에서 [&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;@BotFather&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;](&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;&lt;a href=&quot;https://t.me/BotFather&quot;&gt;https://t.me/BotFather&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;)로 봇 생성 &amp;rarr; Bot Token 발급&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;@userinfobot&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;](&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;&lt;a href=&quot;https://t.me/userinfobot&quot;&gt;https://t.me/userinfobot&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;)에게 메시지 &amp;rarr; 내 Chat ID 확인&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;### 설치 &amp;amp; 실행&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```bash&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# 1. 의존성 설치 (서버 + 클라이언트 한 번에)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;setup&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# 2. 환경 설정&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# .env 파일에 Bot Token 입력&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;TELEGRAM_BOT_TOKEN&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;your_bot_token_here&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;3001&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# 3-A. 프로덕션 모드&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;build&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;start&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# &amp;rarr; http://localhost:3001&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# 3-B. 개발 모드 (핫 리로드)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a5d6ff;&quot;&gt;dev&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;# &amp;rarr; http://localhost:5173&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;```&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## Google 캘린더에서 영감을 받다&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;반복 유형 설계 시 Google 캘린더의 일정 반복 옵션을 참고했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #7ee787;&quot;&gt; 1회 / 매시 / 매일 / 매주 / 매월 / 매년 &amp;mdash; 실무에서 쓰이는 대부분의 반복 패턴을 커버합니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;캘린더 뷰도 주간&amp;middot;월간&amp;middot;연간 모드를 제공해서, 등록된 알림을 시각적으로 확인할 수 있습니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 주의사항&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c9d1d9;&quot;&gt;**로컬 전용**&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;입니다. PC가 켜져 있고 앱이 실행 중일 때만 알림이 발송됩니다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; PC 종료 시 알림이 밀리지만, 재시작하면 활성 스케줄이 자동 복원됩니다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffa657;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; 보안상 &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`.env`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; 파일의 Bot Token은 절대 외부에 노출하지 마세요.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;---&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;## 마치며&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;&quot;서버 없이 내 PC에서 Telegram 알림을 자동화하고 싶다&quot;는 단순한 니즈에서 시작한 프로젝트입니다. SQLite 덕분에 별도 DB 설치가 필요 없고, &lt;/span&gt;&lt;span style=&quot;color: #79c0ff;&quot;&gt;`npm run setup`&lt;/span&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt; 한 줄이면 바로 사용할 수 있습니다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;개인 리마인더, 팀 알림, 정기 보고 리마인더 등 다양하게 활용해 보세요.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #bbbebf;&quot;&gt;소스 코드는 GitHub에서 확인할 수 있습니다.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Programing</category>
      <category>Express</category>
      <category>node-cron</category>
      <category>node.js</category>
      <category>React</category>
      <category>sqlite</category>
      <category>telegram</category>
      <category>사이드프로젝트</category>
      <category>스케줄러</category>
      <category>알림자동화</category>
      <category>텔레그램봇</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/693</guid>
      <comments>https://applejara.tistory.com/693#entry693comment</comments>
      <pubDate>Tue, 7 Apr 2026 16:02:41 +0900</pubDate>
    </item>
    <item>
      <title>Outlook &amp;harr; Google Calendar 양방향 동기화 구현 (실사용 후기 + 삽질 정리)</title>
      <link>https://applejara.tistory.com/692</link>
      <description>&lt;p data-end=&quot;197&quot; data-start=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;최근에&lt;br /&gt;  &lt;b&gt;Outlook Calendar + Google Calendar 양방향 동기화&lt;/b&gt;를 직접 구현해봤습니다.&lt;/p&gt;
&lt;p data-end=&quot;208&quot; data-start=&quot;199&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면:&lt;/p&gt;
&lt;blockquote data-end=&quot;257&quot; data-start=&quot;210&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;257&quot; data-start=&quot;212&quot; data-ke-size=&quot;size16&quot;&gt;✔️ 구현 가능&lt;br /&gt;❗ 하지만 인증(OAuth) + 권한 설정에서 대부분 막힘&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;282&quot; data-start=&quot;259&quot; data-ke-size=&quot;size16&quot;&gt;특히 Microsoft 쪽이 까다롭습니다.&lt;/p&gt;
&lt;hr data-end=&quot;287&quot; data-start=&quot;284&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;299&quot; data-start=&quot;289&quot; data-section-id=&quot;1lr6spj&quot;&gt;  전체 구조&lt;/h1&gt;
&lt;p data-end=&quot;314&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;구현 방식은 간단합니다:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;Google Calendar API&lt;/span&gt;&lt;br /&gt;&lt;span&gt; ↕&lt;/span&gt;&lt;br /&gt;&lt;span&gt; Sync Script (Python)&lt;/span&gt;&lt;br /&gt;&lt;span&gt; ↕&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Microsoft Graph API (Outlook)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;422&quot; data-start=&quot;419&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;437&quot; data-start=&quot;424&quot; data-section-id=&quot;1qlkvu4&quot;&gt;  핵심 기술 스택&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;520&quot; data-start=&quot;439&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;447&quot; data-start=&quot;439&quot; data-section-id=&quot;2q6buk&quot;&gt;Python&lt;/li&gt;
&lt;li data-end=&quot;469&quot; data-start=&quot;448&quot; data-section-id=&quot;jjz9zf&quot;&gt;Google Calendar API&lt;/li&gt;
&lt;li data-end=&quot;491&quot; data-start=&quot;470&quot; data-section-id=&quot;yh8i7c&quot;&gt;Microsoft Graph API&lt;/li&gt;
&lt;li data-end=&quot;503&quot; data-start=&quot;492&quot; data-section-id=&quot;30qsir&quot;&gt;OAuth 2.0&lt;/li&gt;
&lt;li data-end=&quot;520&quot; data-start=&quot;504&quot; data-section-id=&quot;15do213&quot;&gt;SQLite (ID 매핑)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;525&quot; data-start=&quot;522&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;548&quot; data-start=&quot;527&quot; data-section-id=&quot;kzbsk&quot;&gt;⚠️ 가장 많이 막히는 문제 3가지&lt;/h1&gt;
&lt;hr data-end=&quot;553&quot; data-start=&quot;550&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;592&quot; data-start=&quot;555&quot; data-section-id=&quot;82xduc&quot; data-ke-size=&quot;size26&quot;&gt;1️⃣ Google 로그인 &amp;rarr; 403 access_denied&lt;/h2&gt;
&lt;h3 data-end=&quot;600&quot; data-start=&quot;594&quot; data-section-id=&quot;1hrqn3i&quot; data-ke-size=&quot;size23&quot;&gt;원인&lt;/h3&gt;
&lt;p data-end=&quot;628&quot; data-start=&quot;601&quot; data-ke-size=&quot;size16&quot;&gt;  앱이 &amp;ldquo;테스트 모드&amp;rdquo;인데 사용자 등록 안 함&lt;/p&gt;
&lt;h3 data-end=&quot;636&quot; data-start=&quot;630&quot; data-section-id=&quot;1hrnhqa&quot; data-ke-size=&quot;size23&quot;&gt;해결&lt;/h3&gt;
&lt;p data-end=&quot;663&quot; data-start=&quot;637&quot; data-ke-size=&quot;size16&quot;&gt;  Google Cloud Console에서:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;OAuth 동의 화면 &amp;rarr; 테스트 사용자 추가&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;702&quot; data-start=&quot;699&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;734&quot; data-start=&quot;704&quot; data-section-id=&quot;51a6kx&quot; data-ke-size=&quot;size26&quot;&gt;2️⃣ Outlook 로그인 &amp;rarr; 관리자 승인 필요&lt;/h2&gt;
&lt;h3 data-end=&quot;742&quot; data-start=&quot;736&quot; data-section-id=&quot;1hrqdx6&quot; data-ke-size=&quot;size23&quot;&gt;에러&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;관리자 승인 필요&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;768&quot; data-start=&quot;762&quot; data-section-id=&quot;1hrqn3i&quot; data-ke-size=&quot;size23&quot;&gt;원인&lt;/h3&gt;
&lt;p data-end=&quot;806&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;  회사 계정은 IT 정책 때문에&lt;br /&gt;  앱이 캘린더 접근 못함&lt;/p&gt;
&lt;hr data-end=&quot;811&quot; data-start=&quot;808&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;824&quot; data-start=&quot;813&quot; data-section-id=&quot;vflgk4&quot; data-ke-size=&quot;size26&quot;&gt;  핵심 결론&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;방식가능 여부
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;917&quot; data-start=&quot;826&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;917&quot; data-start=&quot;861&quot;&gt;
&lt;tr data-end=&quot;885&quot; data-start=&quot;861&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;877&quot; data-start=&quot;861&quot;&gt;개인 Outlook 계정&lt;/td&gt;
&lt;td data-end=&quot;885&quot; data-start=&quot;877&quot; data-col-size=&quot;sm&quot;&gt;✅ 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;917&quot; data-start=&quot;886&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;902&quot; data-start=&quot;886&quot;&gt;회사 Outlook 계정&lt;/td&gt;
&lt;td data-end=&quot;917&quot; data-start=&quot;902&quot; data-col-size=&quot;sm&quot;&gt;❌ 관리자 승인 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;922&quot; data-start=&quot;919&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;934&quot; data-start=&quot;924&quot; data-section-id=&quot;8w736g&quot; data-ke-size=&quot;size26&quot;&gt;✅ 해결 방법&lt;/h2&gt;
&lt;h3 data-end=&quot;952&quot; data-start=&quot;936&quot; data-section-id=&quot;r60ard&quot; data-ke-size=&quot;size23&quot;&gt;✔️ 방법 1 (추천)&lt;/h3&gt;
&lt;p data-end=&quot;974&quot; data-start=&quot;953&quot; data-ke-size=&quot;size16&quot;&gt;  개인 Microsoft 계정 사용&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;994&quot; data-start=&quot;976&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;983&quot; data-start=&quot;976&quot; data-section-id=&quot;8f9q94&quot;&gt;바로 동작&lt;/li&gt;
&lt;li data-end=&quot;994&quot; data-start=&quot;984&quot; data-section-id=&quot;63zrzr&quot;&gt;추가 승인 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;999&quot; data-start=&quot;996&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1011&quot; data-start=&quot;1001&quot; data-section-id=&quot;1b18dg&quot; data-ke-size=&quot;size23&quot;&gt;❌ 방법 2&lt;/h3&gt;
&lt;p data-end=&quot;1023&quot; data-start=&quot;1012&quot; data-ke-size=&quot;size16&quot;&gt;  회사 계정 사용&lt;/p&gt;
&lt;p data-end=&quot;1028&quot; data-start=&quot;1025&quot; data-ke-size=&quot;size16&quot;&gt;필요:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1037&quot; data-start=&quot;1029&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1037&quot; data-start=&quot;1029&quot; data-section-id=&quot;iuswgl&quot;&gt;관리자 승인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1039&quot; data-ke-size=&quot;size16&quot;&gt;  현실적으로 어려움&lt;/p&gt;
&lt;hr data-end=&quot;1056&quot; data-start=&quot;1053&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1073&quot; data-start=&quot;1058&quot; data-section-id=&quot;1ypxb8t&quot;&gt;⚠️ 중요한 설정 포인트&lt;/h1&gt;
&lt;hr data-end=&quot;1078&quot; data-start=&quot;1075&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1105&quot; data-start=&quot;1080&quot; data-section-id=&quot;1o99sxw&quot; data-ke-size=&quot;size26&quot;&gt;1️⃣ Azure 앱 등록 시 계정 유형&lt;/h2&gt;
&lt;p data-end=&quot;1114&quot; data-start=&quot;1107&quot; data-ke-size=&quot;size16&quot;&gt;  반드시:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;모든 Entra ID 테넌트 + 개인 Microsoft 계정&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1162&quot; data-start=&quot;1159&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1183&quot; data-start=&quot;1164&quot; data-section-id=&quot;igv03z&quot; data-ke-size=&quot;size26&quot;&gt;2️⃣ Redirect URI&lt;/h2&gt;
&lt;p data-end=&quot;1202&quot; data-start=&quot;1185&quot; data-ke-size=&quot;size16&quot;&gt;  반드시 코드와 동일해야 함&lt;/p&gt;
&lt;p data-end=&quot;1206&quot; data-start=&quot;1204&quot; data-ke-size=&quot;size16&quot;&gt;예:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;http://localhost&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1236&quot; data-start=&quot;1234&quot; data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;http://localhost:8400&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1272&quot; data-start=&quot;1269&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1299&quot; data-start=&quot;1274&quot; data-section-id=&quot;l2u3gy&quot; data-ke-size=&quot;size26&quot;&gt;3️⃣ MSAL 오류 (진짜 많이 걸림)&lt;/h2&gt;
&lt;h3 data-end=&quot;1307&quot; data-start=&quot;1301&quot; data-section-id=&quot;1hrqdx6&quot; data-ke-size=&quot;size23&quot;&gt;에러&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;You cannot use any scope value that is reserved&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1371&quot; data-start=&quot;1365&quot; data-section-id=&quot;1hrqn3i&quot; data-ke-size=&quot;size23&quot;&gt;원인&lt;/h3&gt;
&lt;p data-end=&quot;1404&quot; data-start=&quot;1372&quot; data-ke-size=&quot;size16&quot;&gt;  scope에 offline_access 직접 넣음&lt;/p&gt;
&lt;h3 data-end=&quot;1412&quot; data-start=&quot;1406&quot; data-section-id=&quot;1hrnhqa&quot; data-ke-size=&quot;size23&quot;&gt;해결&lt;/h3&gt;
&lt;p data-end=&quot;1422&quot; data-start=&quot;1414&quot; data-ke-size=&quot;size16&quot;&gt;❌ 잘못된 코드&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;Calendars.ReadWrite&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;offline_access&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1484&quot; data-start=&quot;1480&quot; data-ke-size=&quot;size16&quot;&gt;✅ 수정&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;Calendars.ReadWrite&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1527&quot; data-start=&quot;1524&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1544&quot; data-start=&quot;1529&quot; data-section-id=&quot;1iprga&quot;&gt;  현실적인 사용 방법&lt;/h1&gt;
&lt;p data-end=&quot;1559&quot; data-start=&quot;1546&quot; data-ke-size=&quot;size16&quot;&gt;  대부분 이렇게 씀:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1589&quot; data-start=&quot;1561&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1574&quot; data-start=&quot;1561&quot; data-section-id=&quot;1c03pk4&quot;&gt;Google (개인)&lt;/li&gt;
&lt;li data-end=&quot;1589&quot; data-start=&quot;1575&quot; data-section-id=&quot;18o8zt0&quot;&gt;Outlook (개인)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1608&quot; data-start=&quot;1591&quot; data-ke-size=&quot;size16&quot;&gt;  개인 일정 통합용으로 사용&lt;/p&gt;
&lt;hr data-end=&quot;1613&quot; data-start=&quot;1610&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1633&quot; data-start=&quot;1615&quot; data-section-id=&quot;12pbs77&quot; data-ke-size=&quot;size26&quot;&gt;회사 캘린더까지 쓰고 싶다면&lt;/h2&gt;
&lt;p data-end=&quot;1644&quot; data-start=&quot;1635&quot; data-ke-size=&quot;size16&quot;&gt;  방법 3가지&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1694&quot; data-start=&quot;1646&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1658&quot; data-start=&quot;1646&quot; data-section-id=&quot;lusw7y&quot;&gt;관리자 승인 요청&lt;/li&gt;
&lt;li data-end=&quot;1679&quot; data-start=&quot;1659&quot; data-section-id=&quot;1hythmf&quot;&gt;회사 캘린더 &amp;rarr; 개인 계정 공유&lt;/li&gt;
&lt;li data-end=&quot;1694&quot; data-start=&quot;1680&quot; data-section-id=&quot;1iuem98&quot;&gt;별도 중간 서버 구축&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1699&quot; data-start=&quot;1696&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1712&quot; data-start=&quot;1701&quot; data-section-id=&quot;1lyhksa&quot;&gt;  한 줄 정리&lt;/h1&gt;
&lt;blockquote data-end=&quot;1789&quot; data-start=&quot;1714&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1789&quot; data-start=&quot;1716&quot; data-ke-size=&quot;size16&quot;&gt;Outlook + Google 완전 동기화는 가능하지만&lt;br /&gt;Microsoft 권한 정책 때문에 개인 계정 기반이 가장 현실적이다&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>Tips</category>
      <category>#API연동</category>
      <category>#GoogleAPI</category>
      <category>#GoogleCalendar</category>
      <category>#MicrosoftGraphAPI</category>
      <category>#OAuth</category>
      <category>#OutlookCalendar</category>
      <category>#Python자동화</category>
      <category>#개발삽질</category>
      <category>#자동화프로젝트</category>
      <category>#캘린더동기화</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/692</guid>
      <comments>https://applejara.tistory.com/692#entry692comment</comments>
      <pubDate>Wed, 1 Apr 2026 13:42:32 +0900</pubDate>
    </item>
    <item>
      <title>[Cloud]Oracle Cloud 무료 서버 만들고 SSH 접속까지</title>
      <link>https://applejara.tistory.com/691</link>
      <description>&lt;p data-end=&quot;185&quot; data-start=&quot;116&quot; data-ke-size=&quot;size16&quot;&gt;이번에 Oracle Cloud 무료 서버를 처음부터 만들어서&lt;br /&gt;  &lt;b&gt;SSH 접속 + Node.js 설치까지&lt;/b&gt; 해봤다.&lt;/p&gt;
&lt;p data-end=&quot;209&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;완전 처음 하는 사람 기준으로 정리한다.&lt;/p&gt;
&lt;hr data-end=&quot;214&quot; data-start=&quot;211&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;244&quot; data-start=&quot;216&quot; data-section-id=&quot;1bd8e40&quot;&gt;☁️ 1. Oracle Cloud 인스턴스 생성&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;305&quot; data-start=&quot;246&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;265&quot; data-start=&quot;246&quot; data-section-id=&quot;17c85im&quot;&gt;Oracle Cloud 가입 후&lt;/li&gt;
&lt;li data-end=&quot;305&quot; data-start=&quot;266&quot; data-section-id=&quot;10efwui&quot;&gt;Compute &amp;rarr; Instances &amp;rarr; Create Instance&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;319&quot; data-start=&quot;307&quot; data-ke-size=&quot;size16&quot;&gt;  Ubuntu 선택&lt;/p&gt;
&lt;p data-end=&quot;345&quot; data-start=&quot;321&quot; data-ke-size=&quot;size16&quot;&gt;  Public Subnet 생성 (중요)&lt;/p&gt;
&lt;p data-end=&quot;360&quot; data-start=&quot;347&quot; data-ke-size=&quot;size16&quot;&gt;  인스턴스 생성 완료&lt;/p&gt;
&lt;hr data-end=&quot;365&quot; data-start=&quot;362&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;392&quot; data-start=&quot;367&quot; data-section-id=&quot;1ipo5rq&quot;&gt;  2. Public IP 연결 (핵심)&lt;/h1&gt;
&lt;p data-end=&quot;408&quot; data-start=&quot;394&quot; data-ke-size=&quot;size16&quot;&gt;처음 만들면 접속 안됨 ❗&lt;/p&gt;
&lt;p data-end=&quot;416&quot; data-start=&quot;410&quot; data-ke-size=&quot;size16&quot;&gt;  이유:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;431&quot; data-start=&quot;417&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;431&quot; data-start=&quot;417&quot; data-section-id=&quot;jzbwze&quot;&gt;Public IP 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;442&quot; data-start=&quot;433&quot; data-section-id=&quot;beu0am&quot; data-ke-size=&quot;size23&quot;&gt;해결 방법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;542&quot; data-start=&quot;444&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;482&quot; data-start=&quot;444&quot; data-section-id=&quot;7ver33&quot;&gt;Instance &amp;rarr; Networking &amp;rarr; VNIC 들어가기&lt;/li&gt;
&lt;li data-end=&quot;502&quot; data-start=&quot;483&quot; data-section-id=&quot;155173p&quot;&gt;IPv4 &amp;rarr; Edit 클릭&lt;/li&gt;
&lt;li data-end=&quot;532&quot; data-start=&quot;503&quot; data-section-id=&quot;15yoac2&quot;&gt;&lt;b&gt;Ephemeral Public IP 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;542&quot; data-start=&quot;533&quot; data-section-id=&quot;17w6vi&quot;&gt;Update&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;559&quot; data-start=&quot;544&quot; data-ke-size=&quot;size16&quot;&gt;  그러면 이런 IP 생김&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;xxx.xxx.xxx.xxx&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;589&quot; data-start=&quot;586&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;621&quot; data-start=&quot;591&quot; data-section-id=&quot;1fjc85l&quot;&gt;  3. SSH 접속 프로그램 (Tabby 사용)&lt;/h1&gt;
&lt;p data-end=&quot;657&quot; data-start=&quot;623&quot; data-ke-size=&quot;size16&quot;&gt;Putty 대신 &lt;b&gt;Tabby 추천 (무료 + UI 좋음)&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;662&quot; data-start=&quot;659&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;677&quot; data-start=&quot;664&quot; data-section-id=&quot;1gltnax&quot; data-ke-size=&quot;size26&quot;&gt;Tabby 다운로드&lt;/h2&gt;
&lt;p data-end=&quot;697&quot; data-start=&quot;678&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://tabby.sh&quot;&gt;https://tabby.sh&lt;/a&gt;&lt;/p&gt;
&lt;hr data-end=&quot;702&quot; data-start=&quot;699&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;718&quot; data-start=&quot;704&quot; data-section-id=&quot;wvja90&quot; data-ke-size=&quot;size26&quot;&gt;Tabby 설정 방법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;774&quot; data-start=&quot;720&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;756&quot; data-start=&quot;720&quot; data-section-id=&quot;14ohoba&quot;&gt;Settings &amp;rarr; Profiles &amp;amp; connections&lt;/li&gt;
&lt;li data-end=&quot;774&quot; data-start=&quot;757&quot; data-section-id=&quot;6qx8te&quot;&gt;New profile 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-end=&quot;783&quot; data-start=&quot;776&quot; data-section-id=&quot;1xoakus&quot; data-ke-size=&quot;size23&quot;&gt;입력값&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;Name: oracle-server&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Host: xxx.xxx.xxx.xxx&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Port: 22&lt;/span&gt;&lt;br /&gt;&lt;span&gt;User: ubuntu&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Auth: private key&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;902&quot; data-start=&quot;876&quot; data-ke-size=&quot;size16&quot;&gt;  OCI에서 받은 .pem 키 파일 넣기&lt;/p&gt;
&lt;hr data-end=&quot;907&quot; data-start=&quot;904&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;926&quot; data-start=&quot;909&quot; data-section-id=&quot;5f6941&quot;&gt;  4. SSH 접속 성공&lt;/h1&gt;
&lt;p data-end=&quot;941&quot; data-start=&quot;928&quot; data-ke-size=&quot;size16&quot;&gt;접속하면 이런 화면 뜸:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;ubuntu@instance:~$&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;971&quot; data-ke-size=&quot;size16&quot;&gt;  여기 뜨면 성공이다&lt;/p&gt;
&lt;hr data-end=&quot;989&quot; data-start=&quot;986&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1009&quot; data-start=&quot;991&quot; data-section-id=&quot;159f4le&quot;&gt;⚙️ 5. 서버 기본 업데이트&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt update&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt upgrade &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1077&quot; data-start=&quot;1060&quot; data-ke-size=&quot;size16&quot;&gt;중간에 이런 화면 뜰 수 있음:&lt;/p&gt;
&lt;p data-end=&quot;1101&quot; data-start=&quot;1079&quot; data-ke-size=&quot;size16&quot;&gt;  &quot;restart services?&quot;&lt;/p&gt;
&lt;p data-end=&quot;1116&quot; data-start=&quot;1103&quot; data-ke-size=&quot;size16&quot;&gt;✔ 그냥 OK 누르면 됨&lt;/p&gt;
&lt;hr data-end=&quot;1121&quot; data-start=&quot;1118&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1141&quot; data-start=&quot;1123&quot; data-section-id=&quot;9dbphk&quot;&gt;  6. Node.js 설치&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fsSL&lt;/span&gt;&lt;span&gt; &lt;a href=&quot;https://deb.nodesource.com/setup_20.x&quot;&gt;https://deb.nodesource.com/setup_20.x&lt;/a&gt; | &lt;/span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-E&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt install &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; nodejs&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1252&quot; data-start=&quot;1249&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1262&quot; data-start=&quot;1254&quot; data-section-id=&quot;nojmqc&quot; data-ke-size=&quot;size26&quot;&gt;설치 확인&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;br /&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1295&quot; data-start=&quot;1292&quot; data-ke-size=&quot;size16&quot;&gt;결과:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;v20.x.x&lt;/span&gt;&lt;br /&gt;&lt;span&gt;10.x.x&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1334&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;  최신 버전이면 성공&lt;/p&gt;
&lt;hr data-end=&quot;1339&quot; data-start=&quot;1336&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1359&quot; data-start=&quot;1341&quot; data-section-id=&quot;xkfd2b&quot;&gt;  여기까지 하면 뭐 가능?&lt;/h1&gt;
&lt;p data-end=&quot;1386&quot; data-start=&quot;1361&quot; data-ke-size=&quot;size16&quot;&gt;지금 상태 = &lt;b&gt;클라우드 서버 완성 상태&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1391&quot; data-start=&quot;1388&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1407&quot; data-start=&quot;1393&quot; data-section-id=&quot;1i7tsii&quot; data-ke-size=&quot;size26&quot;&gt;  할 수 있는 것&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1493&quot; data-start=&quot;1409&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1424&quot; data-start=&quot;1409&quot; data-section-id=&quot;q94s42&quot;&gt;Node.js 서버 운영&lt;/li&gt;
&lt;li data-end=&quot;1442&quot; data-start=&quot;1425&quot; data-section-id=&quot;m7dniq&quot;&gt;Express API 만들기&lt;/li&gt;
&lt;li data-end=&quot;1463&quot; data-start=&quot;1443&quot; data-section-id=&quot;1mmc34a&quot;&gt;React / Next.js 배포&lt;/li&gt;
&lt;li data-end=&quot;1472&quot; data-start=&quot;1464&quot; data-section-id=&quot;1q99md5&quot;&gt;크롤링 서버&lt;/li&gt;
&lt;li data-end=&quot;1485&quot; data-start=&quot;1473&quot; data-section-id=&quot;1im7l28&quot;&gt;개인 웹사이트 운영&lt;/li&gt;
&lt;li data-end=&quot;1493&quot; data-start=&quot;1486&quot; data-section-id=&quot;1vfy42&quot;&gt;자동화 봇&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1498&quot; data-start=&quot;1495&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1515&quot; data-start=&quot;1500&quot; data-section-id=&quot;ehuklq&quot;&gt;⚠️ 중요한 것 (필수)&lt;/h1&gt;
&lt;p data-end=&quot;1534&quot; data-start=&quot;1517&quot; data-ke-size=&quot;size16&quot;&gt;  기본적으로 포트 막혀 있음&lt;/p&gt;
&lt;h3 data-end=&quot;1549&quot; data-start=&quot;1536&quot; data-section-id=&quot;1a6vn1x&quot; data-ke-size=&quot;size23&quot;&gt;반드시 해야할 것&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1580&quot; data-start=&quot;1551&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1580&quot; data-start=&quot;1551&quot; data-section-id=&quot;1c7z645&quot;&gt;Security List / NSG에서 포트 열기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1584&quot; data-start=&quot;1582&quot; data-ke-size=&quot;size16&quot;&gt;예:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;22 (SSH)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;80 (웹)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;443 (HTTPS)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;3000 (테스트)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1636&quot; data-start=&quot;1633&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1647&quot; data-start=&quot;1638&quot; data-section-id=&quot;41tamy&quot;&gt;  느낀 점&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1707&quot; data-start=&quot;1649&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1662&quot; data-start=&quot;1649&quot; data-section-id=&quot;q1jhtv&quot;&gt;생각보다 어렵지 않음&lt;/li&gt;
&lt;li data-end=&quot;1685&quot; data-start=&quot;1663&quot; data-section-id=&quot;t4ck0m&quot;&gt;Public IP 설정이 제일 헷갈림&lt;/li&gt;
&lt;li data-end=&quot;1707&quot; data-start=&quot;1686&quot; data-section-id=&quot;f788nk&quot;&gt;SSH만 붙으면 끝난 거나 마찬가지&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Network</category>
      <category>nodejs서버</category>
      <category>oci</category>
      <category>OracleCloud</category>
      <category>ssh접속</category>
      <category>tabby</category>
      <category>ubuntu서버</category>
      <category>개발환경세팅</category>
      <category>무료서버</category>
      <category>서버구축</category>
      <category>클라우드서버</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/691</guid>
      <comments>https://applejara.tistory.com/691#entry691comment</comments>
      <pubDate>Thu, 26 Mar 2026 10:06:24 +0900</pubDate>
    </item>
    <item>
      <title>[Git]개발자의 필수 도구, Git과 GitHub 완벽 정리 (ft. 핵심 명령어)</title>
      <link>https://applejara.tistory.com/690</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;개발 공부를 시작하면 가장 먼저 마주하게 되는 벽이자, 익숙해지면 최고의 무기가 되는 **Git(깃)**에 대해 알아보겠습니다.&lt;br&gt;1. Git이란 무엇인가요? (비유: 게임 저장 데이터)&lt;br&gt;우리가 게임을 할 때 중요한 순간마다 '저장(Save)'을 하죠? 보스 몬스터를 잡기 전으로 돌아가거나, 잘못된 선택을 했을 때 이전 상태로 되돌리기 위해서입니다.&lt;br&gt;Git은 바로 소스 코드의 **'타임머신'**입니다.&lt;br&gt;• 파일을 수정할 때마다 그 기록을 차곡차곡 쌓아둡니다.&lt;br&gt;• 실수로 코드를 망쳤을 때, 어제 작성했던 상태로 완벽하게 되돌릴 수 있습니다.&lt;br&gt;• 여러 명이 같은 파일을 수정해도 누가, 언제, 무엇을 바꿨는지 추적할 수 있습니다.&lt;br&gt;2. Git vs GitHub, 똑같은 거 아닌가요?&lt;br&gt;많은 분이 헷갈려 하시지만, 둘은 엄연히 다릅니다!&lt;br&gt;• Git: 내 컴퓨터에서 돌아가는 프로그램 (일기장)&lt;br&gt;• GitHub: Git으로 관리하는 프로젝트를 올리는 웹사이트 (온라인 도서관)&lt;br&gt;&lt;br&gt;내 컴퓨터(Git)에서 쓴 일기를 전 세계 사람들이 볼 수 있게 공유 공간(GitHub)에 올린다고 생각하면 쉬워요.&lt;br&gt;&lt;br&gt;3. 꼭 알아야 할 핵심 명령어 5가지&lt;br&gt;이 5가지만 알아도 기본 흐름을 따라갈 수 있습니다.&lt;br&gt;1. git init: &quot;자, 이제부터 이 폴더를 Git으로 관리하겠어!&quot; (시작 선언)&lt;br&gt;2. git add: 수정한 파일 중 저장할 것들만 장바구니에 담기&lt;br&gt;3. git commit -m &quot;메시지&quot;: 장바구니에 담긴 파일들을 하나의 버전으로 확정 (영수증 발행)&lt;br&gt;4. git push: 내 컴퓨터의 기록을 GitHub(원격 저장소)로 전송&lt;br&gt;5. git pull: GitHub에 있는 최신 내용을 내 컴퓨터로 당겨오기 (협업 시 필수!)&lt;br&gt;4. 마치며&lt;br&gt;처음에는 명령어가 낯설고 복잡해 보일 수 있지만, 직접 한두 번만 add하고 commit 해보면 금방 익숙해지실 거예요. Claude 같은 AI 도우미를 활용해 커밋 메시지를 추천받는 것도 좋은 방법입니다.&lt;br&gt;&lt;br&gt;코딩 여정에 Git이라는 든든한 보험을 꼭 들어두세요!&lt;/p&gt;</description>
      <category>업무효율화★</category>
      <category>GIT</category>
      <category>github</category>
      <category>vcs</category>
      <category>개발자입문</category>
      <category>깃</category>
      <category>깃허브</category>
      <category>버전관리</category>
      <category>오픈소스</category>
      <category>컴퓨터공학</category>
      <category>코딩독학</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/690</guid>
      <comments>https://applejara.tistory.com/690#entry690comment</comments>
      <pubDate>Fri, 13 Mar 2026 07:30:17 +0900</pubDate>
    </item>
    <item>
      <title>[Claude]터미널에서 떠나는 코딩 여행, Claude Code /btw 명령어 200% 활용하기</title>
      <link>https://applejara.tistory.com/689</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;1. Claude Code란?&lt;br&gt;최근 개발자들 사이에서 화제인 Claude Code는 터미널(CLI) 환경에서 Anthropic의 강력한 AI인 Claude와 직접 상호작용하며 코딩할 수 있는 도구입니다. IDE를 벗어나 터미널에서 즉각적으로 코드를 수정하고, 테스트하고, 배포까지 관리할 수 있다는 점이 가장 큰 매력입니다.&lt;br&gt;2. 마법의 명령어, /btw (By The Way)&lt;br&gt;코딩을 하다 보면 이런 상황이 자주 발생합니다.&lt;br&gt;&lt;br&gt;&quot;아, 맞다! 이 로직 수정하기 전에 저쪽 파일에 변수명 뭐로 되어 있었지?&quot;&lt;br&gt;&lt;br&gt;이때 현재 진행 중인 메인 대화 흐름을 깨지 않고 잠시 '옆길'로 새서 궁금한 것을 물어볼 때 사용하는 명령어가 바로 **/btw**입니다.&lt;br&gt;• 기능: 현재 작업 컨텍스트를 유지하면서 별도의 가벼운 작업이나 확인 요청을 수행합니다.&lt;br&gt;• 장점: 대화의 맥락(Context)을 새로 설정할 필요가 없어 흐름이 끊기지 않습니다.&lt;br&gt;3. 실전 활용 시나리오&lt;br&gt;• 맥락 확인: /btw 이 함수가 참조하고 있는 다른 파일 위치 좀 알려줘.&lt;br&gt;• 단순 테스트: /btw 지금 수정한 부분만 간단히 유닛 테스트 돌려봐 줄래?&lt;br&gt;• 기록 확인: /btw 아까 내가 수정했던 환경 변수 설정값 다시 보여줘.&lt;br&gt;4. 생산성을 높이는 터미널 팁&lt;br&gt;Claude Code 환경에서는 명령어 한 줄로 코드 리뷰를 요청하거나( /review), 길어진 대화 내용을 요약( /compact)하여 토큰 효율을 높일 수 있습니다. 특히 /btw를 적재적소에 사용하면 AI와 마치 실제 동료와 페어 프로그래밍을 하는 듯한 유연함을 경험할 수 있습니다.&lt;/p&gt;</description>
      <category>업무효율화★</category>
      <category>btw</category>
      <category>Claude</category>
      <category>claude code</category>
      <category>code</category>
      <category>기록</category>
      <category>맥락</category>
      <category>멈출수가없다</category>
      <category>실전</category>
      <category>아이디어</category>
      <category>테스트</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/689</guid>
      <comments>https://applejara.tistory.com/689#entry689comment</comments>
      <pubDate>Thu, 12 Mar 2026 19:11:17 +0900</pubDate>
    </item>
    <item>
      <title>[MariaDB]Node.js mysql vs mysql2 차이점 정리 (사용 가능 여부 포함)</title>
      <link>https://applejara.tistory.com/688</link>
      <description>&lt;p data-end=&quot;248&quot; data-start=&quot;127&quot; data-ke-size=&quot;size16&quot;&gt;Node.js에서 MySQL 계열 데이터베이스를 사용할 때 자주 사용하는 패키지가 **mysql**과 **mysql2**입니다.&lt;br /&gt;둘은 이름이 비슷하지만 기능과 사용 방식에서 몇 가지 중요한 차이가 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;271&quot; data-start=&quot;250&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 다음 내용을 정리합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;365&quot; data-start=&quot;273&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;298&quot; data-start=&quot;273&quot; data-section-id=&quot;1ief4nn&quot;&gt;mysql vs mysql2 차이점&lt;/li&gt;
&lt;li data-end=&quot;329&quot; data-start=&quot;299&quot; data-section-id=&quot;olfcxw&quot;&gt;어떤 경우에 mysql2를 사용하는 것이 좋은지&lt;/li&gt;
&lt;li data-end=&quot;365&quot; data-start=&quot;330&quot; data-section-id=&quot;mjiri9&quot;&gt;mysql2를 &lt;b&gt;MariaDB에서 사용할 수 있는지&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;370&quot; data-start=&quot;367&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;398&quot; data-start=&quot;372&quot; data-section-id=&quot;o8l9pm&quot;&gt;1. mysql vs mysql2 기본 개념&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;항목mysqlmysql2
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;656&quot; data-start=&quot;400&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;656&quot; data-start=&quot;438&quot;&gt;
&lt;tr data-end=&quot;480&quot; data-start=&quot;438&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;444&quot; data-start=&quot;438&quot;&gt;패키지&lt;/td&gt;
&lt;td data-end=&quot;460&quot; data-start=&quot;444&quot; data-col-size=&quot;sm&quot;&gt;mysqljs/mysql&lt;/td&gt;
&lt;td data-end=&quot;480&quot; data-start=&quot;460&quot; data-col-size=&quot;sm&quot;&gt;sidorares/mysql2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;527&quot; data-start=&quot;481&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;489&quot; data-start=&quot;481&quot;&gt;개발 시기&lt;/td&gt;
&lt;td data-end=&quot;511&quot; data-start=&quot;489&quot; data-col-size=&quot;sm&quot;&gt;오래된 Node MySQL 드라이버&lt;/td&gt;
&lt;td data-end=&quot;527&quot; data-start=&quot;511&quot; data-col-size=&quot;sm&quot;&gt;mysql의 개선 버전&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;574&quot; data-start=&quot;528&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;541&quot; data-start=&quot;528&quot;&gt;Promise 지원&lt;/td&gt;
&lt;td data-end=&quot;554&quot; data-start=&quot;541&quot; data-col-size=&quot;sm&quot;&gt;❌ 기본 지원 없음&lt;/td&gt;
&lt;td data-end=&quot;574&quot; data-start=&quot;554&quot; data-col-size=&quot;sm&quot;&gt;✅ Promise API 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;615&quot; data-start=&quot;575&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;596&quot; data-start=&quot;575&quot;&gt;Prepared Statement&lt;/td&gt;
&lt;td data-end=&quot;604&quot; data-start=&quot;596&quot; data-col-size=&quot;sm&quot;&gt;❌ 제한적&lt;/td&gt;
&lt;td data-end=&quot;615&quot; data-start=&quot;604&quot; data-col-size=&quot;sm&quot;&gt;✅ 기본 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;636&quot; data-start=&quot;616&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;621&quot; data-start=&quot;616&quot;&gt;성능&lt;/td&gt;
&lt;td data-end=&quot;626&quot; data-start=&quot;621&quot; data-col-size=&quot;sm&quot;&gt;보통&lt;/td&gt;
&lt;td data-end=&quot;636&quot; data-start=&quot;626&quot; data-col-size=&quot;sm&quot;&gt;더 빠른 편&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;656&quot; data-start=&quot;637&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;644&quot; data-start=&quot;637&quot;&gt;유지보수&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;650&quot; data-start=&quot;644&quot;&gt;유지중&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;656&quot; data-start=&quot;650&quot;&gt;활발&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;699&quot; data-start=&quot;658&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 &lt;b&gt;mysql2가 mysql의 개선 버전&lt;/b&gt;이라는 점입니다.&lt;/p&gt;
&lt;p data-end=&quot;734&quot; data-start=&quot;701&quot; data-ke-size=&quot;size16&quot;&gt;또한 &lt;b&gt;API 호환성을 유지하면서 기능을 확장&lt;/b&gt;했습니다.&lt;/p&gt;
&lt;p data-end=&quot;766&quot; data-start=&quot;736&quot; data-ke-size=&quot;size16&quot;&gt;그래서 기존 코드에서 비교적 쉽게 변경할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;771&quot; data-start=&quot;768&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;786&quot; data-start=&quot;773&quot; data-section-id=&quot;plom8c&quot;&gt;2. mysql 특징&lt;/h1&gt;
&lt;p data-end=&quot;828&quot; data-start=&quot;788&quot; data-ke-size=&quot;size16&quot;&gt;mysql은 Node.js에서 오래 사용된 MySQL 드라이버입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;836&quot; data-start=&quot;830&quot; data-section-id=&quot;1hrlj9m&quot; data-ke-size=&quot;size23&quot;&gt;특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;888&quot; data-start=&quot;838&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;849&quot; data-start=&quot;838&quot; data-section-id=&quot;1so1tsl&quot;&gt;콜백 기반 API&lt;/li&gt;
&lt;li data-end=&quot;867&quot; data-start=&quot;850&quot; data-section-id=&quot;p2c92s&quot;&gt;안정적이지만 최신 기능 부족&lt;/li&gt;
&lt;li data-end=&quot;888&quot; data-start=&quot;868&quot; data-section-id=&quot;1nx64y&quot;&gt;Promise를 직접 래핑해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;899&quot; data-start=&quot;890&quot; data-section-id=&quot;qsrzju&quot; data-ke-size=&quot;size23&quot;&gt;예제 코드&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mysql&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;require&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;'mysql'&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connection&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mysql&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createConnection({&lt;/span&gt;&lt;br /&gt;&lt;span&gt; host: &lt;/span&gt;&lt;span&gt;'localhost'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; user: &lt;/span&gt;&lt;span&gt;'root'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; password: &lt;/span&gt;&lt;span&gt;'password'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; database: &lt;/span&gt;&lt;span&gt;'test'&lt;/span&gt;&lt;br /&gt;&lt;span&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;connection&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;query(&lt;/span&gt;&lt;span&gt;'SELECT * FROM users'&lt;/span&gt;&lt;span&gt;, (&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;results&lt;/span&gt;&lt;span&gt;) =&amp;gt; {&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log(&lt;/span&gt;&lt;span&gt;results&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1195&quot; data-start=&quot;1192&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1211&quot; data-start=&quot;1197&quot; data-section-id=&quot;nb49lr&quot;&gt;3. mysql2 특징&lt;/h1&gt;
&lt;p data-end=&quot;1265&quot; data-start=&quot;1213&quot; data-ke-size=&quot;size16&quot;&gt;mysql2는 mysql과 &lt;b&gt;대부분의 API가 호환되면서 추가 기능을 제공&lt;/b&gt;합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1276&quot; data-start=&quot;1267&quot; data-section-id=&quot;h6880r&quot; data-ke-size=&quot;size23&quot;&gt;주요 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1364&quot; data-start=&quot;1278&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1294&quot; data-start=&quot;1278&quot; data-section-id=&quot;1gcuwv3&quot;&gt;Promise API 지원&lt;/li&gt;
&lt;li data-end=&quot;1314&quot; data-start=&quot;1295&quot; data-section-id=&quot;tv39l7&quot;&gt;async/await 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;1338&quot; data-start=&quot;1315&quot; data-section-id=&quot;1tuq2s8&quot;&gt;Prepared Statement 지원&lt;/li&gt;
&lt;li data-end=&quot;1348&quot; data-start=&quot;1339&quot; data-section-id=&quot;c5j7gw&quot;&gt;더 나은 성능&lt;/li&gt;
&lt;li data-end=&quot;1364&quot; data-start=&quot;1349&quot; data-section-id=&quot;a885cf&quot;&gt;TypeScript 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1388&quot; data-start=&quot;1366&quot; data-section-id=&quot;1evtwxt&quot; data-ke-size=&quot;size23&quot;&gt;예제 코드 (Promise 사용)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mysql&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;require&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;'mysql2/promise'&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connection&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mysql&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createConnection({&lt;/span&gt;&lt;br /&gt;&lt;span&gt; host: &lt;/span&gt;&lt;span&gt;'localhost'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; user: &lt;/span&gt;&lt;span&gt;'root'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; password: &lt;/span&gt;&lt;span&gt;'password'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; database: &lt;/span&gt;&lt;span&gt;'test'&lt;/span&gt;&lt;br /&gt;&lt;span&gt; });&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connection&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;execute(&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;'SELECT * FROM users WHERE id = ?'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span&gt; );&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log(&lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1818&quot; data-start=&quot;1751&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;async/await 기반 코드 작성이 가능하기 때문에 최근 프로젝트에서는 mysql2가 더 많이 사용됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1823&quot; data-start=&quot;1820&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1858&quot; data-start=&quot;1825&quot; data-section-id=&quot;1ohuxyu&quot;&gt;4. mysql2를 MariaDB에서 사용할 수 있을까?&lt;/h1&gt;
&lt;p data-end=&quot;1882&quot; data-start=&quot;1860&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면 &lt;b&gt;사용 가능합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1897&quot; data-start=&quot;1884&quot; data-ke-size=&quot;size16&quot;&gt;이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1973&quot; data-start=&quot;1899&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1928&quot; data-start=&quot;1899&quot; data-section-id=&quot;f1dwlq&quot;&gt;&lt;b&gt;MariaDB는 MySQL 프로토콜과 호환&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1973&quot; data-start=&quot;1929&quot; data-section-id=&quot;mamfxj&quot;&gt;mysql / mysql2 드라이버는 &lt;b&gt;MySQL 프로토콜 기반&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2006&quot; data-start=&quot;1975&quot; data-ke-size=&quot;size16&quot;&gt;따라서 일반적인 CRUD 작업에서는 문제없이 동작합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2011&quot; data-start=&quot;2008&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2045&quot; data-start=&quot;2013&quot; data-section-id=&quot;1v06dlv&quot;&gt;5. MariaDB에서 권장되는 Node.js 드라이버&lt;/h1&gt;
&lt;p data-end=&quot;2091&quot; data-start=&quot;2047&quot; data-ke-size=&quot;size16&quot;&gt;MariaDB 공식 문서에서는 &lt;b&gt;MariaDB 전용 드라이버&lt;/b&gt;를 제공합니다.&lt;/p&gt;
&lt;p data-end=&quot;2099&quot; data-start=&quot;2093&quot; data-ke-size=&quot;size16&quot;&gt;추천 패키지&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;mariadb&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;2124&quot; data-start=&quot;2118&quot; data-section-id=&quot;1hrlj9m&quot; data-ke-size=&quot;size23&quot;&gt;특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2192&quot; data-start=&quot;2126&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2148&quot; data-start=&quot;2126&quot; data-section-id=&quot;1w2pb0z&quot;&gt;MariaDB 공식 Connector&lt;/li&gt;
&lt;li data-end=&quot;2175&quot; data-start=&quot;2149&quot; data-section-id=&quot;g3ji8g&quot;&gt;MySQL 및 MariaDB 모두 연결 가능&lt;/li&gt;
&lt;li data-end=&quot;2192&quot; data-start=&quot;2176&quot; data-section-id=&quot;5ebq10&quot;&gt;MariaDB 기능 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;2200&quot; data-start=&quot;2194&quot; data-section-id=&quot;1hrqlw2&quot; data-ke-size=&quot;size23&quot;&gt;예제&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mariadb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;require&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;'mariadb'&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pool&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mariadb&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createPool({&lt;/span&gt;&lt;br /&gt;&lt;span&gt; host: &lt;/span&gt;&lt;span&gt;'localhost'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; user: &lt;/span&gt;&lt;span&gt;'root'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; password: &lt;/span&gt;&lt;span&gt;'password'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; database: &lt;/span&gt;&lt;span&gt;'test'&lt;/span&gt;&lt;br /&gt;&lt;span&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;conn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pool&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;getConnection();&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;conn&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;query(&lt;/span&gt;&lt;span&gt;'SELECT * FROM users'&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log(&lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2526&quot; data-start=&quot;2523&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2550&quot; data-start=&quot;2528&quot; data-section-id=&quot;1wltjxg&quot;&gt;6. 어떤 드라이버를 선택해야 할까?&lt;/h1&gt;
&lt;p data-end=&quot;2568&quot; data-start=&quot;2552&quot; data-ke-size=&quot;size16&quot;&gt;추천 기준은 다음과 같습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2582&quot; data-start=&quot;2570&quot; data-section-id=&quot;orzb2x&quot; data-ke-size=&quot;size23&quot;&gt;MySQL 사용&lt;/h3&gt;
&lt;p data-end=&quot;2586&quot; data-start=&quot;2584&quot; data-ke-size=&quot;size16&quot;&gt;추천&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;mysql2&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2606&quot; data-start=&quot;2604&quot; data-ke-size=&quot;size16&quot;&gt;이유&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2642&quot; data-start=&quot;2608&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2620&quot; data-start=&quot;2608&quot; data-section-id=&quot;1h8prb&quot;&gt;Promise 지원&lt;/li&gt;
&lt;li data-end=&quot;2628&quot; data-start=&quot;2621&quot; data-section-id=&quot;wwjmyo&quot;&gt;성능 개선&lt;/li&gt;
&lt;li data-end=&quot;2642&quot; data-start=&quot;2629&quot; data-section-id=&quot;1cn1tq6&quot;&gt;커뮤니티 사용량 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2647&quot; data-start=&quot;2644&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2663&quot; data-start=&quot;2649&quot; data-section-id=&quot;9b5lir&quot; data-ke-size=&quot;size23&quot;&gt;MariaDB 사용&lt;/h3&gt;
&lt;p data-end=&quot;2667&quot; data-start=&quot;2665&quot; data-ke-size=&quot;size16&quot;&gt;추천&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;mariadb&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2688&quot; data-start=&quot;2686&quot; data-ke-size=&quot;size16&quot;&gt;이유&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2717&quot; data-start=&quot;2690&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2698&quot; data-start=&quot;2690&quot; data-section-id=&quot;117xzyp&quot;&gt;공식 커넥터&lt;/li&gt;
&lt;li data-end=&quot;2717&quot; data-start=&quot;2699&quot; data-section-id=&quot;8gz9y5&quot;&gt;MariaDB 기능 완전 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2722&quot; data-start=&quot;2719&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2740&quot; data-start=&quot;2724&quot; data-section-id=&quot;1c39b3n&quot; data-ke-size=&quot;size23&quot;&gt;기존 프로젝트 유지보수&lt;/h3&gt;
&lt;p data-end=&quot;2762&quot; data-start=&quot;2742&quot; data-ke-size=&quot;size16&quot;&gt;이미 mysql을 사용하고 있다면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2803&quot; data-start=&quot;2764&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2780&quot; data-start=&quot;2764&quot; data-section-id=&quot;15xd0m&quot;&gt;급하게 변경할 필요는 없음&lt;/li&gt;
&lt;li data-end=&quot;2803&quot; data-start=&quot;2781&quot; data-section-id=&quot;1gxf2fp&quot;&gt;새 프로젝트라면 mysql2 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2808&quot; data-start=&quot;2805&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2817&quot; data-start=&quot;2810&quot; data-section-id=&quot;1xj7k1y&quot;&gt;7. 정리&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2972&quot; data-start=&quot;2819&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2852&quot; data-start=&quot;2819&quot; data-section-id=&quot;dxe00b&quot;&gt;mysql2는 mysql의 &lt;b&gt;업그레이드 버전&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2893&quot; data-start=&quot;2853&quot; data-section-id=&quot;numks7&quot;&gt;Promise 기반 개발을 위해 &lt;b&gt;mysql2 사용이 일반적&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2926&quot; data-start=&quot;2894&quot; data-section-id=&quot;x7we18&quot;&gt;mysql2는 &lt;b&gt;MariaDB에서도 사용 가능&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2972&quot; data-start=&quot;2927&quot; data-section-id=&quot;f6fxt5&quot;&gt;하지만 MariaDB에서는 &lt;b&gt;mariadb 공식 드라이버가 더 권장됨&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Database</category>
      <category>MariaDB</category>
      <category>MySQL</category>
      <category>mysql2</category>
      <category>nodeJS</category>
      <category>데이터베이스</category>
      <category>백엔드</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/688</guid>
      <comments>https://applejara.tistory.com/688#entry688comment</comments>
      <pubDate>Wed, 11 Mar 2026 15:46:21 +0900</pubDate>
    </item>
    <item>
      <title>[framework]Express vs NestJS 비교 정리</title>
      <link>https://applejara.tistory.com/687</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. Express.js란?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 Node.js에서 가장 오래되고 널리 사용되는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;웹 프레임워크&lt;/span&gt;&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2010년 출시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;가볍고 단순한 구조&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;자유도가 높은 설계&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 기본적으로 &lt;/span&gt;&lt;b&gt;&lt;span&gt;minimal framework&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이기 때문에&lt;/span&gt;&lt;br /&gt;&lt;span&gt;개발자가 프로젝트 구조를 자유롭게 설계할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예시 코드&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;app.get('/portfolio', async (req, res) =&amp;gt; {
  const data = await portfolioService.getPortfolio()
  res.json(data)
})&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Express 특징&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;매우 가벼운 프레임워크&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;빠른 API 개발&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;구조 강제가 없음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 프로젝트 규모가 커질수록 구조 관리가 어려워질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;2. NestJS란?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NestJS는 Node.js 기반의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;엔터프라이즈 프레임워크&lt;/span&gt;&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;2017년 출시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TypeScript 기반&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Angular / Spring 스타일 아키텍처&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NestJS는 다음과 같은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;구조화된 아키텍처&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Module
Controller
Service
DTO
Repository&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예시 코드&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Controller('portfolio')
export class PortfolioController {

  constructor(private readonly service: PortfolioService) {}

  @Get()
  getPortfolio() {
    return this.service.getPortfolio()
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NestJS는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Dependency Injection(DI)&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 과 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Layered Architecture&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 기본 제공하기 때문에&lt;/span&gt;&lt;br /&gt;&lt;span&gt;대규모 프로젝트에 적합합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;3. Express vs NestJS 구조 비교&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항목ExpressNestJS&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;프레임워크 성격&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Minimal&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Enterprise&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;언어&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;JavaScript&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;TypeScript&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;구조&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;자유&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;표준화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;DI 지원&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;없음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;있음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;대규모 프로젝트&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;관리 어려움&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;관리 용이&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 자유도가 높은 대신 프로젝트마다 구조가 달라질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NestJS는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;구조를 강제하여 유지보수를 쉽게 하는 방식&lt;/span&gt;&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;4. 개발 생산성&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Express&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;장점&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;빠른 개발&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;가벼운 구조&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;러닝 커브 낮음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단점&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프로젝트 구조가 팀마다 다름&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;코드 관리 어려움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대규모 프로젝트 불리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;NestJS&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;장점&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;구조화된 아키텍처&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;TypeScript 안정성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;의존성 주입(DI)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;테스트 구조 제공&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단점&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;초기 학습 비용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;보일러플레이트 코드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;초기 개발 속도 느림&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;5. 보안 및 인증 구조&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 인증과 권한 구조를 직접 구현해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;JWT middleware
RBAC middleware
validation
error handler&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반면 NestJS는 인증/인가 구조를 체계적으로 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arcade&quot;&gt;&lt;code&gt;Guard
Interceptor
Pipe
Filter&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;AuthGuard&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;RolesGuard&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;ValidationPipe&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 구조로 보안 로직을 분리할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;금융 시스템처럼 &lt;/span&gt;&lt;b&gt;&lt;span&gt;권한 관리와 감사 로그가 중요한 환경에서는 큰 장점&lt;/span&gt;&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;6. 마이크로서비스 확장성&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;NestJS는 기본적으로 다음 기술을 지원합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Kafka
Redis
RabbitMQ
gRPC
WebSocket&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 &lt;/span&gt;&lt;b&gt;&lt;span&gt;마이크로서비스 아키텍처(MSA)&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 로 확장하기 쉽습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 이런 기능을 직접 구현해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;7. 언제 Express를 사용하는 것이 좋을까?&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;소규모 프로젝트&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;스타트업 MVP&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단순 REST API&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;개발자 1~2명&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;8. 언제 NestJS가 더 적합할까?&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;기업 내부 시스템&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;금융 PMS / AMS&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대규모 API 서버&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;마이크로서비스 아키텍처&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;장기 운영 시스템&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;9. 결론&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express와 NestJS는 서로 경쟁 관계라기보다는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;용도가 다른 프레임워크&lt;/span&gt;&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Express는 빠른 개발에 유리하고,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;NestJS는 장기 운영과 대규모 시스템에 유리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 금융 시스템이나 기업 내부 플랫폼처럼&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span&gt;안정성과 유지보수가 중요한 환경이라면 NestJS가 더 적합한 선택이 될 가능성이 높습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>Programing</category>
      <category>BackendDevelopment</category>
      <category>expressjs</category>
      <category>FullStackDevelopment</category>
      <category>microservices</category>
      <category>nestjs</category>
      <category>nodeJS</category>
      <category>softwarearchitecture</category>
      <category>techblog</category>
      <category>typescript</category>
      <category>webframework</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/687</guid>
      <comments>https://applejara.tistory.com/687#entry687comment</comments>
      <pubDate>Wed, 11 Mar 2026 15:24:48 +0900</pubDate>
    </item>
    <item>
      <title>[브라우저] PC 브라우저에서 ChatGPT 계정 2개 분리해서 사용하기 (바탕화면 바로가기 설정)</title>
      <link>https://applejara.tistory.com/686</link>
      <description>&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;업무를 하다 보면 ChatGPT 계정을 여러 개 사용해야 할 때가 있습니다. 매번 로그아웃하고 다시 로그인하는 번거로움 없이, **크롬(Chrome)**과 **엣지(Edge)**를 활용해 각각의 계정으로 즉시 접속하는 &lt;b data-index-in-node=&quot;122&quot; data-path-to-node=&quot;3&quot;&gt;바탕화면 바로가기 생성 방법&lt;/b&gt;을 소개합니다.&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;4&quot; data-ke-size=&quot;size23&quot;&gt;  핵심 요약&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;5&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,0,0&quot;&gt;A계정:&lt;/b&gt; 기존 크롬(Chrome) 브라우저 전용&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0&quot;&gt;B계정:&lt;/b&gt; 엣지(Edge) 브라우저 전용&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0&quot;&gt;방법:&lt;/b&gt; 바탕화면 우클릭 메뉴를 이용한 '항목 위치 입력' 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-path-to-node=&quot;6&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;1. 엣지(Edge) 브라우저 전용 바로가기 만들기 (B계정용)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;바탕화면에서 클릭 한 번으로 엣지를 실행해 B계정 ChatGPT로 접속하는 방법입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;바탕화면 빈 곳에서 **[마우스 우클릭] &amp;gt; [새로 만들기(W)] &amp;gt; [바로 가기(S)]**를 클릭합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;항목 위치 입력(T)&lt;/b&gt; 칸에 아래 경로를 그대로 복사해서 붙여넣으세요.&lt;/li&gt;
&lt;li data-path-to-node=&quot;9,1,1&quot;&gt;&quot;C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe&quot; &lt;a href=&quot;https://chatgpt.com&quot;&gt;https://chatgpt.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,2,0&quot;&gt;[다음]&lt;/b&gt; 버튼을 누른 후, 바로 가기 이름을 **ChatGPT (B계정)**으로 입력하고 **[마침]**을 누릅니다.&lt;/li&gt;
&lt;li&gt;생성된 아이콘을 실행해 &lt;b data-index-in-node=&quot;13&quot; data-path-to-node=&quot;9,3,0&quot;&gt;B계정&lt;/b&gt;으로 로그인해두면 이후부터는 자동 접속됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-path-to-node=&quot;10&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;11&quot; data-ke-size=&quot;size23&quot;&gt;2. 크롬(Chrome) 브라우저 전용 바로가기 만들기 (A계정용)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;기존에 사용하던 크롬 환경 그대로 A계정 전용 아이콘을 만듭니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;13&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;바탕화면 빈 곳에서 **[마우스 우클릭] &amp;gt; [새로 만들기(W)] &amp;gt; [바로 가기(S)]**를 클릭합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,1,0&quot;&gt;항목 위치 입력(T)&lt;/b&gt; 칸에 아래 경로를 복사해서 붙여넣으세요.&lt;/li&gt;
&lt;li data-path-to-node=&quot;13,1,1&quot;&gt;&quot;C:\Program Files\Google\Chrome\Application\chrome.exe&quot; &lt;a href=&quot;https://chatgpt.com&quot;&gt;https://chatgpt.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,2,0&quot;&gt;[다음]&lt;/b&gt; 버튼을 누른 후, 이름을 **ChatGPT (A계정)**으로 입력하고 **[마침]**을 누릅니다.&lt;/li&gt;
&lt;li&gt;아이콘을 실행해 &lt;b data-index-in-node=&quot;9&quot; data-path-to-node=&quot;13,3,0&quot;&gt;A계정&lt;/b&gt;으로 로그인하면 설정이 완료됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-path-to-node=&quot;14&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;15&quot; data-ke-size=&quot;size23&quot;&gt;  설정 시 주의사항 (Troubleshooting)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;16&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,0,0&quot;&gt;경로 오류가 날 경우:&lt;/b&gt; PC 환경에 따라 브라우저 설치 폴더가 다를 수 있습니다. 이 경우 바탕화면에 있는 기존 브라우저 아이콘을 **[우클릭] &amp;gt; [속성] &amp;gt; [대상(T)]**에 있는 경로를 복사해 사용하세요.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,1,0&quot;&gt;아이콘 구분하기:&lt;/b&gt; 두 아이콘의 모양이 같아 헷갈린다면, 생성된 아이콘 &lt;b data-index-in-node=&quot;39&quot; data-path-to-node=&quot;16,1,0&quot;&gt;[우클릭] &amp;gt; [속성] &amp;gt; [아이콘 변경]&lt;/b&gt; 메뉴에서 서로 다른 모양으로 바꿔주면 식별이 훨씬 쉽습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Tips</category>
      <category>ChatGPT</category>
      <category>ChatGPT계정2개</category>
      <category>IT팁</category>
      <category>멀티계정</category>
      <category>바로가기아이콘</category>
      <category>바탕화면바로가기</category>
      <category>챗gpt</category>
      <category>챗GPT로그인</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/686</guid>
      <comments>https://applejara.tistory.com/686#entry686comment</comments>
      <pubDate>Wed, 11 Mar 2026 10:50:45 +0900</pubDate>
    </item>
    <item>
      <title>[Claude]구글 시트를 넘어 클로드 바이브로: 2주 만에 구축한 임직원용 PMS 개발기(전체 레이아웃만)</title>
      <link>https://applejara.tistory.com/685</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;bull; 2월 말부터 2주간 임직원이 사용하는 PMS (Project Management System) 개발&lt;br /&gt;&amp;bull; 기존 구글 시트 사용에서 클로드 바이브 (Claude Vibe) 코딩으로 전환&lt;br /&gt;&amp;bull; 전환의 장점: 쉽고 빠른 구현, 아이디어 및 경험 반영 용이, 적용 편리&lt;br /&gt;&amp;bull; 전환의 단점: 프로 구독형으로도 부족한 기능 (Max 5-20배 더 강력한 기능 필요 : Pro부족)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXnxly/dJMcahQ8G2A/cyyHsoO72mEIP8zTdk5vlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXnxly/dJMcahQ8G2A/cyyHsoO72mEIP8zTdk5vlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXnxly/dJMcahQ8G2A/cyyHsoO72mEIP8zTdk5vlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXnxly%2FdJMcahQ8G2A%2FcyyHsoO72mEIP8zTdk5vlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;768&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&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;1200&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPKlvy/dJMcahKoMzy/aP96RkSf0XJRK5j9sjJKJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPKlvy/dJMcahKoMzy/aP96RkSf0XJRK5j9sjJKJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPKlvy/dJMcahKoMzy/aP96RkSf0XJRK5j9sjJKJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPKlvy%2FdJMcahKoMzy%2FaP96RkSf0XJRK5j9sjJKJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;893&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>업무효율화★</category>
      <category>#PMS #개발 #코딩 #구글시트 #클로드바이브 #프로젝트관리 #시스템 #임직원 #사용 #2주 #2월말 #장점 #단점 #프로구독형 #한계 #극복 #블로그 #포스팅</category>
      <category>구독</category>
      <category>바이브</category>
      <category>바이브코딩</category>
      <category>클로드</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/685</guid>
      <comments>https://applejara.tistory.com/685#entry685comment</comments>
      <pubDate>Tue, 10 Mar 2026 19:07:55 +0900</pubDate>
    </item>
    <item>
      <title>[IT 지식] Express.js란 무엇일까? 웹 개발의 핵심 구조 이해하기</title>
      <link>https://applejara.tistory.com/684</link>
      <description>&lt;p data-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;당사 주과장님과 MC블랙스완님을 위해, 사진 자료와 《비전공자를 위한 이해할 수 있는 IT 지식》의 내용을 바탕으로 블로그 기재용 포스팅을 정리하였습니다.&lt;/p&gt;
&lt;hr data-path-to-node=&quot;1&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;4&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4&quot;&gt;1. 기술 카테고리: Express.js는 '프레임워크'입니다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;전체적인 IT 기술 스택에서 Express.js는 서버를 만들기 위한 &lt;b data-index-in-node=&quot;39&quot; data-path-to-node=&quot;5&quot;&gt;뼈대&lt;/b&gt; 역할을 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;6&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,0,0&quot;&gt;상위 카테고리&lt;/b&gt;: Angular.js, React.js와 나란히 &lt;b data-index-in-node=&quot;35&quot; data-path-to-node=&quot;6,0,0&quot;&gt;'프레임워크, 라이브러리'&lt;/b&gt; 군에 속해 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,1,0&quot;&gt;연결 기술&lt;/b&gt;: JAVA, PHP, Python 같은 프로그래밍 언어를 기반으로, MySQL이나 MariaDB 같은 데이터베이스와 상호작용하며 동작합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;7&quot;&gt;2. 직군별 역할: '서버 개발자'의 핵심 도구&lt;/b&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;실무에서 누가 이 기술을 쓰는지 알면 구조가 더 명확해집니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,0,0&quot;&gt;서버 개발자 (Server Developer)&lt;/b&gt;: 리눅스나 우분투 환경에서 &lt;b data-index-in-node=&quot;41&quot; data-path-to-node=&quot;9,0,0&quot;&gt;Express.js&lt;/b&gt;를 주력으로 사용하여 서버 로직을 구축합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;협업 프로세스&lt;/b&gt;: 웹 개발자가 만든 화면의 요청을 **네트워크(API, JSON)**가 전달하면, 서버 개발자가 Express.js를 통해 이를 처리하고 응답합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;10&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;3. 전체 개발 생태계와 협업 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;Express.js는 백엔드의 중심에서 다양한 파트와 유기적으로 연결됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;12&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,0,0&quot;&gt;프론트엔드 (Front end)&lt;/b&gt;: 애플리케이션과 웹 화면 등 사용자가 직접 보는 영역입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,1,0&quot;&gt;백엔드 (Back end)&lt;/b&gt;: **서버(Express.js)**와 데이터베이스가 위치하는 영역으로, 서비스의 엔진 역할을 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,2,0&quot;&gt;통합 관리&lt;/b&gt;: 개발자는 프로그래밍 언어와 OS 지식을 바탕으로 &lt;b data-index-in-node=&quot;34&quot; data-path-to-node=&quot;12,2,0&quot;&gt;프레임워크&lt;/b&gt;와 **깃(Git)**을 활용하며, 디자인 파트와 협업하여 결과물을 완성합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-path-to-node=&quot;13&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;blockquote data-path-to-node=&quot;14&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-path-to-node=&quot;14,0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,0&quot;&gt;  핵심 요약&lt;/b&gt; Express.js는 &lt;b data-index-in-node=&quot;21&quot; data-path-to-node=&quot;14,0&quot;&gt;서버 개발자&lt;/b&gt;가 더 빠르고 안정적으로 서비스를 만들기 위해 사용하는 &lt;b data-index-in-node=&quot;58&quot; data-path-to-node=&quot;14,0&quot;&gt;백엔드 프레임워크&lt;/b&gt;입니다.&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;본 블로그 포스팅에 이 구조도가 큰 도움이 되길 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_7564.PNG&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ML12C/dJMcacI4M36/TwD9MOxTUFPDk7QqdLO2nK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ML12C/dJMcacI4M36/TwD9MOxTUFPDk7QqdLO2nK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ML12C/dJMcacI4M36/TwD9MOxTUFPDk7QqdLO2nK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FML12C%2FdJMcacI4M36%2FTwD9MOxTUFPDk7QqdLO2nK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1279&quot; height=&quot;816&quot; data-filename=&quot;IMG_7564.PNG&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_7567.PNG&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EBVGL/dJMcabKaWln/ogPvXHZj18akVp5f5ZAJIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EBVGL/dJMcabKaWln/ogPvXHZj18akVp5f5ZAJIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EBVGL/dJMcabKaWln/ogPvXHZj18akVp5f5ZAJIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEBVGL%2FdJMcabKaWln%2FogPvXHZj18akVp5f5ZAJIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;IMG_7567.PNG&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Programing</category>
      <category>개발자</category>
      <category>네트워크</category>
      <category>데이터베이스</category>
      <category>서버</category>
      <category>애플리케이션</category>
      <category>운영체제</category>
      <category>웹</category>
      <category>웹개발자</category>
      <category>프레임워크</category>
      <category>프로그래밍</category>
      <author>애플자라</author>
      <guid isPermaLink="true">https://applejara.tistory.com/684</guid>
      <comments>https://applejara.tistory.com/684#entry684comment</comments>
      <pubDate>Mon, 9 Mar 2026 13:16:56 +0900</pubDate>
    </item>
  </channel>
</rss>