제가 해결하는 문제

포트폴리오는 보통 무엇을 만들었는지를 보여준다. 그런데 회사가 사는 것은 어떤 문제가 없어지는지다. 이 문서는 그 사이를 잇는다.

아래 사례는 전부 실제로 운영 중인 사이트에서 나왔고, 숫자는 측정값이다. 추정치나 예시가 아니다.

1매출로 가는 길이 조용히 끊긴 것을 찾아낸다

증상 (회사가 실제로 하는 말)

"광고는 돌리는데 문의가 안 들어와요." "예전엔 왔는데 요즘 뜸하네요."

실제로 일어나는 일

문의 폼이 죽어도 화면은 멀쩡해 보인다. 방문자는 "문제가 발생했습니다"를 보고 그냥 나간다. 아무도 회사에 알려주지 않는다. 광고비는 그대로 나간다.

2026-08-18, 운영 중인 webcare.forblune.com 에서 실제로 이 일이 있었다. 정적 파일만 배포하는 과정에서 서버 함수가 통째로 빠졌고, 문의 접수 API 가 약 4시간 동안 405 를 돌려주고 있었다. 화면은 정상이었다.

어떻게 찾았나

배포본별로 같은 요청을 던져 경계를 좁혔다.

2일 전 배포   POST /api/lead → 400   (함수 살아 있음, 잘못된 본문을 거부)
오늘 배포     POST /api/lead → 405   (함수 없음)

400 과 405 의 차이 하나로 "언제부터, 무엇 때문에"가 확정된다. 로그를 뒤지기 전에 재현 가능한 경계를 먼저 만든다.

조치

회사가 얻는 것

리드 유실을 시간 단위가 아니라 분 단위로 줄인다. 그리고 같은 사고가 다시 나면 배포 즉시 걸린다.

2"알림이 없어서 아무도 모르는" 구조를 끝낸다

증상

"문의가 들어오면 알림이 오죠?"

실제로 일어나는 일

위 사고를 고치고 나서 더 큰 것을 발견했다. 알림이 처음부터 없었다. 문의는 데이터베이스에 저장만 되고, 사람이 직접 조회하기 전까지 아무도 몰랐다. 저장소 전 브랜치를 훑어도 메일 발송 코드가 한 줄도 없었다.

화면에서는 이렇게 약속하고 있었다.

"담당자가 빠른 시일 내 연락드리겠습니다."

문의가 들어와도 며칠 방치될 수 있는 구조였다. 광고를 켜는 순간 바로 손실이 된다.

조치

메일 알림을 붙이되, 알림이 문의를 잡아먹지 않도록 설계했다.

이 설계는 곧바로 값을 했다. 첫 설정에서 API 키가 잘못 들어가 발송이 실패했는데, 문의는 정상 저장됐고 로그에 lead_notify_failed <문의ID> 401 이 남아 원인이 5분 만에 확정됐다.

회사가 얻는 것

장애를 늦게 아는 비용이 장애 자체보다 크다. 그 시간을 없앤다.

3"어느 게 최신인지 모르겠는" 상태를 끝낸다

증상

"그 파일 어디 있죠?" "고쳤는데 배포하니까 예전 걸로 돌아갔어요."

실제로 일어나는 일

운영 중인 사이트의 소스가 git 어디에도 없었다.

로컬에 후보가 8곳 있었다 — 저장소 본체, 빌드 산출물, v3, v5, v6, v6 2, v6-v2, 복구본. 라이브와 해시를 전부 대조했다.

후보 8곳  →  라이브와 일치: 0곳

Git 연동 없이 직접 업로드하는 방식이라 이력이 남지 않아 생긴 공백이었다. 이 상태에서는 누가 무엇을 고쳐도 다음 배포에 사라질 수 있다. 실제로 과거에 구버전이 최종본을 덮은 사고가 있었다.

조치

배포 스크립트에 넣은 안전장치:

장치막는 사고
기본이 미리보기, --apply 필요의도치 않은 즉시 반영
대상 저장소 origin 확인엉뚱한 저장소 덮어쓰기
대상에 미커밋 변경 있으면 중단남의 작업 날리기
빌드 실패 시 중단낡은 산출물 배포
삭제 파일 개수 표시 + yes 입력 요구대량 삭제

