feat(memos): include source_channel=email in memo inbox list
list 쿼리 확장: - 기존 source_channel IN (memo, voice) → OR (source_channel = email AND source_external_id IS NOT NULL) - mailplus_archive 의 INBOX root archive row (source_external_id=NULL) 는 자동 제외 - inbox_ingest 가 만든 email memo 만 /memos UI 에 노출 MemoResponse 확장: - source_external_id: Message-ID 또는 imap UID fallback - email_subject: email_metadata.subject (UI 부제/툴팁) _to_memo_response 가 email_metadata JSONB 에서 subject 추출. ingest 가 만든 row 가 UI 에 보이는 게 PR-2B 의 분류 배지/4 버튼/promote flow 자산 재사용의 전제. plan: ~/.claude/plans/document-enchanted-candy.md
This commit is contained in:
+11
-2
@@ -15,7 +15,7 @@ from typing import Annotated, Any
|
||||
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, Query, UploadFile
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy import delete, func, select
|
||||
from sqlalchemy import delete, func, select, or_, and_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from core.auth import get_current_user
|
||||
@@ -178,6 +178,9 @@ class MemoResponse(BaseModel):
|
||||
source_channel: str | None = None # voice/memo 등 진입점 식별 (UI 배지)
|
||||
file_type: str | None = None # audio (voice 메모) vs note (text 메모)
|
||||
file_path: str | None = None # voice 메모의 NAS audio 경로 (audio player 용)
|
||||
# PR-4 Email Ingest — 이메일 source 메모 식별 + UI 표시용
|
||||
source_external_id: str | None = None # email 의 Message-ID 또는 imap UID fallback
|
||||
email_subject: str | None = None # email_metadata.subject — 메모 카드 부제 / 툴팁
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
@@ -212,6 +215,8 @@ def _to_memo_response(doc: Document) -> MemoResponse:
|
||||
source_channel=doc.source_channel,
|
||||
file_type=doc.file_type,
|
||||
file_path=doc.file_path,
|
||||
source_external_id=doc.source_external_id,
|
||||
email_subject=(doc.email_metadata or {}).get('subject') if doc.email_metadata else None,
|
||||
created_at=doc.created_at,
|
||||
updated_at=doc.updated_at,
|
||||
)
|
||||
@@ -274,8 +279,12 @@ async def list_memos(
|
||||
voice 메모는 file_type='immutable' + category='audio' + source_channel='voice' 패턴.
|
||||
source_channel 만으로 분리 (file_type 필터는 immutable 다른 binary 까지 끌어옴 — 회피).
|
||||
"""
|
||||
# PR-4: inbox_ingest 가 만든 email memo 도 포함 (source_external_id != NULL 로 mailplus_archive 의 archive row 제외)
|
||||
base = select(Document).where(
|
||||
Document.source_channel.in_(("memo", "voice")),
|
||||
or_(
|
||||
Document.source_channel.in_(("memo", "voice")),
|
||||
and_(Document.source_channel == "email", Document.source_external_id.isnot(None)),
|
||||
),
|
||||
Document.deleted_at == None, # noqa: E711
|
||||
Document.archived == archived,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user