Files
multica/packages/views/locales/ko/inbox.json
Naiyuan Qing 6b2097ccbb feat(inbox): archived notifications sub-view (MUL-3736) (#5518)
Adds an "Archived" sub-view to the Inbox, reachable from an entry at the
bottom of the main list, with per-row unarchive. Mirrors chat's archived
sub-view so the two surfaces share one mental model.

Backend:
- GET /api/inbox/archived and POST /api/inbox/{id}/unarchive. Kept off the
  existing GET /api/inbox so installed clients keep their contract and the
  unbounded archive never rides along with the main list.
- The archived query excludes any issue that still has an active row. Archiving
  is issue-level, so a new notification on an archived issue leaves old archived
  rows beside a fresh active one — without the guard the issue renders in BOTH
  lists. The exclusion lives in SQL so neither list depends on the other's cache.
- Unarchive is issue-level (mirroring archive) and leaves `read` untouched, so a
  restored unread item raises the unread badge again.
- v1 ships no pagination: LIMIT 200, newest-first, so truncation drops the
  oldest rows and never hides a group's newest one.
- inbox:unarchived event, fanned out to the recipient like the other personal
  inbox events.
- Two CONCURRENTLY-built indexes; inbox_item previously had none covering
  workspace/archived/created_at.

Frontend:
- Separate TanStack cache per list; every inbox event invalidates the workspace
  prefix, since any of them can move an item across the boundary.
- View persisted as ?view=archived, so refresh, back/forward, and the mobile
  detail-back all return to the list the user was in.
- Batch actions stay main-view only — they archive from the MAIN inbox, so
  offering them over the archived list would do the opposite of what it reads.
- Mobile subscribes to inbox:unarchived (its list gains the restored row); its
  own archived view remains follow-up.

Known debt: no pagination, so an archive past ~200 rows is truncated silently
in the UI; the entry's count is the deduplicated count of the rows returned.

Verified: pnpm typecheck/test/lint (0 errors), go build/vet, Go inbox suite
against a real Postgres, migrations up+down, and EXPLAIN confirming both new
indexes serve the query.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-07-16 14:58:42 +08:00

79 lines
2.9 KiB
JSON

{
"page": {
"title": "인박스",
"back": "인박스"
},
"menu": {
"mark_all_read": "모두 읽음으로 표시",
"archive_all": "모두 보관",
"archive_all_read": "읽은 항목 모두 보관",
"archive_completed": "완료된 항목 보관"
},
"list": {
"empty": "알림이 없습니다",
"mark_done_tooltip": "완료로 표시",
"archive_tooltip": "보관",
"time": {
"just_now": "방금 전",
"minutes": "{{count}}분",
"hours": "{{count}}시간",
"days": "{{count}}일"
},
"archived_title": "보관됨",
"archived_empty": "보관된 알림이 없습니다",
"unarchive_tooltip": "보관 해제"
},
"detail": {
"select_prompt": "자세히 볼 알림을 선택하세요",
"empty": "인박스가 비어 있습니다",
"original_input": "원본 입력",
"edit_advanced": "고급 양식으로 수정",
"archive": "보관",
"unarchive": "보관 해제"
},
"types": {
"issue_assigned": "할당됨",
"issue_subscribed": "구독됨",
"unassigned": "할당 해제됨",
"assignee_changed": "담당자 변경됨",
"status_changed": "상태 변경됨",
"priority_changed": "우선순위 변경됨",
"start_date_changed": "시작일 변경됨",
"due_date_changed": "마감일 변경됨",
"new_comment": "새 댓글",
"mentioned": "멘션됨",
"review_requested": "리뷰 요청됨",
"task_completed": "작업 완료됨",
"task_failed": "작업 실패함",
"agent_blocked": "에이전트 막힘",
"agent_completed": "에이전트 완료됨",
"reaction_added": "반응 추가됨",
"quick_create_done": "에이전트로 생성됨",
"quick_create_failed": "에이전트 생성 실패"
},
"labels": {
"set_status_to": "상태 변경:",
"set_priority_to": "우선순위 변경:",
"assigned_to": "{{name}}님에게 할당",
"removed_assignee": "담당자 제거됨",
"set_start_date_to": "시작일: {{date}}",
"removed_start_date": "시작일 제거됨",
"set_due_date_to": "마감일: {{date}}",
"removed_due_date": "마감일 제거됨",
"reacted_to_comment": "내 댓글에 {{emoji}} 반응을 남겼습니다",
"created_with_agent": "에이전트가 생성: {{identifier}}",
"failed_with_detail": "실패: {{detail}}"
},
"errors": {
"mark_read_failed": "읽음 표시를 하지 못했습니다",
"archive_failed": "보관하지 못했습니다",
"mark_done_failed": "완료 표시를 하지 못했습니다",
"mark_all_read_failed": "모두 읽음으로 표시하지 못했습니다",
"archive_all_failed": "모두 보관하지 못했습니다",
"archive_all_read_failed": "읽은 항목을 보관하지 못했습니다",
"archive_completed_failed": "완료된 항목을 보관하지 못했습니다",
"unarchive_failed": "보관 해제에 실패했습니다",
"archived_load_failed": "보관된 알림을 불러오지 못했습니다"
}
}