chore: update roadmap, client README, push plugin integration, and assets
This commit is contained in:
parent
68989ec79c
commit
a90d15f85e
10 changed files with 112 additions and 24 deletions
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
- [진행중] Workflow Core
|
||||
- 경로: `agent-ops/roadmap/phase/workflow-core/PHASE.md`
|
||||
- [계획] External Integration
|
||||
- 경로: `agent-ops/roadmap/phase/external-integration/PHASE.md`
|
||||
|
||||
## 활성 Milestone
|
||||
|
||||
|
|
@ -13,6 +15,9 @@
|
|||
- [계획] Workflow Core
|
||||
- Phase: `agent-ops/roadmap/phase/workflow-core/PHASE.md`
|
||||
- 경로: `agent-ops/roadmap/phase/workflow-core/milestones/workflow-core.md`
|
||||
- [계획] Mattermost Messaging Android Smoke
|
||||
- Phase: `agent-ops/roadmap/phase/external-integration/PHASE.md`
|
||||
- 경로: `agent-ops/roadmap/phase/external-integration/milestones/mattermost-messaging-android-smoke.md`
|
||||
|
||||
## 선택 규칙
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ Work Item Provider Pipeline Design과 Workflow Core 이후 Plane/Jira 확장, Ma
|
|||
완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다.
|
||||
완료, 검토중, 진행중, 계획 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||
|
||||
- [계획] Mattermost Messaging Android Smoke
|
||||
- 경로: `agent-ops/roadmap/phase/external-integration/milestones/mattermost-messaging-android-smoke.md`
|
||||
- 요약: `mattermost_push_plugin`이 `../nexo/packages/messaging_flutter`로 서버와 함께 합쳐지고 메시징 지원 방향으로 확장된 뒤, 원격 Android SDK 환경에서 build와 알림 도착 smoke를 확인한다.
|
||||
|
||||
- [계획] External Integration
|
||||
- 경로: `agent-ops/roadmap/phase/external-integration/milestones/external-integration.md`
|
||||
- 요약: Plane/Jira/Mattermost/Agent Integrator/IOP 호출 경계를 실제 통합 adapter 흐름으로 확장한다.
|
||||
|
|
@ -20,5 +24,6 @@ Work Item Provider Pipeline Design과 Workflow Core 이후 Plane/Jira 확장, Ma
|
|||
## Phase 경계
|
||||
|
||||
- 외부 provider 세부 구현은 adapter 경계 밖으로 새지 않게 한다.
|
||||
- Mattermost messaging Android smoke는 사용자 테스트를 제외하고 원격 Android SDK build와 알림 도착 확인까지만 완료 범위로 둔다.
|
||||
- IOP 내부 모델 라우팅, 모델 프로파일, RAG, MCP, output validation, fallback 정책은 NomadCode 범위에서 제외한다.
|
||||
- A2A 도입 시점과 Agent Integrator 유지 여부는 사용자 결정이 필요하다.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# Milestone: Mattermost Messaging Android Smoke
|
||||
|
||||
## 위치
|
||||
|
||||
- Roadmap: `agent-ops/roadmap/ROADMAP.md`
|
||||
- Phase: `agent-ops/roadmap/phase/external-integration/PHASE.md`
|
||||
|
||||
## 목표
|
||||
|
||||
`mattermost_push_plugin`이 서버와 같은 `../nexo` repo의 `packages/messaging_flutter` package로 합쳐지고, 알림 전용에서 메시징 지원까지 포함하는 방향으로 전환된 현재 상태를 Android 기준으로 검증한다. 사용자 테스트까지 진행하지 않고, 원격 Android SDK 환경에서 build가 통과하고 Mattermost 메시지/FCM 알림이 실제 Android runtime에 도착하는지 확인하는 데서 완료 범위를 닫는다.
|
||||
|
||||
## 상태
|
||||
|
||||
[계획]
|
||||
|
||||
## 구현 잠금
|
||||
|
||||
- 상태: 해제
|
||||
- 결정 필요: 없음
|
||||
|
||||
## 범위
|
||||
|
||||
- `apps/client` host와 `../nexo/packages/messaging_flutter` package 경계가 현재 messaging 방향성과 충돌하지 않는지 확인
|
||||
- 원격 Android SDK runner에서 `apps/client`의 Android debug build 검증
|
||||
- Android device 또는 emulator에서 앱 boot, Firebase 초기화, Mattermost auth/token handoff, 알림 callback이 깨지지 않는지 smoke 확인
|
||||
- Mattermost 메시지 또는 push trigger를 통해 Android 시스템 알림이 도착하는지 확인
|
||||
- 검증 중 드러나는 build/configuration regression은 smoke를 통과시키는 최소 수정 범위에서 처리
|
||||
|
||||
## 기능
|
||||
|
||||
### Epic: [android-smoke] Remote Android notification verification
|
||||
|
||||
Mattermost messaging package 전환 이후 Android build와 알림 수신 경로가 실제 환경에서 깨지지 않았는지 확인한다.
|
||||
|
||||
- [x] [scope-check] `apps/client`, `apps/client/push-notification-todo.md`, `../nexo/packages/messaging_flutter` 경계를 확인해 현재 repo 업데이트가 메시징 지원 방향성과 맞는지 정리한다.
|
||||
- [ ] [remote-build] `docs/test-environments.md#android-sdk-remote-runner` 기준 원격 Android SDK 환경에서 `apps/client`의 `flutter pub get`과 `flutter build apk --debug`를 통과시킨다. 검증: 원격 host, branch/commit, 주요 command 결과를 secret 없이 evidence로 남긴다.
|
||||
- [ ] [runtime-smoke] Android device 또는 emulator에서 앱을 실행해 앱 boot, Firebase 초기화, Mattermost auth/token handoff가 crash 없이 진행되는지 확인한다. 검증: `flutter run -d <device-id>` 또는 동등한 runtime 실행 결과를 남긴다.
|
||||
- [ ] [notification-arrival] Mattermost 메시지 또는 push trigger로 Android 시스템 알림이 도착하는지 확인한다. 검증: 알림 도착 여부, 앱 callback 관찰 여부, 실패 시 원인 후보를 secret 없이 기록한다.
|
||||
- [ ] [evidence-note] build와 알림 smoke 결과, 사용자 테스트 미포함 한계, 후속 보완이 필요한 경우를 완료 리뷰 근거로 남긴다.
|
||||
|
||||
## 완료 리뷰
|
||||
|
||||
- 상태: 없음
|
||||
- 요청일: 없음
|
||||
- 완료 근거: 없음
|
||||
- 리뷰 필요:
|
||||
- [ ] 사용자가 완료 결과를 확인했다
|
||||
- [ ] archive 이동을 승인했다
|
||||
- 리뷰 코멘트: 없음
|
||||
|
||||
## 범위 제외
|
||||
|
||||
- 사용자 테스트, UAT, 제품 사용성 검증
|
||||
- iOS/macOS native push full implementation 또는 runtime smoke
|
||||
- Mattermost 메시징 제품 UX 구현
|
||||
- Mattermost server-side plugin 대규모 기능 확장
|
||||
- External Integration Milestone의 Plane/Jira/Agent Integrator/IOP adapter 구현
|
||||
|
||||
## 작업 컨텍스트
|
||||
|
||||
- 관련 경로: `apps/client/`, `apps/client/push-notification-todo.md`, `docs/test-environments.md`, `../nexo/packages/messaging_flutter`
|
||||
- 연관 core 경계: `services/core/internal/adapters/mattermost/`, `services/core/internal/notification/`
|
||||
- 선행 작업: Mattermost Push Plugin Extraction, Client Integration Standardization
|
||||
- 후속 작업: External Integration의 Mattermost 메시지 발송 adapter 구현
|
||||
- 표준선: Android SDK 의존 검증은 `docs/test-environments.md#android-sdk-remote-runner`를 따른다.
|
||||
- 보안 주의: Mattermost token, Firebase credential, signing key, device token은 roadmap이나 문서에 기록하지 않는다.
|
||||
- 2026-05-26 scope-check: `apps/client` host dependency/import 문서를 `../nexo/packages/messaging_flutter`의 현재 Dart package명 `nexo_messaging`과 `NexoMessagingPlugin` API에 맞췄고, ignored `assets/mattermost_credentials.json`을 smoke 때 bundle할 수 있도록 assets 디렉터리를 선언했다. 원격 Android build와 실제 알림 도착 smoke는 환경 의존 작업으로 plan에서 수행한다.
|
||||
|
|
@ -38,7 +38,7 @@ We prioritize and validate two primary platforms in this milestone, while ensuri
|
|||
|
||||
`apps/client/lib/src/integrations/` groups all external-system adapters behind small Dart interfaces:
|
||||
|
||||
- `integrations/mattermost/` — `MattermostPushClient` interface, `MattermostPushPluginClient` adapter (the only production reference to `MattermostPushPlugin.instance`), `MattermostPushHostIntegration` (initialize + auth handoff + navigation callbacks), and `MattermostAuthService`.
|
||||
- `integrations/mattermost/` — `MattermostPushClient` interface, `MattermostPushPluginClient` adapter (the only production reference to `NexoMessagingPlugin.instance`), `MattermostPushHostIntegration` (initialize + auth handoff + navigation callbacks), and `MattermostAuthService`.
|
||||
- `integrations/proto_socket/` — `ProtoSocketEndpointConfig` and `ProtoSocketLifecycle` facade over the local `proto_socket` Dart path dependency. Bootstrap does not auto-connect; enabling and wiring a real connector are deferred to the next milestone.
|
||||
|
||||
For detailed integration boundaries, platform targets, and clone handoff guidelines, see [push-notification-todo.md](push-notification-todo.md).
|
||||
|
|
@ -47,7 +47,7 @@ For detailed integration boundaries, platform targets, and clone handoff guideli
|
|||
|
||||
## Mattermost Push Notification Integration
|
||||
|
||||
Mattermost push notification delivery is implemented via the local `mattermost_push_plugin` path dependency.
|
||||
Mattermost push notification delivery is implemented via the local `nexo_messaging` path dependency at `../nexo/packages/messaging_flutter`.
|
||||
|
||||
### Architecture & Responsibility Split
|
||||
|
||||
|
|
@ -55,11 +55,11 @@ To maintain a clean and maintainable codebase, the responsibilities are split be
|
|||
|
||||
#### Host Application (`apps/client`) Responsibilities:
|
||||
- **Firebase Configuration**: Contains the standard Firebase configuration files (`android/app/google-services.json`) and performs the standard `Firebase.initializeApp()` call in Dart main.
|
||||
- **Mattermost Authentication**: Handles login and session lifecycles, and passes the user authentication token and server signing key through the `MattermostPushClient` boundary. The production `MattermostPushPluginClient` adapter owns the plugin singleton calls.
|
||||
- **Mattermost Authentication**: Handles login and session lifecycles, and passes the user authentication token and server signing key through the `MattermostPushClient` boundary. The production `MattermostPushPluginClient` adapter owns the plugin singleton calls. Local smoke credentials may be provided as ignored `assets/mattermost_credentials.json`.
|
||||
- **Navigation Callbacks**: Registers standard Flutter navigation callbacks `onNavigateToChannel` and `onNavigateToThread` to handle workspace channel and CRT thread routing upon user interaction.
|
||||
- **FCM Token Sync**: Listens to device token registrations via `onDeviceTokenReady` and registers the token with the Mattermost server.
|
||||
|
||||
#### Mattermost Push Plugin (`mattermost_push_plugin`) Responsibilities:
|
||||
#### Nexo Messaging Plugin (`nexo_messaging`) Responsibilities:
|
||||
- **Native Android FCM Service**: Intercepts background/foreground FCM notifications securely via a custom Kotlin FCM service.
|
||||
- **Signature Verification**: Validates incoming push payload signatures against stored public signing keys (using `JJWT`).
|
||||
- **System Notification Builder**: Displays structured notifications with local avatar caches, thread summaries, and action buttons.
|
||||
|
|
|
|||
1
apps/client/assets/.gitkeep
Normal file
1
apps/client/assets/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
import 'package:mattermost_push_plugin/mattermost_push_plugin.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:nexo_messaging/nexo_messaging.dart';
|
||||
|
||||
import 'mattermost_push_client.dart';
|
||||
|
||||
/// Production adapter wrapping the platform-channel singleton.
|
||||
///
|
||||
/// This is the ONLY file in production that should reference
|
||||
/// `MattermostPushPlugin.instance`. Everything else depends on
|
||||
/// `NexoMessagingPlugin.instance`. Everything else depends on
|
||||
/// [MattermostPushClient].
|
||||
class MattermostPushPluginClient implements MattermostPushClient {
|
||||
final MattermostPushPlugin _plugin;
|
||||
final NexoMessagingPlugin _plugin;
|
||||
|
||||
MattermostPushPluginClient({MattermostPushPlugin? plugin})
|
||||
: _plugin = plugin ?? MattermostPushPlugin.instance;
|
||||
MattermostPushPluginClient({NexoMessagingPlugin? plugin})
|
||||
: _plugin = plugin ?? NexoMessagingPlugin.instance;
|
||||
|
||||
@override
|
||||
Stream<Map<String, dynamic>> get onNotification => _plugin.onNotification;
|
||||
|
|
@ -32,7 +34,9 @@ class MattermostPushPluginClient implements MattermostPushClient {
|
|||
|
||||
@override
|
||||
set onDeviceTokenReady(Future<void> Function(String token)? callback) {
|
||||
_plugin.onDeviceTokenReady = callback;
|
||||
_plugin.onDeviceTokenReady = callback == null
|
||||
? null
|
||||
: (token) => unawaited(callback(token));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Foundation
|
|||
|
||||
import firebase_core
|
||||
import firebase_messaging
|
||||
import mattermost_push_plugin
|
||||
import nexo_messaging
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
|
|
|
|||
|
|
@ -208,13 +208,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
mattermost_push_plugin:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../../nexo/packages/messaging_flutter"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -223,6 +216,13 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
nexo_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../../nexo/packages/messaging_flutter"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ dependencies:
|
|||
# Firebase
|
||||
firebase_core: ^3.13.0
|
||||
|
||||
# Mattermost push plugin
|
||||
mattermost_push_plugin:
|
||||
# Nexo messaging / Mattermost-compatible push plugin
|
||||
nexo_messaging:
|
||||
path: ../../../nexo/packages/messaging_flutter
|
||||
|
||||
# proto-socket: shared protocol/transport library (local path)
|
||||
|
|
@ -99,3 +99,8 @@ flutter:
|
|||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.dev/to/font-from-package
|
||||
|
||||
assets:
|
||||
# Local Mattermost smoke credentials live at assets/mattermost_credentials.json
|
||||
# and are ignored by apps/client/.gitignore.
|
||||
- assets/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
> [!IMPORTANT]
|
||||
> **Host App Integration Standard**
|
||||
> As of the `mattermost-push-plugin-extraction` milestone, all native FCM services, Room DB structures, JJWT signature verification, inline reply/dismiss receivers, notification builders, and ACK request handling have been successfully extracted into the local Flutter plugin package.
|
||||
> The package now lives in the `nexo` monorepo at `../nexo/packages/messaging_flutter` while keeping the Dart package name `mattermost_push_plugin` for compatibility.
|
||||
> The package now lives in the `nexo` monorepo at `../nexo/packages/messaging_flutter` with Dart package name `nexo_messaging`. The host-facing interface keeps Mattermost naming because this app consumes the Mattermost-compatible messaging boundary.
|
||||
>
|
||||
> **Do NOT edit native push files directly inside this host app repository (`apps/client/android`).** All native push logic and platform services now reside in and must be maintained within the plugin repository.
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ To keep host architectures generic and lightweight, we maintain a strict boundar
|
|||
- Initializing Firebase inside `lib/src/app/bootstrap.dart` via `Firebase.initializeApp()`.
|
||||
2. **Credential Plumbing**:
|
||||
- Host standardizes all credential synchronization through the `MattermostPushClient` interface rather than accessing the native plugin directly:
|
||||
- Local smoke credentials may be provided as ignored `assets/mattermost_credentials.json`.
|
||||
- Login: Sync authorization credentials via `pushClient.setAuthToken(serverUrl, token)`.
|
||||
- Logout: Revoke and clear credentials via `pushClient.setAuthToken(serverUrl, '')`.
|
||||
- Asymmetric Signing Keys: Register server public keys via `pushClient.setSigningKey(serverUrl, publicKey)`.
|
||||
|
|
@ -29,8 +30,8 @@ To keep host architectures generic and lightweight, we maintain a strict boundar
|
|||
- `onNavigateToThread = (serverUrl, rootId) => ...`: Handles CRT thread view navigation.
|
||||
4. **Device Token Sync**:
|
||||
- Listen to token registration callbacks via the `onDeviceTokenReady` callback on `MattermostPushClient` interface, and forward the target device token back to the Mattermost backend server.
|
||||
- *Note*: Production calls to `MattermostPushPlugin.instance` are strictly isolated and encapsulated within the `MattermostPushPluginClient` adapter implementation, maintaining a generic, testable host bootstrap.
|
||||
- **Mattermost Push Plugin (`mattermost_push_plugin`) Responsibilities**:
|
||||
- *Note*: Production calls to `NexoMessagingPlugin.instance` are strictly isolated and encapsulated within the `MattermostPushPluginClient` adapter implementation, maintaining a generic, testable host bootstrap.
|
||||
- **Nexo Messaging Plugin (`nexo_messaging`) Responsibilities**:
|
||||
- Intercepting incoming FCM pushes via Kotlin services (`MattermostFirebaseMessagingService`).
|
||||
- Parsing payloads and verifying cryptographic signatures with JJWT.
|
||||
- Interacting with local SQLite database (Room DB).
|
||||
|
|
@ -74,7 +75,7 @@ When replicating this integration boundary in sibling repositories (`../iop` and
|
|||
1. **Firebase Credential Sync**: Provide valid `google-services.json` (Android) and `GoogleService-Info.plist` (iOS) in respective project roots.
|
||||
2. **Local Path Imports**: Ensure `pubspec.yaml` points correctly to the actual sibling workspace dependency paths:
|
||||
```yaml
|
||||
mattermost_push_plugin:
|
||||
nexo_messaging:
|
||||
path: ../../../nexo/packages/messaging_flutter
|
||||
proto_socket:
|
||||
path: ../../../proto-socket/dart
|
||||
|
|
|
|||
Loading…
Reference in a new issue