@coda-console/protocol 1.7.0 → 1.9.0

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,920 @@
1
+ {
2
+ "description": "流程结构:支持的元素、事件位置、局部节点规则与属性位置。rules 对 structure.mjs 的无环节点投影运行 JSON Schema;跨节点引用、配对、可达性与生命周期等待由固定图检查负责。",
3
+ "unsupported": {
4
+ "bpmn:SendTask": "Coda 的消息是外部来的事件,流程只收不发;流程里互相通知用信号(signal)",
5
+ "bpmn:BusinessRuleTask": "Coda 不带决策表:判断写成网关的条件,或一个 scriptTask",
6
+ "bpmn:ComplexGateway": "引擎不运行复杂网关:写成包容网关,各出口带条件",
7
+ "bpmn:DataObject": "数据按任务结果与变量传递(见「表达式」),不写数据对象",
8
+ "bpmn:DataObjectReference": "数据按任务结果与变量传递(见「表达式」),不写数据对象",
9
+ "bpmn:DataStoreReference": "数据按任务结果与变量传递(见「表达式」),不写数据对象",
10
+ "bpmn:ImplicitThrowEvent": "它不是流程里的元素",
11
+ "bpmn:ChoreographyTask": "协作图的元素不在流程里运行",
12
+ "bpmn:SubChoreography": "协作图的元素不在流程里运行",
13
+ "bpmn:CallChoreography": "协作图的元素不在流程里运行"
14
+ },
15
+ "events": {
16
+ "start": [
17
+ "Message",
18
+ "Timer"
19
+ ],
20
+ "eventStart": [
21
+ "Message",
22
+ "Timer",
23
+ "Signal",
24
+ "Conditional",
25
+ "Error",
26
+ "Escalation"
27
+ ],
28
+ "innerStart": [],
29
+ "bpmn:EndEvent": [
30
+ "Error",
31
+ "Terminate",
32
+ "Signal",
33
+ "Escalation",
34
+ "Compensate",
35
+ "Cancel"
36
+ ],
37
+ "bpmn:IntermediateCatchEvent": [
38
+ "Timer",
39
+ "Message",
40
+ "Signal",
41
+ "Conditional",
42
+ "Link"
43
+ ],
44
+ "bpmn:IntermediateThrowEvent": [
45
+ "Signal",
46
+ "Escalation",
47
+ "Link",
48
+ "Compensate"
49
+ ],
50
+ "bpmn:BoundaryEvent": [
51
+ "Error",
52
+ "Timer",
53
+ "Message",
54
+ "Signal",
55
+ "Escalation",
56
+ "Conditional",
57
+ "Compensate",
58
+ "Cancel"
59
+ ]
60
+ },
61
+ "eventNames": {
62
+ "start": "流程的开始事件",
63
+ "eventStart": "事件子流程的开始事件",
64
+ "innerStart": "子流程的开始事件",
65
+ "bpmn:EndEvent": "结束事件",
66
+ "bpmn:IntermediateCatchEvent": "中间捕获事件",
67
+ "bpmn:IntermediateThrowEvent": "中间抛出事件",
68
+ "bpmn:BoundaryEvent": "边界事件"
69
+ },
70
+ "kindNames": {
71
+ "Message": "消息",
72
+ "Timer": "计时器",
73
+ "Signal": "信号",
74
+ "Conditional": "条件",
75
+ "Error": "出错",
76
+ "Escalation": "升级",
77
+ "Terminate": "终止",
78
+ "Link": "连接",
79
+ "Compensate": "补偿",
80
+ "Cancel": "取消"
81
+ },
82
+ "topLevel": [
83
+ "bpmn:Process",
84
+ "bpmn:Error",
85
+ "bpmn:Signal",
86
+ "bpmn:Escalation",
87
+ "bpmn:Message"
88
+ ],
89
+ "id": {
90
+ "pattern": "^[A-Za-z_][A-Za-z0-9_-]{0,63}$",
91
+ "description": "id 须为字母开头的字母、数字、「_」「-」"
92
+ },
93
+ "requiredEvents": [
94
+ "eventStart",
95
+ "bpmn:IntermediateCatchEvent",
96
+ "bpmn:BoundaryEvent"
97
+ ],
98
+ "eventSuffix": {
99
+ "start": ";运行里发生的信号、条件、出错或升级,交给事件子流程(triggeredByEvent)",
100
+ "innerStart": ";只有最外层的开始事件能带计时器或消息,子流程里要等事件,用中间捕获事件或事件子流程"
101
+ },
102
+ "throwing": [
103
+ "bpmn:IntermediateThrowEvent",
104
+ "bpmn:EndEvent"
105
+ ],
106
+ "steps": [
107
+ "bpmn:ScriptTask",
108
+ "bpmn:ServiceTask",
109
+ "bpmn:UserTask",
110
+ "bpmn:CallActivity"
111
+ ],
112
+ "maxScripts": 50,
113
+ "schedule": {
114
+ "maxLength": 200,
115
+ "minMilliseconds": 300000,
116
+ "settingsPattern": "^\\s*=\\s*vars(\\.[A-Za-z0-9_-]+)+\\s*$",
117
+ "description": "定时开始只接受无限重复、无结束时间、间隔至少 5 分钟;表达式只读插件设置。"
118
+ },
119
+ "lifecycle": {
120
+ "waitTypes": [
121
+ "bpmn:ReceiveTask",
122
+ "bpmn:IntermediateCatchEvent",
123
+ "bpmn:CallActivity",
124
+ "bpmn:ScriptTask"
125
+ ],
126
+ "waitActions": [
127
+ "run-workflows"
128
+ ],
129
+ "description": "这些节点会等待;其余带计时边界的非子流程节点也会等待。生命周期流程的等待必须能收会话事实。"
130
+ },
131
+ "userMessages": {
132
+ "prefix": "user.",
133
+ "maxLabelLength": 40
134
+ },
135
+ "inputFields": [
136
+ "text",
137
+ "secret"
138
+ ],
139
+ "rules": [
140
+ {
141
+ "description": "coda:expect 只写在子流程上",
142
+ "schema": {
143
+ "properties": {
144
+ "subprocess": {
145
+ "const": true
146
+ }
147
+ }
148
+ },
149
+ "when": {
150
+ "required": [
151
+ "expect"
152
+ ]
153
+ }
154
+ },
155
+ {
156
+ "description": "coda:optional 只写在最外层的子流程上(事件子流程不是阶段)",
157
+ "schema": {
158
+ "allOf": [
159
+ {
160
+ "properties": {
161
+ "subprocess": {
162
+ "const": true
163
+ },
164
+ "top": {
165
+ "const": true
166
+ }
167
+ }
168
+ },
169
+ {
170
+ "not": {
171
+ "properties": {
172
+ "triggeredByEvent": {
173
+ "const": true
174
+ }
175
+ }
176
+ }
177
+ }
178
+ ]
179
+ },
180
+ "when": {
181
+ "required": [
182
+ "optional"
183
+ ]
184
+ }
185
+ },
186
+ {
187
+ "description": "coda:notify 只写在流程最外层的结束事件上",
188
+ "schema": {
189
+ "properties": {
190
+ "type": {
191
+ "const": "bpmn:EndEvent"
192
+ },
193
+ "top": {
194
+ "const": true
195
+ }
196
+ }
197
+ },
198
+ "when": {
199
+ "required": [
200
+ "notify"
201
+ ]
202
+ }
203
+ },
204
+ {
205
+ "description": "coda:reportTo、coda:reportOn、coda:scope 只写在定时开始事件上(由会话发起的运行交给发起它的会话)",
206
+ "schema": {
207
+ "properties": {
208
+ "position": {
209
+ "const": "start"
210
+ },
211
+ "eventKind": {
212
+ "const": "Timer"
213
+ }
214
+ }
215
+ },
216
+ "when": {
217
+ "anyOf": [
218
+ {
219
+ "required": [
220
+ "reportTo"
221
+ ]
222
+ },
223
+ {
224
+ "required": [
225
+ "reportOn"
226
+ ]
227
+ },
228
+ {
229
+ "required": [
230
+ "scope"
231
+ ]
232
+ }
233
+ ]
234
+ }
235
+ },
236
+ {
237
+ "description": "脚本步骤写成 <scriptTask scriptFormat=\"bash\">,脚本放在 <script> 里;serviceTask 只用于 coda:action",
238
+ "schema": {
239
+ "required": [
240
+ "action"
241
+ ]
242
+ },
243
+ "on": [
244
+ "bpmn:ServiceTask"
245
+ ],
246
+ "when": {
247
+ "properties": {
248
+ "hasScriptExtension": {
249
+ "const": true
250
+ }
251
+ }
252
+ }
253
+ },
254
+ {
255
+ "description": "serviceTask 是 Coda 自己做的一步,须写 coda:action;脚本步骤写成 scriptTask",
256
+ "schema": {
257
+ "required": [
258
+ "action"
259
+ ]
260
+ },
261
+ "on": [
262
+ "bpmn:ServiceTask"
263
+ ]
264
+ },
265
+ {
266
+ "description": "coda:action 的步骤由 Coda 执行,不写脚本与 coda:audience、coda:group、coda:timeout、coda:checkout、coda:retry 等(要为一段占组用 hold-group)",
267
+ "schema": {
268
+ "allOf": [
269
+ {
270
+ "properties": {
271
+ "hasScriptExtension": {
272
+ "const": false
273
+ }
274
+ }
275
+ },
276
+ {
277
+ "not": {
278
+ "anyOf": [
279
+ {
280
+ "required": [
281
+ "audience"
282
+ ]
283
+ },
284
+ {
285
+ "required": [
286
+ "group"
287
+ ]
288
+ },
289
+ {
290
+ "required": [
291
+ "timeout"
292
+ ]
293
+ },
294
+ {
295
+ "required": [
296
+ "cancelTimeout"
297
+ ]
298
+ },
299
+ {
300
+ "required": [
301
+ "workingDirectory"
302
+ ]
303
+ },
304
+ {
305
+ "required": [
306
+ "checkout"
307
+ ]
308
+ },
309
+ {
310
+ "required": [
311
+ "retry"
312
+ ]
313
+ },
314
+ {
315
+ "required": [
316
+ "implementation"
317
+ ],
318
+ "properties": {
319
+ "implementation": {
320
+ "minLength": 1
321
+ }
322
+ }
323
+ }
324
+ ]
325
+ }
326
+ }
327
+ ]
328
+ },
329
+ "on": [
330
+ "bpmn:ServiceTask"
331
+ ]
332
+ },
333
+ {
334
+ "description": "callActivity 的 calledElement 写要调用的能力或流程名(小写字母、数字和「-」,以字母开头)",
335
+ "schema": {
336
+ "required": [
337
+ "calledElement"
338
+ ],
339
+ "properties": {
340
+ "calledElement": {
341
+ "type": "string",
342
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
343
+ }
344
+ }
345
+ },
346
+ "on": [
347
+ "bpmn:CallActivity"
348
+ ]
349
+ },
350
+ {
351
+ "description": "scriptTask 写 scriptFormat=\"bash\"(脚本由 bash -e 执行)",
352
+ "schema": {
353
+ "required": [
354
+ "scriptFormat"
355
+ ],
356
+ "properties": {
357
+ "scriptFormat": {
358
+ "const": "bash"
359
+ }
360
+ }
361
+ },
362
+ "on": [
363
+ "bpmn:ScriptTask"
364
+ ]
365
+ },
366
+ {
367
+ "description": "脚本放在 scriptTask 的 <script> 里,不写 coda:script",
368
+ "schema": {
369
+ "properties": {
370
+ "hasScriptExtension": {
371
+ "const": false
372
+ }
373
+ }
374
+ },
375
+ "on": [
376
+ "bpmn:ScriptTask"
377
+ ]
378
+ },
379
+ {
380
+ "description": "scriptTask 需要 <script>",
381
+ "schema": {
382
+ "required": [
383
+ "script"
384
+ ],
385
+ "properties": {
386
+ "script": {
387
+ "pattern": "\\S"
388
+ }
389
+ }
390
+ },
391
+ "on": [
392
+ "bpmn:ScriptTask"
393
+ ]
394
+ },
395
+ {
396
+ "description": "脚本过长",
397
+ "schema": {
398
+ "properties": {
399
+ "script": {
400
+ "x-length": 20000
401
+ }
402
+ }
403
+ },
404
+ "on": [
405
+ "bpmn:ScriptTask"
406
+ ]
407
+ },
408
+ {
409
+ "description": "coda:output 只写在自动步骤与结束事件上",
410
+ "schema": {
411
+ "properties": {
412
+ "type": {
413
+ "enum": [
414
+ "bpmn:ScriptTask",
415
+ "bpmn:EndEvent"
416
+ ]
417
+ }
418
+ }
419
+ },
420
+ "when": {
421
+ "properties": {
422
+ "hasOutputs": {
423
+ "const": true
424
+ }
425
+ }
426
+ }
427
+ },
428
+ {
429
+ "description": "脚本步骤的 coda:output 只写 name,值由脚本写进 $GITHUB_OUTPUT",
430
+ "schema": {
431
+ "properties": {
432
+ "outputHasValue": {
433
+ "const": false
434
+ }
435
+ }
436
+ },
437
+ "on": [
438
+ "bpmn:ScriptTask"
439
+ ]
440
+ },
441
+ {
442
+ "description": "documentation 过长",
443
+ "schema": {
444
+ "properties": {
445
+ "documentation": {
446
+ "x-length": 4000
447
+ }
448
+ }
449
+ },
450
+ "on": [
451
+ "bpmn:UserTask"
452
+ ]
453
+ },
454
+ {
455
+ "description": "有输入字段(text、secret 或 coda:fields)的任务只交给用户,写 coda:assignee=\"user\"",
456
+ "schema": {
457
+ "required": [
458
+ "assignee"
459
+ ],
460
+ "properties": {
461
+ "assignee": {
462
+ "const": "user"
463
+ }
464
+ }
465
+ },
466
+ "on": [
467
+ "bpmn:UserTask"
468
+ ],
469
+ "when": {
470
+ "properties": {
471
+ "hasInputFields": {
472
+ "const": true
473
+ }
474
+ }
475
+ }
476
+ },
477
+ {
478
+ "description": "不支持标准循环(standardLoopCharacteristics):重复做一件事写成连回去的连线加网关,按集合或次数做多份写多实例",
479
+ "schema": {
480
+ "properties": {
481
+ "loopType": {
482
+ "const": "bpmn:MultiInstanceLoopCharacteristics"
483
+ }
484
+ }
485
+ },
486
+ "when": {
487
+ "required": [
488
+ "loopType"
489
+ ]
490
+ },
491
+ "at": "path"
492
+ },
493
+ {
494
+ "description": "多实例只写在任务、子流程与 callActivity 上",
495
+ "schema": {
496
+ "allOf": [
497
+ {
498
+ "properties": {
499
+ "type": {
500
+ "enum": [
501
+ "bpmn:Task",
502
+ "bpmn:ManualTask",
503
+ "bpmn:ScriptTask",
504
+ "bpmn:ServiceTask",
505
+ "bpmn:UserTask",
506
+ "bpmn:ReceiveTask",
507
+ "bpmn:CallActivity",
508
+ "bpmn:SubProcess",
509
+ "bpmn:Transaction",
510
+ "bpmn:AdHocSubProcess"
511
+ ]
512
+ }
513
+ }
514
+ },
515
+ {
516
+ "not": {
517
+ "properties": {
518
+ "triggeredByEvent": {
519
+ "const": true
520
+ }
521
+ }
522
+ }
523
+ }
524
+ ]
525
+ },
526
+ "when": {
527
+ "required": [
528
+ "loopType"
529
+ ]
530
+ },
531
+ "at": "path"
532
+ },
533
+ {
534
+ "description": "多实例要写做几份:coda:inputCollection(按集合,每份一个元素)或 loopCardinality(次数)",
535
+ "schema": {
536
+ "anyOf": [
537
+ {
538
+ "required": [
539
+ "collection"
540
+ ]
541
+ },
542
+ {
543
+ "required": [
544
+ "cardinality"
545
+ ]
546
+ }
547
+ ]
548
+ },
549
+ "when": {
550
+ "required": [
551
+ "loopType"
552
+ ]
553
+ },
554
+ "at": "path"
555
+ },
556
+ {
557
+ "description": "loopCardinality 写非负整数,或「=」开头的 FEEL 表达式",
558
+ "schema": {
559
+ "properties": {
560
+ "cardinality": {
561
+ "pattern": "^(?:\\s*=|\\d+$)"
562
+ }
563
+ }
564
+ },
565
+ "when": {
566
+ "required": [
567
+ "cardinality"
568
+ ]
569
+ },
570
+ "at": "path"
571
+ },
572
+ {
573
+ "description": "completionCondition 须为「=」开头的 FEEL 表达式,如 =deploy.ok",
574
+ "schema": {
575
+ "properties": {
576
+ "loopCompletion": {
577
+ "pattern": "^\\s*="
578
+ }
579
+ }
580
+ },
581
+ "when": {
582
+ "required": [
583
+ "loopCompletion"
584
+ ]
585
+ },
586
+ "at": "path"
587
+ },
588
+ {
589
+ "description": "completionCondition 须为「=」开头的 FEEL 表达式",
590
+ "schema": {
591
+ "properties": {
592
+ "completion": {
593
+ "pattern": "^\\s*="
594
+ }
595
+ }
596
+ },
597
+ "on": [
598
+ "bpmn:AdHocSubProcess"
599
+ ],
600
+ "when": {
601
+ "required": [
602
+ "completion"
603
+ ]
604
+ }
605
+ },
606
+ {
607
+ "description": "自由子流程里不写开始、结束事件:里面没有进线的节点都会开始",
608
+ "schema": {
609
+ "properties": {
610
+ "hasStartOrEnd": {
611
+ "const": false
612
+ }
613
+ }
614
+ },
615
+ "on": [
616
+ "bpmn:AdHocSubProcess"
617
+ ]
618
+ },
619
+ {
620
+ "description": "出错开始的事件子流程总是打断它所在的范围,不写 isInterrupting=\"false\"",
621
+ "schema": {
622
+ "not": {
623
+ "properties": {
624
+ "isInterrupting": {
625
+ "const": false
626
+ }
627
+ }
628
+ }
629
+ },
630
+ "when": {
631
+ "properties": {
632
+ "position": {
633
+ "const": "eventStart"
634
+ },
635
+ "eventKind": {
636
+ "const": "Error"
637
+ }
638
+ }
639
+ },
640
+ "at": "path"
641
+ },
642
+ {
643
+ "description": "事件子流程的计时器写 timeDuration 或 timeDate,从它所在的范围开始时算起",
644
+ "schema": {
645
+ "properties": {
646
+ "hasTimeCycle": {
647
+ "const": false
648
+ }
649
+ }
650
+ },
651
+ "when": {
652
+ "properties": {
653
+ "position": {
654
+ "const": "eventStart"
655
+ },
656
+ "eventKind": {
657
+ "const": "Timer"
658
+ }
659
+ }
660
+ },
661
+ "at": "path"
662
+ },
663
+ {
664
+ "description": "消息须引用一个有 name 的 <message>(name 是 Coda 的事件名,如 session.facts)",
665
+ "schema": {
666
+ "properties": {
667
+ "messageNamed": {
668
+ "const": true
669
+ }
670
+ }
671
+ },
672
+ "when": {
673
+ "properties": {
674
+ "eventKind": {
675
+ "const": "Message"
676
+ }
677
+ }
678
+ },
679
+ "at": "path"
680
+ },
681
+ {
682
+ "description": "receiveTask 须引用一个有 name 的 <message>(name 是 Coda 的事件名,如 session.facts)",
683
+ "schema": {
684
+ "properties": {
685
+ "messageNamed": {
686
+ "const": true
687
+ }
688
+ }
689
+ },
690
+ "on": [
691
+ "bpmn:ReceiveTask"
692
+ ],
693
+ "at": "path"
694
+ },
695
+ {
696
+ "description": "信号须引用一个 <signal>,抛出与捕获按它配对",
697
+ "schema": {
698
+ "properties": {
699
+ "signalReferenced": {
700
+ "const": true
701
+ }
702
+ }
703
+ },
704
+ "when": {
705
+ "properties": {
706
+ "eventKind": {
707
+ "const": "Signal"
708
+ }
709
+ }
710
+ },
711
+ "at": "path"
712
+ },
713
+ {
714
+ "description": "抛出的升级须引用一个 <escalation>",
715
+ "schema": {
716
+ "properties": {
717
+ "escalationReferenced": {
718
+ "const": true
719
+ }
720
+ }
721
+ },
722
+ "on": [
723
+ "bpmn:IntermediateThrowEvent",
724
+ "bpmn:EndEvent"
725
+ ],
726
+ "when": {
727
+ "properties": {
728
+ "eventKind": {
729
+ "const": "Escalation"
730
+ }
731
+ }
732
+ },
733
+ "at": "path"
734
+ },
735
+ {
736
+ "description": "连接事件须写 name,抛出与捕获按它配对",
737
+ "schema": {
738
+ "properties": {
739
+ "linkNamed": {
740
+ "const": true
741
+ }
742
+ }
743
+ },
744
+ "when": {
745
+ "properties": {
746
+ "eventKind": {
747
+ "const": "Link"
748
+ }
749
+ }
750
+ },
751
+ "at": "path"
752
+ },
753
+ {
754
+ "description": "条件只支持 FEEL 表达式,不运行脚本",
755
+ "schema": {
756
+ "properties": {
757
+ "conditionLanguage": {
758
+ "enum": [
759
+ "",
760
+ "feel"
761
+ ]
762
+ }
763
+ }
764
+ },
765
+ "when": {
766
+ "required": [
767
+ "conditionLanguage"
768
+ ]
769
+ },
770
+ "at": "path"
771
+ },
772
+ {
773
+ "description": "条件事件的条件须为「=」开头的 FEEL 表达式,如 =checks.passed",
774
+ "schema": {
775
+ "required": [
776
+ "condition"
777
+ ],
778
+ "properties": {
779
+ "condition": {
780
+ "pattern": "^\\s*="
781
+ }
782
+ }
783
+ },
784
+ "when": {
785
+ "properties": {
786
+ "eventKind": {
787
+ "const": "Conditional"
788
+ }
789
+ }
790
+ },
791
+ "at": "path"
792
+ },
793
+ {
794
+ "description": "条件须为「=」开头的 FEEL 表达式,如 =check.go",
795
+ "schema": {
796
+ "required": [
797
+ "condition"
798
+ ],
799
+ "properties": {
800
+ "condition": {
801
+ "pattern": "^\\s*="
802
+ }
803
+ }
804
+ },
805
+ "on": [
806
+ "bpmn:SequenceFlow"
807
+ ],
808
+ "when": {
809
+ "properties": {
810
+ "hasCondition": {
811
+ "const": true
812
+ }
813
+ }
814
+ },
815
+ "at": "path"
816
+ },
817
+ {
818
+ "description": "取消结束事件只写在事务子流程(transaction)里",
819
+ "schema": {
820
+ "properties": {
821
+ "parentType": {
822
+ "const": "bpmn:Transaction"
823
+ }
824
+ }
825
+ },
826
+ "on": [
827
+ "bpmn:EndEvent"
828
+ ],
829
+ "when": {
830
+ "properties": {
831
+ "eventKind": {
832
+ "const": "Cancel"
833
+ }
834
+ }
835
+ }
836
+ },
837
+ {
838
+ "description": "取消边界事件只挂在事务子流程(transaction)上",
839
+ "schema": {
840
+ "properties": {
841
+ "attachedType": {
842
+ "const": "bpmn:Transaction"
843
+ }
844
+ }
845
+ },
846
+ "on": [
847
+ "bpmn:BoundaryEvent"
848
+ ],
849
+ "when": {
850
+ "properties": {
851
+ "eventKind": {
852
+ "const": "Cancel"
853
+ }
854
+ }
855
+ }
856
+ }
857
+ ],
858
+ "readable": [
859
+ {
860
+ "property": "condition",
861
+ "where": "path"
862
+ },
863
+ {
864
+ "property": "cardinality",
865
+ "where": "path 的 loopCardinality"
866
+ },
867
+ {
868
+ "property": "loopCompletion",
869
+ "where": "path 的 completionCondition"
870
+ },
871
+ {
872
+ "property": "completion",
873
+ "where": "id 的 completionCondition"
874
+ },
875
+ {
876
+ "property": "documentation",
877
+ "where": "id 的 documentation"
878
+ },
879
+ {
880
+ "property": "timeDuration",
881
+ "where": "path 的 timeDuration"
882
+ },
883
+ {
884
+ "property": "timeDate",
885
+ "where": "path 的 timeDate"
886
+ },
887
+ {
888
+ "property": "timeCycle",
889
+ "where": "path 的 timeCycle"
890
+ }
891
+ ],
892
+ "projection": {
893
+ "description": "rules.schema 和 rules.when 检查节点的无环投影;on 是精确 BPMN 类型列表;at 为 path 时使用 process/子流程/节点,其余用节点 id。未提供的属性为 undefined(Ajv 当作缺失)。原始标量属性按原名保留。",
894
+ "facts": {
895
+ "type": "BPMN 类型",
896
+ "top": "是否直属 process",
897
+ "parentType": "父元素类型",
898
+ "subprocess": "是否属于 SubProcess(含 transaction 与 adHoc)",
899
+ "position": "开始事件按 start / innerStart / eventStart 区分,其余为 BPMN 类型",
900
+ "eventKind": "第一个事件定义的种类;事件数量另按 events 表检查",
901
+ "messageNamed": "引用的 message 是否有 name",
902
+ "signalReferenced": "是否引用 signal",
903
+ "escalationReferenced": "是否引用 escalation",
904
+ "linkNamed": "link 是否有非空 name",
905
+ "attachedType": "边界事件挂靠节点的类型",
906
+ "condition": "条件正文",
907
+ "conditionLanguage": "条件声明的语言",
908
+ "hasCondition": "是否写了条件",
909
+ "timeDuration / timeDate / timeCycle": "第一个事件定义中对应时间的正文",
910
+ "loopType / collection / cardinality / loopCompletion": "多实例类型、集合、次数和完成条件",
911
+ "completion": "自由子流程的完成条件",
912
+ "hasStartOrEnd": "直接子节点是否有开始或结束事件",
913
+ "hasScriptExtension": "是否写 coda:script",
914
+ "hasOutputs / outputHasValue": "是否有 coda:output,以及是否有输出声明 value",
915
+ "documentation": "人工任务 documentation 合并后的文字",
916
+ "hasInputFields": "是否有 inputFields 中类型的字段或动态 coda:fields",
917
+ "hasTimeCycle": "是否声明 timeCycle 元素(包括空元素)"
918
+ }
919
+ }
920
+ }