nomadcode/agent-roadmap/archive/phase/mattermost-push-plugin-extraction/milestones/mattermost-push-plugin-extraction.md
toki e2e595db74 정리: 로드맵 디렉터리를 분리한다
agent-ops 공통 파일과 프로젝트 로드맵 상태를 분리해 sync 대상과 로드맵 문서 관리를 독립적으로 유지한다.
2026-05-27 11:18:34 +09:00

7.2 KiB

Milestone: Mattermost Push Plugin Extraction

위치

  • Roadmap: agent-roadmap/ROADMAP.md
  • Phase: agent-roadmap/archive/phase/mattermost-push-plugin-extraction/PHASE.md

목표

Flutter 앱 내부에 직접 이식된 Mattermost push notification 기능을 ../mattermost-push-plugin 독립 Flutter plugin repo로 분리한다. NomadCode 앱은 Firebase 설정, 로그인/라우팅, 제품 UI만 유지하고, Mattermost push 수신/표시/답장/ACK/토큰 저장 경계는 plugin API를 통해 소비하도록 전환한다.

상태

[완료]

구현 잠금

  • 상태: 해제
  • 결정 필요: 없음

범위

  • ../mattermost-push-plugin repo를 Flutter plugin 프로젝트로 구성
  • apps/mobile/lib/services/push_notification_service.dart의 public Dart facade를 plugin API로 승격
  • Android native FCM service, notification builder, reply/dismiss receiver, ACK delivery, Room DB helper, network helper, notification resource를 plugin 소유로 이동
  • MainActivityMainApplication 직접 의존을 제거하고 Flutter plugin 등록/초기화 경계로 전환
  • NomadCode 앱은 plugin path dependency, Firebase project 설정, Mattermost 로그인/credential 관리, 알림 클릭 라우팅만 보유
  • 현재 Android-first 구현을 기준으로 하되 iOS/macOS는 no-op 또는 후속 확장 지점을 명확히 둠
  • 기존 push-notification-todo.md의 남은 Android DB stub과 singleton DB close 위험을 plugin extraction 과정에서 추적 가능한 작업으로 재배치

필수 기능

Epic: [extraction] Plugin extraction boundary

Flutter host 앱에 있던 Mattermost push domain을 독립 plugin repo와 host consumer 경계로 분리한다.

  • [plugin-scaffold] ../mattermost-push-pluginmattermost_push_plugin Flutter plugin repo로 구성했다.
  • [dart-api] push 초기화, 알림 stream, opened event, device token, auth token, signing key 저장 API를 plugin Dart surface로 정의했다.
  • [android-native] Android FCM service, notification builder, ACK, inline reply, dismiss, Room DB, network helper, notification resource를 plugin Android implementation으로 이동했다.
  • [host-boundary] MainActivity/MainApplication 직접 참조를 제거하고 launch intent, lifecycle, channel registration, DB/channel 초기화를 plugin-safe 방식으로 정리했다.
  • [app-consumer] apps/mobile을 plugin consumer로 전환하고 앱에는 Firebase 설정, Mattermost auth flow, 라우팅 콜백만 남겼다.
  • [risk-hardening] Room DB singleton close, PushNotificationDataHelper DAO stub, Firebase Messaging manifest 충돌 위험을 처리하거나 명시적 follow-up으로 남겼다.
  • [docs-verify] plugin README, host app 통합 메모, 검증 명령과 수동 smoke 기준을 작성했다.

완료 기준

  • ../mattermost-push-plugin에 Flutter plugin 구조, Dart API, Android implementation, Android manifest/resource/dependency가 존재한다.
  • apps/mobile은 Mattermost push 관련 native service/helper/resource를 직접 소유하지 않고 plugin path dependency로 연동한다.
  • Android 알림 수신, 시스템 알림 표시, 알림 탭 event, inline reply, ACK, device/auth/signing key 저장 경계가 plugin API 또는 plugin native 구현으로 닫힌다.
  • host 앱이 유지해야 하는 Firebase 설정, google-services.json, Mattermost login/credential, 라우팅 callback 책임이 문서화되어 있다.
  • apps/mobileflutter test가 통과하고, Android build 또는 명시한 대체 검증으로 plugin 통합이 깨지지 않음을 확인한다. 대체 검증은 plugin/app flutter test와 host/plugin boundary 파일 확인으로 남겼으며, Android SDK가 있는 환경의 debug APK/device smoke는 최종 리뷰 확인 항목으로 둔다.
  • iOS/macOS 지원 범위가 no-op인지 후속 구현인지 문서에 명확히 남아 있다.

