5장 입력 경계에서 실패를 설계한다
폼의 required는 편의 기능이지 보안 경계가 아니다. API는 브라우저를 거치지 않은 요청도 받는다. validateBrief는 고객명, 요구 길이, 예산, 날짜, 동의, 허용 채널을 다시 검사한다. 여러 오류를 한 번에 돌려주면 사용자가 왕복을 줄일 수 있다.

const errors = [];
if (!input.consent) errors.push('CONSENT_REQUIRED');
if (!Array.isArray(input.channels)) errors.push('CHANNEL_INVALID');
return { ok: errors.length === 0, errors };
서버는 본문 크기를 제한하고 JSON 파싱 실패를 400으로 반환한다. 검증 실패는 422, 없는 자원은 404, 허용하지 않은 메서드는 405로 구분한다. 오류 코드는 안정적으로, 한국어 문구는 UI에서 번역한다. 그래야 앱과 자동화 클라이언트가 같은 API를 쓸 수 있다.
경계값 실습
요구를 19자와 20자로 각각 제출한다. 예산에 -1, 날짜에 2026/11/20, 채널에 sms를 직접 API로 보낸다. UI가 막는 값도 테스트에서는 함수에 직접 전달한다.
node --test --test-name-pattern="동의"
현재 모음에서는 동의 관련 테스트 두 개만 실행된다. 예산·날짜·채널 경계는 별도 테스트 이름을 추가한 뒤 그 이름으로 골라 실행한다.