1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! `posts/createPosts` 出站 — 批量转发消息(forward to N channels)。
//!
//! ## 行为真源(证据链,frontend-source-derived = 等价抓包)
//!
//! 现网前端 `message.service.ts::sendRelayMessages(params)` 把 `params` **逐字透传**到
//! `POST /posts/createPosts`(无任何字段重命名)。两个真实 caller 都构造 **camelCase**:
//! - `chat-content/chat-content-base.component.ts:967`:`sendRelayMessages({ posts, channelIds })`
//! - `messageContainerShared.service.ts:245`:`sendRelayMessages({ posts: [post], channelIds: [channelId] })`
//!
//! 后端 `server/channels/csesapi/posts.go::createPosts` 解构体:
//! ```go
//! var param struct {
//! Posts *entity.Posts // entity.Posts = []*Post(数组)
//! ChannelIds []string
//! }
//! ```
//! **两字段均无 json tag** → Go `encoding/json` case-insensitive 匹配,camelCase
//! `posts`/`channelIds` 与 PascalCase `Posts`/`ChannelIds` **都能解**。但**真实 wire = 前端
//! 实际构造的 camelCase**(PascalCase 只是 Go 字段名,从未上线)——故 helix 按 camelCase 拼装。
//!
//! > 标注:本结论 **frontend-source-derived 非 live 抓包**(`真机curl真源.md` 未含 createPosts
//! > 抓包);但前端构造的 body 就是上线的真实 wire(HTTP body 逐字透传),等价抓包强度。
//!
//! ## wire 形态
//!
//! `{"posts":[<Post>...],"channelIds":[<channelId>...]}` —— `posts` 是 Post 对象数组
//! (`type Posts []*Post`),`channelIds` 是目标 channel 字符串数组。App 层
//! `CreateCsesPosts` 遍历 channelIds × posts 在每个目标 channel 建消息。
//!
//! ## 接管入参约定(C1 纯渲染:前端只传 UI 字段 + 已构造好的 post 对象数组)
//!
//! - `posts`:必填,**非空 JSON 数组**(每元素 = 待转发的 Post 对象,前端已从本地库取出)。
//! - `channel_ids`:必填,**非空字符串数组**(目标 channel)。snake_case UI param(C1),
//! 翻成 wire `channelIds`。
use ;
use crateImError;
use crate;
/// 取必填**非空数组**字段,缺/类型错/空 → `ImError::Parse`(边界零信任,HX-C 不变量 4)。
/// POST /api/cses/posts/createPosts — 批量转发 → 每个目标 channel 推 `post`(逐 channel WS new_post)。
///
/// 真源:前端 `sendRelayMessages` camelCase 透传 + Go `createPosts` 无 tag case-insensitive 解构。
/// wire body camelCase:`{"posts":[...],"channelIds":[...]}`。
;
static CREATE_POSTS: CreatePostsCommand = CreatePostsCommand;
submit!