Dev Notes
& Snippets
코드 중심 기술 글
AI로 만드는 ERP인데, 1단계에는 AI가 한 줄도 없다
이관 어시스턴트를 만들기로 하고 가장 먼저 짠 것은 재고 원장과 비관적 락이었다. 그리고 가장 값진 버그는 내가 만든 데드락을 테스트가 잡아준 것이었다.
트리거를 볼 권한이 없는 채로 레거시를 이관했다
헤더가 4행부터 시작하는 엑셀과 문자셋이 euckr인 구 시스템. 숨은 규칙을 끝내 보지 못했는데도 구·신 재고가 한 자리도 안 틀리게 맞았다.
AI를 잘 맞히게 만드는 게 목표가 아니었다
컬럼 6개 중 5개를 AI가 읽어냈다. 그런데 이 단계에서 제일 공들인 건 나머지 두 개를 모른다고 말하게 만드는 쪽이었다.
AI에게 SQL을 쥐여주기 전에, 삭제부터 시켜 봤다
자연어로 물으면 AI가 조회문을 만들어 진짜 DB에서 실행한다. 그 앞에 방어를 네 겹으로 세웠고, 마지막 한 겹은 코드가 아니라 DB 권한이다.
화면의 숫자가 거짓말을 하고 있었다
에러를 내고 죽는 버그는 차라리 낫다. 이 편은 아무 소리 없이 틀려 있던 것들 — 페이징, 일괄 치환, 컨테이너 초기화, 그리고 내가 고쳤다고 말한 색 이야기다.
라이트하우스가 시킨 것, 그리고 안 고친 것 하나
숨겼는데 경고가 안 사라졌다. ul 을 줬는데 ul 이 아니라고 했다. 도구가 맞았고 내가 틀렸다. 다만 하나는 알면서 안 고쳤다.
AI를 안 쓰기로 했다
카드 상세의 개인 맞춤 분석은 외부 AI를 한 번도 부르지 않는다. 문장 조각 124개와 가중치 규칙만으로 수천 가지 결과를 만든다. 그리고 같은 사람은 언제나 같은 결과를 받는다.
로컬은 다 통과하는데 운영만 죽는다
테스트 82개가 전부 초록불인데 배포하면 502가 반복됐다. 로그를 볼 수 없는 곳에서, 볼 수 있게 만드는 것부터 시작해야 했다.
에러가 나도 화면은 죽지 않게
외부 API가 실패해도 페이지 전체가 무너지지 않게 하는 전략. 에러 상태도 디자인의 일부다.
카운트는 다 달랐는데 차트는 평평했다
데이터를 고쳤는데 화면이 안 바뀐다. 이미지도, 통계도 그랬다. 저장된 값과 화면에 그려지는 값은 다른 층위다. 그걸 세 번 더 배웠다.
className 지옥에서 벗어나기 — CSS 객체 패턴
JSX를 뒤덮은 Tailwind 클래스 문자열을 tw() 헬퍼와 CSS 객체로 분리해 마크업 가독성을 되찾은 기록.
로딩바 하나에 세 번 속았다
RSC와 react-query 중 하나를 고르지 않았다. 셋을 공존시키고 화면마다 골랐다. 그런데 원칙대로 만든 화면 하나가 3~4초씩 멈췄고, 나는 하루에 세 번 원인을 헛짚었다.
접근성은 미루면 빚이 된다
aria-label과 포커스를 나중에 몰아 고치다 깨달은 것. 시맨틱하게 짜면 접근성의 8할은 공짜다.
GitHub Actions로 블로그 운영을 자동화했다
콘텐츠 저장소에 push하면 배포까지 알아서 굴러가는 파이프라인을 만들었다. 혼자 운영해도 시스템은 팀처럼 돌아가야 한다.
백엔드를 숨기지 않기로 했다
디자이너·퍼블리셔와 함께 만든 풀스택 프로젝트 DevTI. 첫 결정은 기능이 아니라 구조였다. 서버액션으로 백엔드를 대체하면 편하지만, 그러면 백엔드가 사라진다.
폼 검증, 어디까지 해야 하나
문의 폼을 만들며 정리한 검증 전략. 클라이언트와 서버는 애초에 목적이 다르다.
Lighthouse 100점에 집착해봤다
블로그 성능을 튜닝하면서 폰트, 이미지, 'use client'를 하나씩 손봤다. 점수보다 과정에서 배운 게 더 컸다.
백엔드가 무서웠는데, Supabase로 하루 만에 뭔가 만들었다
프론트만 하던 사람이 Supabase로 방명록을 만들어봤다. RLS에서 한참 헤맸지만, 백엔드 감각이 생기니 프론트 설계가 달라진다.
OG 이미지를 코드로 만든다
next/og의 ImageResponse로 페이지별 OG 이미지를 동적 생성한다. 디자인 툴로 하나하나 만들던 걸 코드로 시스템화한 기록.
블로그에 검색을 달았다 — Fuse.js 적용기
서버 없이 클라이언트 퍼지 검색으로 블로그 검색을 구현했다. 가중치 튜닝과 한글 검색의 미묘함을 기록한다.