fix: 오류 사전 문구 18곳을 사람이 말하듯 다듬는다

2026-11-07 사용자가 "자연스러운 문구가 아니라 시스템, 설계 문구 형식"이라고 짚은
글을 고친다(규칙 9 · 10 — 화면 설명 · 번역투 빼기). "일시적인 시스템 오류가
발생했습니다" · "요청하신 정보나 페이지를 찾을 수 없습니다" · "허용 범위를 초과했습니다"
같은 안내문 말투를 무엇이 안 됐고 무엇을 하면 되는지로 바꾼다.
적용하며 셋을 더 다듬었다: REQ_001 은 가장 자주 보는 로그인 · 코드 실패 한도와 진행
중인 일에 함께 맞게, MAIL_003 은 용량이 휴지통도 세므로 휴지통 비우기까지, FILE_001
은 전달하는 원본 첨부에도 맞게. 코드 · 상태 · 뜻은 그대로이고, 웹 · 앱 사전은 sync 로
다시 만들었다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-07 14:09:51 +09:00
parent b9336b6db5
commit 76cbdcf74c
5 changed files with 59 additions and 57 deletions
+21 -19
View File
@@ -20,30 +20,32 @@ export interface ErrorCodeDefinition {
const COMMON_ERROR_CODES = {
SYS_001: {
status: HttpStatus.INTERNAL_SERVER_ERROR,
message: '일시적인 시스템 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.',
message:
'문제가 생겨 하던 일을 마치지 못했습니다. 잠시 뒤 다시 시도해 주세요.',
},
REQ_001: {
status: HttpStatus.TOO_MANY_REQUESTS,
message: '요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.',
message:
'너무 여러 번 시도했거나 같은 일이 이미 진행 중입니다. 잠시 뒤 다시 시도해 주세요.',
},
AUTH_001: {
status: HttpStatus.UNAUTHORIZED,
message: '로그인이 필요한 서비스입니다. 로그인 후 이용해 주세요.',
message: '로그인이 필요합니다. 로그인한 뒤 다시 시도해 주세요.',
},
AUTH_002: {
status: HttpStatus.UNAUTHORIZED,
message: '안전을 위해 로그아웃 되었습니다. 다시 로그인해 주세요.',
message: '안전을 위해 로그아웃했습니다. 다시 로그인해 주세요.',
// 세션 만료는 클라이언트가 "인증된 세션이 있었는데 401 을 받은" 상황에서 생성한다.
clientOnly: true,
},
AUTH_003: {
status: HttpStatus.FORBIDDEN,
message: '해당 메뉴나 기능에 접근할 수 있는 권한이 없습니다.',
message: '이 기능을 쓸 수 있는 권한이 없습니다.',
},
// 로그인 자격 증명 불일치 — 계정 없음/비밀번호 틀림을 구분하지 않는다 (.claude/rules/security.md)
AUTH_004: {
status: HttpStatus.UNAUTHORIZED,
message: '이메일 또는 비밀번호가 올바르지 않습니다.',
message: '메일 주소나 비밀번호가 맞지 않습니다. 다시 확인해 주세요.',
},
// 비밀번호 바꾸기(PUT /api/auth/password)의 지금 비밀번호가 틀림 — 세션은 그대로다.
// 401 이 아니라 400 인 까닭: 웹 클라이언트는 401 이면 세션을 갱신하고 같은 요청을 다시 보낸다 (계약 1절)
@@ -56,7 +58,7 @@ const COMMON_ERROR_CODES = {
AUTH_006: {
status: HttpStatus.BAD_REQUEST,
message:
'코드가 올바르지 않습니다. 휴대폰의 날짜와 시간이 자동으로 맞춰지도록 설정되어 있는지 확인해 주세요.',
'코드가 맞지 않습니다. 휴대폰 설정에서 날짜와 시간을 자동으로 맞추게 해 두었는지 확인해 주세요.',
},
// 2단계 인증을 켠 직원의 요청에 코드가 없음 — 다른 곳에서 켠 뒤의 화면. 화면은 코드 칸을 보인다 (계약 5절)
AUTH_007: {
@@ -88,11 +90,11 @@ const COMMON_ERROR_CODES = {
},
RES_001: {
status: HttpStatus.NOT_FOUND,
message: '요청하신 정보나 페이지를 찾을 수 없습니다.',
message: '찾을 수 없습니다. 이미 지워졌거나 옮겨졌을 수 있습니다.',
},
BIZ_001: {
status: HttpStatus.BAD_REQUEST,
message: '요청하신 작업을 완료하지 못했습니다. 다시 시도해 주세요.',
message: '하려던 일을 마치지 못했습니다. 다시 시도해 주세요.',
},
} as const satisfies Record<string, ErrorCodeDefinition>;
@@ -109,24 +111,24 @@ const COMMON_ERROR_CODES = {
const DOMAIN_ERROR_CODES = {
FILE_001: {
status: HttpStatus.BAD_REQUEST,
message: '허용되지 않는 파일 형식입니다. 파일을 확인해 주세요.',
message:
'쓸 수 없는 형식의 파일입니다. 그 파일을 빼거나 다른 파일로 바꿔 주세요.',
},
FILE_002: {
status: HttpStatus.PAYLOAD_TOO_LARGE,
message: '파일 크기가 허용 범위를 초과했습니다.',
message: '파일이 너무 커서 올릴 수 없습니다.',
},
// 대용량 첨부(11단계 — 계약 4절) — 올리기 · 파일의 지금 상태와 맞지 않는 요청: 끝낸 올리기에 조각 · 같은 조각을 동시에 · 받은 조각과 내용이 다른 조각 ·
// 빠진 조각이 있는데 끝내기 · 끝내기가 진행 중 · 살아 있는 링크에 실린 파일 지우기. 아무것도 바꾸지 않았다 — 클라이언트는 GET 으로 상태를 보고 잇는다
FILE_003: {
status: HttpStatus.CONFLICT,
message:
'파일 상태가 그사이 바뀌어 처리하지 못했습니다. 다시 시도해 주세요.',
'그사이 파일이 바뀌어 하던 일을 마치지 못했습니다. 다시 시도해 주세요.',
},
// 조각의 Content-Digest(sha-256)가 받은 바이트와 다르다 — 그 조각을 받지 않았다 (같은 조각을 다시 보낸다)
FILE_004: {
status: HttpStatus.BAD_REQUEST,
message:
'파일을 올리는 중에 일부가 제대로 전달되지 않았습니다. 다시 시도해 주세요.',
message: '파일 일부가 제대로 올라가지 않았습니다. 다시 시도해 주세요.',
},
// 직원 보관 한도(보관량 · 보내지 않은 파일 수)를 넘는다 — 만들지 않았다. 문구에 숫자를 넣지 않는다(한도가 env 로 바뀐다)
FILE_005: {
@@ -138,7 +140,7 @@ const DOMAIN_ERROR_CODES = {
FILE_006: {
status: HttpStatus.INSUFFICIENT_STORAGE,
message:
'서버의 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
'회사 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
},
// 더 내려받을 수 없는 파일 — 기간 지남 · 공유 멈춤 · 횟수 초과 · 위험 · 찾을 수 없음 (공개 받기 · 우리 웹메일 받기)
FILE_007: {
@@ -163,14 +165,14 @@ const DOMAIN_ERROR_CODES = {
MAIL_003: {
status: HttpStatus.BAD_REQUEST,
message:
'메일함 용량이 부족합니다. 불필요한 메일을 정리한 뒤 다시 시도해 주세요.',
'메일함이 가득 찼습니다. 필요 없는 메일을 지우고 휴지통을 비운 뒤 다시 시도해 주세요.',
},
// 발송 때 엔진에서 첨부(blob)를 찾지 못함 — 올려 두고 오래 지나 만료된 업로드·그사이 지워진 원본 메일의 첨부(전달)·잘못된 첨부 id.
// 문구는 원인을 단정하지 않는다 — 올린 파일은 다시 올리고, 전달하는 원본 첨부는 빼야 한다 (계약 2절)
MAIL_004: {
status: HttpStatus.BAD_REQUEST,
message:
'첨부 파일을 찾을 수 없습니다. 해당 첨부를 빼거나 다시 올린 뒤 보내 주세요.',
'첨부 파일을 찾을 수 없습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
},
// 같은 Idempotency-Key 로 이미 보낸 메일과 내용(받는 사람·제목·본문·첨부)이 다르다 — 보내지 않는다.
// 첫 메일이 실제로 나갔을 수 있으므로 클라이언트는 보낸편지함을 확인하게 하고 새 키로 다시 보내게 한다
@@ -183,7 +185,7 @@ const DOMAIN_ERROR_CODES = {
// 문구의 숫자는 attachment.policy.ts 의 MAX_ATTACHMENTS_PER_MESSAGE 와 같아야 한다 (attachment.policy.spec.ts 가 확인한다)
MAIL_006: {
status: HttpStatus.BAD_REQUEST,
message: '첨부는 한 메일에 최대 20개까지 보낼 수 있습니다.',
message: '첨부 파일은 메일 한 통에 20개까지 보낼 수 있습니다.',
},
// 본문이 너무 길다 — 텍스트 100,000자·서식 본문 500,000자 초과, 서식 본문이 정화 전 비용 한도나 정화 뒤 2,000,000바이트를 넘음.
// 메일은 나가지 않는다. 클라이언트는 보내기 전에 같은 한도로 미리 막고 본문 아래에 이 문구를 보인다 (계약 2절)
@@ -248,7 +250,7 @@ const DOMAIN_ERROR_CODES = {
MAIL_016: {
status: HttpStatus.BAD_REQUEST,
message:
'대용량 첨부 파일을 보낼 수 없습니다. 해당 파일을 빼거나 다시 올린 뒤 보내 주세요.',
'보낼 수 없는 대용량 첨부 파일이 있습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
},
// 주소록(8단계) — 그룹 만들기 · 이름 바꾸기 때 이 주소록에 같은 이름의 그룹이 있다(앞뒤 공백을 빼고 ASCII 대소문자를 무시하고 견준다).
// 화면은 이름 칸 아래에 알림 없이 보인다 (계약 3절)
@@ -150,7 +150,7 @@ describe('엔진 웹훅 본문 파서 (createMailEngineEventsBodyParser)', () =>
success: false,
error: {
code: 'AUTH_001',
message: '로그인이 필요한 서비스입니다. 로그인 후 이용해 주세요.',
message: '로그인이 필요합니다. 로그인한 뒤 다시 시도해 주세요.',
traceId: 'trace-e',
},
};
+18 -18
View File
@@ -1,35 +1,35 @@
// backend/src/common/errors/error-codes.ts 에서 자동 생성된 파일입니다. 직접 수정하지 마세요.
const Map<String, String> kErrorCodeMessages = {
'SYS_001': '일시적인 시스템 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.',
'REQ_001': '요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.',
'AUTH_001': '로그인이 필요한 서비스입니다. 로그인 후 이용해 주세요.',
'AUTH_002': '안전을 위해 로그아웃 되었습니다. 다시 로그인해 주세요.',
'AUTH_003': '해당 메뉴나 기능에 접근할 수 있는 권한이 없습니다.',
'AUTH_004': '이메일 또는 비밀번호가 올바르지 않습니다.',
'SYS_001': '문제가 생겨 하던 일을 마치지 못했습니다. 잠시 뒤 다시 시도해 주세요.',
'REQ_001': '너무 여러 번 시도했거나 같은 일이 이미 진행 중입니다. 잠시 뒤 다시 시도해 주세요.',
'AUTH_001': '로그인이 필요합니다. 로그인한 뒤 다시 시도해 주세요.',
'AUTH_002': '안전을 위해 로그아웃했습니다. 다시 로그인해 주세요.',
'AUTH_003': '이 기능을 쓸 수 있는 권한이 없습니다.',
'AUTH_004': '메일 주소나 비밀번호가 맞지 않습니다. 다시 확인해 주세요.',
'AUTH_005': '지금 비밀번호가 올바르지 않습니다.',
'AUTH_006': '코드가 올바르지 않습니다. 휴대폰의 날짜와 시간이 자동으로 맞춰지도록 설정되어 있는지 확인해 주세요.',
'AUTH_006': '코드가 맞지 않습니다. 휴대폰 설정에서 날짜와 시간을 자동으로 맞추게 해 두었는지 확인해 주세요.',
'AUTH_007': '인증 앱의 코드를 입력해 주세요.',
'AUTH_008': '2단계 인증 설정이 그사이 바뀌었거나 시간이 지났습니다. 처음부터 다시 해 주세요.',
'AUTH_009': '5개까지 만들 수 있습니다. 쓰지 않는 앱 비밀번호를 지운 뒤 만들어 주세요.',
'AUTH_010': '먼저 비밀번호를 바꾸거나 2단계 인증을 켜 주세요.',
'VAL_001': '입력하신 내용을 다시 확인해 주세요. 빠진 칸이 있거나 형식이나 길이가 맞지 않습니다.',
'RES_001': '요청하신 정보나 페이지를 찾을 수 없습니다.',
'BIZ_001': '요청하신 작업을 완료하지 못했습니다. 다시 시도해 주세요.',
'FILE_001': '허용되지 않는 파일 형식입니다. 파일을 확인해 주세요.',
'FILE_002': '파일 크기가 허용 범위를 초과했습니다.',
'FILE_003': '파일 상태가 그사이 바뀌어 처리하지 못했습니다. 다시 시도해 주세요.',
'FILE_004': '파일을 올리는 중에 일부가 제대로 전달되지 않았습니다. 다시 시도해 주세요.',
'RES_001': '찾을 수 없습니다. 이미 지워졌거나 옮겨졌을 수 있습니다.',
'BIZ_001': '하려던 일을 마치지 못했습니다. 다시 시도해 주세요.',
'FILE_001': '쓸 수 없는 형식의 파일입니다. 그 파일을 빼거나 다른 파일로 바꿔 주세요.',
'FILE_002': '파일이 너무 커서 올릴 수 없습니다.',
'FILE_003': '그사이 파일이 바뀌어 하던 일을 마치지 못했습니다. 다시 시도해 주세요.',
'FILE_004': '파일 일부가 제대로 올라가지 않았습니다. 다시 시도해 주세요.',
'FILE_005': '대용량 첨부 보관 한도를 넘어 더 올릴 수 없습니다. 보낸 파일의 링크를 끊거나 보내지 않은 파일을 지우면 공간이 생깁니다.',
'FILE_006': '서버의 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
'FILE_006': '회사 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
'FILE_007': '이 파일은 더 내려받을 수 없습니다. 필요하면 보낸 사람에게 문의해 주세요.',
'FILE_008': '보안 검사가 끝나지 않은 파일입니다. 잠시 뒤 다시 시도해 주세요.',
'MAIL_001': '메일 서비스에 연결할 수 없습니다. 잠시 후 다시 시도해 주세요.',
'MAIL_002': '받는 사람 주소를 다시 확인해 주세요.',
'MAIL_003': '메일함 용량이 부족합니다. 불필요한 메일을 정리한 뒤 다시 시도해 주세요.',
'MAIL_004': '첨부 파일을 찾을 수 없습니다. 해당 첨부를 빼거나 다시 올린 뒤 보내 주세요.',
'MAIL_003': '메일함이 가득 찼습니다. 필요 없는 메일을 지우고 휴지통을 비운 뒤 다시 시도해 주세요.',
'MAIL_004': '첨부 파일을 찾을 수 없습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
'MAIL_005': '이미 보낸 메일과 내용이 달라 보내지 않았습니다. 보낸편지함을 확인한 뒤 다시 보내 주세요.',
'MAIL_006': '첨부는 한 메일에 최대 20개까지 보낼 수 있습니다.',
'MAIL_006': '첨부 파일은 메일 한 통에 20개까지 보낼 수 있습니다.',
'MAIL_007': '본문이 너무 길어 보낼 수 없습니다. 내용을 줄인 뒤 다시 보내 주세요.',
'MAIL_008': '임시 저장한 메일이 다른 곳에서 바뀌었거나 지워졌습니다. 지금 내용을 새 임시 저장본으로 남겨 주세요.',
'MAIL_009': '같은 이름의 메일함이 이미 있습니다.',
@@ -39,7 +39,7 @@ const Map<String, String> kErrorCodeMessages = {
'MAIL_013': '필터나 차단 목록이 너무 길어 저장할 수 없습니다. 조건을 줄이거나, 쓰지 않는 필터나 차단한 주소를 지워 주세요.',
'MAIL_014': '이미 보낸 메일이라 취소할 수 없습니다.',
'MAIL_015': '보내기를 기다리는 메일은 옮기거나 지울 수 없습니다. 먼저 보내기를 취소해 주세요.',
'MAIL_016': '대용량 첨부 파일을 보낼 수 없습니다. 해당 파일을 빼거나 다시 올린 뒤 보내 주세요.',
'MAIL_016': '보낼 수 없는 대용량 첨부 파일이 있습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
'CONTACT_001': '같은 이름의 그룹이 있습니다. 다른 이름을 써 주세요.',
'CONTACT_002': '주소록 한도를 넘어 더 넣을 수 없습니다. 연락처 3,000개, 그룹 100개, 그룹 하나에 500명까지 넣을 수 있습니다.',
};
+1 -1
View File
@@ -7,7 +7,7 @@ void main() {
test('등록된 코드는 해당 한국어 메시지를 반환한다', () {
expect(
ErrorLexicon.getMessage('AUTH_001'),
'로그인이 필요한 서비스입니다. 로그인 후 이용해 주세요.',
'로그인이 필요합니다. 로그인한 뒤 다시 시도해 주세요.',
);
});
@@ -1,35 +1,35 @@
// backend/src/common/errors/error-codes.ts 에서 자동 생성된 파일입니다. 직접 수정하지 마세요.
export const ERROR_CODE_MESSAGES = {
SYS_001: '일시적인 시스템 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.',
REQ_001: '요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.',
AUTH_001: '로그인이 필요한 서비스입니다. 로그인 후 이용해 주세요.',
AUTH_002: '안전을 위해 로그아웃 되었습니다. 다시 로그인해 주세요.',
AUTH_003: '해당 메뉴나 기능에 접근할 수 있는 권한이 없습니다.',
AUTH_004: '이메일 또는 비밀번호가 올바르지 않습니다.',
SYS_001: '문제가 생겨 하던 일을 마치지 못했습니다. 잠시 뒤 다시 시도해 주세요.',
REQ_001: '너무 여러 번 시도했거나 같은 일이 이미 진행 중입니다. 잠시 뒤 다시 시도해 주세요.',
AUTH_001: '로그인이 필요합니다. 로그인한 뒤 다시 시도해 주세요.',
AUTH_002: '안전을 위해 로그아웃했습니다. 다시 로그인해 주세요.',
AUTH_003: '이 기능을 쓸 수 있는 권한이 없습니다.',
AUTH_004: '메일 주소나 비밀번호가 맞지 않습니다. 다시 확인해 주세요.',
AUTH_005: '지금 비밀번호가 올바르지 않습니다.',
AUTH_006: '코드가 올바르지 않습니다. 휴대폰의 날짜와 시간이 자동으로 맞춰지도록 설정되어 있는지 확인해 주세요.',
AUTH_006: '코드가 맞지 않습니다. 휴대폰 설정에서 날짜와 시간을 자동으로 맞추게 해 두었는지 확인해 주세요.',
AUTH_007: '인증 앱의 코드를 입력해 주세요.',
AUTH_008: '2단계 인증 설정이 그사이 바뀌었거나 시간이 지났습니다. 처음부터 다시 해 주세요.',
AUTH_009: '5개까지 만들 수 있습니다. 쓰지 않는 앱 비밀번호를 지운 뒤 만들어 주세요.',
AUTH_010: '먼저 비밀번호를 바꾸거나 2단계 인증을 켜 주세요.',
VAL_001: '입력하신 내용을 다시 확인해 주세요. 빠진 칸이 있거나 형식이나 길이가 맞지 않습니다.',
RES_001: '요청하신 정보나 페이지를 찾을 수 없습니다.',
BIZ_001: '요청하신 작업을 완료하지 못했습니다. 다시 시도해 주세요.',
FILE_001: '허용되지 않는 파일 형식입니다. 파일을 확인해 주세요.',
FILE_002: '파일 크기가 허용 범위를 초과했습니다.',
FILE_003: '파일 상태가 그사이 바뀌어 처리하지 못했습니다. 다시 시도해 주세요.',
FILE_004: '파일을 올리는 중에 일부가 제대로 전달되지 않았습니다. 다시 시도해 주세요.',
RES_001: '찾을 수 없습니다. 이미 지워졌거나 옮겨졌을 수 있습니다.',
BIZ_001: '하려던 일을 마치지 못했습니다. 다시 시도해 주세요.',
FILE_001: '쓸 수 없는 형식의 파일입니다. 그 파일을 빼거나 다른 파일로 바꿔 주세요.',
FILE_002: '파일이 너무 커서 올릴 수 없습니다.',
FILE_003: '그사이 파일이 바뀌어 하던 일을 마치지 못했습니다. 다시 시도해 주세요.',
FILE_004: '파일 일부가 제대로 올라가지 않았습니다. 다시 시도해 주세요.',
FILE_005: '대용량 첨부 보관 한도를 넘어 더 올릴 수 없습니다. 보낸 파일의 링크를 끊거나 보내지 않은 파일을 지우면 공간이 생깁니다.',
FILE_006: '서버의 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
FILE_006: '회사 저장 공간이 모자라 지금은 파일을 올릴 수 없습니다. 잠시 뒤 다시 시도해 주세요.',
FILE_007: '이 파일은 더 내려받을 수 없습니다. 필요하면 보낸 사람에게 문의해 주세요.',
FILE_008: '보안 검사가 끝나지 않은 파일입니다. 잠시 뒤 다시 시도해 주세요.',
MAIL_001: '메일 서비스에 연결할 수 없습니다. 잠시 후 다시 시도해 주세요.',
MAIL_002: '받는 사람 주소를 다시 확인해 주세요.',
MAIL_003: '메일함 용량이 부족합니다. 불필요한 메일을 정리한 뒤 다시 시도해 주세요.',
MAIL_004: '첨부 파일을 찾을 수 없습니다. 해당 첨부를 빼거나 다시 올린 뒤 보내 주세요.',
MAIL_003: '메일함이 가득 찼습니다. 필요 없는 메일을 지우고 휴지통을 비운 뒤 다시 시도해 주세요.',
MAIL_004: '첨부 파일을 찾을 수 없습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
MAIL_005: '이미 보낸 메일과 내용이 달라 보내지 않았습니다. 보낸편지함을 확인한 뒤 다시 보내 주세요.',
MAIL_006: '첨부는 한 메일에 최대 20개까지 보낼 수 있습니다.',
MAIL_006: '첨부 파일은 메일 한 통에 20개까지 보낼 수 있습니다.',
MAIL_007: '본문이 너무 길어 보낼 수 없습니다. 내용을 줄인 뒤 다시 보내 주세요.',
MAIL_008: '임시 저장한 메일이 다른 곳에서 바뀌었거나 지워졌습니다. 지금 내용을 새 임시 저장본으로 남겨 주세요.',
MAIL_009: '같은 이름의 메일함이 이미 있습니다.',
@@ -39,7 +39,7 @@ export const ERROR_CODE_MESSAGES = {
MAIL_013: '필터나 차단 목록이 너무 길어 저장할 수 없습니다. 조건을 줄이거나, 쓰지 않는 필터나 차단한 주소를 지워 주세요.',
MAIL_014: '이미 보낸 메일이라 취소할 수 없습니다.',
MAIL_015: '보내기를 기다리는 메일은 옮기거나 지울 수 없습니다. 먼저 보내기를 취소해 주세요.',
MAIL_016: '대용량 첨부 파일을 보낼 수 없습니다. 해당 파일을 빼거나 다시 올린 뒤 보내 주세요.',
MAIL_016: '보낼 수 없는 대용량 첨부 파일이 있습니다. 그 파일을 빼거나 다시 올린 뒤 보내 주세요.',
CONTACT_001: '같은 이름의 그룹이 있습니다. 다른 이름을 써 주세요.',
CONTACT_002: '주소록 한도를 넘어 더 넣을 수 없습니다. 연락처 3,000개, 그룹 100개, 그룹 하나에 500명까지 넣을 수 있습니다.',
} as const