2026년 10월
총 114편
웅파 · 2026-10-20
WYSIWYG 에디터의 이미지 alt가 저장되지 않은 진짜 원인
빈 속성값과 속성창의 차이 이미지에 대체 설명문을 입력했는데 저장 후 사라지는 문제가 있었다. 처음에는 서버 저장 로직이나 데이터베이스 컬럼을 의심하기 쉽다. “폼에서 값이 전송되지 않았나?”“Controller가…
웅파 · 2026-10-20
테스트가 서로를 망가뜨릴 때: 주문 테스트 고아 행으로 찾은 스위트 오염
테스트는 각각 독립적으로 통과했는데, 전체 테스트 스위트로 실행하면 일부 테스트가 실패하는 일이 있다. 이런 문제를 처음 만나면 테스트 순서, 실행 속도, 공유 Mock, 혹은 CI 환경을 의심하기 쉽다. 이번에는…
웅파 · 2026-10-20
운영 배포에서만 실패한 slug 마이그레이션: 무음 실패를 실패로 보이게 만들기
운영 배포가 계속 성공했다고 나왔지만, 실제로는 마이그레이션이 매번 실패하고 있었다. 문제의 시작은 게시판 slug 변경이었다. 기존 게시판의 slug를 다음처럼 바꾸는 마이그레이션을 만들었다. boards.slug…
웅파 · 2026-10-20
AI 개발 컨설팅 첫 상담에서 실제로 묻는 질문들
AI 코딩 도구를 도입한 팀과 첫 30분을 보낼 때, 저는 도구 이야기를 거의 하지 않습니다. Claude Code를 쓰는지, 어떤 모델인지는 두 번째 문제입니다. 대신 아래 열두 가지를 묻습니다. 답이 막히는 곳이…
웅파 · 2026-10-20
제품 11개를 한 사람이 운영하는 법: AIFid·AILign·AILicet·AICassa 등 공통 골격과 MSA 서비스 분할 기준
들어가며 저는 AIvance라는 이름으로 SaaS 제품 11개를 혼자 만들고 운영합니다. 비결은 제품을 11번 만든 게 아니라, 골격을 한 번 만들고 11번 재사용했다는 데 있습니다. "혼자서 11개를 어떻게 관리하…
웅파 · 2026-10-20
MSA 신규 시작 vs 기존 모놀리스 유지: 억지로 쪼개지 않는 판단 기준
들어가며 결론부터 말하면, 저는 새 서비스를 거의 항상 모놀리스로 시작합니다. 그리고 쪼갤 때는 "도메인이 다르다"가 아니라 "안 쪼개면 안 돌아간다"는 이유가 있을 때만 쪼갭니다. PHP를 26년 가까이 했고, 주…
웅파 · 2026-10-20
26년 차 개발자가 AI 시대에 직접 쥐는 결정 4가지: 제품 범위, 아키텍처, 가격, 보안
AI가 코드를 쓰는 시대에도 끝까지 내 손에 남겨두는 결정은 네 가지다. 제품 범위, 아키텍처, 가격, 보안. PHP를 26년 했다. 한동안 손을 놓았다가 1년 전 클로드 코드로 다시 개발을 시작했고, 그사이 AIv…
웅파 · 2026-10-20
웅파 17년: CodeIgniter 포럼 운영하며 배운 것
문을 닫고 나서야 쓰는 글 올해 봄, CodeIgniter 한국사용자포럼(CI Korea)의 게시판을 닫았습니다. 지금 cikorea.net에 들어가면 CI4·CI3 매뉴얼 링크와 문의 메일 주소만 남은 한 장짜리…
웅파 · 2026-10-20
OpenAPI를 PHP 어트리뷰트로: $ref 재사용 컴포넌트와 공통 ErrorResponse
에러 응답 스키마는 한 번만 정의하고, 모든 엔드포인트는 $ref 한 줄로 가리킨다. 이 글은 swagger-php의 PHP 8 어트리뷰트로 그 구조를 만든 기록입니다. 왜 이 주제인가 저는 오랫동안 API 문서를…
웅파 · 2026-10-20
CI4 모델·서비스 계층 분리: 컨트롤러를 얇게 유지하는 규칙과 트랜잭션 위치
결론부터 말하면 규칙은 두 줄이다. 컨트롤러는 "검증 → 서비스 호출 → 응답"만 한다. 트랜잭션은 유스케이스를 대표하는 서비스 메서드 하나가 연다. 나머지는 이 두 줄을 지키기 위한 장치다. 왜 이 규칙을 정했나…
웅파 · 2026-10-20
프론트 로그를 큐로 받는 수집 파이프라인: 즉시 202 → Redis → 워커 → 파일 + DB, 실패 시 dead-letter
한 줄 요약 — 로그 수집 API는 받은 것을 Redis에 넣고 바로 202를 돌려줍니다. 파일과 DB에 쓰는 일은 워커가 배치로 하고, 끝내 처리하지 못한 로그는 버리지 않고 dead-letter 큐에 모읍니다.…
웅파 · 2026-10-20
목록에 —가 그대로 찍혔다: strip_tags 다음에 빠진 한 단계
한 줄 요약 — 본문 HTML에서 태그만 벗기고 엔티티는 디코딩하지 않은 채 요약을 잘랐습니다. 그리고 뷰에서 esc()가 &를 한 번 더 이스케이프하면서 —가 글자 그대로 화면에 나왔습니다. 요약을 만들…
웅파 · 2026-10-20
페이지 번호가 41개 전부 나왔다: AI가 만든 페이저 뷰에서 빠진 한 줄
한 줄 요약 — 클로드코드가 만든 커스텀 페이저 템플릿에 $pager->setSurroundCount() 호출이 빠져 있었고, CI4 PagerRenderer는 이 값이 없으면 첫 페이지부터 마지막 페이지까지 전부…
웅파 · 2026-10-20
API 부하 분산 기본기: Redis 캐시 TTL 표, 큐 + 202 Accepted, N+1과 SELECT * 금지
한 줄 요약 — API가 느려지면 서버부터 늘리고 싶어집니다. 하지만 제 경험상 먼저 할 일은 요청 하나가 하는 일을 줄이는 것입니다. 같은 걸 두 번 계산하지 않고(캐시), 기다릴 필요 없는 일을 응답 밖으로 빼고…
웅파 · 2026-10-20
CodeIgniter 4 + 모던 PHP 8.4: readonly DTO, backed enum, match로 배열·define() 걷어내기
들어가며 결론부터 말하면, 상태·역할 같은 "닫힌 값의 집합"은 backed enum으로, 계층 사이를 오가는 데이터는 readonly DTO로, 값에 따른 분기는 match로 옮기면 define()과 매직 배열의…
웅파 · 2026-10-20
JWT 직접 만들지 마라: alg:none 우회, Access/Refresh 분리, Redis 회전·블랙리스트
JWT는 서명이 아니라 검증에서 무너진다 JWT를 base64_encode와 hash_hmac으로 직접 조립하지 마십시오. 토큰을 만드는 쪽은 단순하지만, 받은 토큰을 믿을지 판단하는 쪽에 함정이 몰려 있습니다. 올…
웅파 · 2026-10-20
AI 코드 리뷰를 규칙으로 고정하기
리뷰어가 없는 개발자의 리뷰 AI에게 "꼼꼼하게 리뷰해 줘"라고 부탁하는 것으로는 품질이 지켜지지 않습니다. 저는 규칙을 파일로 고정하고, 지키지 않으면 통과하지 못하게 만드는 쪽을 택했습니다. 저는 CodeIgni…
웅파 · 2026-10-20
코드 그래프(graft)로 AI의 탐색 비용 줄이기: grep/read 대비 토큰 절감 체감
한 줄 요약 — AI 에이전트는 작업마다 저장소를 처음부터 다시 탐색합니다. 코드 그래프 도구 graft를 붙여 그 탐색을 "한 번 만든 지도 읽기"로 바꿨고, LLM 요약(--deep) 없이 구조 그래프만으로도 g…
웅파 · 2026-10-20
스킬로 반복 작업 자동화: 이슈 착수부터 종료까지 한 명령으로 묶은 dev-issue 사례
이제 클로드코드에 "이슈 231 개발" 한 줄만 입력합니다. 그러면 브랜치 생성, 테스트 먼저 쓰기, 구현, PR, 머지, 이슈 종료까지 한 흐름으로 끝납니다. 이 글은 그 한 줄을 만든 dev-issue 스킬 이야…
웅파 · 2026-10-20
AI에게 기억을 심는 법: 메모리 파일로 삽질 교훈을 세션 간에 유지하기
어제 고친 버그를 오늘 또 만드는 AI 결론부터 말하면, AI는 똑똑하지만 기억력이 없다. 그래서 삽질에서 얻은 교훈은 사람이 아니라 파일에 남겨야 한다. 1년 전 Claude Code로 개발에 복귀한 뒤 CodeI…