[n8n] 근무 일수, 주급 조회하는 텔레그램봇 만들기
·
AI & Tools
일전에 n8n을 활용해 내 아이폰 캘린더의 일정을 기반으로 근무일지 시트를 작성했다. [n8n] 파트타임 근무 시간 기록 자동화개요시급제 파트타임으로 일한지 한달 째. 매일 근무 시간이 달라 매주 주급을 계산하는게 일이었다.스케줄을 아이폰 캘린더에 저장해뒀다가 매주마다 근무 시간을 세고 있던 것도 한달 째.요hyun-eee.tistory.com 주급을 계산하기 위해 매번 이 시트를 열어보는 것도 귀찮은데...텔레그램에서 명령어만 입력하면 내가 원하는 날짜의 주급을 알려주면 좋겠다, 싶어근무일지 시트를 연동한 텔레그램봇을 만들었다. 텔레그램봇은 BotFather로 간단하게 만들었다. (접근 제한을 안해둬서 이름은 비공개) 동작은 두가지 밖에 없다. Switch 노드로 구분했다.1) /check_pay ..
[n8n] 파트타임 근무 시간 기록 자동화
·
AI & Tools
개요시급제 파트타임으로 일한지 한달 째. 매일 근무 시간이 달라 매주 주급을 계산하는게 일이었다.스케줄을 아이폰 캘린더에 저장해뒀다가 매주마다 근무 시간을 세고 있던 것도 한달 째.요즘 같은 세상에 이걸 직접 세고 있을 순 없다 싶어 자동화를 만들었다. 이번에 사용한 도구는 n8n.노코드 기반 워크플로우 자동화 도구이다.클라우드 서비스는 유료이나 14일간의 트라이얼을 활용해 무료로 이용했다.유용하게 이용되면 설치해 볼 예정.시나리오매일 오후 9시,나의 '근무' 캘린더에서 당일의 이벤트를 근무일지 스프레드 시트에 양식에 맞춰 기록하기 작업 내용위와 같이 워크플로우를 구성했다. Schedule Trigget : 특정 시점에 워크플로우를 실행시키는 트리거 Get many events : 구글 캘린더의 이벤..
iOS 단축어 활용해 미리 알림 항목을 노션에 추가하는 방법
·
etc
개요나는 할 일 관리를 위해 아이폰 미리알림과 노션 캘린더를 주로 사용한다.두 앱을 번갈아가며 사용하다보니 놓치는 항목도 있고 해서 통합할 수 있는 방법을 찾다가iOS 기본 앱인 단축어를 통해 해결을 해보기로 했고몇 시간 삽질한 끝에 완성했다....내가 원했던 동작을 정리하자면1. 노션 캘린더 앱을 실행하면2. 미리알림 항목 중 오늘 마감 & 완료하지 않은 항목을3. 노션 캘린더에 연동된 노션 데이터베이스에 추가하기 작업은 크게 3파트로 구분된다. 1. 노션 API 통합 및 API key와 database id 정보 확인 (상세 단계 1-2)2. 단축어 추가 (상세 단계 3)3. 자동화 설정 (상세 단계 4) 상세 단계1. 노션 API 연결우선 단축어 앱과 노션을 연동하기 위해선 API integra..
로그인/보안 시스템 개선기 - 취약점 발견부터 단계별 강화까지
·
Backend / Server
시작하며이번 프로젝트에서 매직링크 기반 로그인과 JWT 인증을 구현하면서 보안 강화 과정을 거쳤다. 처음에는 단순히 "동작하는" 로그인 시스템을 만드는 것이 목표였지만, 실제로 테스트하고 분석하면서 여러 보안 취약점을 발견했다. 이 글에서는 JWT 토큰 관리 전략부터 실제 구현, 문제점 발견, 그리고 단계별 개선 과정까지 정리해보려 한다. 1. JWT 토큰 관리 전략구현에 앞서 JWT 토큰을 어떻게 관리할지 전략을 세워야 했다.JWT 토큰의 역할 이해JWT 인증에서는 일반적으로 두 가지 토큰을 사용한다.Access Token API 요청에 사용하는 인증 토큰이다. 수명이 짧게 설정되어 있는데, 보통 15분에서 1시간 정도다. 만약 토큰이 탈취되더라도 짧은 시간 내에 만료되기 때문에 피해를 최소화할 수 ..
DB 마이그레이션 Flyway 도입기
·
Backend / Server
DB 마이그레이션DB 마이그레이션이란데이터베이스 스키마(테이블 구조, 인덱스, 제약조건 등)를 안전하게 버전별로 관리하며, 여러 환경(로컬, 개발, 운영 등)에 일관되게 반영하는 프로세스를 의미한다.소스코드를 Git으로 관리하듯, DB 스키마도 버전으로 관리하는 것과 유사하다. DB 구조를 수동으로 수정하는 프로세스를 자동화하고 안정화하는 것이 목적이다. DB 마이그레이션 툴이란DB 변경 내역을 코드화하여 버전 관리하고, 여러 환경에서 동일하게 실행되도록 자동화해주는 도구이다.DB 스키마 변경을 SQL로 정의하고, 실행된 마이그레이션 버전을 기록하고, 충돌 방지, 실행 순서 보장 등 기능을 제공한다. DB 마이그레이션의 필요성이전 프로젝트를 하면서 필요성을 느꼈다.로컬 환경, 운영 환경 각각의 DB를 사..
Claude Code 활용 로그: 개발 루틴 자동화
·
AI & Tools
혼자서 Claude Code를 활용해 웹서비스를 만들고 있다. 코드 작성 뿐만 아니라 워크플로우 전반에 걸쳐 Claude Code를 사용하고 있는데,Claude Code는 질문이나 요청에 대한 답과 가이드를 주는 것을 넘어 직접 처리해주는게 핵심이다. 어쩌면 코드 작성보다 더욱 편리하고 유용한 활용 방법을 기록해둔다. 1. 맥락 참조 문서 세팅하기프로젝트 루트에 참조 문서들을 셋업해두었다. Claude Code가 파악해야 할 맥락을 정리한 것.CLAUDE.md: 프로젝트 핵심 요약 및 절대 어기면 안 되는 대원칙들.domain-glossary.md: 용어집. (예: User는 '사용자'인가 '회원'인가? 변수명은 user인가 member인가?)openapi.yaml: API 스펙이 정의된 파일web-se..
바이브 코딩용 개발 도구 선택 후기 - Cursor vs. Claude Code
·
AI & Tools
목차 바이브 코딩으로 앱 개발을 시작했다.바이브 코딩용 도구를 이것저것 써봤고, 그중에서도 고민을 제일 많이 했던 게 Cursor와 Claude Code였다.(우리 교수님이 Cursor에 돈을 엄청 쓰셨다고 해서;;) 결론은 Cursor를 처음에 써봤다가 Claude Code 써보고 바로 갈아탔다. 이 글은 그냥 내가 왜 Cursor에서 Claude Code(IntelliJ)로 넘어갔는지에 대한 기록.개인적인 사용 경험과 느낌 위주라서 정답은 아닐 수 있음. Cursor의 모든 기능을 완전히 이해하고 사용한 상태에서 비교하는 게 아닙니다.IntelliJ + Claude Code가 훨씬 쉽고 유용하게 느껴졌을 뿐.. 1. Cursor Cursor는 VS Code 기반 IDE라 굉장히 직관적이고 빠르다..
리버스 프록시 개념 이해
·
Infra/DevOps
프록시 서버는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 하는 컴퓨터 시스템이나 응용 프로그램을 말합니다. 보안 상의 이유로 직접 통신할 수 없는 서로 다른 네트워크 사이에서 중개 역할을 수행합니다. 프론트 프록시와 리버스 프록시로 구분할 수 있는데, 본 글에선 리버스 프록시에 대해 정리했습니다. 1. 리버스 프록시(Reverse Proxy)리버스 프록시란 클라이언트와 웹 서버 사이에서 중개를 하는 서버를 말합니다. 클라이언트의 요청을 리버스 프록시가 대신 받아 웹 서버에 전달하고, 웹 서버의 응답을 다시 클라이언트에게 전달합니다. 중개 역할을 통해 웹 서버의 부하를 분산시키고 보안을 강화하는 등 다양한 기능을 수행할 수 있습니다. 2. 리버스 프록시 사용 이점 서버 ..
[Spring] Mixed Content 에러 (HTTPS 페이지에서 보안이 적용되지 않은 HTTP 리소스 로드 시)
·
Trouble Shooting
목차프론트엔드와 백엔드 서버를 각각 Vercel, AWS EC2에 배포한 후, 프론트엔드 서버에서 백엔드 API를 호출하는 과정에서 Mixed Content 에러가 발생했습니다. 1. Mixed Content 에러 프로젝트 환경:Frontend: Vercel에 배포된 웹 애플리케이션 (https://xxxxx.vercel.app)Backend: AWS EC2에 배포된 Spring Boot API 서버 (http://3.38.xx.xxx:8080)문제 현상:프론트엔드 애플리케이션에서 백엔드 API로 데이터 요청(fetch/axios)을 보냈을 때, 브라우저 개발자 도구의 네트워크 탭에서 요청 상태가 (차단됨:mixed-content) 로 표시되며 API 호출이 실패함.콘솔 탭에는 "Mixed Conten..
Spring Boot 멀티 모듈 아키텍처
·
Backend / Server
목차최근 진행한 프로젝트를 멀티 모듈 아키텍처로 설계했습니다.API 처리 서버(Main Server)와 비동기 작업 처리 서버(Worker Server)를 하나의 프로젝트에서 모듈로 분리한 것인데요.하나의 레포지토리에서 두 서버를 독립적으로 빌드 & 실행할 수 있었습니다. 제가 직접 구현한 담당자는 아니었지만, 이에 대해 기록해보려 합니다. 1. 멀티 모듈 프로젝트 구조두 개의 모듈을 관리할 수 있도록 프로젝트 구조는 아래와 같이 구성했습니다.web-ide-be/├── main-server/ # 사용자 API, 인증, WebSocket 등│ ├── build.gradle│ ├── Dockerfile├── worker-server/ # 코드 실행, 비동기 작업 처리│ ├──..
채팅 기능의 마크다운 렌더링 기능 개선 과정
·
Backend / Server
목차 Web IDE 프로젝트 중 채팅 기능의 마크다운 렌더링 기능을 개선했던 경험을 공유하고자 합니다. 사용성 향상과 프론트엔드 작업 최소화라는 두 가지 목표를 달성하기 위해 어떤 고민을 했고, 어떻게 코드를 변경했는지 정리해 보았습니다. java 기반 마크다운 파싱 라이브러리 중 commonmark-java가 가장 일반적으로 사용되는 것으로 보여 이를 사용했습니다. 1. AS-IS (개선 전)기존 시스템은 사용자의 채팅 메시지를 받으면, 이를 그대로 클라이언트에 전송하는 구조였습니다.// 채팅 메시지 전송 로직 (개선 전)return new ChattingResponseDto(..., content);이렇게 되면 마크다운으로 작성된 메시지를 화면에 표시하기 위해 클라이언트(프론트엔드)에서 마크다운 파싱..
UriComponentsBuilder 사용해 URI 작성하기
·
Backend / Server
목차1. UriComponentsBuilder 소개URI를 안전하게 생성하기 위한 Spring 제공 빌더 클래스입니다.하드코딩 없이 경로, 쿼리 파라미터, 인코딩 등 URI의 각 요소를 체이닝 방식으로 조립하여 깔끔하게 처리할 수 있습니다.코드의 가독성을 높이고 인코딩 실수를 방지할 수 있습니다.단순 문자열 조합 방식보다 안전하고 유지보수가 쉬운 방식으로 URI를 조립할 수 있게 합니다. 단순 문자열 연결 방식String url = "http://localhost:3000/auth/login" + "&userId=" + tokens.userId() + "&name=" + URLEncoder.encode(tokens.name(), "UTF-8");오타나 파라미터 인코딩 실수의 위험이 있습니다.복..
Swagger에서 Refresh Token 검증 테스트
·
Trouble Shooting
Spring Boot + Swagger 환경에서 JWT Refresh Token RTR 방식을 적용하다가 쿠키가 내려오지 않는 문제를 겪었다. 오늘 하루 동안의 트러블슈팅 과정을 정리한다. JWT Access/Refresh Token 발급과 Redis 저장까지는 정상적으로 동작했다. 그러나 Swagger에서 /auth/refresh 테스트를 하면 자꾸만 invalid token이라는 응답만이 돌아올 뿐이었다.. 코드를 이리저리 고쳐보다가 Swagger에서 /auth/login 요청 후 응답 헤더에 Set-Cookie 항목이 보이지 않는 것을 발견했고, 따라서 Refresh Token을 확보해 /auth/refresh 요청을 테스트할 수 없었다는 것을 깨달았다. 시도한 방법처음에는 시크릿 키 인코딩 문..
Spring Cache(@CachePut) + Spring Data Redis 사용 시 직렬화 오류
·
Trouble Shooting
Chats 객체 캐시 저장 시도 -> 에러 WebSocketAnnotationMethodMessageHandler ... Could not write JSON: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling로그 전체 🔽더보기2025-08-20T16:01:44.759Z ERROR 3007 --- [boundChannel-13] .WebSocketAnnotationMethodMessageHandler : Unhandled exception from message handler m..
[Spring Boot] 하나의 애플리케이션에서 둘 이상의 용도로 Redis 사용하기
·
Trouble Shooting
사용 중인 Redis : Redis Cloud Free Trial1 databasemax 30MB용도별 Redis 사용:리프레시 토큰 저장채팅 메시지 임시 캐싱 하나의 애플리케이션에서 둘 이상의 용도로 Redis 사용하는 방법1. 단일 Redis 인스턴스 내에서 DB index로 구분 - 유료 플랜만 지원2. 단일 Redis DB에 Key Prefix로 구분 - refresh:USERID, chat:ROOMID 등으로 key 구분3. Redis Cloud 계정 2개 생성 - 복잡 - 멀티 Redis 설정 예시 // application.ymlspring: data: redis: first: # refresh token host: ${REDIS_HOST_RT} ..
command not found: -p (CLI 공백 주의)
·
Trouble Shooting
RabitMQ 설치하려고 docker run 명령어를 입력했다 docker run -d --name rabbitmq \\ -p 5672:5672 \\ -p 15672:15672 \\ -p 61613:61613 \\ rabbitmq:management 실행 실패. 로그는 command not found: -p docker: invalid reference formatRun 'docker run --help' for more informationzsh: command not found: -pzsh: command not found: -pzsh: command not found: -pzsh: command not found: rabbitmq:management 구글링 시 환경변수 설정에 대한 글만 나..
[React] Drag and Drop 구현하기 (HTML API)
·
Frontend/HTML/CSS/JavaScript
리액트 투두리스트 과제 중, Drag and Drop 기능을 구현했다.react-beautiful-dnd는 지원이 종료되어, HTML Drag and Drop API를 활용했다.지금은 Drag and Drop 1단계 정도고, 계속 응용 해볼 예정. 참고: MDN 문서  | 인파, 드래그 앤 드롭 기능 이해 & 구현하기 | jinist, [React] Drag and Drop 이벤트 적용해보기       우선 이 투두리스트 드래그앤드랍 기능과 관련한 컴포넌트는 두 개가 있다. (1. 최상위 컴포넌트 2. Todo Item 컴포넌트) 1. 최상위 컴포넌트드래그 이벤트 함수를 정의한다.const App = () => { // 드래그 중인 요소, 드래그 하면서 지나치고 있는 요소를 useState로 정의한..
[React/JSX] 클래스 컴포넌트 vs 함수형 컴포넌트
·
Frontend/HTML/CSS/JavaScript
Class Component vs Functional Component (React JSX) React에서는 컴포넌트를 만들 때 두 가지 방식이 있다:Class Component (클래스 컴포넌트)Functional Component (함수형 컴포넌트) 🎯 1. Class Component (클래스 컴포넌트) 클래스를 사용해 컴포넌트를 정의하는 방식 (ES6 Class 문법 활용)state와 라이프사이클 메서드를 사용할 수 있음.  예제:import React, { Component } from 'react';class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; // sta..
[JavaScript] Symbol이란?
·
Frontend/HTML/CSS/JavaScript
Symbol은 JavaScript에서 유일한(Unique) 값을 생성하는 데이터 타입.ES6(ES2015)에서 도입되었으며, 객체의 프로퍼티 키로 사용하면 다른 코드와 충돌하지 않도록 보호할 수 있다. 1️⃣ Symbol 기본 사용법 Symbol 생성하기const sym1 = Symbol();const sym2 = Symbol();console.log(sym1 === sym2); // false (항상 서로 다른 값)두 개의 Symbol은 같은 값처럼 보여도 서로 다른 값임. 2️⃣ Symbol의 주요 특징 Symbol은 고유한 값을 가지며, 절대 중복되지 않음 Symbol은 자동 형 변환이 불가능 (alert(Symbol()) 하면 에러 발생) Symbol은 객체의 키(key)로 사용 가능 Symbol..
[JavaScript] 디자인 패턴
·
Frontend/HTML/CSS/JavaScript
디자인 패턴은 효율적이고 유지보수하기 쉬운 코드 구조를 만들기 위한 일반적인 해결 방법이다.JavaScript에서는 객체지향 프로그래밍(OOP), 모듈화, 비동기 처리 등을 다루는 여러 패턴이 존재. 🎯 1. Singleton Pattern (싱글턴 패턴) • 하나의 인스턴스만 생성하고, 어디서든 동일한 인스턴스를 공유하는 패턴.• 전역적으로 공유해야 하는 설정 데이터, 데이터베이스 연결, 상태 관리 등에 많이 사용됨. 📌 JavaScript에서 싱글턴 패턴 구현const Singleton = (function () { let instance; // 단 하나의 인스턴스를 저장할 변수 function createInstance() { return { message: "나는 유일한..