@ichinese/open-sdk 0.0.0-stage → 1.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3102 @@
1
+ export interface paths {
2
+ "/auth/app_access_token": {
3
+ parameters: {
4
+ query?: never;
5
+ header?: never;
6
+ path?: never;
7
+ cookie?: never;
8
+ };
9
+ get?: never;
10
+ put?: never;
11
+ /**
12
+ * 取应用令牌
13
+ * @description 用 App ID 和 App Secret 换应用令牌。网关按 `app_id` 的区前缀转到应用所在区。
14
+ */
15
+ post: operations["getAppAccessToken"];
16
+ delete?: never;
17
+ options?: never;
18
+ head?: never;
19
+ patch?: never;
20
+ trace?: never;
21
+ };
22
+ "/auth/tenant_access_token": {
23
+ parameters: {
24
+ query?: never;
25
+ header?: never;
26
+ path?: never;
27
+ cookie?: never;
28
+ };
29
+ get?: never;
30
+ put?: never;
31
+ /**
32
+ * 取机构令牌
33
+ * @description 机构装了应用(并且应用的这个版本对它可用)才给。网关按 `tenant_key` 的区前缀转到机构所在区;应用在别的区时,
34
+ * 机构所在区去应用所在区核对 App Secret。令牌里的权限是机构管理员批了的那些(随时可能被撤销)。
35
+ * `tenant_key` 在 `app.installed` 事件和开发者后台里能看到。
36
+ */
37
+ post: operations["getTenantAccessToken"];
38
+ delete?: never;
39
+ options?: never;
40
+ head?: never;
41
+ patch?: never;
42
+ trace?: never;
43
+ };
44
+ "/auth/exchange_auth_code": {
45
+ parameters: {
46
+ query?: never;
47
+ header?: never;
48
+ path?: never;
49
+ cookie?: never;
50
+ };
51
+ get?: never;
52
+ put?: never;
53
+ /**
54
+ * 授权码换用户令牌(网页免登)
55
+ * @description 应用后端用前端拿到的授权码换用户令牌和 `open_id`(同一个人在同一个应用里的 `open_id` 不变,在不同应用里不同)。
56
+ * 两种码都接受:
57
+ * - **网页免登的授权码**:应用网页在桌面端或手机 App 里调 JS SDK 的 `requestAuthCode()` 拿到,带区前缀、
58
+ * 5 分钟、只能用一次、绑定这个应用和页面来源;不用传 `redirect_uri`。
59
+ * - **标准 OIDC 的授权码**:普通浏览器里 JS SDK 退回签发方 `/authorize`(先 `prompt=none` 静默)拿到的码;
60
+ * 要传当时的 `redirect_uri`(和登记的一致),公开客户端用了 PKCE 时传 `code_verifier`。
61
+ * 网关按码的区前缀转到用户的归属区。码过期返回 400 `details.reason = code_expired`,用过返回 400 `code_used`,
62
+ * 不是这个应用的码返回 400 `code_invalid`。
63
+ */
64
+ post: operations["exchangeAuthCode"];
65
+ delete?: never;
66
+ options?: never;
67
+ head?: never;
68
+ patch?: never;
69
+ trace?: never;
70
+ };
71
+ "/auth/refresh_user_token": {
72
+ parameters: {
73
+ query?: never;
74
+ header?: never;
75
+ path?: never;
76
+ cookie?: never;
77
+ };
78
+ get?: never;
79
+ put?: never;
80
+ /**
81
+ * 刷新用户令牌
82
+ * @description 刷新令牌用一次换一对新的(旧的作废)。用户撤销授权或卸载应用后刷新令牌失效(401 `invalid_token`)。
83
+ */
84
+ post: operations["refreshUserToken"];
85
+ delete?: never;
86
+ options?: never;
87
+ head?: never;
88
+ patch?: never;
89
+ trace?: never;
90
+ };
91
+ "/auth/revoke": {
92
+ parameters: {
93
+ query?: never;
94
+ header?: never;
95
+ path?: never;
96
+ cookie?: never;
97
+ };
98
+ get?: never;
99
+ put?: never;
100
+ /** 作废一个令牌(用户退出应用时) */
101
+ post: operations["revokeToken"];
102
+ delete?: never;
103
+ options?: never;
104
+ head?: never;
105
+ patch?: never;
106
+ trace?: never;
107
+ };
108
+ "/user/info": {
109
+ parameters: {
110
+ query?: never;
111
+ header?: never;
112
+ path?: never;
113
+ cookie?: never;
114
+ };
115
+ /**
116
+ * 当前用户(用户令牌)
117
+ * @description 总有 `open_id`;`name`、`avatar_url`、`locale` 要用户批了 `profile`。
118
+ */
119
+ get: operations["getUserInfo"];
120
+ put?: never;
121
+ post?: never;
122
+ delete?: never;
123
+ options?: never;
124
+ head?: never;
125
+ patch?: never;
126
+ trace?: never;
127
+ };
128
+ "/tenant": {
129
+ parameters: {
130
+ query?: never;
131
+ header?: never;
132
+ path?: never;
133
+ cookie?: never;
134
+ };
135
+ /** 装了应用的机构(机构令牌) */
136
+ get: operations["getTenant"];
137
+ put?: never;
138
+ post?: never;
139
+ delete?: never;
140
+ options?: never;
141
+ head?: never;
142
+ patch?: never;
143
+ trace?: never;
144
+ };
145
+ "/tenant/members": {
146
+ parameters: {
147
+ query?: never;
148
+ header?: never;
149
+ path?: never;
150
+ cookie?: never;
151
+ };
152
+ /** 机构成员(通讯录),各区的成员一起列,不暴露区 */
153
+ get: operations["listTenantMembers"];
154
+ put?: never;
155
+ post?: never;
156
+ delete?: never;
157
+ options?: never;
158
+ head?: never;
159
+ patch?: never;
160
+ trace?: never;
161
+ };
162
+ "/tenant/invitations": {
163
+ parameters: {
164
+ query?: never;
165
+ header?: never;
166
+ path?: never;
167
+ cookie?: never;
168
+ };
169
+ get?: never;
170
+ put?: never;
171
+ /**
172
+ * 邀请成员(对方接受后才加入;和机构后台的邀请一样)
173
+ * @description 响应里的 `invite_link` 是邀请链接,只给这一次,由你的应用发给对方(比如在你的应用里展示、发到你们自己的群)。
174
+ * 邮箱会另外收到一封邀请邮件,手机号不发短信(M6.03)。链接会核对打开的人是不是这个号码或邮箱的主人。
175
+ */
176
+ post: operations["inviteTenantMember"];
177
+ delete?: never;
178
+ options?: never;
179
+ head?: never;
180
+ patch?: never;
181
+ trace?: never;
182
+ };
183
+ "/classes": {
184
+ parameters: {
185
+ query?: never;
186
+ header?: never;
187
+ path?: never;
188
+ cookie?: never;
189
+ };
190
+ /** 班级:机构令牌是机构的全部班级;用户令牌是这个用户教的班级 */
191
+ get: operations["listClasses"];
192
+ put?: never;
193
+ post?: never;
194
+ delete?: never;
195
+ options?: never;
196
+ head?: never;
197
+ patch?: never;
198
+ trace?: never;
199
+ };
200
+ "/classes/{class_id}": {
201
+ parameters: {
202
+ query?: never;
203
+ header?: never;
204
+ path?: never;
205
+ cookie?: never;
206
+ };
207
+ /** 一个班级 */
208
+ get: operations["getClass"];
209
+ put?: never;
210
+ post?: never;
211
+ delete?: never;
212
+ options?: never;
213
+ head?: never;
214
+ patch?: never;
215
+ trace?: never;
216
+ };
217
+ "/classes/{class_id}/members": {
218
+ parameters: {
219
+ query?: never;
220
+ header?: never;
221
+ path?: never;
222
+ cookie?: never;
223
+ };
224
+ /** 花名册(老师和学员) */
225
+ get: operations["listClassMembers"];
226
+ put?: never;
227
+ /**
228
+ * 把本机构的一个成员加进班级(做学员)
229
+ * @description 要是本机构在这个区的成员;别的区的成员要按平台的邀请加入(他们本人同意后才跨区,D2),这里返回 409 `details.reason = member_in_other_region`。
230
+ * 已经在班里返回 409 `already_member`。
231
+ */
232
+ post: operations["addClassMember"];
233
+ delete?: never;
234
+ options?: never;
235
+ head?: never;
236
+ patch?: never;
237
+ trace?: never;
238
+ };
239
+ "/classes/{class_id}/members/{open_id}": {
240
+ parameters: {
241
+ query?: never;
242
+ header?: never;
243
+ path?: never;
244
+ cookie?: never;
245
+ };
246
+ get?: never;
247
+ put?: never;
248
+ post?: never;
249
+ /** 把学员移出班级 */
250
+ delete: operations["removeClassMember"];
251
+ options?: never;
252
+ head?: never;
253
+ patch?: never;
254
+ trace?: never;
255
+ };
256
+ "/classes/{class_id}/sessions": {
257
+ parameters: {
258
+ query?: never;
259
+ header?: never;
260
+ path?: never;
261
+ cookie?: never;
262
+ };
263
+ /** 班级的课次(时间段内,最多 100 天) */
264
+ get: operations["listClassSessions"];
265
+ put?: never;
266
+ post?: never;
267
+ delete?: never;
268
+ options?: never;
269
+ head?: never;
270
+ patch?: never;
271
+ trace?: never;
272
+ };
273
+ "/classes/{class_id}/sessions/{session_id}/cancel": {
274
+ parameters: {
275
+ query?: never;
276
+ header?: never;
277
+ path?: never;
278
+ cookie?: never;
279
+ };
280
+ get?: never;
281
+ put?: never;
282
+ /** 取消一次课(成员收到通知,和课表里取消一样) */
283
+ post: operations["cancelClassSession"];
284
+ delete?: never;
285
+ options?: never;
286
+ head?: never;
287
+ patch?: never;
288
+ trace?: never;
289
+ };
290
+ "/classes/{class_id}/sessions/{session_id}/reschedule": {
291
+ parameters: {
292
+ query?: never;
293
+ header?: never;
294
+ path?: never;
295
+ cookie?: never;
296
+ };
297
+ get?: never;
298
+ put?: never;
299
+ /** 改期一次课 */
300
+ post: operations["rescheduleClassSession"];
301
+ delete?: never;
302
+ options?: never;
303
+ head?: never;
304
+ patch?: never;
305
+ trace?: never;
306
+ };
307
+ "/classes/{class_id}/sessions/{session_id}/attendance": {
308
+ parameters: {
309
+ query?: never;
310
+ header?: never;
311
+ path?: never;
312
+ cookie?: never;
313
+ };
314
+ /**
315
+ * 一次课的考勤(谁来了、在课堂里待了多久)
316
+ * @description 每个学员一条(老师、助教不列);没进过课堂的 `attended: false`、`seconds: 0`,正在课堂里的时长算到现在。
317
+ */
318
+ get: operations["getSessionAttendance"];
319
+ put?: never;
320
+ post?: never;
321
+ delete?: never;
322
+ options?: never;
323
+ head?: never;
324
+ patch?: never;
325
+ trace?: never;
326
+ };
327
+ "/classes/{class_id}/assignments": {
328
+ parameters: {
329
+ query?: never;
330
+ header?: never;
331
+ path?: never;
332
+ cookie?: never;
333
+ };
334
+ /**
335
+ * 班级的作业和考试
336
+ * @description 作业(含草稿)和考试,新的在前;随堂小测(练习,不限次数)不列。考试的 `due_at` 是截止时间,`max_score` 是总分。
337
+ */
338
+ get: operations["listAssignments"];
339
+ put?: never;
340
+ /** 布置作业(文字说明 + 截止时间;题目在平台里编辑)。用户令牌要是这个班的老师 */
341
+ post: operations["createAssignment"];
342
+ delete?: never;
343
+ options?: never;
344
+ head?: never;
345
+ patch?: never;
346
+ trace?: never;
347
+ };
348
+ "/classes/{class_id}/assignments/{assignment_id}/submissions": {
349
+ parameters: {
350
+ query?: never;
351
+ header?: never;
352
+ path?: never;
353
+ cookie?: never;
354
+ };
355
+ /** 一份作业的提交和分数 */
356
+ get: operations["listSubmissions"];
357
+ put?: never;
358
+ post?: never;
359
+ delete?: never;
360
+ options?: never;
361
+ head?: never;
362
+ patch?: never;
363
+ trace?: never;
364
+ };
365
+ "/classes/{class_id}/assignments/{assignment_id}/submissions/{open_id}/score": {
366
+ parameters: {
367
+ query?: never;
368
+ header?: never;
369
+ path?: never;
370
+ cookie?: never;
371
+ };
372
+ get?: never;
373
+ /**
374
+ * 回写分数(外部批改的结果),学员收到「成绩已发布」
375
+ * @description 只用于作业。分数超过满分 400;作业被退回重做、等学员再交时 409 `awaiting_resubmission`;学员没交 404 `not_submitted`;
376
+ * 考试按题在平台里批,这里返回 409 `exam_scored_per_question`。
377
+ */
378
+ put: operations["setSubmissionScore"];
379
+ post?: never;
380
+ delete?: never;
381
+ options?: never;
382
+ head?: never;
383
+ patch?: never;
384
+ trace?: never;
385
+ };
386
+ "/classes/{class_id}/grades": {
387
+ parameters: {
388
+ query?: never;
389
+ header?: never;
390
+ path?: never;
391
+ cookie?: never;
392
+ };
393
+ /** 导出成绩(每个学员每份作业一行) */
394
+ get: operations["exportClassGrades"];
395
+ put?: never;
396
+ post?: never;
397
+ delete?: never;
398
+ options?: never;
399
+ head?: never;
400
+ patch?: never;
401
+ trace?: never;
402
+ };
403
+ "/courses": {
404
+ parameters: {
405
+ query?: never;
406
+ header?: never;
407
+ path?: never;
408
+ cookie?: never;
409
+ };
410
+ /** 机构的视频课(机构令牌)或这个用户编写的课(用户令牌) */
411
+ get: operations["listCourses"];
412
+ put?: never;
413
+ post?: never;
414
+ delete?: never;
415
+ options?: never;
416
+ head?: never;
417
+ patch?: never;
418
+ trace?: never;
419
+ };
420
+ "/courses/{course_id}": {
421
+ parameters: {
422
+ query?: never;
423
+ header?: never;
424
+ path?: never;
425
+ cookie?: never;
426
+ };
427
+ /** 课程大纲(章节和课时的标题、顺序) */
428
+ get: operations["getCourseOutline"];
429
+ put?: never;
430
+ post?: never;
431
+ delete?: never;
432
+ options?: never;
433
+ head?: never;
434
+ /** 改课程的标题、简介;改了的已发布课程照常重新走审核 */
435
+ patch: operations["updateCourseOutline"];
436
+ trace?: never;
437
+ };
438
+ "/courses/{course_id}/progress": {
439
+ parameters: {
440
+ query?: never;
441
+ header?: never;
442
+ path?: never;
443
+ cookie?: never;
444
+ };
445
+ /**
446
+ * 学员的学习进度(学完的课时数)。用户令牌只能看自己的
447
+ * @description 学习进度存在每个学员的归属区(D2)。本区的学员直接列;别的区的学员由他们的归属区回答,只列本人同意把这门课的进度给开课机构的
448
+ * (平台的 `PUT /me/courses/{itemId}/progress-sharing`),只带必要字段(学完几课、最后学习时间),两边记跨境日志(D3)。
449
+ * 别的区暂时连不上时它的学员缺席,`partial: true`。
450
+ */
451
+ get: operations["listCourseProgress"];
452
+ put?: never;
453
+ post?: never;
454
+ delete?: never;
455
+ options?: never;
456
+ head?: never;
457
+ patch?: never;
458
+ trace?: never;
459
+ };
460
+ "/im/messages": {
461
+ parameters: {
462
+ query?: never;
463
+ header?: never;
464
+ path?: never;
465
+ cookie?: never;
466
+ };
467
+ get?: never;
468
+ put?: never;
469
+ /**
470
+ * 机器人发消息(文字或卡片),发到机器人所在的群,或私聊装了应用的用户
471
+ * @description 私聊(`receive_id_type = open_id`)要求对方装了应用或所在机构装了应用;群(`chat_id`)要机器人已经在群里
472
+ * (机构管理员把它拉进班级群或机构群)。内容照常过审核。卡片按钮点了以后,平台把 `card.action` 推到应用的
473
+ * 卡片回调地址。
474
+ * 私聊(`open_id`):由本区的「系统通知」发出,正文前标应用名(「<应用名>」…),卡片按文字发(标题、正文、按钮链接)。
475
+ * 群(`chat_id`,取自 `GET /im/chats` 或 `im.message_received`):以应用机器人的名义发进群,卡片是真的卡片(按钮可回调);
476
+ * 机器人不在这个群里返回 409 `details.reason = bot_not_in_chat`。机构令牌只能发机构安装授权加进去的群,应用令牌能发所有加了它的群。
477
+ */
478
+ post: operations["sendBotMessage"];
479
+ delete?: never;
480
+ options?: never;
481
+ head?: never;
482
+ patch?: never;
483
+ trace?: never;
484
+ };
485
+ "/im/chats": {
486
+ parameters: {
487
+ query?: never;
488
+ header?: never;
489
+ path?: never;
490
+ cookie?: never;
491
+ };
492
+ /**
493
+ * 机器人所在的群
494
+ * @description 机构令牌:这个机构的人(凭机构的授权)加了机器人的群;`chat_id` 就是平台的会话 ID。
495
+ */
496
+ get: operations["listBotChats"];
497
+ put?: never;
498
+ post?: never;
499
+ delete?: never;
500
+ options?: never;
501
+ head?: never;
502
+ patch?: never;
503
+ trace?: never;
504
+ };
505
+ "/notifications": {
506
+ parameters: {
507
+ query?: never;
508
+ header?: never;
509
+ path?: never;
510
+ cookie?: never;
511
+ };
512
+ get?: never;
513
+ put?: never;
514
+ /** 给本机构成员发通知(进「系统通知」,按对方的通知设置和免打扰时段推送) */
515
+ post: operations["sendNotification"];
516
+ delete?: never;
517
+ options?: never;
518
+ head?: never;
519
+ patch?: never;
520
+ trace?: never;
521
+ };
522
+ "/classes/{class_id}/recordings": {
523
+ parameters: {
524
+ query?: never;
525
+ header?: never;
526
+ path?: never;
527
+ cookie?: never;
528
+ };
529
+ /** 班级在线课堂的回放和课后总结(不给播放地址;`watch_url` 打开平台里的回放页) */
530
+ get: operations["listClassRecordings"];
531
+ put?: never;
532
+ post?: never;
533
+ delete?: never;
534
+ options?: never;
535
+ head?: never;
536
+ patch?: never;
537
+ trace?: never;
538
+ };
539
+ "/events": {
540
+ parameters: {
541
+ query?: never;
542
+ header?: never;
543
+ path?: never;
544
+ cookie?: never;
545
+ };
546
+ /** 机构的活动(含草稿和待审) */
547
+ get: operations["listTenantEvents"];
548
+ put?: never;
549
+ /**
550
+ * 建一个活动(草稿;发布由机构在机构后台做,照常审核)
551
+ * @description 课次和在线课堂照平台的规则建好;记作机构负责人建的(课堂的主持人是负责人)。
552
+ */
553
+ post: operations["createTenantEvent"];
554
+ delete?: never;
555
+ options?: never;
556
+ head?: never;
557
+ patch?: never;
558
+ trace?: never;
559
+ };
560
+ "/events/{event_id}": {
561
+ parameters: {
562
+ query?: never;
563
+ header?: never;
564
+ path?: never;
565
+ cookie?: never;
566
+ };
567
+ get?: never;
568
+ put?: never;
569
+ post?: never;
570
+ delete?: never;
571
+ options?: never;
572
+ head?: never;
573
+ /**
574
+ * 改一个活动(字段同平台机构后台的活动编辑)
575
+ * @description 已发布的活动改了以后照常重新发布(易盾机审,D20);有人报名后不能改参加方式(409 `mode_locked`),名额不能少于已确认的人数
576
+ * (409 `capacity_below_confirmed`),取消了的活动不能改(409 `cancelled`)。记作机构负责人改的。
577
+ */
578
+ patch: operations["updateTenantEvent"];
579
+ trace?: never;
580
+ };
581
+ "/events/{event_id}/registrations": {
582
+ parameters: {
583
+ query?: never;
584
+ header?: never;
585
+ path?: never;
586
+ cookie?: never;
587
+ };
588
+ /** 活动的报名和签到 */
589
+ get: operations["listEventRegistrations"];
590
+ put?: never;
591
+ post?: never;
592
+ delete?: never;
593
+ options?: never;
594
+ head?: never;
595
+ patch?: never;
596
+ trace?: never;
597
+ };
598
+ "/jobs": {
599
+ parameters: {
600
+ query?: never;
601
+ header?: never;
602
+ path?: never;
603
+ cookie?: never;
604
+ };
605
+ /** 机构的职位(含草稿和待审) */
606
+ get: operations["listTenantJobs"];
607
+ put?: never;
608
+ /** 同步一个职位进来(草稿;提交和发布仍走本机构审核和易盾机审) */
609
+ post: operations["createTenantJob"];
610
+ delete?: never;
611
+ options?: never;
612
+ head?: never;
613
+ patch?: never;
614
+ trace?: never;
615
+ };
616
+ "/jobs/{job_id}/candidates": {
617
+ parameters: {
618
+ query?: never;
619
+ header?: never;
620
+ path?: never;
621
+ cookie?: never;
622
+ };
623
+ /** 职位的候选人(投递时本人同意给机构的那些字段) */
624
+ get: operations["listJobCandidates"];
625
+ put?: never;
626
+ post?: never;
627
+ delete?: never;
628
+ options?: never;
629
+ head?: never;
630
+ patch?: never;
631
+ trace?: never;
632
+ };
633
+ "/trial/venues": {
634
+ parameters: {
635
+ query?: never;
636
+ header?: never;
637
+ path?: never;
638
+ cookie?: never;
639
+ };
640
+ /** 机构的教学点(排试听时段用它的 venue_id) */
641
+ get: operations["listTrialVenues"];
642
+ put?: never;
643
+ post?: never;
644
+ delete?: never;
645
+ options?: never;
646
+ head?: never;
647
+ patch?: never;
648
+ trace?: never;
649
+ };
650
+ "/trial/slots": {
651
+ parameters: {
652
+ query?: never;
653
+ header?: never;
654
+ path?: never;
655
+ cookie?: never;
656
+ };
657
+ /** 试听时段(默认只列没结束的,按时间) */
658
+ get: operations["listTrialSlots"];
659
+ put?: never;
660
+ /**
661
+ * 排试听时段(可以按周重复);教学点要已发布
662
+ * @description 409 `venue_not_published`;开始时间已过 400。老师在平台里指定(第一批不按 open_id 指定老师)。
663
+ */
664
+ post: operations["createTrialSlots"];
665
+ delete?: never;
666
+ options?: never;
667
+ head?: never;
668
+ patch?: never;
669
+ trace?: never;
670
+ };
671
+ "/trial/slots/{slot_id}/cancel": {
672
+ parameters: {
673
+ query?: never;
674
+ header?: never;
675
+ path?: never;
676
+ cookie?: never;
677
+ };
678
+ get?: never;
679
+ put?: never;
680
+ /** 取消一个试听时段(已约的人照常收到通知,预约随之取消) */
681
+ post: operations["cancelTrialSlot"];
682
+ delete?: never;
683
+ options?: never;
684
+ head?: never;
685
+ patch?: never;
686
+ trace?: never;
687
+ };
688
+ "/trial/bookings": {
689
+ parameters: {
690
+ query?: never;
691
+ header?: never;
692
+ path?: never;
693
+ cookie?: never;
694
+ };
695
+ /** 机构各教学点的试听预约 */
696
+ get: operations["listTrialBookings"];
697
+ put?: never;
698
+ post?: never;
699
+ delete?: never;
700
+ options?: never;
701
+ head?: never;
702
+ patch?: never;
703
+ trace?: never;
704
+ };
705
+ "/trial/bookings/{booking_id}/confirm": {
706
+ parameters: {
707
+ query?: never;
708
+ header?: never;
709
+ path?: never;
710
+ cookie?: never;
711
+ };
712
+ get?: never;
713
+ put?: never;
714
+ /** 确认一个试听预约 */
715
+ post: operations["confirmTrialBooking"];
716
+ delete?: never;
717
+ options?: never;
718
+ head?: never;
719
+ patch?: never;
720
+ trace?: never;
721
+ };
722
+ "/trade/orders": {
723
+ parameters: {
724
+ query?: never;
725
+ header?: never;
726
+ path?: never;
727
+ cookie?: never;
728
+ };
729
+ /** 机构的订单(只读对账)。跟钱有关的写操作不开放 */
730
+ get: operations["listTradeOrders"];
731
+ put?: never;
732
+ post?: never;
733
+ delete?: never;
734
+ options?: never;
735
+ head?: never;
736
+ patch?: never;
737
+ trace?: never;
738
+ };
739
+ "/reviews": {
740
+ parameters: {
741
+ query?: never;
742
+ header?: never;
743
+ path?: never;
744
+ cookie?: never;
745
+ };
746
+ /** 对本机构(及其课程、教学点)的评价 */
747
+ get: operations["listTenantReviews"];
748
+ put?: never;
749
+ post?: never;
750
+ delete?: never;
751
+ options?: never;
752
+ head?: never;
753
+ patch?: never;
754
+ trace?: never;
755
+ };
756
+ "/reviews/{review_id}/reply": {
757
+ parameters: {
758
+ query?: never;
759
+ header?: never;
760
+ path?: never;
761
+ cookie?: never;
762
+ };
763
+ get?: never;
764
+ put?: never;
765
+ /** 以机构的名义回复一条评价(每条只能回复一次,内容照常审核) */
766
+ post: operations["replyReview"];
767
+ delete?: never;
768
+ options?: never;
769
+ head?: never;
770
+ patch?: never;
771
+ trace?: never;
772
+ };
773
+ "/public/{kind}": {
774
+ parameters: {
775
+ query?: never;
776
+ header?: never;
777
+ path?: never;
778
+ cookie?: never;
779
+ };
780
+ /**
781
+ * 本区显示的公开课程、活动、职位
782
+ * @description 每个应用每种每天最多返回 10000 条(按返回条数算),超了 429 `daily_quota_exceeded`。
783
+ */
784
+ get: operations["listPublicContent"];
785
+ put?: never;
786
+ post?: never;
787
+ delete?: never;
788
+ options?: never;
789
+ head?: never;
790
+ patch?: never;
791
+ trace?: never;
792
+ };
793
+ "/user/profile/interests": {
794
+ parameters: {
795
+ query?: never;
796
+ header?: never;
797
+ path?: never;
798
+ cookie?: never;
799
+ };
800
+ /**
801
+ * 用户的兴趣画像(话题、内容类型的权重标签,不给原始的浏览和互动记录)
802
+ * @description 用户关了「个性化推荐」时返回空(`personalized: false`)。只给金牌机构开发的应用。
803
+ */
804
+ get: operations["getUserInterests"];
805
+ put?: never;
806
+ post?: never;
807
+ delete?: never;
808
+ options?: never;
809
+ head?: never;
810
+ patch?: never;
811
+ trace?: never;
812
+ };
813
+ "/user/profile/interest_signals": {
814
+ parameters: {
815
+ query?: never;
816
+ header?: never;
817
+ path?: never;
818
+ cookie?: never;
819
+ };
820
+ get?: never;
821
+ put?: never;
822
+ /**
823
+ * 加一条带来源的兴趣信号
824
+ * @description 只能加,不能删别人的、不能改等级。权重 0–1(平台再按上限折算,一个应用对一个话题的总权重有上限);
825
+ * 推荐依据里显示「来自 xx 应用」,用户能看、能删。用户关了「个性化推荐」时不写(返回 `accepted: false`)。
826
+ */
827
+ post: operations["addInterestSignal"];
828
+ delete?: never;
829
+ options?: never;
830
+ head?: never;
831
+ patch?: never;
832
+ trace?: never;
833
+ };
834
+ "/user/profile/learning": {
835
+ parameters: {
836
+ query?: never;
837
+ header?: never;
838
+ path?: never;
839
+ cookie?: never;
840
+ };
841
+ /** 用户的学习画像(等级、目标、在学的语言) */
842
+ get: operations["getUserLearningProfile"];
843
+ put?: never;
844
+ post?: never;
845
+ delete?: never;
846
+ options?: never;
847
+ head?: never;
848
+ patch?: never;
849
+ trace?: never;
850
+ };
851
+ "/reports": {
852
+ parameters: {
853
+ query?: never;
854
+ header?: never;
855
+ path?: never;
856
+ cookie?: never;
857
+ };
858
+ get?: never;
859
+ put?: never;
860
+ /** 代用户举报一条公开内容(进平台的审核队列,用户能在自己的举报记录里看到) */
861
+ post: operations["reportOnBehalf"];
862
+ delete?: never;
863
+ options?: never;
864
+ head?: never;
865
+ patch?: never;
866
+ trace?: never;
867
+ };
868
+ }
869
+ export interface webhooks {
870
+ event: {
871
+ parameters: {
872
+ query?: never;
873
+ header?: never;
874
+ path?: never;
875
+ cookie?: never;
876
+ };
877
+ get?: never;
878
+ put?: never;
879
+ /**
880
+ * 事件推送(平台 → 应用的请求地址)
881
+ * @description 订阅的事件发生时,平台 POST 到应用在「事件与回调」里填的请求地址。
882
+ * - **签名**:`X-Ich-Timestamp`(秒)、`X-Ich-Nonce`、`X-Ich-Signature: v1=<hex>`,
883
+ * 其中 `hex = HMAC-SHA256(签名密钥, timestamp + "." + nonce + "." + 原始请求体)`。应用要验签,并拒绝
884
+ * 时间戳和当前相差 5 分钟以上的请求。
885
+ * - **加密(可选)**:填了加密密钥时请求体是 `{"encrypt": "<base64>"}`,内容是 AES-256-GCM 加密的事件 JSON:
886
+ * 密钥 = SHA-256(加密密钥),base64 解出来依次是 12 字节 IV、密文、16 字节认证标签。签名对加密后的请求体算。
887
+ * - **重试**:应用 5 秒内回 2xx 算成功;否则按 1、2、4、8 … 分钟退避重试,最多 12 次(约 3 天),每次都进
888
+ * 事件推送日志,开发者后台能手动重推。同一个事件重试时 `event_id` 不变,应用按它去重(幂等)。
889
+ * - **地址验证**:保存请求地址时平台先推一次 `{"type": "url_verification", "challenge": "…"}`,应用原样回
890
+ * `{"challenge": "…"}`(同样签名)。
891
+ * - 按机构订阅(机构令牌的事件)的,只推装了应用的机构的事件,`header.tenant_key` 是那个机构;个人数据只在
892
+ * 用户授权了相应权限时才带(否则只带 `open_id`)。
893
+ */
894
+ post: operations["onEvent"];
895
+ delete?: never;
896
+ options?: never;
897
+ head?: never;
898
+ patch?: never;
899
+ trace?: never;
900
+ };
901
+ "card.action": {
902
+ parameters: {
903
+ query?: never;
904
+ header?: never;
905
+ path?: never;
906
+ cookie?: never;
907
+ };
908
+ get?: never;
909
+ put?: never;
910
+ /**
911
+ * 卡片回调(用户点了机器人卡片上的按钮 → 应用的卡片回调地址)
912
+ * @description 签名和加密同事件推送。应用 3 秒内可以回一张新卡片替换原来的(`{"card": {...}}`),或回空。
913
+ */
914
+ post: operations["onCardAction"];
915
+ delete?: never;
916
+ options?: never;
917
+ head?: never;
918
+ patch?: never;
919
+ trace?: never;
920
+ };
921
+ }
922
+ export interface components {
923
+ schemas: {
924
+ PageMeta: {
925
+ has_more: boolean;
926
+ page_token?: string | null;
927
+ };
928
+ /**
929
+ * @description 错误的细分原因(`error.details.reason`)
930
+ * @enum {string}
931
+ */
932
+ OpenErrorReason: "invalid_credentials" | "invalid_token" | "token_expired" | "token_type" | "app_disabled" | "not_installed" | "not_available" | "scope_denied" | "scope_pending" | "scope_not_declared" | "gold_only" | "rate_limited" | "daily_quota_exceeded" | "code_expired" | "code_used" | "code_invalid" | "redirect_uri_mismatch" | "origin_not_trusted" | "ip_not_allowed";
933
+ ErrorResponse: {
934
+ error: {
935
+ /** @enum {string} */
936
+ code: "UNAUTHENTICATED" | "FORBIDDEN" | "NOT_FOUND" | "VALIDATION_FAILED" | "CONFLICT" | "RATE_LIMITED" | "PAYLOAD_TOO_LARGE" | "WRONG_REGION" | "SERVICE_UNAVAILABLE" | "INTERNAL";
937
+ /** @description 按 Accept-Language 本地化的提示 */
938
+ message: string;
939
+ request_id: string;
940
+ details?: {
941
+ reason?: components["schemas"]["OpenErrorReason"];
942
+ scope?: string;
943
+ never_ask?: boolean;
944
+ } & {
945
+ [key: string]: unknown;
946
+ };
947
+ };
948
+ };
949
+ /** @description 一个人在一个应用里的 ID(同一个人在不同应用里不同,和 OIDC 的 `sub` 相同) */
950
+ OpenId: string;
951
+ /** @description 装了应用的机构(`<机构所在区>.<机构 ID>`) */
952
+ TenantKey: string;
953
+ /** @description App ID(`<应用所在区>.cli_…`),也是 OIDC 的 client_id */
954
+ AppId: string;
955
+ /** @description 权限码(目录见 `ScopeCode`;平台的 `GET /api/v1/open/scopes` 返回带说明的目录) */
956
+ Scope: string;
957
+ /** @enum {string} */
958
+ ScopeCode: "openid" | "profile" | "org:member:readonly" | "org:member" | "class:readonly" | "class:member" | "schedule:readonly" | "schedule" | "attendance:readonly" | "coursework" | "grade:readonly" | "course" | "learning:progress:readonly" | "im:message:send_as_bot" | "im:chat:readonly" | "notify:send" | "live:recording:readonly" | "event" | "event:registration:readonly" | "job" | "job:candidate:readonly" | "trial" | "trade:order:readonly" | "review" | "profile:interest:readonly" | "profile:interest" | "profile:learning:readonly" | "report:create";
959
+ /** @enum {string} */
960
+ OrgRole: "owner" | "admin" | "academic" | "editor" | "content_reviewer" | "teacher" | "community" | "recruiter" | "member";
961
+ AppCredentials: {
962
+ app_id: components["schemas"]["AppId"];
963
+ app_secret: string;
964
+ };
965
+ AppAccessToken: {
966
+ app_access_token: string;
967
+ /** @description 秒 */
968
+ expires_in: number;
969
+ };
970
+ TenantAccessToken: {
971
+ tenant_access_token: string;
972
+ expires_in: number;
973
+ tenant_key: components["schemas"]["TenantKey"];
974
+ /** @description 机构管理员批了的权限 */
975
+ scopes: components["schemas"]["Scope"][];
976
+ };
977
+ UserAccessToken: {
978
+ access_token: string;
979
+ /** @enum {string} */
980
+ token_type: "Bearer";
981
+ expires_in: number;
982
+ refresh_token: string;
983
+ refresh_expires_in: number;
984
+ open_id: components["schemas"]["OpenId"];
985
+ /** @description 用户批了的权限 */
986
+ scopes: components["schemas"]["Scope"][];
987
+ /** @description 用户拒绝的权限 */
988
+ denied_scopes: components["schemas"]["Scope"][];
989
+ /** @description 用户通过机构装的应用时,是那个机构 */
990
+ tenant_key?: string | null;
991
+ };
992
+ OpenUser: {
993
+ open_id: components["schemas"]["OpenId"];
994
+ name?: string;
995
+ avatar_url?: string | null;
996
+ locale?: string;
997
+ };
998
+ Tenant: {
999
+ tenant_key: components["schemas"]["TenantKey"];
1000
+ name: string;
1001
+ kind: string;
1002
+ /** @description ISO 3166-1 alpha-2 */
1003
+ country: string;
1004
+ verified: boolean;
1005
+ /** @enum {string} */
1006
+ rating: "standard" | "silver" | "gold";
1007
+ };
1008
+ TenantMember: {
1009
+ open_id: components["schemas"]["OpenId"];
1010
+ name: string;
1011
+ roles: components["schemas"]["OrgRole"][];
1012
+ /** Format: date-time */
1013
+ joined_at: string;
1014
+ };
1015
+ OpenClass: {
1016
+ /** Format: uuid */
1017
+ class_id: string;
1018
+ name: string;
1019
+ description?: string | null;
1020
+ student_count: number;
1021
+ /** Format: date-time */
1022
+ created_at: string;
1023
+ };
1024
+ ClassMember: {
1025
+ open_id: components["schemas"]["OpenId"];
1026
+ name: string;
1027
+ /** @enum {string} */
1028
+ role: "teacher" | "assistant" | "student";
1029
+ /** Format: date-time */
1030
+ joined_at?: string | null;
1031
+ };
1032
+ OpenSession: {
1033
+ /** Format: uuid */
1034
+ session_id: string;
1035
+ /** Format: uuid */
1036
+ class_id: string;
1037
+ title: string;
1038
+ /** Format: date-time */
1039
+ starts_at: string;
1040
+ /** Format: date-time */
1041
+ ends_at: string;
1042
+ /** @enum {string} */
1043
+ status: "scheduled" | "live" | "ended" | "cancelled";
1044
+ /** @description 是不是在在线课堂里上(课次都是) */
1045
+ live?: boolean;
1046
+ };
1047
+ AttendanceRecord: {
1048
+ open_id: components["schemas"]["OpenId"];
1049
+ attended: boolean;
1050
+ /** @description 在课堂里待了多久 */
1051
+ seconds: number;
1052
+ /** Format: date-time */
1053
+ first_joined_at?: string | null;
1054
+ };
1055
+ OpenAssignment: {
1056
+ /** Format: uuid */
1057
+ assignment_id: string;
1058
+ /** Format: uuid */
1059
+ class_id: string;
1060
+ /** @enum {string} */
1061
+ kind: "homework" | "exam";
1062
+ title: string;
1063
+ /** @enum {string} */
1064
+ status: "draft" | "published" | "closed";
1065
+ /** Format: date-time */
1066
+ due_at?: string | null;
1067
+ max_score?: number | null;
1068
+ /** Format: date-time */
1069
+ created_at: string;
1070
+ };
1071
+ OpenSubmission: {
1072
+ open_id: components["schemas"]["OpenId"];
1073
+ /** @enum {string} */
1074
+ status: "not_submitted" | "submitted" | "graded";
1075
+ /** Format: date-time */
1076
+ submitted_at?: string | null;
1077
+ score?: number | null;
1078
+ max_score?: number | null;
1079
+ feedback?: string | null;
1080
+ };
1081
+ GradeRow: {
1082
+ open_id: components["schemas"]["OpenId"];
1083
+ /** Format: uuid */
1084
+ assignment_id: string;
1085
+ title?: string;
1086
+ score: number | null;
1087
+ max_score?: number | null;
1088
+ /** Format: date-time */
1089
+ graded_at?: string | null;
1090
+ };
1091
+ OpenCourse: {
1092
+ /** Format: uuid */
1093
+ course_id: string;
1094
+ title: string;
1095
+ summary?: string | null;
1096
+ /** @description draft / in_review / published / … */
1097
+ status: string;
1098
+ lesson_count?: number;
1099
+ /** Format: date-time */
1100
+ updated_at: string;
1101
+ };
1102
+ CourseOutline: components["schemas"]["OpenCourse"] & {
1103
+ sections: {
1104
+ title: string;
1105
+ lessons: {
1106
+ lesson_id: string;
1107
+ title: string;
1108
+ kind?: string;
1109
+ }[];
1110
+ }[];
1111
+ };
1112
+ CourseProgress: {
1113
+ open_id: components["schemas"]["OpenId"];
1114
+ completed_lessons: number;
1115
+ total_lessons: number;
1116
+ /** Format: date-time */
1117
+ last_studied_at?: string | null;
1118
+ };
1119
+ BotMessage: {
1120
+ /** @enum {string} */
1121
+ receive_id_type: "open_id" | "chat_id";
1122
+ receive_id: string;
1123
+ /** @enum {string} */
1124
+ msg_type: "text" | "card";
1125
+ content: {
1126
+ text: string;
1127
+ } | {
1128
+ card: components["schemas"]["Card"];
1129
+ };
1130
+ /** @description 幂等键:同一个 uuid 1 小时内只发一次 */
1131
+ uuid?: string;
1132
+ };
1133
+ /** @description 消息卡片(和平台的卡片消息同一套:标题、正文、按钮;按钮的 value 原样回到卡片回调) */
1134
+ Card: {
1135
+ title: string;
1136
+ body?: string;
1137
+ /** Format: uri */
1138
+ image_url?: string;
1139
+ buttons?: {
1140
+ text: string;
1141
+ /**
1142
+ * Format: uri
1143
+ * @description 打开链接(要在可信域名里)
1144
+ */
1145
+ url?: string;
1146
+ /** @description 回调时原样带回(≤1 KB) */
1147
+ value?: {
1148
+ [key: string]: unknown;
1149
+ };
1150
+ }[];
1151
+ };
1152
+ BotChat: {
1153
+ chat_id: string;
1154
+ name: string;
1155
+ /** @enum {string} */
1156
+ kind: "class" | "org" | "group";
1157
+ member_count: number;
1158
+ };
1159
+ OpenRecording: {
1160
+ /** Format: uuid */
1161
+ session_id: string;
1162
+ title: string;
1163
+ /** Format: date-time */
1164
+ starts_at: string;
1165
+ duration_seconds: number;
1166
+ /**
1167
+ * Format: uri
1168
+ * @description 平台里的回放页(要登录、有权限的人才能看)
1169
+ */
1170
+ watch_url: string;
1171
+ /** @description 课后总结(AI 生成,老师确认过的) */
1172
+ summary?: string | null;
1173
+ };
1174
+ OpenEvent: {
1175
+ /** Format: uuid */
1176
+ event_id: string;
1177
+ title: string;
1178
+ status: string;
1179
+ /** Format: date-time */
1180
+ starts_at: string;
1181
+ /** Format: date-time */
1182
+ ends_at?: string | null;
1183
+ registered?: number;
1184
+ capacity?: number | null;
1185
+ };
1186
+ EventRegistration: {
1187
+ open_id: components["schemas"]["OpenId"];
1188
+ name: string;
1189
+ /** @description registered / checked_in / cancelled / waitlisted */
1190
+ status: string;
1191
+ /** Format: date-time */
1192
+ registered_at: string;
1193
+ /** Format: date-time */
1194
+ checked_in_at?: string | null;
1195
+ };
1196
+ OpenJob: {
1197
+ /** Format: uuid */
1198
+ job_id: string;
1199
+ title: string;
1200
+ status: string;
1201
+ city?: string | null;
1202
+ /** Format: date-time */
1203
+ updated_at: string;
1204
+ };
1205
+ OpenJobBody: {
1206
+ title: string;
1207
+ description: string;
1208
+ city?: string;
1209
+ country?: string;
1210
+ /** @description 应用自己系统里的 ID(同一个 external_id 再同步时更新原来那条) */
1211
+ external_id?: string;
1212
+ };
1213
+ JobCandidate: {
1214
+ candidate_id: string;
1215
+ open_id?: components["schemas"]["OpenId"];
1216
+ name: string;
1217
+ status: string;
1218
+ /** Format: date-time */
1219
+ applied_at: string;
1220
+ };
1221
+ /**
1222
+ * @description 和平台机构后台建活动的请求体相同(`CreateOrgEventBody`,见 openapi.yaml):至少 `type`、`title`、`mode`、`time_zone`、
1223
+ * `sessions`(每个课次 `starts_at`、`ends_at`);其余(简介、日程、地点、名额、报名问题、标签、等级……)照那里的规则。
1224
+ * `cover_key` 不收(封面在平台里上传)。
1225
+ */
1226
+ OpenEventCreate: {
1227
+ type: string;
1228
+ title: string;
1229
+ /** @enum {string} */
1230
+ mode: "offline" | "online";
1231
+ time_zone: string;
1232
+ summary?: string;
1233
+ capacity?: number | null;
1234
+ sessions: {
1235
+ /** Format: date-time */
1236
+ starts_at: string;
1237
+ /** Format: date-time */
1238
+ ends_at: string;
1239
+ }[];
1240
+ } & {
1241
+ [key: string]: unknown;
1242
+ };
1243
+ /** @description 和平台机构后台改活动的请求体相同(`UpdateOrgEventBody`);`cover_key` 不收。 */
1244
+ OpenEventPatch: {
1245
+ [key: string]: unknown;
1246
+ };
1247
+ TrialVenue: {
1248
+ /** Format: uuid */
1249
+ venue_id: string;
1250
+ name: string;
1251
+ status: string;
1252
+ city?: string | null;
1253
+ time_zone: string;
1254
+ };
1255
+ TrialSlot: {
1256
+ /** Format: uuid */
1257
+ slot_id: string;
1258
+ /** Format: uuid */
1259
+ venue_id: string;
1260
+ /** Format: date-time */
1261
+ starts_at: string;
1262
+ /** Format: date-time */
1263
+ ends_at: string;
1264
+ time_zone?: string;
1265
+ capacity: number;
1266
+ booked: number;
1267
+ pending: number;
1268
+ course_title: string;
1269
+ series_id?: string | null;
1270
+ /** @enum {string} */
1271
+ status: "open" | "cancelled";
1272
+ };
1273
+ TrialBooking: {
1274
+ /** Format: uuid */
1275
+ booking_id: string;
1276
+ venue_id?: string;
1277
+ open_id?: components["schemas"]["OpenId"];
1278
+ status: string;
1279
+ /** Format: date-time */
1280
+ starts_at: string;
1281
+ /** Format: date-time */
1282
+ ends_at?: string | null;
1283
+ course_title?: string | null;
1284
+ };
1285
+ TradeOrder: {
1286
+ order_id: string;
1287
+ status: string;
1288
+ amount_minor: number;
1289
+ currency: string;
1290
+ item_title?: string | null;
1291
+ open_id?: components["schemas"]["OpenId"];
1292
+ /** Format: date-time */
1293
+ created_at: string;
1294
+ /** Format: date-time */
1295
+ paid_at?: string | null;
1296
+ };
1297
+ OpenReview: {
1298
+ review_id: string;
1299
+ /** @description 评价对象的公开内容 ID */
1300
+ target_id: string;
1301
+ stars: number;
1302
+ body?: string | null;
1303
+ author_name?: string | null;
1304
+ replied?: boolean;
1305
+ /** Format: date-time */
1306
+ created_at: string;
1307
+ };
1308
+ PublicContent: {
1309
+ item_id: string;
1310
+ kind: string;
1311
+ title: string;
1312
+ summary?: string | null;
1313
+ /**
1314
+ * Format: uri
1315
+ * @description 平台里的详情页
1316
+ */
1317
+ url?: string;
1318
+ /** Format: date-time */
1319
+ updated_at?: string | null;
1320
+ };
1321
+ InterestProfile: {
1322
+ /** @description 用户关了「个性化推荐」时为 false,其余为空 */
1323
+ personalized: boolean;
1324
+ topics: {
1325
+ topic: string;
1326
+ /** @description 归一化后的权重 */
1327
+ weight: number;
1328
+ }[];
1329
+ /** @description 三等九级的级(1–9,D27) */
1330
+ level?: number | null;
1331
+ content_types?: {
1332
+ /** @enum {string} */
1333
+ type: "post" | "video" | "course" | "event";
1334
+ weight: number;
1335
+ }[];
1336
+ };
1337
+ LearningProfile: {
1338
+ level?: number | null;
1339
+ goals: string[];
1340
+ /** @description 在学的语言(BCP 47) */
1341
+ languages: string[];
1342
+ };
1343
+ /**
1344
+ * @description 可订阅的事件(取自通知目录里以机构为中心的事件)。`x-token` 说明按机构还是按用户订阅,`x-scope` 是要的权限。
1345
+ * @enum {string}
1346
+ */
1347
+ EventType: "app.installed" | "app.uninstalled" | "app.scopes_changed" | "coursework.submitted" | "grade.published" | "schedule.session_changed" | "event.registered" | "job.candidate_applied" | "trade.order_paid" | "review.created" | "trial.booked" | "im.message_received";
1348
+ EventEnvelope: {
1349
+ /** @enum {string} */
1350
+ schema: "1.0";
1351
+ header: {
1352
+ event_id: string;
1353
+ event_type: components["schemas"]["EventType"];
1354
+ /** Format: date-time */
1355
+ create_time: string;
1356
+ app_id: components["schemas"]["AppId"];
1357
+ tenant_key?: string | null;
1358
+ };
1359
+ /** @description 各事件自己的字段(只带 ID 和 open_id,详情用接口取) */
1360
+ event: {
1361
+ [key: string]: unknown;
1362
+ };
1363
+ };
1364
+ EncryptedEnvelope: {
1365
+ /** @description base64(IV 12 字节 + 密文 + 认证标签 16 字节) */
1366
+ encrypt: string;
1367
+ };
1368
+ UrlVerification: {
1369
+ /** @enum {string} */
1370
+ type: "url_verification";
1371
+ challenge: string;
1372
+ };
1373
+ CardActionEnvelope: {
1374
+ /** @enum {string} */
1375
+ schema: "1.0";
1376
+ header: {
1377
+ event_id: string;
1378
+ app_id: components["schemas"]["AppId"];
1379
+ tenant_key?: string | null;
1380
+ /** Format: date-time */
1381
+ create_time: string;
1382
+ };
1383
+ operator?: {
1384
+ open_id?: components["schemas"]["OpenId"];
1385
+ };
1386
+ /** @description 卡片所在的会话 */
1387
+ chat_id?: string;
1388
+ action: {
1389
+ value: {
1390
+ [key: string]: unknown;
1391
+ };
1392
+ };
1393
+ message_id?: string;
1394
+ };
1395
+ };
1396
+ responses: {
1397
+ /** @description VALIDATION_FAILED(`details.reason` 可能是 `code_expired`、`code_used`、`code_invalid`、`redirect_uri_mismatch`) */
1398
+ ValidationFailed: {
1399
+ headers: {
1400
+ [name: string]: unknown;
1401
+ };
1402
+ content: {
1403
+ "application/json": components["schemas"]["ErrorResponse"];
1404
+ };
1405
+ };
1406
+ /** @description UNAUTHENTICATED(`details.reason`:`token_expired` 或 `invalid_token`),带 `WWW-Authenticate` */
1407
+ Unauthenticated: {
1408
+ headers: {
1409
+ [name: string]: unknown;
1410
+ };
1411
+ content: {
1412
+ "application/json": components["schemas"]["ErrorResponse"];
1413
+ };
1414
+ };
1415
+ /** @description UNAUTHENTICATED(`details.reason = invalid_credentials`:App ID 或 App Secret 不对) */
1416
+ InvalidCredentials: {
1417
+ headers: {
1418
+ [name: string]: unknown;
1419
+ };
1420
+ content: {
1421
+ "application/json": components["schemas"]["ErrorResponse"];
1422
+ };
1423
+ };
1424
+ /**
1425
+ * @description FORBIDDEN(`details.reason`:`app_disabled` 应用被停用或下架,`not_installed` 机构或用户没装,
1426
+ * `not_available` 当前版本对这个机构或用户不可用,`token_type` 这个接口不接受这种令牌)
1427
+ */
1428
+ Forbidden: {
1429
+ headers: {
1430
+ [name: string]: unknown;
1431
+ };
1432
+ content: {
1433
+ "application/json": components["schemas"]["ErrorResponse"];
1434
+ };
1435
+ };
1436
+ /**
1437
+ * @description FORBIDDEN,`details.reason` 是 `scope_denied`(用户或机构管理员拒绝了,`details.scope`、`details.never_ask`)、
1438
+ * `scope_pending`(新版本加的权限还没问到)、`scope_not_declared`(应用没声明这个权限)、`gold_only`
1439
+ * (金牌机构专属)或 `token_type`。应用要能降级。
1440
+ */
1441
+ ScopeDenied: {
1442
+ headers: {
1443
+ [name: string]: unknown;
1444
+ };
1445
+ content: {
1446
+ "application/json": components["schemas"]["ErrorResponse"];
1447
+ };
1448
+ };
1449
+ /** @description NOT_FOUND(没权限时同样返回 404) */
1450
+ NotFound: {
1451
+ headers: {
1452
+ [name: string]: unknown;
1453
+ };
1454
+ content: {
1455
+ "application/json": components["schemas"]["ErrorResponse"];
1456
+ };
1457
+ };
1458
+ /** @description CONFLICT(`details.reason` 说明) */
1459
+ Conflict: {
1460
+ headers: {
1461
+ [name: string]: unknown;
1462
+ };
1463
+ content: {
1464
+ "application/json": components["schemas"]["ErrorResponse"];
1465
+ };
1466
+ };
1467
+ /** @description RATE_LIMITED(`details.reason`:`rate_limited` 或 `daily_quota_exceeded`) */
1468
+ RateLimited: {
1469
+ headers: {
1470
+ "Retry-After"?: number;
1471
+ "X-RateLimit-Limit"?: number;
1472
+ "X-RateLimit-Remaining"?: number;
1473
+ "X-RateLimit-Reset"?: number;
1474
+ [name: string]: unknown;
1475
+ };
1476
+ content: {
1477
+ "application/json": components["schemas"]["ErrorResponse"];
1478
+ };
1479
+ };
1480
+ };
1481
+ parameters: {
1482
+ PageSize: number;
1483
+ PageToken: string;
1484
+ ClassId: string;
1485
+ SessionId: string;
1486
+ AssignmentId: string;
1487
+ CourseId: string;
1488
+ EventId: string;
1489
+ JobIdPath: string;
1490
+ BookingId: string;
1491
+ OpenIdPath: components["schemas"]["OpenId"];
1492
+ };
1493
+ requestBodies: never;
1494
+ headers: never;
1495
+ pathItems: never;
1496
+ }
1497
+ export type $defs = Record<string, never>;
1498
+ export interface operations {
1499
+ getAppAccessToken: {
1500
+ parameters: {
1501
+ query?: never;
1502
+ header?: never;
1503
+ path?: never;
1504
+ cookie?: never;
1505
+ };
1506
+ requestBody: {
1507
+ content: {
1508
+ "application/json": components["schemas"]["AppCredentials"];
1509
+ };
1510
+ };
1511
+ responses: {
1512
+ /** @description OK */
1513
+ 200: {
1514
+ headers: {
1515
+ [name: string]: unknown;
1516
+ };
1517
+ content: {
1518
+ "application/json": components["schemas"]["AppAccessToken"];
1519
+ };
1520
+ };
1521
+ 400: components["responses"]["ValidationFailed"];
1522
+ 401: components["responses"]["InvalidCredentials"];
1523
+ 403: components["responses"]["Forbidden"];
1524
+ 429: components["responses"]["RateLimited"];
1525
+ };
1526
+ };
1527
+ getTenantAccessToken: {
1528
+ parameters: {
1529
+ query?: never;
1530
+ header?: never;
1531
+ path?: never;
1532
+ cookie?: never;
1533
+ };
1534
+ requestBody: {
1535
+ content: {
1536
+ "application/json": components["schemas"]["AppCredentials"] & {
1537
+ tenant_key: components["schemas"]["TenantKey"];
1538
+ };
1539
+ };
1540
+ };
1541
+ responses: {
1542
+ /** @description OK */
1543
+ 200: {
1544
+ headers: {
1545
+ [name: string]: unknown;
1546
+ };
1547
+ content: {
1548
+ "application/json": components["schemas"]["TenantAccessToken"];
1549
+ };
1550
+ };
1551
+ 400: components["responses"]["ValidationFailed"];
1552
+ 401: components["responses"]["InvalidCredentials"];
1553
+ 403: components["responses"]["Forbidden"];
1554
+ 429: components["responses"]["RateLimited"];
1555
+ };
1556
+ };
1557
+ exchangeAuthCode: {
1558
+ parameters: {
1559
+ query?: never;
1560
+ header?: never;
1561
+ path?: never;
1562
+ cookie?: never;
1563
+ };
1564
+ requestBody: {
1565
+ content: {
1566
+ "application/json": components["schemas"]["AppCredentials"] & {
1567
+ /** @description 授权码(带区前缀) */
1568
+ code: string;
1569
+ /**
1570
+ * Format: uri
1571
+ * @description 标准 OIDC 的码要传
1572
+ */
1573
+ redirect_uri?: string;
1574
+ /** @description 用了 PKCE 时传 */
1575
+ code_verifier?: string;
1576
+ };
1577
+ };
1578
+ };
1579
+ responses: {
1580
+ /** @description OK */
1581
+ 200: {
1582
+ headers: {
1583
+ [name: string]: unknown;
1584
+ };
1585
+ content: {
1586
+ "application/json": components["schemas"]["UserAccessToken"];
1587
+ };
1588
+ };
1589
+ 400: components["responses"]["ValidationFailed"];
1590
+ 401: components["responses"]["InvalidCredentials"];
1591
+ 403: components["responses"]["Forbidden"];
1592
+ 429: components["responses"]["RateLimited"];
1593
+ };
1594
+ };
1595
+ refreshUserToken: {
1596
+ parameters: {
1597
+ query?: never;
1598
+ header?: never;
1599
+ path?: never;
1600
+ cookie?: never;
1601
+ };
1602
+ requestBody: {
1603
+ content: {
1604
+ "application/json": components["schemas"]["AppCredentials"] & {
1605
+ refresh_token: string;
1606
+ };
1607
+ };
1608
+ };
1609
+ responses: {
1610
+ /** @description OK */
1611
+ 200: {
1612
+ headers: {
1613
+ [name: string]: unknown;
1614
+ };
1615
+ content: {
1616
+ "application/json": components["schemas"]["UserAccessToken"];
1617
+ };
1618
+ };
1619
+ 400: components["responses"]["ValidationFailed"];
1620
+ 401: components["responses"]["InvalidCredentials"];
1621
+ 429: components["responses"]["RateLimited"];
1622
+ };
1623
+ };
1624
+ revokeToken: {
1625
+ parameters: {
1626
+ query?: never;
1627
+ header?: never;
1628
+ path?: never;
1629
+ cookie?: never;
1630
+ };
1631
+ requestBody: {
1632
+ content: {
1633
+ "application/json": components["schemas"]["AppCredentials"] & {
1634
+ /** @description 用户令牌或刷新令牌 */
1635
+ token: string;
1636
+ };
1637
+ };
1638
+ };
1639
+ responses: {
1640
+ /** @description 已作废(本来就无效也返回 204) */
1641
+ 204: {
1642
+ headers: {
1643
+ [name: string]: unknown;
1644
+ };
1645
+ content?: never;
1646
+ };
1647
+ 401: components["responses"]["InvalidCredentials"];
1648
+ };
1649
+ };
1650
+ getUserInfo: {
1651
+ parameters: {
1652
+ query?: never;
1653
+ header?: never;
1654
+ path?: never;
1655
+ cookie?: never;
1656
+ };
1657
+ requestBody?: never;
1658
+ responses: {
1659
+ /** @description OK */
1660
+ 200: {
1661
+ headers: {
1662
+ [name: string]: unknown;
1663
+ };
1664
+ content: {
1665
+ "application/json": components["schemas"]["OpenUser"];
1666
+ };
1667
+ };
1668
+ 401: components["responses"]["Unauthenticated"];
1669
+ 429: components["responses"]["RateLimited"];
1670
+ };
1671
+ };
1672
+ getTenant: {
1673
+ parameters: {
1674
+ query?: never;
1675
+ header?: never;
1676
+ path?: never;
1677
+ cookie?: never;
1678
+ };
1679
+ requestBody?: never;
1680
+ responses: {
1681
+ /** @description OK */
1682
+ 200: {
1683
+ headers: {
1684
+ [name: string]: unknown;
1685
+ };
1686
+ content: {
1687
+ "application/json": components["schemas"]["Tenant"];
1688
+ };
1689
+ };
1690
+ 401: components["responses"]["Unauthenticated"];
1691
+ };
1692
+ };
1693
+ listTenantMembers: {
1694
+ parameters: {
1695
+ query?: {
1696
+ role?: components["schemas"]["OrgRole"];
1697
+ page_size?: components["parameters"]["PageSize"];
1698
+ page_token?: components["parameters"]["PageToken"];
1699
+ };
1700
+ header?: never;
1701
+ path?: never;
1702
+ cookie?: never;
1703
+ };
1704
+ requestBody?: never;
1705
+ responses: {
1706
+ /** @description OK */
1707
+ 200: {
1708
+ headers: {
1709
+ [name: string]: unknown;
1710
+ };
1711
+ content: {
1712
+ "application/json": components["schemas"]["PageMeta"] & {
1713
+ items: components["schemas"]["TenantMember"][];
1714
+ };
1715
+ };
1716
+ };
1717
+ 401: components["responses"]["Unauthenticated"];
1718
+ 403: components["responses"]["ScopeDenied"];
1719
+ 429: components["responses"]["RateLimited"];
1720
+ };
1721
+ };
1722
+ inviteTenantMember: {
1723
+ parameters: {
1724
+ query?: never;
1725
+ header?: never;
1726
+ path?: never;
1727
+ cookie?: never;
1728
+ };
1729
+ requestBody: {
1730
+ content: {
1731
+ "application/json": {
1732
+ /** @description 邮箱或手机号(E.164) */
1733
+ identifier: string;
1734
+ roles: components["schemas"]["OrgRole"][];
1735
+ };
1736
+ };
1737
+ };
1738
+ responses: {
1739
+ /** @description 已创建 */
1740
+ 201: {
1741
+ headers: {
1742
+ [name: string]: unknown;
1743
+ };
1744
+ content: {
1745
+ "application/json": {
1746
+ invitation_id: string;
1747
+ /** @enum {string} */
1748
+ status: "sent" | "already_member";
1749
+ /** @description 邀请链接,只给这一次 */
1750
+ invite_link: string;
1751
+ };
1752
+ };
1753
+ };
1754
+ 400: components["responses"]["ValidationFailed"];
1755
+ 401: components["responses"]["Unauthenticated"];
1756
+ 403: components["responses"]["ScopeDenied"];
1757
+ 429: components["responses"]["RateLimited"];
1758
+ };
1759
+ };
1760
+ listClasses: {
1761
+ parameters: {
1762
+ query?: {
1763
+ page_size?: components["parameters"]["PageSize"];
1764
+ page_token?: components["parameters"]["PageToken"];
1765
+ };
1766
+ header?: never;
1767
+ path?: never;
1768
+ cookie?: never;
1769
+ };
1770
+ requestBody?: never;
1771
+ responses: {
1772
+ /** @description OK */
1773
+ 200: {
1774
+ headers: {
1775
+ [name: string]: unknown;
1776
+ };
1777
+ content: {
1778
+ "application/json": components["schemas"]["PageMeta"] & {
1779
+ items: components["schemas"]["OpenClass"][];
1780
+ };
1781
+ };
1782
+ };
1783
+ 401: components["responses"]["Unauthenticated"];
1784
+ 403: components["responses"]["ScopeDenied"];
1785
+ };
1786
+ };
1787
+ getClass: {
1788
+ parameters: {
1789
+ query?: never;
1790
+ header?: never;
1791
+ path: {
1792
+ class_id: components["parameters"]["ClassId"];
1793
+ };
1794
+ cookie?: never;
1795
+ };
1796
+ requestBody?: never;
1797
+ responses: {
1798
+ /** @description OK */
1799
+ 200: {
1800
+ headers: {
1801
+ [name: string]: unknown;
1802
+ };
1803
+ content: {
1804
+ "application/json": components["schemas"]["OpenClass"];
1805
+ };
1806
+ };
1807
+ 401: components["responses"]["Unauthenticated"];
1808
+ 403: components["responses"]["ScopeDenied"];
1809
+ 404: components["responses"]["NotFound"];
1810
+ };
1811
+ };
1812
+ listClassMembers: {
1813
+ parameters: {
1814
+ query?: {
1815
+ page_size?: components["parameters"]["PageSize"];
1816
+ page_token?: components["parameters"]["PageToken"];
1817
+ };
1818
+ header?: never;
1819
+ path: {
1820
+ class_id: components["parameters"]["ClassId"];
1821
+ };
1822
+ cookie?: never;
1823
+ };
1824
+ requestBody?: never;
1825
+ responses: {
1826
+ /** @description OK */
1827
+ 200: {
1828
+ headers: {
1829
+ [name: string]: unknown;
1830
+ };
1831
+ content: {
1832
+ "application/json": components["schemas"]["PageMeta"] & {
1833
+ items: components["schemas"]["ClassMember"][];
1834
+ };
1835
+ };
1836
+ };
1837
+ 401: components["responses"]["Unauthenticated"];
1838
+ 403: components["responses"]["ScopeDenied"];
1839
+ 404: components["responses"]["NotFound"];
1840
+ };
1841
+ };
1842
+ addClassMember: {
1843
+ parameters: {
1844
+ query?: never;
1845
+ header?: never;
1846
+ path: {
1847
+ class_id: components["parameters"]["ClassId"];
1848
+ };
1849
+ cookie?: never;
1850
+ };
1851
+ requestBody: {
1852
+ content: {
1853
+ "application/json": {
1854
+ open_id: components["schemas"]["OpenId"];
1855
+ };
1856
+ };
1857
+ };
1858
+ responses: {
1859
+ /** @description 已加入 */
1860
+ 201: {
1861
+ headers: {
1862
+ [name: string]: unknown;
1863
+ };
1864
+ content: {
1865
+ "application/json": components["schemas"]["ClassMember"];
1866
+ };
1867
+ };
1868
+ 401: components["responses"]["Unauthenticated"];
1869
+ 403: components["responses"]["ScopeDenied"];
1870
+ 404: components["responses"]["NotFound"];
1871
+ 409: components["responses"]["Conflict"];
1872
+ };
1873
+ };
1874
+ removeClassMember: {
1875
+ parameters: {
1876
+ query?: never;
1877
+ header?: never;
1878
+ path: {
1879
+ class_id: components["parameters"]["ClassId"];
1880
+ open_id: components["parameters"]["OpenIdPath"];
1881
+ };
1882
+ cookie?: never;
1883
+ };
1884
+ requestBody?: never;
1885
+ responses: {
1886
+ /** @description 已移出 */
1887
+ 204: {
1888
+ headers: {
1889
+ [name: string]: unknown;
1890
+ };
1891
+ content?: never;
1892
+ };
1893
+ 401: components["responses"]["Unauthenticated"];
1894
+ 403: components["responses"]["ScopeDenied"];
1895
+ 404: components["responses"]["NotFound"];
1896
+ };
1897
+ };
1898
+ listClassSessions: {
1899
+ parameters: {
1900
+ query: {
1901
+ from: string;
1902
+ to: string;
1903
+ page_size?: components["parameters"]["PageSize"];
1904
+ page_token?: components["parameters"]["PageToken"];
1905
+ };
1906
+ header?: never;
1907
+ path: {
1908
+ class_id: components["parameters"]["ClassId"];
1909
+ };
1910
+ cookie?: never;
1911
+ };
1912
+ requestBody?: never;
1913
+ responses: {
1914
+ /** @description OK */
1915
+ 200: {
1916
+ headers: {
1917
+ [name: string]: unknown;
1918
+ };
1919
+ content: {
1920
+ "application/json": components["schemas"]["PageMeta"] & {
1921
+ items: components["schemas"]["OpenSession"][];
1922
+ };
1923
+ };
1924
+ };
1925
+ 400: components["responses"]["ValidationFailed"];
1926
+ 401: components["responses"]["Unauthenticated"];
1927
+ 403: components["responses"]["ScopeDenied"];
1928
+ 404: components["responses"]["NotFound"];
1929
+ };
1930
+ };
1931
+ cancelClassSession: {
1932
+ parameters: {
1933
+ query?: never;
1934
+ header?: never;
1935
+ path: {
1936
+ class_id: components["parameters"]["ClassId"];
1937
+ session_id: components["parameters"]["SessionId"];
1938
+ };
1939
+ cookie?: never;
1940
+ };
1941
+ requestBody?: never;
1942
+ responses: {
1943
+ /** @description OK */
1944
+ 200: {
1945
+ headers: {
1946
+ [name: string]: unknown;
1947
+ };
1948
+ content: {
1949
+ "application/json": components["schemas"]["OpenSession"];
1950
+ };
1951
+ };
1952
+ 401: components["responses"]["Unauthenticated"];
1953
+ 403: components["responses"]["ScopeDenied"];
1954
+ 404: components["responses"]["NotFound"];
1955
+ 409: components["responses"]["Conflict"];
1956
+ };
1957
+ };
1958
+ rescheduleClassSession: {
1959
+ parameters: {
1960
+ query?: never;
1961
+ header?: never;
1962
+ path: {
1963
+ class_id: components["parameters"]["ClassId"];
1964
+ session_id: components["parameters"]["SessionId"];
1965
+ };
1966
+ cookie?: never;
1967
+ };
1968
+ requestBody: {
1969
+ content: {
1970
+ "application/json": {
1971
+ /** Format: date-time */
1972
+ starts_at: string;
1973
+ duration_minutes?: number;
1974
+ };
1975
+ };
1976
+ };
1977
+ responses: {
1978
+ /** @description OK */
1979
+ 200: {
1980
+ headers: {
1981
+ [name: string]: unknown;
1982
+ };
1983
+ content: {
1984
+ "application/json": components["schemas"]["OpenSession"];
1985
+ };
1986
+ };
1987
+ 400: components["responses"]["ValidationFailed"];
1988
+ 401: components["responses"]["Unauthenticated"];
1989
+ 403: components["responses"]["ScopeDenied"];
1990
+ 404: components["responses"]["NotFound"];
1991
+ 409: components["responses"]["Conflict"];
1992
+ };
1993
+ };
1994
+ getSessionAttendance: {
1995
+ parameters: {
1996
+ query?: never;
1997
+ header?: never;
1998
+ path: {
1999
+ class_id: components["parameters"]["ClassId"];
2000
+ session_id: components["parameters"]["SessionId"];
2001
+ };
2002
+ cookie?: never;
2003
+ };
2004
+ requestBody?: never;
2005
+ responses: {
2006
+ /** @description OK */
2007
+ 200: {
2008
+ headers: {
2009
+ [name: string]: unknown;
2010
+ };
2011
+ content: {
2012
+ "application/json": {
2013
+ items: components["schemas"]["AttendanceRecord"][];
2014
+ };
2015
+ };
2016
+ };
2017
+ 401: components["responses"]["Unauthenticated"];
2018
+ 403: components["responses"]["ScopeDenied"];
2019
+ 404: components["responses"]["NotFound"];
2020
+ };
2021
+ };
2022
+ listAssignments: {
2023
+ parameters: {
2024
+ query?: {
2025
+ page_size?: components["parameters"]["PageSize"];
2026
+ page_token?: components["parameters"]["PageToken"];
2027
+ };
2028
+ header?: never;
2029
+ path: {
2030
+ class_id: components["parameters"]["ClassId"];
2031
+ };
2032
+ cookie?: never;
2033
+ };
2034
+ requestBody?: never;
2035
+ responses: {
2036
+ /** @description OK */
2037
+ 200: {
2038
+ headers: {
2039
+ [name: string]: unknown;
2040
+ };
2041
+ content: {
2042
+ "application/json": components["schemas"]["PageMeta"] & {
2043
+ items: components["schemas"]["OpenAssignment"][];
2044
+ };
2045
+ };
2046
+ };
2047
+ 401: components["responses"]["Unauthenticated"];
2048
+ 403: components["responses"]["ScopeDenied"];
2049
+ 404: components["responses"]["NotFound"];
2050
+ };
2051
+ };
2052
+ createAssignment: {
2053
+ parameters: {
2054
+ query?: never;
2055
+ header?: never;
2056
+ path: {
2057
+ class_id: components["parameters"]["ClassId"];
2058
+ };
2059
+ cookie?: never;
2060
+ };
2061
+ requestBody: {
2062
+ content: {
2063
+ "application/json": {
2064
+ title: string;
2065
+ instructions?: string;
2066
+ /** Format: date-time */
2067
+ due_at?: string | null;
2068
+ /** @default 100 */
2069
+ max_score?: number;
2070
+ /**
2071
+ * @description false 时留作草稿
2072
+ * @default true
2073
+ */
2074
+ publish?: boolean;
2075
+ };
2076
+ };
2077
+ };
2078
+ responses: {
2079
+ /** @description Created */
2080
+ 201: {
2081
+ headers: {
2082
+ [name: string]: unknown;
2083
+ };
2084
+ content: {
2085
+ "application/json": components["schemas"]["OpenAssignment"];
2086
+ };
2087
+ };
2088
+ 400: components["responses"]["ValidationFailed"];
2089
+ 401: components["responses"]["Unauthenticated"];
2090
+ 403: components["responses"]["ScopeDenied"];
2091
+ 404: components["responses"]["NotFound"];
2092
+ };
2093
+ };
2094
+ listSubmissions: {
2095
+ parameters: {
2096
+ query?: {
2097
+ page_size?: components["parameters"]["PageSize"];
2098
+ page_token?: components["parameters"]["PageToken"];
2099
+ };
2100
+ header?: never;
2101
+ path: {
2102
+ class_id: components["parameters"]["ClassId"];
2103
+ assignment_id: components["parameters"]["AssignmentId"];
2104
+ };
2105
+ cookie?: never;
2106
+ };
2107
+ requestBody?: never;
2108
+ responses: {
2109
+ /** @description OK */
2110
+ 200: {
2111
+ headers: {
2112
+ [name: string]: unknown;
2113
+ };
2114
+ content: {
2115
+ "application/json": components["schemas"]["PageMeta"] & {
2116
+ items: components["schemas"]["OpenSubmission"][];
2117
+ };
2118
+ };
2119
+ };
2120
+ 401: components["responses"]["Unauthenticated"];
2121
+ 403: components["responses"]["ScopeDenied"];
2122
+ 404: components["responses"]["NotFound"];
2123
+ };
2124
+ };
2125
+ setSubmissionScore: {
2126
+ parameters: {
2127
+ query?: never;
2128
+ header?: never;
2129
+ path: {
2130
+ class_id: components["parameters"]["ClassId"];
2131
+ assignment_id: components["parameters"]["AssignmentId"];
2132
+ open_id: components["parameters"]["OpenIdPath"];
2133
+ };
2134
+ cookie?: never;
2135
+ };
2136
+ requestBody: {
2137
+ content: {
2138
+ "application/json": {
2139
+ score: number;
2140
+ feedback?: string;
2141
+ };
2142
+ };
2143
+ };
2144
+ responses: {
2145
+ /** @description OK */
2146
+ 200: {
2147
+ headers: {
2148
+ [name: string]: unknown;
2149
+ };
2150
+ content: {
2151
+ "application/json": components["schemas"]["OpenSubmission"];
2152
+ };
2153
+ };
2154
+ 400: components["responses"]["ValidationFailed"];
2155
+ 401: components["responses"]["Unauthenticated"];
2156
+ 403: components["responses"]["ScopeDenied"];
2157
+ 404: components["responses"]["NotFound"];
2158
+ };
2159
+ };
2160
+ exportClassGrades: {
2161
+ parameters: {
2162
+ query?: {
2163
+ page_size?: components["parameters"]["PageSize"];
2164
+ page_token?: components["parameters"]["PageToken"];
2165
+ };
2166
+ header?: never;
2167
+ path: {
2168
+ class_id: components["parameters"]["ClassId"];
2169
+ };
2170
+ cookie?: never;
2171
+ };
2172
+ requestBody?: never;
2173
+ responses: {
2174
+ /** @description OK */
2175
+ 200: {
2176
+ headers: {
2177
+ [name: string]: unknown;
2178
+ };
2179
+ content: {
2180
+ "application/json": components["schemas"]["PageMeta"] & {
2181
+ items: components["schemas"]["GradeRow"][];
2182
+ };
2183
+ };
2184
+ };
2185
+ 401: components["responses"]["Unauthenticated"];
2186
+ 403: components["responses"]["ScopeDenied"];
2187
+ 404: components["responses"]["NotFound"];
2188
+ };
2189
+ };
2190
+ listCourses: {
2191
+ parameters: {
2192
+ query?: {
2193
+ page_size?: components["parameters"]["PageSize"];
2194
+ page_token?: components["parameters"]["PageToken"];
2195
+ };
2196
+ header?: never;
2197
+ path?: never;
2198
+ cookie?: never;
2199
+ };
2200
+ requestBody?: never;
2201
+ responses: {
2202
+ /** @description OK */
2203
+ 200: {
2204
+ headers: {
2205
+ [name: string]: unknown;
2206
+ };
2207
+ content: {
2208
+ "application/json": components["schemas"]["PageMeta"] & {
2209
+ items: components["schemas"]["OpenCourse"][];
2210
+ };
2211
+ };
2212
+ };
2213
+ 401: components["responses"]["Unauthenticated"];
2214
+ 403: components["responses"]["ScopeDenied"];
2215
+ };
2216
+ };
2217
+ getCourseOutline: {
2218
+ parameters: {
2219
+ query?: never;
2220
+ header?: never;
2221
+ path: {
2222
+ course_id: components["parameters"]["CourseId"];
2223
+ };
2224
+ cookie?: never;
2225
+ };
2226
+ requestBody?: never;
2227
+ responses: {
2228
+ /** @description OK */
2229
+ 200: {
2230
+ headers: {
2231
+ [name: string]: unknown;
2232
+ };
2233
+ content: {
2234
+ "application/json": components["schemas"]["CourseOutline"];
2235
+ };
2236
+ };
2237
+ 401: components["responses"]["Unauthenticated"];
2238
+ 403: components["responses"]["ScopeDenied"];
2239
+ 404: components["responses"]["NotFound"];
2240
+ };
2241
+ };
2242
+ updateCourseOutline: {
2243
+ parameters: {
2244
+ query?: never;
2245
+ header?: never;
2246
+ path: {
2247
+ course_id: components["parameters"]["CourseId"];
2248
+ };
2249
+ cookie?: never;
2250
+ };
2251
+ requestBody: {
2252
+ content: {
2253
+ "application/json": {
2254
+ title?: string;
2255
+ summary?: string;
2256
+ };
2257
+ };
2258
+ };
2259
+ responses: {
2260
+ /** @description OK */
2261
+ 200: {
2262
+ headers: {
2263
+ [name: string]: unknown;
2264
+ };
2265
+ content: {
2266
+ "application/json": components["schemas"]["CourseOutline"];
2267
+ };
2268
+ };
2269
+ 400: components["responses"]["ValidationFailed"];
2270
+ 401: components["responses"]["Unauthenticated"];
2271
+ 403: components["responses"]["ScopeDenied"];
2272
+ 404: components["responses"]["NotFound"];
2273
+ };
2274
+ };
2275
+ listCourseProgress: {
2276
+ parameters: {
2277
+ query?: {
2278
+ page_size?: components["parameters"]["PageSize"];
2279
+ page_token?: components["parameters"]["PageToken"];
2280
+ };
2281
+ header?: never;
2282
+ path: {
2283
+ course_id: components["parameters"]["CourseId"];
2284
+ };
2285
+ cookie?: never;
2286
+ };
2287
+ requestBody?: never;
2288
+ responses: {
2289
+ /** @description OK */
2290
+ 200: {
2291
+ headers: {
2292
+ [name: string]: unknown;
2293
+ };
2294
+ content: {
2295
+ "application/json": components["schemas"]["PageMeta"] & {
2296
+ items: components["schemas"]["CourseProgress"][];
2297
+ /** @description 有别的区没回答(它的学员这次缺席) */
2298
+ partial?: boolean;
2299
+ };
2300
+ };
2301
+ };
2302
+ 401: components["responses"]["Unauthenticated"];
2303
+ 403: components["responses"]["ScopeDenied"];
2304
+ 404: components["responses"]["NotFound"];
2305
+ };
2306
+ };
2307
+ sendBotMessage: {
2308
+ parameters: {
2309
+ query?: never;
2310
+ header?: never;
2311
+ path?: never;
2312
+ cookie?: never;
2313
+ };
2314
+ requestBody: {
2315
+ content: {
2316
+ "application/json": components["schemas"]["BotMessage"];
2317
+ };
2318
+ };
2319
+ responses: {
2320
+ /** @description 已发出 */
2321
+ 201: {
2322
+ headers: {
2323
+ [name: string]: unknown;
2324
+ };
2325
+ content: {
2326
+ "application/json": {
2327
+ message_id: string;
2328
+ };
2329
+ };
2330
+ };
2331
+ 400: components["responses"]["ValidationFailed"];
2332
+ 401: components["responses"]["Unauthenticated"];
2333
+ 403: components["responses"]["ScopeDenied"];
2334
+ 404: components["responses"]["NotFound"];
2335
+ };
2336
+ };
2337
+ listBotChats: {
2338
+ parameters: {
2339
+ query?: {
2340
+ page_size?: components["parameters"]["PageSize"];
2341
+ page_token?: components["parameters"]["PageToken"];
2342
+ };
2343
+ header?: never;
2344
+ path?: never;
2345
+ cookie?: never;
2346
+ };
2347
+ requestBody?: never;
2348
+ responses: {
2349
+ /** @description OK */
2350
+ 200: {
2351
+ headers: {
2352
+ [name: string]: unknown;
2353
+ };
2354
+ content: {
2355
+ "application/json": components["schemas"]["PageMeta"] & {
2356
+ items: components["schemas"]["BotChat"][];
2357
+ };
2358
+ };
2359
+ };
2360
+ 401: components["responses"]["Unauthenticated"];
2361
+ 403: components["responses"]["ScopeDenied"];
2362
+ };
2363
+ };
2364
+ sendNotification: {
2365
+ parameters: {
2366
+ query?: never;
2367
+ header?: never;
2368
+ path?: never;
2369
+ cookie?: never;
2370
+ };
2371
+ requestBody: {
2372
+ content: {
2373
+ "application/json": {
2374
+ open_ids: components["schemas"]["OpenId"][];
2375
+ title: string;
2376
+ body?: string;
2377
+ /**
2378
+ * Format: uri
2379
+ * @description 必须在应用登记的可信域名里(否则 400)。通知卡片上出现「打开 xx 应用」按钮,点了在应用的容器里打开这个地址
2380
+ * (桌面端、手机走免登桥;`ChatSystemNotice.action`)。
2381
+ */
2382
+ link?: string;
2383
+ };
2384
+ };
2385
+ };
2386
+ responses: {
2387
+ /** @description 已接收(不是本机构成员的 open_id 跳过,列在 skipped 里) */
2388
+ 202: {
2389
+ headers: {
2390
+ [name: string]: unknown;
2391
+ };
2392
+ content: {
2393
+ "application/json": {
2394
+ sent: number;
2395
+ skipped: components["schemas"]["OpenId"][];
2396
+ };
2397
+ };
2398
+ };
2399
+ 400: components["responses"]["ValidationFailed"];
2400
+ 401: components["responses"]["Unauthenticated"];
2401
+ 403: components["responses"]["ScopeDenied"];
2402
+ };
2403
+ };
2404
+ listClassRecordings: {
2405
+ parameters: {
2406
+ query?: {
2407
+ page_size?: components["parameters"]["PageSize"];
2408
+ page_token?: components["parameters"]["PageToken"];
2409
+ };
2410
+ header?: never;
2411
+ path: {
2412
+ class_id: components["parameters"]["ClassId"];
2413
+ };
2414
+ cookie?: never;
2415
+ };
2416
+ requestBody?: never;
2417
+ responses: {
2418
+ /** @description OK */
2419
+ 200: {
2420
+ headers: {
2421
+ [name: string]: unknown;
2422
+ };
2423
+ content: {
2424
+ "application/json": components["schemas"]["PageMeta"] & {
2425
+ items: components["schemas"]["OpenRecording"][];
2426
+ };
2427
+ };
2428
+ };
2429
+ 401: components["responses"]["Unauthenticated"];
2430
+ 403: components["responses"]["ScopeDenied"];
2431
+ 404: components["responses"]["NotFound"];
2432
+ };
2433
+ };
2434
+ listTenantEvents: {
2435
+ parameters: {
2436
+ query?: {
2437
+ page_size?: components["parameters"]["PageSize"];
2438
+ page_token?: components["parameters"]["PageToken"];
2439
+ };
2440
+ header?: never;
2441
+ path?: never;
2442
+ cookie?: never;
2443
+ };
2444
+ requestBody?: never;
2445
+ responses: {
2446
+ /** @description OK */
2447
+ 200: {
2448
+ headers: {
2449
+ [name: string]: unknown;
2450
+ };
2451
+ content: {
2452
+ "application/json": components["schemas"]["PageMeta"] & {
2453
+ items: components["schemas"]["OpenEvent"][];
2454
+ };
2455
+ };
2456
+ };
2457
+ 401: components["responses"]["Unauthenticated"];
2458
+ 403: components["responses"]["ScopeDenied"];
2459
+ };
2460
+ };
2461
+ createTenantEvent: {
2462
+ parameters: {
2463
+ query?: never;
2464
+ header?: never;
2465
+ path?: never;
2466
+ cookie?: never;
2467
+ };
2468
+ requestBody: {
2469
+ content: {
2470
+ "application/json": components["schemas"]["OpenEventCreate"];
2471
+ };
2472
+ };
2473
+ responses: {
2474
+ /** @description Created */
2475
+ 201: {
2476
+ headers: {
2477
+ [name: string]: unknown;
2478
+ };
2479
+ content: {
2480
+ "application/json": components["schemas"]["OpenEvent"];
2481
+ };
2482
+ };
2483
+ 400: components["responses"]["ValidationFailed"];
2484
+ 401: components["responses"]["Unauthenticated"];
2485
+ 403: components["responses"]["ScopeDenied"];
2486
+ 409: components["responses"]["Conflict"];
2487
+ };
2488
+ };
2489
+ updateTenantEvent: {
2490
+ parameters: {
2491
+ query?: never;
2492
+ header?: never;
2493
+ path: {
2494
+ event_id: components["parameters"]["EventId"];
2495
+ };
2496
+ cookie?: never;
2497
+ };
2498
+ requestBody: {
2499
+ content: {
2500
+ "application/json": components["schemas"]["OpenEventPatch"];
2501
+ };
2502
+ };
2503
+ responses: {
2504
+ /** @description OK */
2505
+ 200: {
2506
+ headers: {
2507
+ [name: string]: unknown;
2508
+ };
2509
+ content: {
2510
+ "application/json": components["schemas"]["OpenEvent"];
2511
+ };
2512
+ };
2513
+ 400: components["responses"]["ValidationFailed"];
2514
+ 401: components["responses"]["Unauthenticated"];
2515
+ 403: components["responses"]["ScopeDenied"];
2516
+ 404: components["responses"]["NotFound"];
2517
+ 409: components["responses"]["Conflict"];
2518
+ };
2519
+ };
2520
+ listEventRegistrations: {
2521
+ parameters: {
2522
+ query?: {
2523
+ page_size?: components["parameters"]["PageSize"];
2524
+ page_token?: components["parameters"]["PageToken"];
2525
+ };
2526
+ header?: never;
2527
+ path: {
2528
+ event_id: components["parameters"]["EventId"];
2529
+ };
2530
+ cookie?: never;
2531
+ };
2532
+ requestBody?: never;
2533
+ responses: {
2534
+ /** @description OK */
2535
+ 200: {
2536
+ headers: {
2537
+ [name: string]: unknown;
2538
+ };
2539
+ content: {
2540
+ "application/json": components["schemas"]["PageMeta"] & {
2541
+ items: components["schemas"]["EventRegistration"][];
2542
+ };
2543
+ };
2544
+ };
2545
+ 401: components["responses"]["Unauthenticated"];
2546
+ 403: components["responses"]["ScopeDenied"];
2547
+ 404: components["responses"]["NotFound"];
2548
+ };
2549
+ };
2550
+ listTenantJobs: {
2551
+ parameters: {
2552
+ query?: {
2553
+ page_size?: components["parameters"]["PageSize"];
2554
+ page_token?: components["parameters"]["PageToken"];
2555
+ };
2556
+ header?: never;
2557
+ path?: never;
2558
+ cookie?: never;
2559
+ };
2560
+ requestBody?: never;
2561
+ responses: {
2562
+ /** @description OK */
2563
+ 200: {
2564
+ headers: {
2565
+ [name: string]: unknown;
2566
+ };
2567
+ content: {
2568
+ "application/json": components["schemas"]["PageMeta"] & {
2569
+ items: components["schemas"]["OpenJob"][];
2570
+ };
2571
+ };
2572
+ };
2573
+ 401: components["responses"]["Unauthenticated"];
2574
+ 403: components["responses"]["ScopeDenied"];
2575
+ };
2576
+ };
2577
+ createTenantJob: {
2578
+ parameters: {
2579
+ query?: never;
2580
+ header?: never;
2581
+ path?: never;
2582
+ cookie?: never;
2583
+ };
2584
+ requestBody: {
2585
+ content: {
2586
+ "application/json": components["schemas"]["OpenJobBody"];
2587
+ };
2588
+ };
2589
+ responses: {
2590
+ /** @description Created */
2591
+ 201: {
2592
+ headers: {
2593
+ [name: string]: unknown;
2594
+ };
2595
+ content: {
2596
+ "application/json": components["schemas"]["OpenJob"];
2597
+ };
2598
+ };
2599
+ 400: components["responses"]["ValidationFailed"];
2600
+ 401: components["responses"]["Unauthenticated"];
2601
+ 403: components["responses"]["ScopeDenied"];
2602
+ };
2603
+ };
2604
+ listJobCandidates: {
2605
+ parameters: {
2606
+ query?: {
2607
+ page_size?: components["parameters"]["PageSize"];
2608
+ page_token?: components["parameters"]["PageToken"];
2609
+ };
2610
+ header?: never;
2611
+ path: {
2612
+ job_id: components["parameters"]["JobIdPath"];
2613
+ };
2614
+ cookie?: never;
2615
+ };
2616
+ requestBody?: never;
2617
+ responses: {
2618
+ /** @description OK */
2619
+ 200: {
2620
+ headers: {
2621
+ [name: string]: unknown;
2622
+ };
2623
+ content: {
2624
+ "application/json": components["schemas"]["PageMeta"] & {
2625
+ items: components["schemas"]["JobCandidate"][];
2626
+ };
2627
+ };
2628
+ };
2629
+ 401: components["responses"]["Unauthenticated"];
2630
+ 403: components["responses"]["ScopeDenied"];
2631
+ 404: components["responses"]["NotFound"];
2632
+ };
2633
+ };
2634
+ listTrialVenues: {
2635
+ parameters: {
2636
+ query?: {
2637
+ page_size?: components["parameters"]["PageSize"];
2638
+ page_token?: components["parameters"]["PageToken"];
2639
+ };
2640
+ header?: never;
2641
+ path?: never;
2642
+ cookie?: never;
2643
+ };
2644
+ requestBody?: never;
2645
+ responses: {
2646
+ /** @description OK */
2647
+ 200: {
2648
+ headers: {
2649
+ [name: string]: unknown;
2650
+ };
2651
+ content: {
2652
+ "application/json": components["schemas"]["PageMeta"] & {
2653
+ items: components["schemas"]["TrialVenue"][];
2654
+ };
2655
+ };
2656
+ };
2657
+ 401: components["responses"]["Unauthenticated"];
2658
+ 403: components["responses"]["ScopeDenied"];
2659
+ };
2660
+ };
2661
+ listTrialSlots: {
2662
+ parameters: {
2663
+ query?: {
2664
+ venue_id?: string;
2665
+ include_past?: boolean;
2666
+ page_size?: components["parameters"]["PageSize"];
2667
+ page_token?: components["parameters"]["PageToken"];
2668
+ };
2669
+ header?: never;
2670
+ path?: never;
2671
+ cookie?: never;
2672
+ };
2673
+ requestBody?: never;
2674
+ responses: {
2675
+ /** @description OK */
2676
+ 200: {
2677
+ headers: {
2678
+ [name: string]: unknown;
2679
+ };
2680
+ content: {
2681
+ "application/json": components["schemas"]["PageMeta"] & {
2682
+ items: components["schemas"]["TrialSlot"][];
2683
+ };
2684
+ };
2685
+ };
2686
+ 401: components["responses"]["Unauthenticated"];
2687
+ 403: components["responses"]["ScopeDenied"];
2688
+ };
2689
+ };
2690
+ createTrialSlots: {
2691
+ parameters: {
2692
+ query?: never;
2693
+ header?: never;
2694
+ path?: never;
2695
+ cookie?: never;
2696
+ };
2697
+ requestBody: {
2698
+ content: {
2699
+ "application/json": {
2700
+ /** Format: uuid */
2701
+ venue_id: string;
2702
+ /** Format: date-time */
2703
+ starts_at: string;
2704
+ duration_minutes: number;
2705
+ capacity: number;
2706
+ course_title: string;
2707
+ /** @default 0 */
2708
+ repeat_weeks?: number;
2709
+ };
2710
+ };
2711
+ };
2712
+ responses: {
2713
+ /** @description Created */
2714
+ 201: {
2715
+ headers: {
2716
+ [name: string]: unknown;
2717
+ };
2718
+ content: {
2719
+ "application/json": {
2720
+ items: components["schemas"]["TrialSlot"][];
2721
+ };
2722
+ };
2723
+ };
2724
+ 400: components["responses"]["ValidationFailed"];
2725
+ 401: components["responses"]["Unauthenticated"];
2726
+ 403: components["responses"]["ScopeDenied"];
2727
+ 409: components["responses"]["Conflict"];
2728
+ };
2729
+ };
2730
+ cancelTrialSlot: {
2731
+ parameters: {
2732
+ query?: never;
2733
+ header?: never;
2734
+ path: {
2735
+ slot_id: string;
2736
+ };
2737
+ cookie?: never;
2738
+ };
2739
+ requestBody?: {
2740
+ content: {
2741
+ "application/json": {
2742
+ reason?: string;
2743
+ };
2744
+ };
2745
+ };
2746
+ responses: {
2747
+ /** @description OK */
2748
+ 200: {
2749
+ headers: {
2750
+ [name: string]: unknown;
2751
+ };
2752
+ content: {
2753
+ "application/json": components["schemas"]["TrialSlot"];
2754
+ };
2755
+ };
2756
+ 401: components["responses"]["Unauthenticated"];
2757
+ 403: components["responses"]["ScopeDenied"];
2758
+ 404: components["responses"]["NotFound"];
2759
+ };
2760
+ };
2761
+ listTrialBookings: {
2762
+ parameters: {
2763
+ query?: {
2764
+ status?: "pending" | "confirmed" | "cancelled" | "reschedule_proposed" | "attended" | "expired";
2765
+ page_size?: components["parameters"]["PageSize"];
2766
+ page_token?: components["parameters"]["PageToken"];
2767
+ };
2768
+ header?: never;
2769
+ path?: never;
2770
+ cookie?: never;
2771
+ };
2772
+ requestBody?: never;
2773
+ responses: {
2774
+ /** @description OK */
2775
+ 200: {
2776
+ headers: {
2777
+ [name: string]: unknown;
2778
+ };
2779
+ content: {
2780
+ "application/json": components["schemas"]["PageMeta"] & {
2781
+ items: components["schemas"]["TrialBooking"][];
2782
+ };
2783
+ };
2784
+ };
2785
+ 401: components["responses"]["Unauthenticated"];
2786
+ 403: components["responses"]["ScopeDenied"];
2787
+ };
2788
+ };
2789
+ confirmTrialBooking: {
2790
+ parameters: {
2791
+ query?: never;
2792
+ header?: never;
2793
+ path: {
2794
+ booking_id: components["parameters"]["BookingId"];
2795
+ };
2796
+ cookie?: never;
2797
+ };
2798
+ requestBody?: never;
2799
+ responses: {
2800
+ /** @description OK */
2801
+ 200: {
2802
+ headers: {
2803
+ [name: string]: unknown;
2804
+ };
2805
+ content: {
2806
+ "application/json": components["schemas"]["TrialBooking"];
2807
+ };
2808
+ };
2809
+ 401: components["responses"]["Unauthenticated"];
2810
+ 403: components["responses"]["ScopeDenied"];
2811
+ 404: components["responses"]["NotFound"];
2812
+ 409: components["responses"]["Conflict"];
2813
+ };
2814
+ };
2815
+ listTradeOrders: {
2816
+ parameters: {
2817
+ query?: {
2818
+ status?: string;
2819
+ page_size?: components["parameters"]["PageSize"];
2820
+ page_token?: components["parameters"]["PageToken"];
2821
+ };
2822
+ header?: never;
2823
+ path?: never;
2824
+ cookie?: never;
2825
+ };
2826
+ requestBody?: never;
2827
+ responses: {
2828
+ /** @description OK */
2829
+ 200: {
2830
+ headers: {
2831
+ [name: string]: unknown;
2832
+ };
2833
+ content: {
2834
+ "application/json": components["schemas"]["PageMeta"] & {
2835
+ items: components["schemas"]["TradeOrder"][];
2836
+ };
2837
+ };
2838
+ };
2839
+ 401: components["responses"]["Unauthenticated"];
2840
+ 403: components["responses"]["ScopeDenied"];
2841
+ };
2842
+ };
2843
+ listTenantReviews: {
2844
+ parameters: {
2845
+ query?: {
2846
+ page_size?: components["parameters"]["PageSize"];
2847
+ page_token?: components["parameters"]["PageToken"];
2848
+ };
2849
+ header?: never;
2850
+ path?: never;
2851
+ cookie?: never;
2852
+ };
2853
+ requestBody?: never;
2854
+ responses: {
2855
+ /** @description OK */
2856
+ 200: {
2857
+ headers: {
2858
+ [name: string]: unknown;
2859
+ };
2860
+ content: {
2861
+ "application/json": components["schemas"]["PageMeta"] & {
2862
+ items: components["schemas"]["OpenReview"][];
2863
+ };
2864
+ };
2865
+ };
2866
+ 401: components["responses"]["Unauthenticated"];
2867
+ 403: components["responses"]["ScopeDenied"];
2868
+ };
2869
+ };
2870
+ replyReview: {
2871
+ parameters: {
2872
+ query?: never;
2873
+ header?: never;
2874
+ path: {
2875
+ review_id: string;
2876
+ };
2877
+ cookie?: never;
2878
+ };
2879
+ requestBody: {
2880
+ content: {
2881
+ "application/json": {
2882
+ body: string;
2883
+ };
2884
+ };
2885
+ };
2886
+ responses: {
2887
+ /** @description 已提交 */
2888
+ 201: {
2889
+ headers: {
2890
+ [name: string]: unknown;
2891
+ };
2892
+ content?: never;
2893
+ };
2894
+ 400: components["responses"]["ValidationFailed"];
2895
+ 401: components["responses"]["Unauthenticated"];
2896
+ 403: components["responses"]["ScopeDenied"];
2897
+ 404: components["responses"]["NotFound"];
2898
+ 409: components["responses"]["Conflict"];
2899
+ };
2900
+ };
2901
+ listPublicContent: {
2902
+ parameters: {
2903
+ query?: {
2904
+ q?: string;
2905
+ page_size?: components["parameters"]["PageSize"];
2906
+ page_token?: components["parameters"]["PageToken"];
2907
+ };
2908
+ header?: never;
2909
+ path: {
2910
+ kind: "courses" | "events" | "jobs";
2911
+ };
2912
+ cookie?: never;
2913
+ };
2914
+ requestBody?: never;
2915
+ responses: {
2916
+ /** @description OK */
2917
+ 200: {
2918
+ headers: {
2919
+ /** @description 今天这一种还能取多少条 */
2920
+ "X-Daily-Quota-Remaining"?: number;
2921
+ [name: string]: unknown;
2922
+ };
2923
+ content: {
2924
+ "application/json": components["schemas"]["PageMeta"] & {
2925
+ items: components["schemas"]["PublicContent"][];
2926
+ };
2927
+ };
2928
+ };
2929
+ 401: components["responses"]["Unauthenticated"];
2930
+ 429: components["responses"]["RateLimited"];
2931
+ };
2932
+ };
2933
+ getUserInterests: {
2934
+ parameters: {
2935
+ query?: never;
2936
+ header?: never;
2937
+ path?: never;
2938
+ cookie?: never;
2939
+ };
2940
+ requestBody?: never;
2941
+ responses: {
2942
+ /** @description OK */
2943
+ 200: {
2944
+ headers: {
2945
+ [name: string]: unknown;
2946
+ };
2947
+ content: {
2948
+ "application/json": components["schemas"]["InterestProfile"];
2949
+ };
2950
+ };
2951
+ 401: components["responses"]["Unauthenticated"];
2952
+ 403: components["responses"]["ScopeDenied"];
2953
+ };
2954
+ };
2955
+ addInterestSignal: {
2956
+ parameters: {
2957
+ query?: never;
2958
+ header?: never;
2959
+ path?: never;
2960
+ cookie?: never;
2961
+ };
2962
+ requestBody: {
2963
+ content: {
2964
+ "application/json": {
2965
+ /** @description 话题(和社区话题同一套写法,例如「商务中文」) */
2966
+ topic: string;
2967
+ /** @default 0.5 */
2968
+ weight?: number;
2969
+ /** @description 给用户看的来源说明,例如「在 xx 里常学商务中文」 */
2970
+ reason: string;
2971
+ };
2972
+ };
2973
+ };
2974
+ responses: {
2975
+ /** @description OK */
2976
+ 201: {
2977
+ headers: {
2978
+ [name: string]: unknown;
2979
+ };
2980
+ content: {
2981
+ "application/json": {
2982
+ accepted: boolean;
2983
+ signal_id?: string;
2984
+ };
2985
+ };
2986
+ };
2987
+ 400: components["responses"]["ValidationFailed"];
2988
+ 401: components["responses"]["Unauthenticated"];
2989
+ 403: components["responses"]["ScopeDenied"];
2990
+ };
2991
+ };
2992
+ getUserLearningProfile: {
2993
+ parameters: {
2994
+ query?: never;
2995
+ header?: never;
2996
+ path?: never;
2997
+ cookie?: never;
2998
+ };
2999
+ requestBody?: never;
3000
+ responses: {
3001
+ /** @description OK */
3002
+ 200: {
3003
+ headers: {
3004
+ [name: string]: unknown;
3005
+ };
3006
+ content: {
3007
+ "application/json": components["schemas"]["LearningProfile"];
3008
+ };
3009
+ };
3010
+ 401: components["responses"]["Unauthenticated"];
3011
+ 403: components["responses"]["ScopeDenied"];
3012
+ };
3013
+ };
3014
+ reportOnBehalf: {
3015
+ parameters: {
3016
+ query?: never;
3017
+ header?: never;
3018
+ path?: never;
3019
+ cookie?: never;
3020
+ };
3021
+ requestBody: {
3022
+ content: {
3023
+ "application/json": {
3024
+ /** @description 公开内容 ID(`<区>:<种类>:<ID>`) */
3025
+ item_id: string;
3026
+ /**
3027
+ * @description 和平台举报的类别相同
3028
+ * @enum {string}
3029
+ */
3030
+ category: "illegal" | "hate" | "harassment" | "violence" | "sexual" | "minors" | "self_harm" | "spam" | "scam" | "misinformation" | "privacy" | "ip" | "other";
3031
+ details?: string;
3032
+ };
3033
+ };
3034
+ };
3035
+ responses: {
3036
+ /** @description 已提交 */
3037
+ 201: {
3038
+ headers: {
3039
+ [name: string]: unknown;
3040
+ };
3041
+ content?: never;
3042
+ };
3043
+ 400: components["responses"]["ValidationFailed"];
3044
+ 401: components["responses"]["Unauthenticated"];
3045
+ 403: components["responses"]["ScopeDenied"];
3046
+ 404: components["responses"]["NotFound"];
3047
+ };
3048
+ };
3049
+ onEvent: {
3050
+ parameters: {
3051
+ query?: never;
3052
+ header: {
3053
+ "X-Ich-Timestamp": string;
3054
+ "X-Ich-Nonce": string;
3055
+ "X-Ich-Signature": string;
3056
+ "X-Ich-Event-Id": string;
3057
+ };
3058
+ path?: never;
3059
+ cookie?: never;
3060
+ };
3061
+ requestBody: {
3062
+ content: {
3063
+ "application/json": components["schemas"]["EventEnvelope"] | components["schemas"]["EncryptedEnvelope"] | components["schemas"]["UrlVerification"];
3064
+ };
3065
+ };
3066
+ responses: {
3067
+ /** @description 收到 */
3068
+ 200: {
3069
+ headers: {
3070
+ [name: string]: unknown;
3071
+ };
3072
+ content?: never;
3073
+ };
3074
+ };
3075
+ };
3076
+ onCardAction: {
3077
+ parameters: {
3078
+ query?: never;
3079
+ header?: never;
3080
+ path?: never;
3081
+ cookie?: never;
3082
+ };
3083
+ requestBody: {
3084
+ content: {
3085
+ "application/json": components["schemas"]["CardActionEnvelope"];
3086
+ };
3087
+ };
3088
+ responses: {
3089
+ /** @description 收到 */
3090
+ 200: {
3091
+ headers: {
3092
+ [name: string]: unknown;
3093
+ };
3094
+ content: {
3095
+ "application/json": {
3096
+ card?: components["schemas"]["Card"];
3097
+ };
3098
+ };
3099
+ };
3100
+ };
3101
+ };
3102
+ }