본문 바로가기

전체 글111

Dart CLI 하나에 REPL과 원샷 명령을 같이 두는 법 CLI 계산기를 만든다고 해봅시다.보통 첫 버전은 이런 모양입니다.dart run calculator:calculate "2+3"결과를 출력하고 종료합니다.자동화 스크립트에서 쓰기 좋고, 셸 파이프라인에도 넣기 좋습니다.그런데 직접 여러 식을 입력하며 놀아보려면 매번 명령을 다시 실행해야 합니다.그래서 인터프리터를 하나 더 만들고 싶어집니다.dart run calculator:interpreter> 1/5Result: 0.2> historyCalculation History:- 1/5 = 0.2이때 선택지가 생깁니다.두 프로그램을 별도 패키지로 만들까요?하나의 실행 파일에 옵션을 잔뜩 붙일까요?flutter_calculator_app은 같은 Dart 패키지에 실행 진입점 두 개를 둡니다.calculato.. 2026. 8. 28.
Pigeon 생성 모델을 공개 API로 내보내면 안 되는 이유 Flutter 플러그인에서 Pigeon을 쓰면 참 편합니다.Dart와 Kotlin, Swift 사이에 오가는 메시지 타입과 채널 코드를 만들어주니까요.스키마를 작성하고 생성 명령을 돌리면 DTO도 생깁니다.이미 타입도 있고 필드도 다 있는데 굳이 모델을 하나 더 만들 필요가 있을까요?있습니다.그것도 꽤 강하게요.생성된 DTO를 그대로 플러그인의 공개 API로 내보내면, 플랫폼 채널의 내부 사정이 사용자 코드의 계약이 됩니다.Pigeon 스키마를 바꾸는 순간 생성 코드만 바뀌는 게 아니라 플러그인을 사용하는 모든 앱의 타입까지 흔들릴 수 있습니다.warm_alarm의 구조는 이 문제를 공개 모델과 전송 모델의 경계로 풀었습니다.앱 코드 -> 손으로 작성한 공개 모델 -> 플랫폼 구현의 매핑 계층 ->.. 2026. 8. 27.
번역 라이브러리 없이 다국어 상태 만들기: useSyncExternalStore와 localStorage 다국어 지원을 붙여야 한다고 하면 보통 패키지부터 찾습니다.next-intl, react-i18next, i18next 같은 이름들이 줄줄이 나오죠.당연합니다.복수형, ICU MessageFormat, 번역 파일 분할, 지연 로딩, 번역 플랫폼 연동까지 생각하면 검증된 라이브러리를 쓰는 게 맞습니다.그런데 영문과 한글만 있는 작은 단일 페이지라면 어떨까요?필요한 건 사실 네 가지뿐일 수 있습니다.현재 언어를 읽는다.언어를 바꾸면 React 컴포넌트가 다시 렌더링된다.새로고침해도 선택이 남는다.서버 렌더링 중에는 window를 찾다가 쓰러지지 않는다.localizations 저장소에서는 이 문제를 useSyncExternalStore와 localStorage로 풀었습니다.거창한 프레임워크를 새로 만든 건 .. 2026. 8. 27.
임계값 하나로는 '확신'을 표현할 수 없다 (feat. 1등과 2등이 붙어 있을 때) 사진 정리 도구를 만들다가 자동 라벨링 기능을 붙였습니다. 얼굴을 찾고, 임베딩을 뽑고, 비슷한 것끼리 묶고, "이 사진은 A네" 하고 자동으로 딱지를 붙여주는 그거요.처음엔 당연히 이렇게 짰습니다.if score >= threshold: auto_label(photo, top_candidate)점수가 기준을 넘으면 자동 확정. 안 넘으면 사람이 봐라. 깔끔하죠. 슬라이더 하나 만들어서 대시보드에 꽂아놓고 뿌듯해했습니다.이게 왜 부족한지 깨닫는 데 시간이 좀 걸렸습니다.0.85와 0.84가 나란히 있을 때문제 상황을 그림으로 그려볼게요. 임계값을 0.8로 잡아뒀습니다.사진 #1 1등: A(0.93) 2등: B(0.41) → 통과사진 #2 1등: A(0.85) 2등: B(0.84) .. 2026. 8. 26.
긴급도를 저장하지 않기로 했습니다 (매초 UPDATE 치는 대신) 할 일 관리 앱을 만들면서 아이젠하워 매트릭스의 발상을 가져왔습니다. 아시죠, 긴급도와 중요도 두 축으로 할 일을 갈라 보는 그거. 화면에 네 칸을 그린 건 아니고, 두 값을 곱해 하나의 등급으로 만들어 목록을 정렬합니다.중요도는 쉬웠습니다. 사용자가 정하는 값이니까 그냥 저장하면 돼요.긴급도에서 막혔습니다. 긴급도는 마감이 다가올수록 올라가야 하거든요. 오늘 저녁 마감인 일과 다음 달 마감인 일이 같은 칸에 있으면 안 되니까요.그래서 처음 든 생각이 이거였습니다. "그럼 긴급도를 어떻게 저장하지?"이 질문 자체가 잘못됐다는 걸 아는 데 좀 걸렸습니다.저장하려고 했더니 나오는 선택지들긴급도를 컬럼으로 들고 있으려면 누군가는 그 값을 갱신해야 합니다. 방법을 세 개 떠올렸는데, 전부 마음에 안 들었어요.1.. 2026. 8. 26.
내 파이프라인이 내 옛날 블로그를 차단했습니다 (feat. 자기 조상 잡아먹기) 요즘 개인 프로젝트로 수입 고양이 사료 영양 카탈로그를 만들고 있습니다.집에 고양이가 있으니 사료 성분표를 자주 들여다보게 되는데, 브랜드마다 표기 방식이 제각각이라 한자리에 모아서 비교하고 싶었거든요.Next.js에 Supabase, 그리고 빈칸 채우는 건 Anthropic API를 붙였습니다."AI한테 시키면 알아서 채워주겠지" 하는 그 흔한 낙관으로 시작했죠.그러다 어느 날 제가 짠 코드 한 줄을 보고 잠깐 멈췄습니다.const BLOCKED_DOMAINS = ["catminzzi.tistory.com"];catminzzi.tistory.com.이거, 제가 예전에 열심히 쓰던 고양이 사료 블로그입니다.대부분 2020년쯤 사료 리뷰를 부지런히 올리던, 그 시절의 저 말이에요.참고로 지금도 멀쩡히 살아.. 2026. 8. 26.