
— AI는 가설을 던지고, 운영자는 시나리오를 안다
지난 글에서 사업자번호를 묶음 키로 쓰는 의료 다중 영역 설계를 적었다.
설계는 단순했다.
가입은 영역을 다중 체크해서 한 번에. 시트엔 영역마다 1행씩. 매칭·충전·CS는 행 단위로 완전 독립.
문제는 그 설계를 실제 회원가입 폼으로 옮기는 작업이었다.
옵티스랩의 파트너 가입 폼은 WordPress 위에 구축돼 있다. 단순해 보이지만, 다중 영역 분기 + 라디오 + 콤마 정렬 + 데이터 무결성을 한 화면에 박는 일이었다.
여섯 시간 걸렸다.
복잡해 보이는 구조를 한 줄로 압축했다.
업종이 N개 들어오면 라우터로 분기시키고, 업종 수만큼 행에 넣으면 거의 끝난 게임이다.
시트 행만 분리하면 나머지 로직은 기존 그대로 작동한다. 백엔드는 안 건드린다. 작업은 프론트의 회원가입 폼에서 끝난다.
그렇게 시작했다.
파트너 가입 폼에 영역 다중 선택 체크박스를 추가했다. 피부·탈모·성형 중 복수 선택 가능.
다중 선택 시 처리해야 할 두 가지가 있었다.
1. 의원/병원 라디오 노출 분기
UI는 단순해지고, 데이터는 시장 현실에 맞게 자동으로 채워진다.
2. 영역별 콤마 자동 처리
다중 선택 시 시트에 들어가는 값:
다영역 선택 → "성형 분기, 피부 분기, 탈모 분기"
2영역 선택 → "피부 분기, 탈모 분기"
단일 선택 → "피부 분기"
영역 사이에만 콤마가 들어가야 한다. 맨 앞·맨 뒤에는 콤마 X. 빈 영역 자리에는 콤마도 빠져야 한다.
이 두 가지를 풀려고 시작했는데, 폼 빌더가 그렇게 단순하지 않았다.
라디오 버튼을 조건부로 숨겼다. UI에서는 안 보이게 처리. 그런데 시트에 데이터가 빈 값으로 들어왔다.
폼 빌더는 숨겨진 필드를 데이터에서 자동 제외했다. 자체 클래스 + 내부 로직으로.
JS로 클래스를 제거해봤다. 안 먹었다. 폼이 다시 숨겼다. 우회 시도 여러 번 — 모두 차단.
다음으로 콤마 처리에 들어갔다.
가장 단순한 답은 JS로 영역 사이에 콤마를 강제로 넣는 것이었다. 그런데 영역이 빠진 자리에서는 빈 콤마가 남는다. 시트에는 "피부과 의원,, 탈모 전문 병원" 같은 값이 들어간다.
Make 시나리오에서 빈 콤마를 정리하면 되긴 한다. 하지만 그러면 Make 후처리 로직이 폭증한다. 시나리오를 새로 짜야 한다. 운영 중인 시스템에서 가장 피하고 싶은 자리다.
다른 답이 필요했다.
머지태그 사이에 텍스트 필드 자체를 끼워 넣었다. 콤마를 텍스트 필드의 기본값으로 박았다. 그리고 그 텍스트 필드 자체에 조건부 IF를 걸었다.
영역 출력 = 성형 + [comma01] + 피부 + [comma02] + 탈모
comma01 = "성형+피부" OR "성형+탈모" OR "성형+피부+탈모" 일 때만 출력
comma02 = "피부+탈모" OR "성형+피부+탈모" 일 때만 출력
콤마 매트릭스를 폼이 자체적으로 결정하게 만들었다. JS X, Make 후처리 X. 빠진 케이스 없는 완벽한 조건.
그런데 또 막혔다.
콤마용 텍스트 필드를 조건부 숨김으로 처리했다. 안 보이는 콤마는 출력 안 됨.
→ 폼이 그것도 데이터에서 제외했다.
"숨김 처리 못 하는데 보이게 하는 게 가능할 리 없잖아."
방향을 뒤집었다. 시각만 가리고 데이터는 살리는 방법으로.
position: absolute;
left: -9999px;
visibility: hidden;
화면에서는 안 보인다. 데이터는 살아 있다. off-screen 트릭이다.
콤마 처리 — 끝.
다음 자리는 라디오였다. 다중 선택일 때 의원/병원 라디오를 안 보이게 처리해야 한다.
같은 off-screen 트릭을 라디오에도 적용했다. 시각만 가리고 기본값 "병원"은 데이터로 살림.
여기까지는 됐다.
테스트 결과 시트에 들어간 값:
"종합 성형 외과,피부과 의원,탈모 전문 병원"
콤마 뒤 띄어쓰기 X. 콤마 매트릭스의 텍스트 필드 기본값을 콤마 한 글자로 박았기 때문.
기본값을 ", " (콤마 + 공백) 으로 바꿨다.
"종합 성형 외과, 피부과 의원, 탈모 전문 병원"
깔끔. 다음.
여기서 진짜 함정이 나타났다.
테스트 결과:
피부 + 탈모 선택 → "피부과 의원, " (탈모 라디오 값 빠짐)
성형 + 피부 + 탈모 선택 → "종합 성형 외과, , " (피부·탈모 라디오 값 빠짐)
라디오 기본값은 박혀 있는데, 시트에는 빈 값으로 들어갔다.
신기한 건, 피부 단독은 들어왔다. 처음 선택한 성형도 들어왔다. 그 뒤에 추가로 선택한 영역만 빈 값이었다. 콤마 자리는 만들어졌지만 내용이 비어있는 상태.
AI에 물어봤다.
"클래스 잔재일 수 있어요."
"conditional logic 캐시 문제일 수도 있습니다."
"disabled 속성이 남아 있어서일 수 있어요."
기술적 가설 N개. 모두 헛다리.
코드를 다시 봤다. 한 가지 함수가 보였다. 체크 해제된 영역의 라디오 값을 비우는 자리. 다중 체크 시 호출 순서에 따라 비우고 다시 안 채우는 구간이 있는지 살폈다.
머릿속에서 시나리오를 돌렸다.
피부 클릭 → 비우는 함수 호출
탈모 체크 안 됨 → 탈모 라디오 비움 ← 여기
탈모 클릭 → 비우는 함수 호출
탈모 체크됨 → 비우지 않음
그런데 1번에서 이미 비워진 상태 → 그대로 빈 채
한 줄로 박혔다.
이거 혹시 다른 거 선택할 때 라디오 버튼 강제로 벨류값 지우는 영향????
거기에 변수를 넣지 않아서????? 일 확률 99프로
정답이었다.
한 번 비워진 라디오는 동적 기본값으로 자동 복원되지 않는다.
해결은 세 줄이었다.
// 라디오 체크 시 비어있으면 기본값 강제 복원
if (areaChecked && radio.value === '') {
radio.value = defaultValue;
}
테스트 — 모든 케이스 통과.
✅ 3개 다중: "종합 성형 외과, 피부과 의원, 탈모 전문 병원"
✅ 피부+탈모: "피부과 의원, 탈모 전문 병원"
✅ 법률 왔다갔다: "부동산 전문, 개인회생 전문" (잔재 X)
✅ 탈모 실수로 피부 갔다 옴: "탈모 클리닉" (잔재 X)
AI가 던진 가설은 클래스 잔재, conditional logic 캐시, disabled 속성 — 모두 기술적 추측이었다.
정답은 시나리오에 있었다. 한 번 비운 라디오는 다시 안 채워진다. 코드 레벨이 아니라 동작 흐름 레벨의 이해.
AI는 코드를 본다. 운영자는 자기가 짠 시나리오를 본다.
조각난 데이터를 보는 AI에게는, 시나리오를 관통해서 시스템을 하나의 파이프라인으로 볼 수 있는 충분한 데이터가 없다.
그 차이가 여섯 시간과 1초의 차이를 만든다.
한 번 비워진 자리는 다시 자동으로 채워지지 않는다. 라디오 얘기지만, 운영의 다른 자리에도 적용된다.
누군가 체크할 때 비어있으면 기본값을 복원해라. — 명시적 코드 한 줄을 짜둬야 한다.
다음 글에서는 이 파트너 가입 폼을 대시보드·Make·마케팅 ROI 페이지까지 풀스택으로 통합한 작업을 적는다.