공정관리 시스템, 공정 단계를 직접 바꾸는 기능이 꼭 필요할까?
제조 고객사의 공정관리 앱을 만들면서 계약서에 이런 한 줄이 들어갔습니다. 「직원이 공정 단계를 직접 정의하고, 진행 상태를 기록한다.」 진행 상태 기록은 이미 넘치게 만들어 둔 뒤였습니다. 남은 것은 「정의」 쪽이었고, 처음에는 설정 화면 하나면 끝날 일로 보였습니다.
제조 고객사의 공정관리 앱을 만들면서 계약서에 이런 한 줄이 들어갔습니다. 「직원이 공정 단계를 직접 정의하고, 진행 상태를 기록한다.」 진행 상태 기록은 이미 넘치게 만들어 둔 뒤였습니다. 남은 것은 「정의」 쪽이었고, 처음에는 설정 화면 하나면 끝날 일로 보였습니다.
긴 작업 중간에 코딩 에이전트가 Conversation compacted라는 한 줄을 띄웁니다. 작업은 끊기지 않고 이어집니다. 그런데 몇 턴 뒤 에이전트가 앞에서 안 된다고 결론 내린 방법을 다시 꺼내 듭니다. 고친 적 있는 파일 경로를 한 글자 틀리게 부르기도 합니다.
웹 서비스 하나가 도커 컨테이너로 떠 있다고 해 보겠습니다. 포트는 리버스 프록시 뒤에 있고, 관리 화면은 막혀 있고, 비밀번호는 길고 무작위입니다. 입구는 잘 잠겨 있습니다.
업무용 PC는 VLAN 10, 손님용 Wi-Fi는 VLAN 20으로 나눴다고 해 보겠습니다. 손님 Wi-Fi에 붙은 노트북에서 업무망 프린터 주소로 ping을 보냅니다. 많은 경우 응답이 돌아옵니다.
새 테이블이 필요한 기능을 배포하면서 운영 DB에 Prisma 마이그레이션을 직접 돌려야 했습니다. 이 프로젝트는 Vercel 빌드에서 마이그레이션을 돌리지 않습니다. 프리뷰 빌드가 운영 DB를 건드리거나, 빌드가 중간에 실패해서 스키마가 반쯤 바뀐 채 남는 일을 막으려고 일부러 뺐습니다. 그래서 스키마를 바꾸는 배포는…
비밀번호 하나로 지키던 관리자 로그인에 TOTP, 신뢰 브라우저, 복구 코드, 패스키를 붙였습니다. 네 수단은 막는 공격이 다르고, 서로 어떻게 맞물리게 할지 정할 것도 생각보다 많았습니다. 이 글은 구현하면서 정한 기준과 중간에 바로잡은 설계의 기록입니다.
웹사이트 기획서에는 「레퍼런스 사이트」라는 장이 자주 들어갑니다. 업계 상위 회사 다섯 곳의 첫 화면 캡처가 나란히 붙고, 그 아래에 「참고: 메인 비주얼 구성, 메뉴 구조, 색감」이라고 적힙니다. 이 장을 따라 만든 사이트는 대개 그 다섯 곳과 닮게 됩니다. 그리고 고객은 여섯 개의 비슷한 사이트 중에서 고르게 됩니다.
회사 소개 사이트의 첫 화면에 흔히 이런 문장이 걸립니다. 「고객 중심의 신뢰할 수 있는 파트너」. 이 문장에서 회사 이름을 경쟁사 이름으로 바꿔 넣어 보면 틀린 데가 하나도 없습니다. 어느 회사에 붙여도 맞는 문장이라면, 그 문장은 아무 회사도 설명하지 못합니다.
「지피지기면 백전백승」이라는 말은 손자병법에 없습니다. 모공편의 원문은 이렇습니다.
운영 데이터베이스가 있고, 데이터베이스 서비스가 매일 자동 백업을 해 주고, 같은 계정의 파일 저장소에 덤프를 하나 더 올려 둡니다. 사본은 셋입니다. 저장 방식도 데이터베이스와 파일 저장소로 둘입니다. 3-2-1 규칙의 숫자는 모두 맞습니다.
LLM 기능을 개발하면서 테스트는 몇 달째 로컬 모델로만 돌리고 있습니다. 대화, 툴을 부르는 에이전트, 문서에서 필드를 뽑는 구조화 추출, 이미지 인식, 요약까지 전부 자체 추론 서버 한 대에서 확인했습니다. 호출 비용이 0원이라 마음 놓고 몇백 번씩 돌릴 수 있다는 점이 가장 컸습니다. 그런데 기능이 늘수록 로컬 모…
고객사 명의로 Supabase Pro 프로젝트를 하나 만들고 운영 DB를 옮겼습니다. 요금표를 읽다 보니 용량 말고도 Pro에서만 켤 수 있는 항목이 몇 개 보였습니다. 사용자 도메인, IPv4 직결, 브랜치입니다. 이름만 보면 다 있으면 좋을 것 같아서 다른 관리형 Postgres(Neon, PlanetScale, A…
직접 빌드한 .dmg를 다른 맥에 보내면 "확인되지 않은 개발자"라는 창이 뜨고 앱이 열리지 않습니다. 같은 앱의 Windows 설치 파일은 파란 "Windows의 PC 보호" 창에 막힙니다. 두 경고 모두 코드 서명이 없어서 생깁니다.
지난 글에서 저는 클립보드 관리자를 Tauri로 만들면 가장 어려운 부분이 결국 네이티브 코드로 남는다고 썼습니다. 그 뒤 실제로 Tauri 2로 CopyFocus라는 클립보드 관리자를 만들었습니다. 결과부터 말하면 예상은 절반만 맞았습니다. 직접 짠 네이티브 코드는 생각보다 훨씬 적었고, 대신 예상하지 못한 곳에서 운…
클립보드 관리자를 만들겠다고 하면 첫 질문은 대개 "UI를 뭘로 짤까"입니다. React가 익숙하면 Electron이나 Tauri, 네이티브가 좋으면 SwiftUI를 떠올립니다. 그런데 이 앱의 화면은 검색창 하나와 목록 하나가 거의 전부입니다. 나머지는 운영체제와 주고받는 일입니다.
Vultr 인스턴스와 다른 ISP 회선에 있는 서버 사이에서 패킷이 하루에 몇 번씩 사라졌습니다. 한 번 시작되면 1분에서 15분 동안 4080%가 손실됐고, 손대지 않아도 다시 멀쩡해졌습니다. 원인은 두 회사 망이 만나는 중간 구간에 있었고, 그 구간은 제 손이 닿지 않는 곳이었습니다.
「체스, 지뢰찾기, 스티커 메모를 빼면 앱이 가벼워지고 빨라질까?」 웹 데스크톱에 메모 앱을 하나 더 붙인 뒤 이 질문이 나왔습니다. 기능이 늘수록 첫 화면이 무거워지는 건 당연해 보였고, 가장 쉬운 답은 덜 쓰는 앱을 지우는 것이었습니다.
배포 버튼을 누르고 얼마 뒤 모니터링에 502 가 몇 개 찍힙니다. 새 버전은 헬스체크를 통과했고, 옛 버전은 로드밸런서에서 뺐습니다. 순서대로 했는데 요청이 끊겼습니다. 같은 시각 브라우저 콘솔에는 ChunkLoadError 가 뜹니다. 방금 받은 페이지가 존재하지 않는 자바스크립트 파일을 달라고 한 것입니다.
구글과 네이버에 서브도메인 열세 개를 등록하고 사이트맵까지 낸 뒤 Bing 등록을 시작하고 나니, 할 일이 끝났다는 기분이 들었습니다. 콘솔마다 「성공」이 떴고 발견된 페이지 수도 나왔습니다. 그런데 네이버 수집요청 가이드에 이런 문장이 있었습니다.
서브도메인 열세 개를 검색엔진에 등록하는 데 구글은 DNS 레코드 한 줄이었고, 네이버는 같은 일을 열세 번 반복해야 했습니다. 두 도구의 기능 목록은 비슷합니다. 사이트맵을 받고, 소유를 확인하고, 수집 현황을 보여 줍니다. 갈리는 것은 무엇을 사이트 하나로 세는가였습니다.