docs: 앱 새 메일 알림 · 업데이트 · 앱 아이콘을 앱 README · flutter README · 스킬 · 계약에 적는다

앱 디자인 README 에 "새 메일 알림 · 업데이트 · 앱 아이콘" 절(허락 묻기 · 설정 줄 상태 · 받기 · 누르기 · 로그아웃 차례 ·
"알림이 멈췄습니다"를 보내는 때)을, flutter README 에 Firebase 설정 파일 · 아이콘 만들기 · Play 데이터 보안 신고를,
flutter 스킬에 새 행을, 계약 2절 "새 메일 확인"에 앱이 알림을 받았을 때 한 번 묻는 줄을 더했다.
보드 App1Push 의 ⑧ 칸 설명은 "알림이 멈췄습니다"를 넓힌 결정대로 고쳤다(캔버스 v66).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-08 00:46:30 +09:00
parent e03eda1fd3
commit 08b8144087
5 changed files with 84 additions and 9 deletions
+46 -3
View File
@@ -174,7 +174,8 @@
- 글자 크기는 테마 크기로 맞췄다(15.5 → 16 · 14와 14.5 → 15 · 13 → 13 · 12.5 → 12).
- **알려진 한계**: 앱이 안 보이게 될 때 칸에 쓰다 만 주소(칩이 되지 않은 글)는 저장에 들지 않고, 나가기 확인 창이 떠 있는 동안은 저장하지 않는다. 앱이 앞에 있는 채로 정리되면 마지막 몇 초를 잃는다.
고르는 동안 앱이 정리되면 고른 파일은 버린다(쓰던 내용은 고르는 창을 열 때 저장된다). 고르는 창에 10분 넘게 머물면 그 고르기는 시한으로 끝난다(알림이 창 뒤에서 뜰 수 있다 — 다시 고른다).
**푸시를 붙일 때**: 다른 화면으로 `go` 해서 쓰기 화면이 내려가면 detach 가 자동 저장을 멈춘다 — 내려가기 전에 마저 저장하게 바꾼다.
**알림 · 업데이트 화면으로 내려갈 때**(2026-11-07): 새 메일 알림을 누르거나 업데이트 화면으로 옮겨(다른 화면으로 `go`) 쓰기 화면이 내려가면, 쓰다 만 주소까지 임시보관함에 마저 저장하고
"임시보관함에 저장했습니다."(저장하지 못하면 그 코드의 사전 문구)로 알린다. 로그아웃 · 세션 끝 · 제한 단계로 옮겨 내려갈 때는 알리지 않는다(그 세션의 쓰기가 끝났다).
- **실기기에서 볼 것**: 삼성 · Gboard 자판의 칩 만들기(쉼표 · [다음] · 한글 조합 중 확정 · 여러 줄 붙여 넣기), 추천 목록이 자판에 가리는지, 예측 뒤로 가기, 홈 · 다른 앱으로 갔을 때 저장, 긴 원문 펼침 스크롤,
서명 그림 폭, TalkBack 차례(칩 · 추천 · 원본 펼침 · 띠), 제스처 내비게이션에서 읽기 화면 알림 자리, 웹 ↔ 앱으로 저장본을 서로 다시 열기, 앱 로그인 서버(feat/app-auth)와 함께 실제 보내기 · 저장 · 서명 그림.
첨부(2차): 고르는 창의 출처마다(내 파일 · Google 드라이브 · 사진 · 다운로드) 이름 · 크기 · 확장자를 주는지, hwp · hwpx 가 창에 보이고 올라가는지 · HEIC 는 `FILE_001` 인지,
@@ -247,8 +248,50 @@
(2차) 자판과 함께 시트가 올라가고 초점 칸이 보이게 스크롤되는지 · 가로 화면 + 자판, 기간 메뉴가 뜨는 자리, 날짜 창의 한국어 머리와 연필(입력) 모드에서 오늘 뒤 날짜를 막는지,
뒤로 가기 · 끌어 닫기 · 가림막에서 고친 값을 버리는지와 닫은 뒤 자판, TalkBack([조건] 펼침 · 기간 단추 · 날짜 칸 값과 오류 · 단추 줄 위 알림 · 닫은 뒤 초점), 큰 글자의 날짜 칸 · 여러 줄 조건 줄,
바뀐 가림막 색(옮기기 시트 포함), 14단계 서버에서 조건만 · 검색어 + 조건(시간대 · 첨부) · from/to 를 실은 강조.
### 새 메일 알림 (푸시)
- 알림 내용은 "새 메일 N통"만 — 보낸 사람 · 제목이 Google · Apple 서버를 거치지 않게. 누르면 메일 모듈의 받은편지함으로(알림에는 모듈 이름과 id 만 싣는다).
### 새 메일 알림 · 업데이트 · 앱 아이콘 (`App1Push` — 2026-11-07 확정)
- **알림 글은 "새 메일 N통"뿐**이다 — 보낸 사람 · 제목은 Google 서버를 거치지 않게 싣지 않는다(잠금 화면도 수만). 새 메일이 더 오면 같은 알림의 수만 바뀌고 쌓이지 않는다.
앱을 보고 있을 때는 띄우지 않는다 — 받은편지함이 보이면 그 자리에서 바로 새 메일을 확인한다. 앱으로 돌아오면 알림창의 새 메일 알림을 지운다.
누르면 늘 메일 탭의 받은편지함이다(읽기 · 쓰기 화면 위에 있었어도 — 쓰던 메일은 임시보관함에 마저 저장하고 알린다). 알림 데이터에는 모듈 이름과 종류만 싣는다.
- **로그인이 끝났다는 알림**: "새 메일 알림이 멈췄습니다" · "안전을 위해 로그아웃했습니다. 앱을 열어 다시 로그인해 주세요."(보드 ⑧ "로그인이 저절로 끝났을 때"의 글).
보내는 때는 2026-11-08 사용자 결정으로 넓어졌다 — 표의 원본은 서버 `modules/push/push.constants.ts` 의 `SESSION_ENDED_NOTICE` 이고, 여기에는 뜻만 적는다.
- 보낸다: 저절로 끝남(14일 동안 쓰지 않음 · 로그인한 지 30일) · 다른 곳에서 비밀번호를 바꿈(바꾸다 결과를 알 수 없게 된 때도) · 앱 로그인 갱신 유예로 끊김 · 리프레시 토큰 재사용을 알아채 끊김.
- 보내지 않는다: 그 휴대폰에서 로그아웃 · 로그인된 기기에서 끊기 · 다른 곳 모두 로그아웃 · 운영 도구(재설정 · 잠금 · 이전 마치기 · 퇴사 마무리) · 계정을 쓸 수 없음 · 2단계 인증을 켜서 끊긴 세션(제한된 세션).
- 서버가 끝난 세션을 5분마다 정리할 때 한 번 보내고, 같은 tag 로 앞의 "새 메일 N통"을 바꿔 쓴다. 누르면 다른 알림처럼 메일 탭으로 가고, 세션이 없으니 첫 요청에서 로그인 화면이 된다(앱은 알림의 종류로 가르지 않는다).
- **허락은 받은편지함에서 한 번 권한다**(①): 안드로이드 13 이상 · 아직 묻지 않음 · 이 휴대폰에서 켬 · 서버가 보낼 수 있음 · 닫은 적 없음일 때만 보인다. 위 막대 아래에 고정이고(목록과 함께 흐르지 않는다) 메일을 고르는 동안은 숨긴다.
휴대폰이 묻는 창(②)은 [알림 켜기]를 누를 때만 띄운다 — 두 번 거절하면 휴대폰이 다시 묻지 않으므로 직원이 고른 때에만 쓴다. 안드로이드 12 이하는 묻지 않고 처음부터 켜져 있다.
고른 뒤(③): 허용 → "새 메일 알림을 켰습니다." · 허용 안 함 → "나중에 [설정] 탭에서 …" · 이미 막혀 창이 뜨지 않음 → 알림 줄 + [설정 열기]. 어느 쪽이든 줄은 사라지고, [✕]로 닫으면 이 휴대폰에서 다시 보이지 않는다.
- **설정 › 새 메일 알림 줄**(④ — 그 밖의 칸 · 로그아웃 확인 창은 `App1Shell`):
| 상태 | 스위치 | 그 밖 |
| --- | --- | --- |
| 켜짐 · 꺼짐 | 누를 수 있음 | — |
| 허락 전(13 이상 — 묻지 않음 · 한 번 거절) | 꺼짐 · 누를 수 있음 | 켜면 휴대폰이 묻는다 |
| 켜는 중 · 끄는 중 | 바꿀 값 쪽 · 다시 받지 않음 | 둥근 진행 표시 — 화면 낭독기는 "켜는 중" · "끄는 중" |
| 휴대폰에서 이 앱 알림이 막힘 | 누를 수 없음 | [설정 열기] → 이 앱의 알림 설정 |
| 휴대폰에서 새 메일 카테고리만 꺼짐 | 누를 수 없음 | [설정 열기] → 그 카테고리 |
| 서버가 보낼 수 없음 · 받을 수 없는 휴대폰(Google Play 서비스 없음 등) | 누를 수 없음 | 앱을 열어 확인해 달라는 글 |
켜기는 서버 등록이 끝나야 켜지고(실패하면 꺼진 채로 돌아가고 그 코드의 사전 문구 — 처음 값이 켬인 휴대폰이 허락 전에서 켰어도 꺼짐으로 둔다), 끄기는 서버 등록을 지운 뒤 꺼진다. 휴대폰 설정에서 돌아오면 다시 읽어 모습을 바꾼다.
[설정 열기]가 휴대폰 설정을 열지 못하면 찾아가는 길을 알린다(④ — 보드의 "설정을 열지 못했을 때"). 화면 낭독기는 스위치를 "새 메일 알림"으로 읽고 줄 아래 글을 설명으로 읽는다.
- **휴대폰 설정의 카테고리**(⑫): 이름 "새 메일" · 설명 "새 메일이 오면 알려 드립니다."만 앱이 정한다. 중요도 높음 — 다른 앱을 쓰는 중에는 화면 위에 잠깐 떴다가 상태 표시줄에 남는다(소리 · 진동은 휴대폰 설정).
- **작은 아이콘**(⑨): ARA 글자 마크의 흰 실루엣(휴대폰은 모양만 쓰고 색은 직접 칠한다 — 알림 앞 동그라미는 강조 #0E7C86). 상태 표시줄에서 가늘다는 걱정이 있어 실기기에서 다시 본다 —
봉투로 바꾸려면 같은 이름(`ic_stat_ara`)의 그림만 바꾼다(앱 매니페스트의 기본 아이콘이 이 이름 하나를 가리킨다 — 서버 메시지는 아이콘 · 색을 싣지 않는다).
- **앱 아이콘**(⑪ — 나안): 남색 #0B3640 바탕 + 흰 ARA 마크. 적응형(배경색 · 앞면 마크 · 안드로이드 13 테마 아이콘용 마크만 담은 그림 한 장 더)이고 마크는 잘리지 않는 가운데 칸 안에 둔다.
안드로이드 7(적응형 전)의 아이콘도 같은 모양이다. 삼성 휴대폰은 알림창에도 앱 아이콘을 쓴다.
- **업데이트 화면**(⑩): 이 앱의 판이 서버가 정한 최소 판보다 낮으면 로그인 전이든 메일을 보던 중이든 이 화면으로 온다(쓰던 메일은 임시보관함에 저장한다). 뒤로 가기는 앱을 닫는다.
[Play 스토어 열기]는 Play 스토어 앱부터, 열리지 않으면 웹 주소. 문의 줄은 로그인 화면과 같은 연락처다. 서버가 최소 판을 내리면 다음 확인(앱으로 돌아올 때 — 1시간마다)에서 원래 화면으로 돌아간다.
- **로그아웃**: 확인 창이 이 휴대폰에 새 메일 알림도 오지 않는다고 알린다(`App1Shell`). 토큰을 지운 뒤 서버 logout 과 함께 이 휴대폰의 알림을 멈춘다(알림창 지우기 · FCM 등록 풀기 — 서로 기다리지 않는다).
서버 줄은 서버가 세션과 함께 지운다. 끊긴 망이라 FCM 등록을 풀지 못했으면 다음 실행 · 다음에 앱으로 돌아올 때 다시 풀고, 그사이 같은 휴대폰에서 다른 직원이 로그인하면 그 등록이 이어받는다(같은 FID 로 올려 서버의 앞 직원 줄이 지워진다).
- 글자는 테마 크기로 맞췄다(15.5 → 16 · 14 → 15 · 13.5 → 13 · 13 → 13 — 위 「쓰기」와 같은 정리).
- **구현하며 정한 것**(2026-11-07 — 보드에 없는 글 · 경우)
- 권하기 줄의 [알림 켜기]를 눌렀는데 새 메일 카테고리만 꺼져 있으면: "휴대폰 설정에서 새 메일 알림이 꺼져 있습니다." + [설정 열기](막혔을 때와 같은 꼴).
- 끄는 중의 화면 낭독기 글 "끄는 중"(보드에는 켜는 중만 있다).
- 문의 연락처를 정하지 않았거나 받지 못했을 때: 설정 › 문의 "앱이나 계정 문제로 도움이 필요하면 관리자에게 문의해 주세요." · 업데이트 화면 "Play 스토어에 업데이트가 보이지 않나요? 관리자에게 문의해 주세요."(로그인 화면의 문의 줄과 같은 꼴).
- 서버가 보낼 수 있는지 아직 모르면(앱 설정을 받기 전 · 받지 못함) 쓸 수 있는 것으로 본다 — 막지 않는다. 앱 설정은 앱을 띄우자마자 세션 되살리기와 나란히 묻는다.
- **실기기 · 실제 Firebase 에서 볼 것**: FID 등록 소식(`onRegistered`)이 자동 초기화를 끈 채 오는지 · 앱 데이터를 지운 뒤 새 FID, 같은 알림을 바꿔 쓰는지(태그 `new-mail`)와 앱으로 돌아올 때 지워지는지,
앱을 보는 중에는 시스템 알림이 뜨지 않는지, 뒤에 있을 때 · 꺼져 있을 때 누른 알림이 받은편지함을 여는지, 두 번 거절한 뒤 스위치가 [설정 열기] 쪽으로 바뀌는지,
카테고리만 끈 상태를 읽는지 · [설정 열기]가 그 카테고리를 여는지(삼성 · Pixel), 상태 표시줄의 작은 아이콘 굵기 · 삼성 알림창의 앱 아이콘 · 테마 아이콘, 절전(Doze) 중 도착 시간,
Play 스토어가 없는 휴대폰의 [Play 스토어 열기], TalkBack(권하기 줄 묶음 · 스위치 이름과 설명 · 켜는 중 알림).
### 처음 판에서 미룬 것
서식 편집 · 대용량 첨부 · 필터 · 주소록 화면 · 서명 고치기 · 계정 설정(웹에서) · 오프라인 저장 · iOS. 검색은 결과에서 여러 통 고르기를 미뤘다(읽기 화면의 같은 대화 · 목록 대화로 묶기도 — 보드 먼저).
+2 -2
View File
@@ -409,8 +409,8 @@ a{color:#0E7C86}a:hover{color:#0A5F67}
<div style="flex: 0 0 390px; display: flex; flex-direction: column; gap: 12px">
<div style="height: 62px; display: flex; flex-direction: column; gap: 2px">
<h3 style="margin: 0; height: 20px; font-size: 13px; line-height: 20px; font-weight: 700; color: #344054">8. 로그인이 저절로 끝났을 때</h3>
<p style="margin: 0; font-size: 12.5px; line-height: 20px; color: #667085; word-break: keep-all">앱을 14일 동안 열지 않았거나 로그인한 지 30일이 지나면 한 번 옵니다. ‘새 메일 N통’ 자리를 바꿔 씁니다.</p>
<h3 style="margin: 0; height: 20px; font-size: 13px; line-height: 20px; font-weight: 700; color: #344054">8. 로그인이 끝났을 때</h3>
<p style="margin: 0; font-size: 12.5px; line-height: 20px; color: #667085; word-break: keep-all">저절로 끝났거나 다른 곳에서 비밀번호를 바꿔 끊겼을 때 한 번 옵니다. ‘새 메일 N통’ 자리를 바꿔 씁니다.</p>
</div>
<div role="img" aria-label="로그인이 끝나 새 메일 알림이 멈췄다는 알림" style="position: relative; width: 390px; height: 844px; border-radius: 28px; overflow: hidden; background: #E8EBEE; box-shadow: 0 0 0 1px #D0D5DD, 0 12px 32px rgba(16, 24, 28, 0.12); display: flex; flex-direction: column">
<div aria-hidden="true" style="display: flex; flex-direction: column">
+2
View File
@@ -657,6 +657,8 @@ interface MailState {
평소 사용과 같은 칸을 쓴다 — `GET /api/messages` 는 대략 "쓰고 있는 탭 수 × 1분에 1번 + 평소 목록 · 더 보기"다(3단계).
5단계부터는 실시간 연결이 살아 있는 동안 1분 확인 대신 "바뀔 때마다(1초 모아서) 보이는 탭 수 × 1번"이다 — 사무실이 바쁠수록 늘 수 있다. 운영 전환 때 직원 수에 맞춰 정한다.
- 5단계부터는 실시간 연결(아래 "실시간 알림")이 살아 있는 동안 1분 확인을 멈추고, 끊기면 1분 확인으로 돌아간다. 이 API 와 규칙은 그대로다.
- **클라이언트 — 앱**(Flutter — 앱 디자인 README "새 메일 알림 · 업데이트 · 앱 아이콘", 2026-11-07): 메일 목록이 보이고 앱이 앞에 있는 동안만 1분마다 묻는다(앞으로 오면 10초 규칙 — 웹과 같다). 실시간 연결(SSE)은 쓰지 않는다.
앞에 있을 때 받은 새 메일 알림(1절 "앱 새 메일 알림 · 앱 설정" — 앱이 앞에 있으면 휴대폰이 알림을 그리지 않는다)이 오면 1분 차례를 기다리지 않고 바로 한 번 묻는다 — 묻는 중이면 그 물음이 끝난 뒤 한 번 더, 목록이 보이지 않으면(다른 탭) 묻지 않는다.
### 검색 (`GET /api/messages` 의 `q`) — 3단계