마지막 항목은 실제 사고에서 나왔다. 같은 날 두 저장소가 양방향으로 갈라진 것을 모르고 동기화를 돌릴 뻔했고, 파일 9개가 지워질 뻔했다.

회사가 얻는 것

인수인계가 가능해진다. 담당자가 바뀌어도 "정본이 어디냐"로 시작하지 않는다.

4크롤로 만든 사본은 사이트의 사본이 아니다

증상

"그대로 옮겼는데 왜 안 되죠?"

실제로 일어나는 일

사이트를 크롤해서 만든 사본에는 보이지 않는 것들이 빠진다.

같은 날 이 방식으로 511KB짜리 og:image 를 지웠다. 8개 페이지의 공유 미리보기 이미지였다. 더 나쁜 건 도메인이 200 을 돌려주고 있었다는 것 — CDN 캐시 때문이었다. 배포본 URL 로 확인해야 404 가 보였다.

조치

이전 배포본에서 파일을 복원하고, 배포 전 점검 목록과 "검증은 도메인이 아니라 배포본 URL 로" 를 문서에 고정했다.

회사가 얻는 것

이전·리뉴얼·업체 교체 과정에서 조용히 사라지는 것을 막는다. 사라진 줄도 모르는 자산이 가장 비싸다.

5남의 서비스 장애가 우리 장애가 되지 않게 한다

증상

"사진이 깨져 보여요. 어제는 됐는데요."

실제로 일어나는 일

디자인 쇼케이스 사이트의 사진이 전부 외부 무료 이미지 서비스를 직접 링크하고 있었다. 그 서비스가 장애를 일으키자 절반 이상이 회색 박스가 됐다. 우리 코드는 아무것도 바뀌지 않았는데 사이트가 망가진 것이다.

외부 핫링크   243건 (24개 페이지)  →  0건
자체 호스팅   234개 파일 / 고유 사진 217장 / 전부 CC0 (상업적 사용 가능)
외부 이미지 의존   0

선별에서 걸러낸 함정

무료 이미지 API 는 그냥 받아 쓰면 안 된다. 실제로 두 가지에 걸렸다.

회사가 얻는 것

우리가 통제할 수 없는 것에 사이트를 걸지 않는다. 공짜 외부 자원은 공짜인 만큼 보장이 없다.

6"AI가 만든 티"를 만드는 실제 원인을 잡는다

증상

"뭔가 어색한데 뭐가 문제인지 모르겠어요." "성의 없어 보인다는 말을 들었어요."

실제로 일어나는 일

대개 콘텐츠가 아니라 기본기다. 가장 흔한 것이 한글 어절이 단어 중간에서 끊기는 문제다. 좁은 화면일수록 심해진다.

저희는 사이트를 점검하고 개선
합니다

이걸 보면 읽는 사람은 내용을 판단하기 전에 "검수가 안 됐구나" 를 먼저 느낀다. 그리고 그 인상은 문의 여부로 이어진다.

원인은 한 줄이다. 한글은 단어 단위 줄바꿈이 기본이 아니다.

word-break: keep-all;        /* 어절 단위로만 끊는다 */
overflow-wrap: break-word;   /* URL 처럼 끊을 수 없는 긴 토큰만 예외 */

overflow-wrap: anywhere 를 쓰면 keep-all 이 무시되어 도로 끊긴다. 이런 것은 알아야 보인다.

운영 중인 4개 사이트 전부에서 이 문제를 찾아 고쳤다. 쇼케이스만 25개 페이지 전부에 적용했다.

같이 잡은 것들

결함왜 문제인가
필수 항목인데 화면에 표시가 없음사용자가 이유를 모른 채 실패하고 이탈한다
모든 오류가 문구 하나로 뭉개짐무엇이 잘못됐는지 아무도 모른다
시스템 다크 모드에서 의도와 다른 색브랜드가 무너진다
입력칸이 빈 흰 상자무엇을 넣어야 할지 모른다

