feat(mail): 전사 메일함 수집 + 요청자 참여(from/to/cc) 가시성 필터
build-and-push / build (push) Successful in 32s

- 수집 대상을 프로젝트 팀 → 전사 모든 구성원 메일함으로 변경(프로젝트 캐시)
- Message.Cc 수집 + Involves(email): 요청자가 수신·참조된 메일만 노출
- 공동 메모는 그대로(프로젝트 구성원 공유)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
theorose49
2026-06-30 11:11:23 +09:00
co-authored by Claude Opus 4.8
parent 751aa8ed97
commit b4b47e5ed1
2 changed files with 43 additions and 27 deletions
+14 -1
View File
@@ -47,6 +47,7 @@ type Message struct {
ThreadID string `json:"threadId"`
From string `json:"from"`
To string `json:"to"`
Cc string `json:"cc"`
Subject string `json:"subject"`
Date string `json:"date"` // raw Date header
Snippet string `json:"snippet"`
@@ -54,6 +55,16 @@ type Message struct {
TS int64 `json:"ts"` // internalDate (ms) for sorting/formatting
}
// Involves reports whether the given email appears in From/To/Cc (case-insensitive).
// Used to gate per-viewer visibility: a member only sees mail they're a party to.
func (m Message) Involves(email string) bool {
if email == "" {
return false
}
hay := strings.ToLower(m.From + " " + m.To + " " + m.Cc)
return strings.Contains(hay, strings.ToLower(email))
}
type tokenEntry struct {
token string
expires time.Time
@@ -187,7 +198,7 @@ func (s *Service) getMeta(ctx context.Context, subject, id string) (Message, err
if err != nil {
return Message{}, err
}
u := fmt.Sprintf("https://gmail.googleapis.com/gmail/v1/users/me/messages/%s?format=metadata&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Subject&metadataHeaders=Date&metadataHeaders=Message-ID", id)
u := fmt.Sprintf("https://gmail.googleapis.com/gmail/v1/users/me/messages/%s?format=metadata&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Cc&metadataHeaders=Subject&metadataHeaders=Date&metadataHeaders=Message-ID", id)
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
req.Header.Set("Authorization", "Bearer "+tok)
resp, err := s.client.Do(req)
@@ -220,6 +231,8 @@ func (s *Service) getMeta(ctx context.Context, subject, id string) (Message, err
m.From = h.Value
case "to":
m.To = h.Value
case "cc":
m.Cc = h.Value
case "subject":
m.Subject = h.Value
case "date":