일기 slecs

끝이 없을 것 같던 하루, 그래도 다 밀었다

목차

오늘은 정말 많이 했다. 커밋 로그처럼 나열하면 글이 아니니까 느낀 것 위주로.

대량환불 파이프라인, 암호화 삽질 포함

제일 오래 붙잡은 건 대량환불 쪽이었다. AES-CBC 암호화를 붙이고, 은행코드 매퍼 짜고, 관리자 화면까지 미리보기·실행 단계로 나눠 올리는 것까지 한 흐름에 다 처리했다. 흐름 자체는 잘 잡혔는데 암호화 키 포맷이랑 패딩 처리에서 예상 외로 시간을 먹었다. "이 정도야" 하고 시작했다가 이십 분을 날렸다.

AES-CBC는 만만해 보이는데 실제로는 잡아먹는 포인트가 세 군데다. IV 생성 방식, 패딩 규격(PKCS7이냐 zero-padding이냐), 그리고 키를 raw 바이트로 주고받느냐 hex 문자열로 전달하느냐 — 이 세 가지 중 하나라도 서버-클라이언트 사이에서 어긋나면 복호화 결과가 그냥 쓰레기가 됨. 에러 메시지도 친절하지 않아서 "데이터가 유효하지 않음" 정도가 전부다. 그 상태로 어디가 문제인지 추적하면 시간이 녹는다.

# IV는 매 암호화마다 새로 생성, 암호문 앞에 붙여서 전달
iv = os.urandom(16)
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
encrypted = iv + cipher.encrypt(pad(plaintext, AES.block_size))

코드 자체는 간단한데, 오늘 문제는 상대 API가 키를 base64로 내려주는 걸 hex라고 착각하고 시작한 것. 스펙 문서를 먼저 열어놨으면 안 났을 버그다. 다음에는 그냥 처음부터 문서 옆에 열어두고 시작하자. 항상 암호화 쪽은 괜찮겠지 싶을 때 한 방 맞는다.

관리자 화면을 미리보기 단계와 실행 단계로 분리한 건 잘한 것 같다. 대량 처리 UI에서 "실행" 버튼 하나만 덩그러니 있으면 언젠가 사고가 난다. 확인 단계를 강제로 끼워넣는 것만으로도 운영 실수를 꽤 줄일 수 있고, 나중에 불편하다고 빼달라는 요청이 오더라도 그건 버텨야 하는 부분이다.

블로그 대청소 + launchd SSH 지옥

블로그는 그야말로 대청소였다. 도메인 이전 반영에 발행 방식도 바꿨다. 커밋마다 글 하나씩 쏘는 구조가 잡음이 너무 많다 싶어서 시간 단위 종합글로 전환하고, 오늘처럼 일과 마지막 회고 일기도 붙이는 구조로 바꿨다. 발행 글 길이도 2500~4000자 수준으로 올렸는데, 짧게 쓰는 게 더 어렵다는 걸 알면서도 길이를 늘린 건 품질 기대치를 높이고 싶어서임.

알림이 텔레그램이랑 디스코드 둘 다로 안 가던 문제도 잡았다. 어이없게도 디스코드 웹훅 URL이 만료된 게 원인이었다. 텔레그램만 잘 오니까 한참 코드를 의심했는데 그냥 토큰 문제. 이런 류의 버그는 증상이 로직 오류처럼 보여서 헛수고를 유도한다. 외부 연동이 끊겼을 때 에러 로깅이 제대로 안 되면 이런 식으로 삽질을 한다. 다음에는 웹훅 상태 체크도 발행 파이프라인 앞단에서 돌리는 게 맞겠다 싶었다.

SSH 인증이 launchd 환경에서 비밀번호 직행으로 안 풀리던 것도 결국 해결했다. 로컬 터미널에서는 멀쩡한데 launchd 컨텍스트에서만 깨지는 그 특유의 불쾌함이 있었다. 원인은 SSH_AUTH_SOCK 환경변수가 launchd job에 전달이 안 되는 것. 소켓이 없으면 키 인증이 스킵되고 패스워드 프롬프트로 떨어지는데, 백그라운드 잡에서는 프롬프트 자체에 응답이 불가라 그냥 조용히 죽는다. macOS는 keychain 연동으로 이걸 우회할 수 있는데, ssh config에 UseKeychain yesAddKeysToAgent yes를 박아두면 launchd 컨텍스트에서도 소켓 없이 인증이 됨. 한 줄 추가로 끝났는데 찾기까지가 문제였다.

AdSense 대응, 디자인 정비, 인프라 이관

opsvoro 쪽은 AdSense 대응이 메인이었다. 가짜 1인칭 표현, 수동태로 쓰인 hands-on 주장 같은 것들을 탐지·제거하는 scrub 로직을 강화했고, 기존에 쌓인 187개 본문을 Sonnet으로 일괄 재작성하는 툴도 만들었다. 이게 좀 씁쓸하다. 글 쓴다고 써놨는데 정작 진짜 경험인 척하는 표현들을 걷어내야 한다는 게, 처음부터 정직하게 썼어야 했다. 저자 표기도 편집팀으로 솔직하게 정리했다. 늦었지만 안 하는 것보다는 낫다.

펫 사이트랑 장례 사이트 디자인도 오늘 둘 다 건드렸다. 펫은 밝고 따뜻한 톤으로 풀 오버홀, 장례는 한지 느낌 격조 테마. 그리고 둘 다 명암비 AA 교정을 꼼꼼히 했다. WCAG AA 기준 4.5:1이 어지간한 색 조합에서 얼마나 자주 미달하는지, 직접 재보기 전엔 잘 모른다. 명암비 작업은 눈에 잘 안 띄지만 할 때마다 "이건 맞는 일이다"라는 느낌이 든다.

카드 썸네일을 AI 이미지 대신 Lucide SVG로 다 교체한 것도 마찬가지. AI 이미지는 렌더링 품질이 들쭉날쭉하고 사이트 전체 스타일을 통일하기가 어렵다. SVG 아이콘은 CSS 한 줄로 컬러 테마를 전체에 먹일 수 있고, 용량도 확연히 가볍다. 간결한 결정이었고 기분이 좋았다.

항목 변경 전 변경 후
카드 썸네일 AI 생성 이미지 Lucide SVG
명암비 미검증 WCAG AA 교정
저자 표기 불명확 편집팀 명시
본문 품질 scrub 없음 탐지·제거 로직
발행 알림 텔레그램만 텔레그램 + 디스코드

DB를 iwinv 관리형으로 이관한 것도 오늘 마무리됐다. 신규 서버 세 대 접속정보 정리, CF rate-limit 자동화 통합까지. 인프라 이전은 끝나고 나서 조용하면 잘 된 거다. 오늘은 조용했다.

내일은 대량환불 실행 로직 마무리 테스트, opsvoro 재작성 완료 확인, 블로그 발행 파이프라인 실제로 한 사이클 눈으로 보는 것. 오늘 너무 많이 열었으니까 내일은 닫는 날로.

댓글 0

첫 댓글 달아줘.