완료 리뷰

  • 상태: 승인됨
  • 요청일: 2026-05-25
  • 완료 근거:
    • ../mattermost-push-plugin sibling repo에 Flutter plugin scaffold, Dart API, Android FCM service/receiver/helper/Room/resource, iOS/macOS no-op scaffold가 존재한다.
    • apps/mobile 미커밋 변경에서 direct push service/native service/resource를 제거하고 mattermost_push_plugin path dependency와 host auth/routing 경계로 전환했다.
    • flutter test../mattermost-push-pluginapps/mobile에서 모두 통과했다. flutter build apk --debug는 현재 환경에 Android SDK가 없어 실행되지 않았다.
  • 리뷰 필요:
    • 사용자가 완료 결과를 확인했다
    • archive 이동을 승인했다
  • 리뷰 코멘트: 2026-05-25 사용자 확인으로 완료 처리하고 archive로 이동했다. Android SDK 또는 실제 device가 있는 환경의 debug APK/FCM 수동 smoke는 필요 시 후속 통합 검증에서 확인한다.

범위 제외

  • Mattermost 서버 push gateway 또는 server-side plugin 구현
  • pub.dev 공개 배포, semantic versioning, release automation
  • iOS/macOS native push full implementation
  • NomadCode project/workspace UX 화면 재설계
  • Mattermost auth 제품 UI 완성
  • core service notification event 또는 Mattermost adapter 구현

작업 컨텍스트

  • 관련 경로: apps/mobile/, ../mattermost-push-plugin/
  • 현재 plugin repo: ../mattermost-push-plugin은 사용자가 생성한 별도 git repo이며, 현재 HEAD는 678302b initial commit: mattermost-push-plugin이고 working tree는 clean 상태다.
  • 표준선(선택): repo명은 mattermost-push-plugin, Dart package name은 mattermost_push_plugin으로 둔다. 첫 구현은 Android-first Flutter plugin으로 잡고, host app이 Firebase project 설정과 Mattermost login/라우팅을 소유한다.
  • 선행 작업: Flutter-first Client Consolidation
  • 후속 작업: Project Workspace Management UX, External Integration의 Mattermost 사용자-facing 흐름
  • 현재 반영 근거:
    • ../mattermost-push-plugin/lib/src/mattermost_push_plugin.dart는 EventChannel/MethodChannel과 FCM token facade를 plugin API로 제공한다.
    • ../mattermost-push-plugin/android/src/main/kotlin/com/tokilabs/mattermost_push_plugin/MattermostFirebaseMessagingService.kt는 native FCM 수신, signature verification, ACK, notification build, EventChannel 전달을 수행한다.
    • ../mattermost-push-plugin/android/src/main/kotlin/com/tokilabs/mattermost_push_plugin/MattermostPushPlugin.kt는 channel registration, DB init, notification channel init, lifecycle tracker, launch intent event를 plugin 경계로 소유한다.
    • apps/mobile/android/app/src/main/java/com/tokilabs/mattermost/MainActivity.kt는 FlutterActivity fullscreen 설정만 남기고 native push channel 직접 등록을 제거했다.
    • apps/mobile/pubspec.yamlmattermost_push_plugin path dependency를 사용하고 firebase_messaging, flutter_local_notifications 직접 dependency를 제거했다.
    • apps/mobile/push-notification-todo.md는 host app 내 native push 파일을 직접 수정하지 않는 handoff 문서로 축소되었다.
  • 검증:
    • flutter test in ../mattermost-push-plugin: 통과
    • flutter test in apps/mobile: 통과
    • flutter build apk --debug in apps/mobile: 실패, ANDROID_HOME 미설정으로 Android SDK를 찾지 못함
  • 확인 필요: 없음