docs: 검색 색인 준비 상태와 개발 쿼리 로그 규칙을 계약 · 규칙 문서에 적는다

계약 2절에 "검색 색인 (GET /api/search-index)" — 색인에 드는 것 · 만드는 때 · 밤 채우기 ·
맞추기 · 조회지만 상태 줄을 만드는 동작(멱등)을 적었다. 로그 규칙에 개발 환경도 DB 쿼리
매개변수를 남기지 않는다는 줄, nestjs 스킬에 mail-search 모듈 줄과 Redis 로 옮길 상태를 더했다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 20:51:15 +09:00
parent 9887035bcd
commit 0fc5735959
3 changed files with 21 additions and 1 deletions
+17
View File
@@ -642,6 +642,23 @@ interface MailState {
범위의 기본값은 검색을 시작한 메일함이고 결과 머리에서 "그 메일함 | 전체 메일함"으로 바꾼다(휴지통 · 스팸메일함에서 시작하면 그 안에서 찾는다).
✕ · Esc · "검색 닫기"는 검색 전 메일함으로 돌아간다. 임시보관함의 결과를 누르면 지금처럼 쓰기 화면에서 이어 쓴다.
### 검색 색인 (`GET /api/search-index`) — 14단계 (색인 바탕 — 검색 · 대화는 다음 차례에 이 절에 더한다)
14단계는 엔진 검색 대신 **서버의 자체 색인**(지금 DB — 디자인 README 「14단계 — 검색 · 대화 묶기」)으로 찾는다. 이 절은 그 바탕 — 색인을 만들고 맞추는 규칙과 준비 상태다.
- **색인에 드는 것**: 직원 주소 + 엔진 메일 id 마다 한 줄 — 메일함 · 키워드 · 받은 시각 · 답장 관계(Message-ID · In-Reply-To · References) · 제목 · 보낸 사람 · 받는 사람 · 참조 · 첨부 이름 · 본문 글(앞 2만 자 — 잰 뒤 정한다).
메일 글이 DB 와 매일 백업에 한 벌 더 들어간다(사용자가 받아들였다). 퇴사 마무리는 이 표도 지운다. 언제나 로그인한 직원 주소로만 읽고 쓴다.
- **만드는 때**: 직원이 웹메일에 처음 로그인할 때(비밀번호가 만료된 로그인은 빼고 — 새 비밀번호를 정하면 만든다) 또는 아래 경로를 처음 물을 때 그 직원의 상태 줄을 `building` 으로 만든다. 로그인한 적 없는 계정은 색인하지 않는다.
- **지난 메일 채우기**: 밤에만 한 사람씩(KST 22:00 ~ 02:45 · 05:00 ~ 07:30 — 03:00 · 04:00 · 04:30 엔진 정리 · 03:30 백업을 피한다). 다 채우면 `ready`.
- **새로 온 · 바뀐 · 지운 메일**은 엔진의 변경(Email/changes)으로 바로 맞춘다 — 실시간 연결이 알릴 때 · 5분마다 · 검색 바로 전. 엔진이 변경을 셀 수 없다고 하면 그 직원 전체를 대조한다.
비밀번호가 만료됐거나 잠긴 계정은 대리 접근이 막혀 건너뛰고, 다음 로그인 · 아래 경로를 물을 때 다시 한다.
- `GET /api/search-index` → `{ status, done, total }`
- `status`: `building`(지난 메일을 채우는 중 — 그동안 그 직원의 검색은 지금 방식(엔진)이고, 화면은 결과 머리 아래에 "검색 준비 중" 줄을 보인다) · `ready`.
- `done`: 채운 메일 수(`total` 을 넘지 않는다) · `total`: 채우기를 시작할 때의 메일 수(시작 전이면 `null`, `ready` 면 `done` 과 같다).
- **조회지만 상태 줄을 만들고 멈춤을 푼다** — 줄이 없던 직원은 이때 `building` 으로 만들고, 대리 접근이 막혀 멈췄던 줄은 다시 해 보게 한다(로그인한 직원이 물었으니 다시 될 것이다). 같은 직원이 여러 번 물어도 결과는 같다(멱등).
- 로그인 필요(401 `AUTH_001`) · 제한된 세션은 403 `AUTH_010`(6절).
- 로그 가림: 검색 조건의 이름 `from` · `to` · `subject` · `body` 도 `q` · `cursor` 처럼 길이만 남긴다(`maskUrlForLog`). 개발 환경도 DB 쿼리 로그(매개변수)를 남기지 않는다 — 메일 글이 DB 에 있다.
### 여러 통 한꺼번에 (`PATCH /api/messages` · `POST /api/message-deletions`) — 3단계
```ts