- Update README with latest project status - Archive upstream-runtime milestone and update roadmap - Update Mattermost Android build configuration - Sync upstream references for core and push-proxy services
185 lines
12 KiB
Markdown
185 lines
12 KiB
Markdown
# nexo
|
|
|
|
`nexo`는 여러 Flutter 앱이 메시징과 푸시 알림 기능을 공통으로 사용할 수 있게 만드는 패키지 워크스페이스다. 핵심 산출물은 `packages/messaging_flutter`이며, 각 앱이 네이티브 메시징/푸시 런타임을 다시 구현하지 않고도 같은 기반을 소비할 수 있게 한다.
|
|
|
|
이 패키지는 여러 소비 제품이 Mattermost 호환 메시징 동작은 필요하지만 Mattermost의 전체 제품 형태를 그대로 물려받고 싶지는 않을 때 쓰는 공통 메시징 계층이다.
|
|
|
|
Mattermost 업스트림 저장소는 이 패키지 주변의 기준선과 검증 참조로 둔다. `apps/mattermost`는 원래 Mattermost 앱, `services/core`는 Mattermost 서버, `services/push-proxy`는 Mattermost 푸시 서버 스냅샷이다. 이 저장소는 별도의 nexo 제품 앱을 담지 않으며, 넓은 Mattermost 포크가 되는 것도 목표가 아니다. Nexo 전용 커스터마이징은 가능한 한 플러그인, compose/런타임 래퍼, 문서, 작고 명시적인 패치에 둔다.
|
|
|
|
## 이름
|
|
|
|
`nexo`는 `nexus`에서 온 이름이다. 여러 앱, 메시지, 알림, 서비스 인프라가 만나는 연결 지점을 뜻한다.
|
|
|
|
## 제품 경계
|
|
|
|
- `packages/messaging_flutter/`는 Nexo가 소유하는 제품 표면이다. 여러 Flutter 앱이 소비할 수 있는 메시징, 푸시 알림, 네이티브 브리지, 알림 탭/수신 동작을 이곳에 둔다.
|
|
- 이 패키지를 소비하는 앱은 각자의 제품 UI, 워크플로우 의미, 앱별 비즈니스 로직을 소유한다. 공통 메시징 런타임은 Nexo에 의존하고, 앱별 동작은 각 프로젝트에 남긴다.
|
|
- Mattermost 업스트림 코드는 비교와 검증을 위한 기준선이지 주 커스터마이징 표면이 아니다. 명시적인 업스트림 갱신이나 작은 대상 패치를 검토하는 경우가 아니라면 `apps/mattermost`, `services/core`, `services/push-proxy`는 기록된 업스트림 스냅샷에 가깝게 유지한다.
|
|
- Mattermost 제품 동작이 소비 앱에 맞지 않을 때는 업스트림 스냅샷을 직접 크게 바꾸기보다 좁은 Nexo 플러그인 계약, 래퍼, 설정 지점, 문서화된 통합 경로를 추가한다.
|
|
|
|
## 현재 상태
|
|
|
|
- `packages/messaging_flutter/`는 Android 우선 Flutter 메시징/푸시 알림 플러그인 패키지이며, 이 저장소의 주 제품 표면이다.
|
|
- `apps/flutter-test/`는 플러그인을 검증하는 테스트용 Flutter 앱이다.
|
|
- `apps/mattermost/`는 원래 Mattermost 모바일 앱 저장소 스냅샷이다. 기준선은 `apps/mattermost/UPSTREAM.md`를 본다.
|
|
- `services/core/`는 Mattermost 서버 저장소 clone이다.
|
|
- `services/push-proxy/`는 Mattermost push-proxy 저장소 스냅샷이다. 기준선은 `services/push-proxy/UPSTREAM.md`를 본다.
|
|
- 공개 package, import, 네이티브 identifier는 Nexo 소유 이름으로 전환 중이다.
|
|
- iOS와 macOS 플러그인 scaffold는 있지만, 현재 구현 대상은 Android다.
|
|
|
|
## 빠른 시작
|
|
|
|
개발 진입점을 확인한다.
|
|
|
|
```sh
|
|
bin/dev
|
|
```
|
|
|
|
Flutter 패키지와 `flutter-test` 호스트 검증을 실행한다.
|
|
|
|
```sh
|
|
bin/test
|
|
bin/lint
|
|
```
|
|
|
|
core compose 런타임을 실행한다.
|
|
|
|
```sh
|
|
cd services/core/compose
|
|
cp .env.example .env
|
|
docker compose up
|
|
```
|
|
|
|
## 주요 명령
|
|
|
|
| 목적 | 명령 | 비고 |
|
|
| --- | --- | --- |
|
|
| 개발 진입점 확인 | `bin/dev` | 테스트 호스트, 플러그인, core compose 명령을 출력한다. |
|
|
| 기본 테스트 실행 | `bin/test` | Flutter 테스트를 실행하고, 기본값에서는 Go 테스트를 건너뛴다. |
|
|
| 기본 lint 실행 | `bin/lint` | Flutter analyze를 실행하고, 기본값에서는 Go vet을 건너뛴다. |
|
|
| 기본 build 실행 | `bin/build` | 설정된 앱 build를 실행한다. web 설정이 없으면 `apps/flutter-test` web build를 건너뛰고, 기본값에서는 Go build를 건너뛴다. |
|
|
| 서버 Go 테스트 포함 | `NEXO_CORE_GO_TEST=1 bin/test` | 로컬 `go`가 필요하다. |
|
|
| 서버 Go vet 포함 | `NEXO_CORE_GO_LINT=1 bin/lint` | 로컬 `go`가 필요하다. |
|
|
| 서버 Go build 포함 | `NEXO_CORE_GO_BUILD=1 bin/build` | 로컬 `go`가 필요하다. |
|
|
| `flutter-test` 호스트 직접 실행 | `cd apps/flutter-test && flutter run` | Flutter SDK가 필요하다. |
|
|
| 플러그인 직접 테스트 | `cd packages/messaging_flutter && flutter test` | Flutter SDK가 필요하다. |
|
|
| Android 네이티브 단위 테스트 실행 | `cd apps/flutter-test/android && ./gradlew testDebugUnitTest` | Android SDK가 필요하다. |
|
|
|
|
`bin/*` helper는 필요한 로컬 도구가 없으면 일부 검증을 건너뛸 수 있다. 작업 보고에는 건너뛴 검증을 함께 적는다.
|
|
|
|
## 구조
|
|
|
|
| 경로 | 역할 |
|
|
| --- | --- |
|
|
| `packages/messaging_flutter/` | 주 Flutter 메시징/푸시 알림 패키지 |
|
|
| `apps/flutter-test/` | 패키지 통합 검증용 `flutter-test` 앱 |
|
|
| `apps/mattermost/` | Mattermost 모바일 앱 저장소 스냅샷 |
|
|
| `services/core/` | Mattermost 서버 저장소 clone과 현재 compose 런타임 |
|
|
| `services/push-proxy/` | Mattermost push-proxy 저장소 스냅샷 |
|
|
| `docs/` | 모듈 간 제품, migration, 운영 문서 |
|
|
| `bin/` | workspace helper 진입점 |
|
|
| `agent-ops/` | agent 규칙, domain rule, 공통 skill 진입점 |
|
|
|
|
## 작업 맥락
|
|
|
|
- 작업을 시작할 때는 `AGENTS.md`를 읽고, 이어서 `agent-ops/rules/project/rules.md`를 읽는다.
|
|
- 변경 경로에 맞는 domain rule은 `agent-ops/rules/project/domain/*/rules.md`에서 확인한다.
|
|
- README, plan, review, commit/push 같은 표준 작업은 `agent-ops/skills/common/router.md`를 통해 공통 skill로 라우팅한다.
|
|
- `packages/messaging_flutter/`를 주 제품으로 본다. 앱별 제품 UI와 비즈니스 로직은 이 저장소가 아니라 패키지를 소비하는 앱의 책임이다.
|
|
- 여러 sibling 또는 외부 제품이 Nexo 메시징 계층을 소비할 수 있다. 공통 동작은 플러그인에 두고, 앱별 동작은 각 프로젝트에 둔다.
|
|
- `apps/flutter-test/`는 플러그인 통합 검증용 호스트로만 본다. 제품 앱으로 키우거나 플러그인 내부 동작을 복제하지 않는다.
|
|
- `apps/mattermost`, `services/core`, `services/push-proxy`는 Mattermost 원본 저장소 clone으로 본다. nexo 소유 앱이나 독자 서버 제품으로 재정의하지 않는다.
|
|
- 명시적인 업스트림 결정 없이 `services/core/UPSTREAM.md`의 기준선 정보를 바꾸지 않는다.
|
|
- 업스트림 작업 clone은 이 저장소 밖의 sibling/external `mattermost/` staging 폴더에 원본 저장소별로 둔다.
|
|
- 업스트림 저장소는 기록된 branch를 따라간다. `mattermost-mobile`은 `main`, `mattermost`와 `mattermost-push-proxy`는 `master`를 기준으로 하며, branch 변경 시점이나 의도적으로 정한 갱신 시점에 스냅샷을 떠서 이 저장소로 merge 요청한다.
|
|
- 이 저장소에 들어오는 스냅샷은 원본 저장소별 정확한 commit SHA를 기록한다.
|
|
- merge 요청은 원칙적으로 업스트림 저장소별로 분리한다. `apps/mattermost`, `services/core`, `services/push-proxy` 스냅샷을 한 요청에 섞지 않는다.
|
|
- staging pull 결과를 이 저장소에 자동 반영하지 않는다. 스냅샷 diff와 관련 smoke 검증을 확인한 뒤 merge 요청한다.
|
|
- Nexo 전용 패치는 가능한 한 업스트림 스냅샷 밖의 compose, 문서, 래퍼, 작고 명시적인 패치로 둔다.
|
|
|
|
## 업스트림 스냅샷 운영
|
|
|
|
workspace script를 둘 때의 계약은 자동 merge가 아니라 snapshot 후보 준비다.
|
|
script는 외부 `mattermost/` staging clone을 기록된 branch로 update하고,
|
|
선택한 commit을 이 repo의 대응 경로로 복사할 수 있다. script 실행만으로
|
|
baseline을 변경한 것으로 보지 않는다.
|
|
|
|
snapshot 반영은 다음 단계를 분리한다.
|
|
|
|
1. staging clone update와 후보 commit 선택
|
|
2. repo별 snapshot copy: `apps/mattermost`, `services/core`, `services/push-proxy` 중 하나
|
|
3. 해당 `UPSTREAM.md`의 source, branch, tag/commit, snapshot date 갱신
|
|
4. snapshot diff 확인과 nexo-local patch inventory 정리
|
|
5. 변경 범위에 맞는 smoke 검증
|
|
6. repo별 merge 요청
|
|
|
|
release watch는 월 1회 Mattermost server/webapp release 흐름과 push-proxy
|
|
`master` 변경을 확인하고, security patch 또는 ESR 영향이 있으면 정기 주기와
|
|
별도로 snapshot 후보를 만든다. watch 결과는 해당 모듈의 `UPSTREAM.md`에
|
|
baseline 후보 또는 보류 사유로 남기고, 검증 증거는 필요하면
|
|
`docs/runtime-image-validation.md`나 merge 요청 본문에 연결한다.
|
|
|
|
## 업스트림 Patch 경계
|
|
|
|
`services/core/server`, `services/core/webapp`, `services/push-proxy`는
|
|
upstream-owned runtime으로 취급한다. Nexo 변경은 upstream snapshot과 다시
|
|
비교하기 쉬운 얇은 layer에 둔다.
|
|
|
|
webapp은 기본 메시지 앱 또는 reference front로 유지한다. branding, copy,
|
|
기능 숨김은 설정, wrapper, 작은 compatibility patch로 제한하고, 제품별 화면
|
|
흐름이나 앱별 business logic은 Nexo Flutter SDK를 소비하는 앱 쪽에서 소유한다.
|
|
|
|
대량 rename, directory 재배치, formatting-only churn, deep fork는 금지한다.
|
|
예외는 보안 패치, upstream update 차단 해소, Nexo runtime 계약 유지에 필요한
|
|
최소 변경일 때만 허용하며, 해당 모듈의 `UPSTREAM.md`에 변경 path, 사유,
|
|
rebase 위험, 검증 결과를 남긴다.
|
|
|
|
upstream 새 기능은 다음 후보로 분류한 뒤 반영한다.
|
|
|
|
| 후보 | 기준 | 처리 |
|
|
| --- | --- | --- |
|
|
| keep | runtime 호환성, 보안, 기본 메시징 동작에 필요 | snapshot에 유지하고 smoke 검증에 포함한다. |
|
|
| hide | 기본 메시지 앱에서 노출하면 혼선을 주지만 upstream 유지에는 유리 | 설정, feature flag, 얇은 UI patch로 숨긴다. |
|
|
| defer | Nexo 계약 영향이 불명확하거나 검증 비용이 큰 기능 | 별도 follow-up으로 보류 사유와 재검토 조건을 남긴다. |
|
|
| remove | 보안, 라이선스, runtime 안정성 문제로 유지할 수 없는 기능 | 제거 사유와 upstream rebase 위험을 기록하고 검증한다. |
|
|
|
|
## 개발 흐름
|
|
|
|
1. 변경할 경로의 domain rule을 읽는다.
|
|
2. 소유 모듈 안에서 변경 범위를 좁게 유지한다.
|
|
3. 변경에 맞는 가장 작은 유효 검증을 실행한다.
|
|
4. workspace 수준 검증이 필요하면 `bin/test`, `bin/lint`, `bin/build`를 사용한다.
|
|
5. 서버 런타임 검증이 필요하면 `services/core/compose/`를 사용한다.
|
|
|
|
## 환경 변수
|
|
|
|
### Core Compose
|
|
|
|
| 이름 | 설명 | 필수 |
|
|
| --- | --- | --- |
|
|
| `NEXO_DB_PASSWORD` | Postgres `mmuser` 계정 password | 예 |
|
|
| `NEXO_SITE_URL` | core service가 사용하는 site URL | 예 |
|
|
| `NEXO_CORE_PORT` | core `8065`에 매핑할 host port | 아니오 |
|
|
| `NEXO_PUSH_PROXY_PORT` | push-proxy `8066`에 매핑할 host port | 아니오 |
|
|
|
|
예시는 `services/core/compose/.env.example`를 본다. 실제 `.env` 파일이나 런타임 데이터는 커밋하지 않는다. Docker network subnet은 `172.38.0.0/16`으로 고정되어 있으므로, 이 범위는 nexo용으로 예약하고 다른 Docker network에서 재사용하지 않는다.
|
|
|
|
### 선택 검증
|
|
|
|
| 이름 | 설명 | 기본값 |
|
|
| --- | --- | --- |
|
|
| `NEXO_CORE_GO_TEST` | `bin/test`에서 서버 Go 테스트를 실행한다. | `0` |
|
|
| `NEXO_CORE_GO_LINT` | `bin/lint`에서 서버 Go vet을 실행한다. | `0` |
|
|
| `NEXO_CORE_GO_BUILD` | `bin/build`에서 서버 Go build를 실행한다. | `0` |
|
|
|
|
## 참고 문서
|
|
|
|
- `AGENTS.md`
|
|
- `agent-ops/rules/project/rules.md`
|
|
- `agent-ops/skills/common/router.md`
|
|
- `services/core/UPSTREAM.md`
|
|
- `services/core/compose/README.md`
|
|
- `packages/messaging_flutter/README.md`
|
|
- `packages/messaging_flutter/docs/android-test-environment.md`
|
|
- `apps/flutter-test/README.md`
|
|
- `docs/README.md`
|