필수 항목 문제는 특히 실제 손실로 이어지고 있었다. 서버는 필수로 검사하는데 화면에는 표시가 없어서, 그 항목을 안 채운 사용자는 "문제가 발생했습니다"만 보고 이유를 알 수 없었다. 제출 전에 잡아서 무엇을 채워야 하는지 알려주도록 고쳤다.

회사가 얻는 것

전환율. 내용이 좋아도 검수 안 된 인상이면 문의하지 않는다.

7기본적인 것이 빠져 있는지 확인한다

증상

"명함에 적은 주소가 안 열린다는데요?"

실제로 일어나는 일

서브도메인 9개는 전부 살아 있는데 루트 도메인만 죽어 있었다. DNS 에 웹 레코드가 아예 없어서 접속 자체가 안 됐다.

메일은 정상이라 아무도 눈치채지 못했다. 명함·메일 서명·검색 결과에서 회사 주소를 치면 안 열리는 상태가 계속되고 있었다.

조치

루트와 www 를 대표 사이트로 301 영구 이동시키되, 경로와 쿼리를 보존했다.

forblune.com/            → portfolio.forblune.com/
www.forblune.com/        → portfolio.forblune.com/
forblune.com/a/b?x=1     → portfolio.forblune.com/a/b?x=1

여기서 중요한 판단

메일 발송용 도메인 인증을 붙일 때, 루트가 아니라 서브도메인을 썼다.

루트에는 이미 Google Workspace 의 메일 설정(MX·SPF)이 걸려 있었다. 루트 SPF 에 새 발송 서비스를 끼워 넣으면 지금 쓰는 회사 메일 수신이 깨질 수 있다. 서브도메인으로 분리하면 그 위험이 없다.

작업 후 메일 레코드(MX·SPF·DMARC) 무결성을 확인했다.

회사가 얻는 것

고치러 갔다가 다른 걸 부수지 않는다. 이게 운영 중인 시스템을 만지는 일의 핵심이다.

정리 — 한 줄로

회사가 겪는 것제가 하는 것
문의가 안 들어오는데 이유를 모름끊긴 경로를 재현 가능한 경계로 찾아 복구하고, 재발을 배포 절차로 막음
장애를 뒤늦게 앎실패가 조용히 죽지 않는 알림·로그 구조를 넣음
최신본이 어디 있는지 모름정본을 확정해 저장소에 고정하고 배포를 단방향으로 못박음
이전·리뉴얼에서 뭔가 사라짐크롤에 안 잡히는 자산까지 포함한 점검 절차
남의 서비스 장애로 우리가 멈춤외부 의존을 걷어내고 통제 가능한 자원으로 대체
"AI가 만든 티" 라는 말을 들음신뢰를 깎는 기본기 결함을 찾아 고침
기본적인 게 빠져 있음살아 있는 것을 부수지 않고 빠진 것만 채움

일하는 방식

추측으로 고치지 않는다. 원인을 확정하는 재현 가능한 경계를 먼저 만든다. 400 인가 405 인가, 해시가 같은가 다른가 — 이런 것으로 확정한 뒤에 손을 댄다.

고친 것은 반드시 확인한다. 코드가 컴파일되는 것과 사용자에게 동작하는 것은 다르다. 실제 화면에서 끝까지 제출해보고, 데이터베이스에 들어갔는지까지 본다.

같은 사고가 두 번 나지 않게 만든다. 고치고 끝내지 않고, 왜 그랬는지와 어떻게 확인하는지를 저장소에 남긴다. 다음 사람이 나일 필요가 없어야 한다.

내 실수도 그대로 적는다. 위 사례 중 1·4번은 제가 만든 사고다. 찾아내고, 원인을 규명하고, 재발 방지까지 하고, 기록으로 남겼다. 사고를 안 내는 사람은 없다. 사고를 숨기지 않고 시스템으로 막는 사람이 필요할 뿐이다.

사례의 모든 숫자는 2026-08-18 실측값이다. 검증 명령과 근거는 각 저장소의 커밋 메시지와 docs/ 에 남아 있다.