Meeting Platform
摘要:Meeting Platform 用于承载会议 SaaS 业务。当前阶段已建立后端模块骨架、应用装配、会议核心数据表、用户侧创建 / 预约 / 入会 token contract、RTC 事件回填和 Provider 验签、主持人控制、会议聊天资料提醒、云录制、录制文件 Core File 绑定和转存快照、转写、AI 摘要、会后纪要、Admin 运维、质量快照和报表 contract、开放平台会议 API / Webhook / Runtime 异步投递 / 企业配额 contract、商业套餐购买、Voucher 套餐优惠和 Cashier / Entitlement / Money 结算 contract,以及 App / PC 会议大厅入口。
模块边界
| 项 | 值 |
|---|---|
| Maven 模块 | spring-open-module-meeting |
| Java 包名 | com.springopen.module.meeting |
| 配置前缀 | spring.open.meeting |
| 用户侧 API 前缀 | /api/v1/meetings |
| 后台 API 前缀 | /api/v1/admin/meetings |
| 开放平台 API 前缀 | /api/v1/open/meetings |
Meeting 模块只保存会议业务事实和快照,不保存媒体流、RTC Provider 密钥、Core File 文件状态、Voucher 模板 / 状态事实、Money 资金余额或 Open Platform 应用密钥。音视频能力通过 spring-open-starter-rtc 的 RtcProvider / RtcProviderManager 衔接;商业套餐购买只保存 Voucher voucherId / voucherLockId / voucherUsageId / 优惠金额快照、Cashier 订单、Entitlement 套餐 / 权益和 Money 结算流水引用。
当前已完成
- 新增
spring-open-module-meeting并挂入spring-open-modules聚合和spring-open-application默认装配。 - 新增基础配置
spring.open.meeting.enabled、default-max-participants、join-token-ttl和waiting-room-enabled-by-default;这些键已由MeetingServiceProvider声明到 lifecycle 配置 schema,后台配置中心可发现会议启停、参会人数上限、入会 token 有效期和默认等候室开关。 - 新增会议骨架表:
meeting_room:会议定义、主持人、等候室、锁会、入会静音和计划时间。meeting_schedule:预约会议、周期规则、时区和取消状态。meeting_session:实际会议场次、RTC room 快照、在线人数和录制状态。meeting_participant:参会成员身份、角色、状态和 RTC participant 快照。meeting_invitation:邀请编码、渠道、受邀人和接受 / 过期状态。meeting_event:RTC provider 事件幂等记录、业务状态推进标记和原始载荷快照。meeting_chat_message:会议聊天消息、发送人、消息类型、内容和状态快照。meeting_material:会议资料绑定的 Core File 资源、文件名、大小、可见范围和上传人快照。meeting_reminder_delivery:预约提醒投递目标、状态、触发人、触发时间和 payload 快照。meeting_recording:会议录制任务、RTC recordingId、输出位置、Core File 资源、文件名、大小和失败原因快照。meeting_transcript:会议转写任务、录制 / 场次绑定、转写 Core File 资源、语言、全文、分段、说话人摘要和失败原因快照。meeting_summary:会议 AI 摘要、结论、待办事项、决议、纪要 Core File 资源、AI provider / model / token 用量和失败原因快照。meeting_quality_snapshot:会议质量快照、RTC provider、成员、音视频指标、质量等级、问题摘要和上报人快照。meeting_commercial_subscription:会议企业套餐订阅快照、Open Platform app 绑定、Entitlement 权益绑定、Cashier 订单 / Money 资产快照、套餐限制和 Open API 月度用量兜底。meeting_commercial_purchase_order:会议商业套餐购买单、原价 / 应付金额、Voucher 锁定 / 核销 / 优惠快照、Cashier 支付订单、Entitlement 套餐绑定、Money 资产 / 结算流水和套餐额度快照。meeting_webhook_endpoint:开放平台会议 Webhook endpoint、订阅事件、目标 URL、密钥掩码、状态和最近测试时间。meeting_webhook_delivery:Webhook 投递快照、事件类型、目标 endpoint、尝试次数、下一次重试时间、响应码、请求载荷和响应摘要。
- 新增实体、Mapper、迁移护栏和应用装配测试。
- 新增用户侧会议 contract:
POST /api/v1/meetings:创建即时会议,登录用户作为主持人和组织者。POST /api/v1/meetings/schedules:预约会议,写入会议定义和一次性预约记录。GET /api/v1/meetings/{roomNo}:查询会议、预约和当前场次快照。POST /api/v1/meetings/{roomNo}/join-token:为登录用户签发短期 RTC 入会 token。POST /api/v1/meetings/rtc/events:接入 RTC provider 回调事件,先基于原始请求体和X-SpringOpen-Rtc-*header 验签,再幂等推进场次和成员状态。POST /api/v1/meetings/{roomNo}/host-controls:主持人 / 联席主持人执行房间级和成员级控制。GET /api/v1/meetings/{roomNo}/messages/POST /api/v1/meetings/{roomNo}/messages:会议消息分页和发送。GET /api/v1/meetings/{roomNo}/materials/POST /api/v1/meetings/{roomNo}/materials:会议资料分页和保存。GET /api/v1/meetings/{roomNo}/recordings/POST /api/v1/meetings/{roomNo}/recordings:会议录制分页和开始录制。POST /api/v1/meetings/{roomNo}/recordings/{recordingNo}/stop:停止 RTC 云录制。POST /api/v1/meetings/{roomNo}/recordings/{recordingNo}/files:保存录制完成 / 失败回调,成功时绑定 Core FileresourceId、storageDisk、sourceUrl、transferStatus和文件快照。GET /api/v1/meetings/{roomNo}/transcripts/POST /api/v1/meetings/{roomNo}/transcripts:会议转写分页和生成 / 回填。GET /api/v1/meetings/{roomNo}/summaries/POST /api/v1/meetings/{roomNo}/summaries:会议 AI 摘要、待办事项和纪要分页 / 生成。POST /api/v1/meetings/{roomNo}/reminders:按预约触发提醒投递快照。
- 新增后台会议运维 contract:
GET /api/v1/admin/meetings:分页查询会议、当前场次、成员数、事件数、录制数和质量异常数。GET /api/v1/admin/meetings/{roomNo}:查询会议详情、成员、近期 RTC 事件和近期质量快照。GET /api/v1/admin/meetings/{roomNo}/events:分页查询会议 RTC provider 回调审计事件。GET /api/v1/admin/meetings/{roomNo}/quality-snapshots:分页查询会议质量快照。POST /api/v1/admin/meetings/{roomNo}/quality-snapshots:由后台或 RTC 运维任务写入会议质量快照。GET /api/v1/admin/meetings/reports/overview:查询会议总数、进行中会议、在线成员、质量异常、录制、转写和纪要摘要。
- App
meeting/index和 PC/meeting已接入会议大厅入口,支持创建即时会议、预约会议、按会议号查询会议详情、签发入会凭证并在主持人 / 联席主持人身份下执行控制;App 服务中心和 PC 导航 / 首页已提供入口。 - Admin
views/meeting/operations已接入会议运维页,支持会议列表、运维概览、会议详情、成员、RTC 事件、质量快照和质量快照上报。 - Admin
views/meeting/operations已接入会议 Webhook 投递运维页块,支持按投递编号 / endpoint / 事件类型 / 状态筛选投递快照,并对未完成投递触发 Runtime Outbox 重试。 - Admin
views/meeting/operations已接入会议商业套餐页块,支持查询购买单、创建购买单和人工结算;创建购买单可传可选voucherId使用consumerCode=meeting的当前用户卡券,锁券后按优惠后的应付金额创建 Cashier 待支付订单,支付成功或人工结算后确认核销、激活订阅、购买 Entitlement 套餐并写入 Money 收益流水。
开放平台 API、Webhook 和商业配额语义
- 开放平台会议 API 前缀为
/api/v1/open/meetings,由 Open Platform 访问凭证解析 app、owner、tenant、organization 和 department 上下文。 - Open Platform scope registry 已注册会议能力:
meeting:read、meeting:write、meeting:join-token、meeting:recording:read、meeting:webhook:write、meeting:commercial:read。 - 开放 API 当前覆盖:
POST /api/v1/open/meetings:按 app owner 创建即时会议或预约会议。GET /api/v1/open/meetings/{roomNo}:读取 app owner 拥有的会议详情。PATCH /api/v1/open/meetings/{roomNo}:更新会议标题、说明、人数和控制开关;预约会议可更新开始 / 结束时间和时区。POST /api/v1/open/meetings/{roomNo}/cancel:取消会议和对应预约。POST /api/v1/open/meetings/{roomNo}/join-token:为指定用户或 app owner 签发入会 token。GET /api/v1/open/meetings/{roomNo}/recordings:分页读取 app owner 会议录制。GET/POST/PATCH/DELETE /api/v1/open/meetings/webhook-endpoints:管理 Webhook endpoint。POST /api/v1/open/meetings/webhook-endpoints/{endpointNo}/test:生成测试投递快照、投递到 Runtime Outbox 并回写 endpoint 最近测试时间。POST /api/v1/open/meetings/webhook-deliveries/{deliveryNo}/retry:重试当前 app endpoint 名下未完成的 Webhook 投递。GET /api/v1/open/meetings/commercial-subscription:读取当前 app 生效的商业订阅快照。
- 商业订阅匹配优先级为 Open Platform app,其次为 owner;只有
active且在有效期窗口内的订阅会生效。 - 创建会议会校验套餐最大参会人数;开放 API 写操作会消耗
meeting.open-api.call配额。 - 已绑定 Entitlement
userEntitlementId时优先走中性 Entitlement quota;未绑定时使用meeting_commercial_subscription.openApiMonthlyQuota/openApiUsed作为月度兜底。 - 商业套餐购买单支付场景为
meeting-package-purchase;Cashier 支付成功处理器只处理该 scene,按购买单号幂等激活订阅,避免重复购买权益或重复写 Money 流水。 - 商业套餐购买单可选使用 Voucher;Meeting 在购买单里保存原价、应付金额、
voucherId、voucherLockId、voucherUsageId和优惠金额快照,不复制 Voucher 模板、状态或核销明细。 - Money 结算以
meeting-package-purchase:<orderNo>作为幂等键写入收益流水;Meeting 只保存moneyLedgerId和资产快照,不读取或修改资金余额细节。 - Webhook target 仅允许
http/https,事件类型限定为meeting.created、meeting.updated、meeting.cancelled、meeting.join-token.issued、meeting.webhook.test。 - Meeting Webhook 测试投递通过 Runtime 通用 Webhook Outbox 执行,投递结果会回写
meeting_webhook_delivery.status、attemptCount、lastAttemptAt、nextRetryAt、responseCode和responseBody;Admin 可通过/api/v1/admin/meetings/webhook-deliveries查看和重试。
入会 token 语义
- 入会 token 通过
spring-open-starter-rtc的RtcProviderManager签发,业务模块不接触 RTC Provider 密钥。 - RTC room name 由业务会议编号派生为
meeting-{roomNo}。 - 首次签发 token 时会创建或复用
meeting_session,并写入当前用户的meeting_participant快照。 - token attributes 固化
roomNo、sessionNo、userId和role,供后续 RTC 事件回调幂等回填成员状态。 - token 有效期使用
spring.open.meeting.join-token-ttl,默认 15 分钟。
RTC 事件回填语义
- RTC 事件入口保留原始请求体,并交由
spring-open-starter-rtc的 Provider 验签;验签失败时直接拒绝,不写入meeting_event。 - 推荐 Provider 回调携带
X-SpringOpen-Rtc-Provider、X-SpringOpen-Rtc-Timestamp、X-SpringOpen-Rtc-Nonce和X-SpringOpen-Rtc-Signature。其中 provider header 可覆盖 body 里的 provider,用于多 Provider 回调统一入口。 - LiveKit webhook secret 优先读取
spring.open.rtc.livekit.webhook-secret,未配置时回退api-secret;签名 canonical string 为timestamp + "\n" + nonce + "\n" + sha256(rawBody),使用 HMAC-SHA256 hex,可带sha256=前缀。 spring.open.rtc.livekit.webhook-tolerance控制 timestamp 容忍窗口,默认 5 分钟;spring.open.rtc.livekit.webhook-signature-required=true时未配置 secret 也会拒绝回调。- RTC provider 回调通过
provider + eventId去重;重复事件只返回既有记录,不再次推进业务状态。 - 事件载荷优先使用
sessionNo定位场次,也支持rtcRoomName/roomName/room和roomNo兜底定位。 - 成员事件优先使用
participantIdentity定位成员,也支持userId和rtcParticipantId兜底定位。 room_started/session_started会把场次推进为live,并回填startedAt。participant_joined/participant_left会回填成员在线状态、入离会时间、RTC participant 快照和当前在线人数。room_ended/session_ended会把场次推进为ended,清零当前在线人数,并结束当前会议定义。- 音频、视频和屏幕共享事件会回填成员的
mutedAudio、mutedVideo和sharingScreen快照。
主持人控制语义
host-controls支持lock、waiting_room、mute_on_join、screen_share、chat、mute_participant、remove_participant和co_host。- 主持人可执行全部控制;联席主持人可执行房间级开关和成员级控制,但不能移除或降级主持人。
- 房间级控制会回写
meeting_room的锁会、等候室、入会静音、共享和聊天开关快照。 - 成员级静音、移除和联席主持人任免会回写
meeting_participant;被移除或拒绝的成员再次请求入会 token 时会被拒绝。 - App / PC 会议大厅在主持人或联席主持人入会凭证下展示控制面板,控制完成后自动刷新会议详情。
聊天、资料和提醒语义
- 会议消息受
chatEnabled、活跃场次和成员状态约束;主持人、联席主持人、组织者和普通参会者均可发送 text 消息,系统消息类型仅作为后续事件投递快照预留。 - 消息分页只返回
sent状态消息,主持人 / 组织者和有效参会者可读取。 - 会议资料必须绑定已有 Core File
resourceId和文件名;文件大小不可为负。 - 资料可见范围支持
all和host;主持人 / 联席主持人 / 组织者可读取全部资料,普通参会者只读取all。 - 预约提醒由主持人 / 联席主持人 / 组织者触发,必须绑定有效
scheduleId;未指定目标时默认给主持人 / 组织者生成投递快照。 - 提醒当前写入
meeting_reminder_delivery,payload 固化eventType=meeting.schedule.reminder、会议号、预约 ID、标题和开始时间,后续通知发送器可按该表做异步投递。
录制和 Core File 绑定语义
- 会议录制由主持人、组织者或联席主持人发起 / 停止,必须存在当前活跃
meeting_session。 - Meeting 调用
spring-open-starter-rtc的RtcProvider.startRecording/stopRecording,业务模块只保存provider、recordingId、rtcRoomName、outputLocation和元数据快照,不保存媒体流或 RTC 密钥。 spring.open.rtc.livekit.http-url配置后,LiveKit Provider 会调用 Twirp/twirp/livekit.RoomService/CreateRoom、/ListRooms、/twirp/livekit.Egress/StartRoomCompositeEgress和/StopEgress;未配置时保持本地快照模式,便于开发期和无 SFU 环境使用。spring.open.rtc.livekit.http-timeout默认 10 秒,用于限制 LiveKit HTTP room / Egress 调用等待时间。- 同一场次同一时间只允许一个
requested/stop_requested录制任务;完成或失败回调后才允许再次发起。 - 录制完成后通过文件回调绑定 Core File
resourceId、storageDisk、文件名、类型、大小、输出位置、转存来源sourceUrl和转存状态transferStatus;失败回调保存failureReason并把状态置为failed。 - 文件回调会先通过 Media starter 的
recording-callback归一化,Provider 回调元数据中的转存来源和状态会进入 Meeting 录制快照,方便排查第三方录制文件下载 / 转存链路。 - 主持人、组织者和联席主持人可读取全状态录制;普通参会者只读取
completed且已绑定 Core File 资源的录制。 meeting_session.recording_status会同步当前录制状态,便于前端和运维视图快速展示。
转写、AI 摘要和纪要语义
- 会议转写由主持人、组织者或联席主持人生成 / 回填,可绑定已完成录制的
recordingNo,并保存转写 Core FileresourceId、语言、全文、分段 JSON、说话人摘要 JSON、失败原因和元数据快照。 completed转写必须存在全文或转写资源;绑定录制时只允许使用已完成录制,且默认继承录制的场次和 Core File 资源。- 主持人、组织者和联席主持人可读取全状态转写;普通参会者只读取
completed转写。 - 会议摘要必须绑定转写;
completed摘要只能基于completed转写生成。 - 摘要请求可显式传入
summaryText、conclusionText、actionItemsJson、decisionsJson和纪要文件快照;未传summaryText时,Meeting 通过spring-open-starter-ai-model调用已配置 AI 模型生成摘要,并记录 provider、model、token 用量和元数据。 - 纪要文件绑定 Core File 时必须同时提供文件名,文件大小不可为负。
- 主持人、组织者和联席主持人可读取全状态摘要;普通参会者只读取
completed摘要。
Admin 运维和质量快照语义
- 后台会议列表按会议维度聚合当前场次、成员、RTC 事件、录制、转写、纪要和质量异常计数,便于运维先从异常会议进入详情。
- 会议详情返回房间、当前场次、成员、近期 RTC 事件和近期质量快照;事件列表用于审计 RTC provider 回调幂等和业务状态推进。
- 质量快照支持
good、fair、poor、unknown,fair/poor会计入质量异常;延迟、抖动、丢包率、码率和 CPU 使用率必须为非负数,百分比类指标最大为 100。 - 质量快照可绑定
sessionNo、成员 ID、用户 ID、RTC participant identity、provider 和 RTC 房间;未显式指定场次时使用会议当前场次或最新场次。 - 后台写入质量快照时保存操作者 userId,便于后续审计和告警追踪。
- 运维概览只提供聚合摘要,不替代后续 Runtime 报表快照 / 异步导出底座。
后续链路
真实 LiveKit HTTP room / Egress 执行器已由 RTC Provider 在配置 spring.open.rtc.livekit.http-url 后支持;本地 Meeting 业务 contract 仍不保存媒体密钥或媒体流。大会场 / Webinar、TURN / SFU 容量压测和真机音视频联调不在当前本地 contract 范围内。