generated from ttipo/project-base
feat(flutter): 앱 첫 판 화면 — 로그인 · 메일 목록 · 읽기 · 쓰기 · 검색 · 새 메일 알림 #21
Reference in New Issue
Block a user
Delete Branch "feat/app-push"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
무엇을 · 왜
앱 첫 판(안드로이드 — 다음은 Play 내부 테스트)의 화면이다. 화면마다 캔버스 보드를 확정한 뒤 만들었다(
docs/design/app/— 보드 · README).register()가 매니페스트 표시firebase_messaging_installation_id_enabled없이 곧바로 거절해 [알림 켜기]가 실패했다(3a25cc5) ② 앱을 보는 중 받은 알림 뒤의 "봤음"이 그 메일과 같은 초가 되어 다음 알림이 한 통 많았다 → 1.5초 늦춤(5670017).확인 방법
flutter analyze0 ·flutter test1,061 ·flutter build apk --debug(합치기 전 마지막). 이번 합침 뒤 analyze 0 · test 1,061 통과.flutter/.env에API_URL,flutter/android/app/google-services.json(커밋하지 않음 — Firebase 콘솔에서 받는다) 뒤flutter run(실기기는adb reverse tcp:3000 tcp:3000).영향 범위
97a989b)ci-flutter.yml경로)체크리스트
ApiException.code분기)npm run sync:error-codes실행 후 생성 파일까지 커밋 (바꾸지 않음)flutter/.env·google-services.json은 무시됨)🤖 Generated with Claude Code
14단계 3차다. 같은 대화(답장 · 전달로 이어진 메일)를 읽기 화면에 보이고, 목록을 대화로 묶어 볼 수 있게 한다. 색인이 준비된 직원은 우리 대화 키로, 채우는 중인 직원은 엔진의 스레드로 묶는다(응답의 basis — 첫 쪽에서 정하고 커서가 잇는다). - 대화 키: 색인 쓰기 때 넣은 메일의 부모 · 자식(References · In-Reply-To) 가운데 말머리 (회신 · 답장 · 전달 포함)를 뗀 제목이 같은 것을 가장 작은 키로 합친다. 늦게 온 원본도 잇고, 다시 넣어도 키는 풀리지 않는다. 색인 판 4 - GET /api/messages/{id}/conversation — 오래된 차례, 휴지통 · 스팸메일함에만 든 메일과 발송 중인 내부 초안은 빼고 지금 메일은 늘 넣는다 - GET /api/conversations?mailboxId= — 그 메일함의 대화 한 줄씩(참여자 10명 · 통 수 · messageIds 최신 500 · pendingSendIds). 직원 주소 btree 로 먼저 좁힌다(10명 흉내 큰 메일함 첫 쪽 81ms) - 설정 groupByConversation(처음 끔) — 서버는 저장만 하고 묶을지는 화면이 정한다 - 마이그레이션 AddMailSearchSender — 참여자는 따로 둔 첫 보낸 사람 칸에서만 읽는다 리뷰 반영: 엔진 방식에 개수 · 시간 상한(같은 대화 한 요청 1,000통 · 묶은 목록 스레드마다 500 · 한 요청 2,000 · 15초, 요약 속성은 내보낼 메일만), Mailbox/get 장애는 503, 꾸민 커서는 엔진 · DB 보다 먼저 400, 같은 대화 한 문장, 이름 안의 <주소>로 참여자를 꾸미지 못하게, 로그 추적 ID. 검색 표본 표 머리 주석(frontend 로 옮겼다)도 함께 고친다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>- 분할 보기에서 대화 줄을 고르면 도구 줄이 두 줄로 넘치던 것, 목록 머리의 안 읽은 수가 1440 에서도 늘 잘리던 것 - 묶은 줄에 한 일의 알림은 "{메일함}에 있는 메일 N통을 …"(줄의 통 수는 대화 전체라서), 되돌리기 알림은 되돌린 메일함을 말한다 - 같은 대화 칸: 펼친 줄의 첨부 수 안내, 우리 원문 인용 머리부터 뺀 미리 보기, 보내기를 기다리는 메일은 줄 끝에 - 검색 준비 중 · 결과 없음 · 하루짜리 기간 · 내 이름 조건의 글, 예약 시각의 띄어쓰기, 이름 맞추기(대화로 묶기 · 내용에 든 말 · 표 머리 참여자) - 다른 탭 · PC 에서 바꾼 설정을 탭으로 돌아올 때 다시 받는다(60초 지났을 때) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>- 대화로 묶은 휴지통에서 줄을 골라 영구 삭제하면 확인 창 · 알림을 "휴지통에 있는 메일 N통을 …"으로 쓴다 — 줄의 통 수는 대화 전체라서 (옮기기 알림 "{메일함}에 있는 메일 N통을 …"과 같은 결) - 값을 끼워 넣는 글의 띄어 쓴 조사를 붙인다(9단계 "@도메인에서", 11단계 "25MB를" · "2GB까지" · "20MB가"), 공개 내려받기 화면의 신고 주소는 끝 글자로 조사를 고른다 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>2026-11-07 사용자가 "자연스러운 문구가 아니라 시스템, 설계 문구 형식"이라고 짚은 글을 웹과 같은 기준으로 고친다. 화면이 하는 일을 설명하는 말("여기에 표시됩니다")과 번역투("맞는 메일")를 빼고, 빈 메일함 안내 · 읽기 화면 본문 안내 · 검색 글 · 로그인 글을 내 메일이 어떻게 되는지와 할 일로 쓴다. 본문을 다 보이지 못할 때는 PC 웹메일에서 원문을 받는 길까지 적고, 사용자가 만든 메일함의 빈 안내는 앱의 [이동]이 아이콘이라 길게 눌러 고르는 말로 쓴다. 오류 사전은 이 브랜치를 main 위로 옮길 때 새 글로 다시 만든다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>계약 1절 끝의 옛 메모(/api/push-devices · { minVersion, latestVersion, storeUrl })를 확정한 경로 · 모양 · 규칙으로 바꾸고 (N · 간격 · 따라잡기 · 엔진 after 의 초 경계 · "알림이 멈췄습니다"를 보내는 까닭 표 · 실패 처리 · 실기기로 확인할 것), "클라이언트 — 앱"에 앱이 실제로 부르는 때를 적었다. 2절 실시간 알림의 붙잡기와 6절 퇴사 마무리 목록도 더했다. nestjs · docker 스킬과 env · 보안 · 로그 규칙에 FCM 키 자리 · 바깥 연결 · 가릴 값을 더했다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>이 PR 이 문구 다듬기 PR 뒤에 빨리 감기로 합쳐지고 CI 가 합친 모습 그대로를 시험하게 한다. 충돌 넷은 모두 설정 › 로그인된 기기의 글이다 — 앱 쪽은 앱 세션이 함께 보여 "브라우저"를 "기기"로, 다듬기 쪽은 같은 안내 문장을 규칙 9 로("여기에 보이지 않습니다" → "이 목록에 없습니다") 바꿨다. 뜻은 앱 쪽 · 문장은 다듬은 글로 풀었고(account-security.ts · LoginSessionList.vue 주석 · 디자인 README), 시험은 두 쪽이 더한 상수를 모두 남기고 글자 그대로 견주던 줄을 상수로 바꿨다(AccountLoginHistoryPage.spec.ts). 합친 뒤 backend tsc · lint 0 · 단위 3,701 · e2e 333, frontend type-check · lint 0 · 단위 2,774 통과. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>