# 系统架构

星线 App 由 iOS、Android 原生客户端、聊天服务、星线 Account 身份服务及通话媒体服务组成。本页依据当前源码说明组件责任、请求路径与实现边界；源码中存在的模块不自动代表客户端已经接入，也不代表生产环境已经完成验收。

## 组件与责任

| 组件 | 责任 | 主要技术 |
| --- | --- | --- |
| iOS 客户端 | 原生登录、聊天、新事、记忆、位置与通话界面；会话和本地加密状态管理 | Swift、SwiftUI、Keychain、CryptoKit、LiveKit |
| Android 客户端 | 原生登录、聊天、新事、记忆、位置与通话界面；本地安全存储 | Kotlin、Jetpack Compose、Android Keystore、LiveKit |
| 聊天服务 | 将 Account 身份映射为聊天用户；会话、好友、群、消息、媒体、新事、事件与通话状态 | Node.js 24 及以上、ES modules、HTTP、内置 SQLite |
| Account | 登录、注册、身份验证、授权页面、OIDC 授权码与用户信息 | 独立身份系统，OIDC issuer 为 `https://account.thestarline.cn/oidc` |
| 加密核心 | MLS 设备、密钥包、群状态、消息验证与加密状态持久化 | Rust、OpenMLS，C ABI 与 WebAssembly 适配 |
| 媒体与推送 | 音视频房间、短期加入凭证、iOS VoIP 来电唤醒 | LiveKit、APNs VoIP |

公开聊天 API 基地址是 `https://chat.thestarline.cn`。下载站及本技术文档位于 `https://app.thestarline.cn`，它们与鉴权 API 分属不同入口。客户端不持有 Account 的机密客户端凭据、LiveKit 服务端密钥或 APNs 签名私钥。

![系统架构：iOS 与 Android 经 HTTPS 访问聊天服务，使用系统浏览器授权；聊天服务连接 Account、SQLite、LiveKit 与 APNs；MLS 核心目前仅有 iOS 独立适配及服务端 WASM 校验器。](https://document.thestarline.cn/app/architecture.svg)

两端通过系统浏览器进入 Account，经聊天服务的授权码回调完成换票；聊天 API 使用 HTTPS JSON、二进制及事件长轮询。通话媒体由客户端直接连接 LiveKit，聊天服务只负责状态、房间控制和短期凭证。图中 MLS 是独立模块能力，不代表默认消息路径已启用。

## 一次登录怎样变成聊天会话

原生客户端生成本机 `codeVerifier`，向 `/auth/native/start` 发送 S256 `codeChallenge`。聊天服务保存挑战并另行生成 Account 授权所用的 verifier、state；浏览器完成 Account 授权后回到 `https://chat.thestarline.cn/auth/callback`。服务端使用机密客户端认证及自己的 verifier 换取 Account 访问令牌，再读取用户信息，将 `sub` 映射到本地聊天用户。

最终返回 App 的是一次性聊天 ticket。App 必须向 `/auth/exchange` 同时提交 ticket、原 state 和本机 verifier，才能获得聊天 Bearer token。Account 访问令牌不会作为聊天 token 下发。详见[登录与会话](https://document.thestarline.cn/app/authentication.md)。

## 数据与同步路径

聊天服务使用 `node:sqlite` 的同步连接，启用外键、WAL 和 5 秒 busy timeout。消息写入、去重和事件生成通常在 `BEGIN IMMEDIATE` 事务中完成，因此客户端可以用同一个 `clientId` 安全重试同一条发送。这个实现模型适合单个服务进程与其数据库协作；当前进程内的长轮询等待器不会在多个实例间自动广播，扩展部署需要另行设计通知和数据一致性方案。

`/events` 是按用户过滤的增量变更通知，携带事件 ID、会话或群 ID 和可选消息 ID，不携带完整聊天正文。客户端收到事件后重新获取列表、消息或通话状态。消息 ID、普通事件 ID、MLS sequence 是不同序列，不能混用。

媒体以 BLOB 保存，客户端先上传取得 `media.id`，随后发送引用该 ID 的消息。下载会重新检查当前用户对媒体的可见性。新事媒体使用单独的数据表、配额和权限规则。记忆主体主要由原生客户端管理，聊天服务提供识别和转出许可桥接，并不存在一组可据此推导的“云端记忆 CRUD”接口。详见[数据模型](https://document.thestarline.cn/app/data-model.md)与[消息和媒体](https://document.thestarline.cn/app/messaging-and-media.md)。

## 加密模块与当前主链路

Rust 核心支持 MLS 1.0，固定使用 `MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519` 套件。聊天服务提供设备密钥包、会话准备、Welcome、Commit、应用密文事件和确认接口。iOS 有独立 `ChatEncryptedTransport` 处理文字密文同步、设备签名密钥固定、离线队列及确认恢复。

当前 iOS `ChatStore` 主聊天发送与 Android 发送仍走普通 `/messages` 路径；iOS 会准备设备密钥包，但不能仅凭此认定某个聊天已启用 MLS。普通媒体上传没有独立附件密钥、客户端封装密文或附件解密路径。文档因此将“加密模块能力”“实际主聊天路径”“生产验收结果”分别说明。已准备的 MLS 会话会拒绝继续通过普通接口发送明文，不能通过回退接口绕过模式约束。

## 产品边界与验收

共享后台还包含 `/enterprise/*` 企业组织、成员、企业频道、待办、公告和服务接口。这些服务于独立的星企产品，使用企业成员与角色校验；不能把它们列为星线 App 的前台工作台功能，也不能把个人聊天群等同于企业频道。

通话 HTTP 状态机、LiveKit SDK 接入和 APNs 发布器均可从源码确认。真实双设备跨网络音视频、后台来电、锁屏接听和生产 APNs 到达率需要单独验收。服务健康返回 `ok` 只说明 HTTP 服务可响应，不证明 Account、模型、MLS 校验器、媒体或推送全部可用。继续阅读[实时同步与通话](https://document.thestarline.cn/app/realtime-and-calls.md)、[测试](https://document.thestarline.cn/app/testing.md)、[运维](https://document.thestarline.cn/app/operations.md)与[安全和隐私](https://document.thestarline.cn/app/security-and-privacy.md)。

深入流程见[联系人与个人群](https://document.thestarline.cn/app/contacts-and-groups.md)、[新事](https://document.thestarline.cn/app/moments.md)、[位置共享](https://document.thestarline.cn/app/location-sharing.md)和[MLS协议](https://document.thestarline.cn/app/mls-protocol.md)；数值与失败处理集中在[限制与错误](https://document.thestarline.cn/app/limits-and-errors.md)。
