— AI는 가설을 던지고, 운영자는 시나리오를 안다

지난 글에서 사업자번호를 묶음 키로 쓰는 의료 다중 영역 설계를 적었다.

설계는 단순했다.

가입은 영역을 다중 체크해서 한 번에. 시트엔 영역마다 1행씩. 매칭·충전·CS는 행 단위로 완전 독립.

문제는 그 설계를 실제 회원가입 폼으로 옮기는 작업이었다.

옵티스랩의 파트너 가입 폼은 WordPress 위에 구축돼 있다. 단순해 보이지만, 다중 영역 분기 + 라디오 + 콤마 정렬 + 데이터 무결성을 한 화면에 박는 일이었다.

여섯 시간 걸렸다.

시작 — 한 줄로 단순화

복잡해 보이는 구조를 한 줄로 압축했다.

업종이 N개 들어오면 라우터로 분기시키고, 업종 수만큼 행에 넣으면 거의 끝난 게임이다.

시트 행만 분리하면 나머지 로직은 기존 그대로 작동한다. 백엔드는 안 건드린다. 작업은 프론트의 회원가입 폼에서 끝난다.

그렇게 시작했다.

UI 분기 — 시장 현실을 반영하다

파트너 가입 폼에 영역 다중 선택 체크박스를 추가했다. 피부·탈모·성형 중 복수 선택 가능.

다중 선택 시 처리해야 할 두 가지가 있었다.

1. 의원/병원 라디오 노출 분기

  • 영역 단일 선택 = 1개 영역만 운영하는 곳 = 클리닉 형태가 많음 → 의원/클리닉/병원 라디오 노출
  • 영역 다중 선택 = 다영역 운영 = 클리닉 형태 거의 없음 → 라디오 숨김, 기본값 "병원" 자동 적용

UI는 단순해지고, 데이터는 시장 현실에 맞게 자동으로 채워진다.

2. 영역별 콤마 자동 처리

다중 선택 시 시트에 들어가는 값:

다영역 선택 → "성형 분기, 피부 분기, 탈모 분기"
2영역 선택 → "피부 분기, 탈모 분기"
단일 선택 → "피부 분기"

영역 사이에만 콤마가 들어가야 한다. 맨 앞·맨 뒤에는 콤마 X. 빈 영역 자리에는 콤마도 빠져야 한다.

이 두 가지를 풀려고 시작했는데, 폼 빌더가 그렇게 단순하지 않았다.

함정 1 — 숨긴 필드는 데이터에서 제외된다

라디오 버튼을 조건부로 숨겼다. UI에서는 안 보이게 처리. 그런데 시트에 데이터가 빈 값으로 들어왔다.

폼 빌더는 숨겨진 필드를 데이터에서 자동 제외했다. 자체 클래스 + 내부 로직으로.

JS로 클래스를 제거해봤다. 안 먹었다. 폼이 다시 숨겼다. 우회 시도 여러 번 — 모두 차단.

함정 2 — 콤마를 JS로 강제하면 후처리가 더 일이다

다음으로 콤마 처리에 들어갔다.

가장 단순한 답은 JS로 영역 사이에 콤마를 강제로 넣는 것이었다. 그런데 영역이 빠진 자리에서는 빈 콤마가 남는다. 시트에는 "피부과 의원,, 탈모 전문 병원" 같은 값이 들어간다.

Make 시나리오에서 빈 콤마를 정리하면 되긴 한다. 하지만 그러면 Make 후처리 로직이 폭증한다. 시나리오를 새로 짜야 한다. 운영 중인 시스템에서 가장 피하고 싶은 자리다.

다른 답이 필요했다.

함정 3 — 머지태그 사이에 텍스트 필드 끼우기

머지태그 사이에 텍스트 필드 자체를 끼워 넣었다. 콤마를 텍스트 필드의 기본값으로 박았다. 그리고 그 텍스트 필드 자체에 조건부 IF를 걸었다.

영역 출력 = 성형 + [comma01] + 피부 + [comma02] + 탈모
comma01 = "성형+피부" OR "성형+탈모" OR "성형+피부+탈모" 일 때만 출력
comma02 = "피부+탈모" OR "성형+피부+탈모" 일 때만 출력

콤마 매트릭스를 폼이 자체적으로 결정하게 만들었다. JS X, Make 후처리 X. 빠진 케이스 없는 완벽한 조건.

그런데 또 막혔다.

함정 4 — 텍스트 필드도 숨기면 데이터 제외된다

콤마용 텍스트 필드를 조건부 숨김으로 처리했다. 안 보이는 콤마는 출력 안 됨.

→ 폼이 그것도 데이터에서 제외했다.

"숨김 처리 못 하는데 보이게 하는 게 가능할 리 없잖아."

