generated from ttipo/project-base
feat(backend): 임시 저장·서명(그림)·받는 사람 추천 API와 MAIL_008
- /api/drafts: 발송과 같은 준비(정화·한도)로 초안을 만들고, 바꿔 저장은 새로 만들어 다시 읽은 뒤 옛것을 지운다. 만들기와 지우기를 한 요청에 넣지 않는다 — 엔진이 만들기가 실패해도 지우기를 해서 저장본이 사라졌다. 옛 초안이 이미 없으면 409 MAIL_008(새 코드), 초안이 아닌 id 는 404 RES_001 로 아무것도 지우지 않는다. - 사용자 메일의 영구 삭제(교체한 옛 초안 · 보낸 뒤 draftId · 휴지통 영구 삭제)는 대상인지 확인한 상태 그대로일 때만 ifInState 로 지운다 — 확인과 지우기 사이에 다른 탭이 옮긴 메일까지 지우지 않게 (Stalwart 0.16.27 에서 확인) - /api/mail-signature: 서명(DB)과 그림(업로드 볼륨). 그림은 확장자·MIME·매직 바이트·크기·가로세로를 보고, 보낼 때 multipart/related 의 cid 그림으로 싣는다. 서명 저장은 사용자별로 잠가 차례로 한다 - /api/recipient-suggestions: 로그인한 직원 기록(mail_directory)과 내 메일함의 최근 주소로 추천, 사용자별 10분 캐시 - 본문 그림은 첨부 표시에서 뺀다(hasAttachment 직접 계산 · isInline), 예외 필터 로그의 검색어(q)는 길이만 남긴다 - 마이그레이션 AddMailSignaturesAndDirectory: 새 표 3개만 만든다 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,32 @@
|
||||
import { isSendMessageRequest } from './app.setup';
|
||||
import { isDraftSaveRequest, isSendMessageRequest } from './app.setup';
|
||||
|
||||
describe('임시 저장 요청 판정 (발송과 같은 JSON 본문 4MB)', () => {
|
||||
it('POST /api/drafts 와 PUT /api/drafts/{id} 는 임시 저장 요청이다 — 대소문자·끝의 / ·쿼리는 가리지 않는다', () => {
|
||||
for (const [method, url] of [
|
||||
['POST', '/api/drafts'],
|
||||
['POST', '/API/Drafts/'],
|
||||
['PUT', '/api/drafts/faaaaabi'],
|
||||
['PUT', '/api/drafts/faaaaabi/?x=1'],
|
||||
] as const) {
|
||||
expect(isDraftSaveRequest({ method, url })).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it('조회·다른 경로·하위 경로는 1MB 그대로다', () => {
|
||||
for (const [method, url] of [
|
||||
['GET', '/api/drafts/faaaaabi'],
|
||||
['PUT', '/api/drafts'],
|
||||
['POST', '/api/drafts/faaaaabi'],
|
||||
['PUT', '/api/drafts/faaaaabi/attachments'],
|
||||
['PATCH', '/api/drafts/faaaaabi'],
|
||||
['POST', '/api/draftsx'],
|
||||
['PUT', '/drafts/faaaaabi'],
|
||||
] as const) {
|
||||
expect(isDraftSaveRequest({ method, url })).toBe(false);
|
||||
}
|
||||
expect(isDraftSaveRequest({ method: 'POST', url: undefined })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('발송 요청 판정 (발송만 JSON 본문 4MB)', () => {
|
||||
it('POST /api/messages 는 발송 요청이다 — 대소문자·끝의 / ·쿼리는 가리지 않는다 (라우터와 같다)', () => {
|
||||
|
||||
Reference in New Issue
Block a user