Commit Graph

4 Commits

Author SHA1 Message Date
ttipo 3a126bdf83 feat(flutter): 메일 쓰기 화면 2차 — 첨부 고르기 · 올리기를 더한다
[파일 첨부]가 안드로이드 고르는 창(권한 없음)을 연다. 고른 파일은 앱 임시 폴더에
복사해 두고 그 복사본을 multipart 로 둘씩 올린다 — 올리기에 실패하거나 서버가 첨부를
찾지 못해도(MAIL_004) 다시 고르지 않고 다시 올리려고.

- 사전 검사 · 보내기 막기는 웹과 같은 차례, 한도는 GET /api/mail-quota
- 기기가 같은 차례로 미리 걸러 넣을 파일만 복사한다(content:// 만, 판정은 Dart 가 다시)
- 다 올리면 서버가 정리한 이름 · 크기로 싣는다(이름 255자 — 웹과 같다)
- MAIL_004 뒤 다시 올릴 수 없는 파일은 빼기 전까지 저장 · 보내기를 막는다
- 가져오는 · 올리는 동안 [보내기]를 막고(가져오기는 10분 시한), 올리는 중 나가기는 따로 묻는다
- 화면이 끝나거나 직원이 바뀌거나 앱을 띄울 때 복사본을 지운다

리뷰(M1~M4 · L 다섯 · 다시 본 리뷰의 L 하나)를 고쳤다. 시험 690 → 750.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 04:19:57 +09:00
ttipo a37045a553 feat(flutter): 메일 읽기 화면을 만든다 (App1Reader)
머리는 앱 화면, 본문은 스크립트를 끈 WebView 에 앱이 감싼 CSP 문서로
보인다. 받은 HTML 은 서버 정화 뒤 앱이 한 번 더 허용 목록으로 다시 쓰고,
외부 이미지는 [이미지 보기] 뒤 앱이 Dio 로 받아 data: 로 넣는다(토큰이
WebView 에 가지 않는다).

- 읽음 · 중요 · 이동 · 스팸 · 삭제 · 영구 삭제, 붙잡힌 메일의 보내기 취소 ·
  예약 취소는 목록과 같은 규칙. 응답은 그 요청이 바꾼 칸만 지금 값에 덮는다
- 첨부는 앱 임시 폴더(cacheDir/downloads)에 받아 FileProvider + ACTION_VIEW
  로 연다(파일 여는 플러그인 없이). 열 형식은 확장자 먼저, 웹 문서 · svg ·
  설치 파일 · 인증서는 받지 않는다
- 응답 인터셉터가 바이트 · 스트림 실패 본문(64KB 까지)에서 코드를 읽고,
  뜻밖의 실패에도 handler.next 로 끝낸다
- 리뷰 H1: 같은 그림을 수백 번 쓴 메일이 문서를 GB 단위로 키우던 것 —
  문서에 싣는 그림 글을 나온 횟수까지 세어 10M 자에서 멈춘다
- 리뷰 M1: 짧고 깊은 본문을 화면 isolate 에서 정화하던 것 — 길이와 중첩
  비용으로 고르고(6,144자 · 비용 5,000), 그 밖은 Isolate.run
- 새 의존성: webview_flutter 4.14.1 · webview_flutter_android 4.12.0 ·
  html 0.15.7(+ csslib 1.0.2) — 배포 2주 넘음. path_provider · mime 은
  lock 에 있던 판을 직접 의존으로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 22:26:09 +09:00
ttipo 35fcf5e4ef feat(flutter): 앱 로그인 · 토큰 갱신 · 모듈 라우터 기반을 만든다
앱 1단계의 바탕이다(계약 1절 "앱 로그인" — 서버는 다음 차례, 지금은 가짜 서버로 시험한다).

- 토큰: 리프레시 토큰은 보안 저장소에만, 액세스 토큰은 메모리에만. 첫 실행 표시가 없으면 남은 토큰을
  지우고, 안드로이드 백업을 끈다. 보안 저장소 일은 차례로 한다
- 인터셉터: 401 이면 갱신 한 번(동시 401 묶음) 뒤 다시 보내기, AUTH_010 은 me 를 다시 받아 그 단계로,
  미리 갱신 30초 전 · 만료는 응답 Date 로, 세션 세대가 바뀐 뒤의 응답은 조용히 버린다,
  비밀이 든 요청의 실패 예외는 본문 · Bearer 를 지운다
- 세션: 로그인 · 코드 · 새 비밀번호 · 2단계 켜기 단계의 상태와 늦은 결과 버리기(버린 로그인의 토큰은
  조용히 logout), 로그아웃은 메모리부터 비운다, 유예 응답이면 세션 끝 + 조용한 logout
- 모듈 틀: go_router StatefulShellRoute 와 아래 탭 막대 — 모듈 목록은 웹 app-modules.ts 와 짝,
  첫 판은 [메일 · 설정]. 모듈끼리 import 하지 않는다
- Riverpod 자동 다시 하기를 끈다, Pretendard 1.3.9(OFL), 확정 글자 크기, 시험 126건
- 판은 Flutter 3.41.9(Dart 3.11.5) — pubspec 의 sdk 하한과 lock 을 함께

리뷰 세 번 반영(AUTH_010 다시 보내기 · 늦은 응답 · 저장 실패 · 로그아웃 차례 · 비밀이 실린 객체 등).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 11:11:28 +09:00
ttipo 18f10cece4 Initial commit 2026-10-26 12:28:48 +09:00