방향을 뒤집었다. 시각만 가리고 데이터는 살리는 방법으로.

position: absolute;
left: -9999px;
visibility: hidden;

화면에서는 안 보인다. 데이터는 살아 있다. off-screen 트릭이다.

콤마 처리 — 끝.

함정 5 — 라디오도 같은 트릭 적용

다음 자리는 라디오였다. 다중 선택일 때 의원/병원 라디오를 안 보이게 처리해야 한다.

같은 off-screen 트릭을 라디오에도 적용했다. 시각만 가리고 기본값 "병원"은 데이터로 살림.

여기까지는 됐다.

함정 6 — 콤마에 띄어쓰기가 빠졌다

테스트 결과 시트에 들어간 값:

"종합 성형 외과,피부과 의원,탈모 전문 병원"
콤마 뒤 띄어쓰기 X. 콤마 매트릭스의 텍스트 필드 기본값을 콤마 한 글자로 박았기 때문.

기본값을 ", " (콤마 + 공백) 으로 바꿨다.

"종합 성형 외과, 피부과 의원, 탈모 전문 병원"

깔끔. 다음.

함정 7 — 진짜 함정

여기서 진짜 함정이 나타났다.

테스트 결과:

피부 + 탈모 선택 → "피부과 의원, " (탈모 라디오 값 빠짐)
성형 + 피부 + 탈모 선택 → "종합 성형 외과, , " (피부·탈모 라디오 값 빠짐)

라디오 기본값은 박혀 있는데, 시트에는 빈 값으로 들어갔다.

신기한 건, 피부 단독은 들어왔다. 처음 선택한 성형도 들어왔다. 그 뒤에 추가로 선택한 영역만 빈 값이었다. 콤마 자리는 만들어졌지만 내용이 비어있는 상태.

AI에 물어봤다.

"클래스 잔재일 수 있어요."
"conditional logic 캐시 문제일 수도 있습니다."
"disabled 속성이 남아 있어서일 수 있어요."

기술적 가설 N개. 모두 헛다리.

코드를 다시 봤다. 한 가지 함수가 보였다. 체크 해제된 영역의 라디오 값을 비우는 자리. 다중 체크 시 호출 순서에 따라 비우고 다시 안 채우는 구간이 있는지 살폈다.

머릿속에서 시나리오를 돌렸다.

피부 클릭 → 비우는 함수 호출
탈모 체크 안 됨 → 탈모 라디오 비움 ← 여기
탈모 클릭 → 비우는 함수 호출
탈모 체크됨 → 비우지 않음
그런데 1번에서 이미 비워진 상태 → 그대로 빈 채

한 줄로 박혔다.

이거 혹시 다른 거 선택할 때 라디오 버튼 강제로 벨류값 지우는 영향????
거기에 변수를 넣지 않아서????? 일 확률 99프로

정답이었다.

한 번 비워진 라디오는 동적 기본값으로 자동 복원되지 않는다.

해결은 세 줄이었다.

// 라디오 체크 시 비어있으면 기본값 강제 복원
if (areaChecked && radio.value === '') {
  radio.value = defaultValue;
}

테스트 — 모든 케이스 통과.

✅ 3개 다중: "종합 성형 외과, 피부과 의원, 탈모 전문 병원"
✅ 피부+탈모: "피부과 의원, 탈모 전문 병원"
✅ 법률 왔다갔다: "부동산 전문, 개인회생 전문" (잔재 X)
✅ 탈모 실수로 피부 갔다 옴: "탈모 클리닉" (잔재 X)

교훈 — AI는 가설을 던지고, 운영자는 시나리오를 안다

AI가 던진 가설은 클래스 잔재, conditional logic 캐시, disabled 속성 — 모두 기술적 추측이었다.

정답은 시나리오에 있었다. 한 번 비운 라디오는 다시 안 채워진다. 코드 레벨이 아니라 동작 흐름 레벨의 이해.

AI는 코드를 본다. 운영자는 자기가 짠 시나리오를 본다.

조각난 데이터를 보는 AI에게는, 시나리오를 관통해서 시스템을 하나의 파이프라인으로 볼 수 있는 충분한 데이터가 없다.

그 차이가 여섯 시간1초의 차이를 만든다.


한 번 비워진 자리는 다시 자동으로 채워지지 않는다. 라디오 얘기지만, 운영의 다른 자리에도 적용된다.

누군가 체크할 때 비어있으면 기본값을 복원해라. — 명시적 코드 한 줄을 짜둬야 한다.

다음 글에서는 이 파트너 가입 폼을 대시보드·Make·마케팅 ROI 페이지까지 풀스택으로 통합한 작업을 적는다.

profile
옵티스랩 리드 생성 인프라 SaaS 기업 CEO

0개의 댓글