@cynodia/axiom-server 0.6.0-alpha.1

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,759 @@
1
+ {
2
+ "conformance": "axiom.conformance.v1",
3
+ "name": "constraint-rolls-back",
4
+ "covers": [
5
+ "constraints",
6
+ "rollback",
7
+ "for-each provisional writes"
8
+ ],
9
+ "description": "Iteration N sees the writes of iterations before it, so two lines for one part are counted together — and the invariant then rolls the whole action back.",
10
+ "principals": {
11
+ "clerk": {
12
+ "field_user_id": "u1",
13
+ "field_user_role": "clerk"
14
+ },
15
+ "admin": {
16
+ "field_user_id": "u2",
17
+ "field_user_role": "admin"
18
+ }
19
+ },
20
+ "serverIR": {
21
+ "contract": "axiom.server.v1",
22
+ "id": "conformance",
23
+ "name": "Conformance",
24
+ "version": "0.6.0",
25
+ "entities": [
26
+ {
27
+ "id": "entity_user",
28
+ "kind": "entity",
29
+ "identityFieldId": "field_user_id",
30
+ "fields": [
31
+ {
32
+ "id": "field_user_id",
33
+ "valueType": {
34
+ "kind": "primitive",
35
+ "primitive": "string"
36
+ },
37
+ "required": true
38
+ },
39
+ {
40
+ "id": "field_user_role",
41
+ "valueType": {
42
+ "kind": "primitive",
43
+ "primitive": "string"
44
+ },
45
+ "required": true
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "id": "entity_part",
51
+ "kind": "entity",
52
+ "identityFieldId": "field_part_id",
53
+ "fields": [
54
+ {
55
+ "id": "field_part_id",
56
+ "valueType": {
57
+ "kind": "primitive",
58
+ "primitive": "string"
59
+ },
60
+ "required": true
61
+ },
62
+ {
63
+ "id": "field_part_stock",
64
+ "valueType": {
65
+ "kind": "primitive",
66
+ "primitive": "number"
67
+ },
68
+ "required": true
69
+ }
70
+ ]
71
+ },
72
+ {
73
+ "id": "entity_line",
74
+ "kind": "entity",
75
+ "identityFieldId": "field_line_id",
76
+ "fields": [
77
+ {
78
+ "id": "field_line_id",
79
+ "valueType": {
80
+ "kind": "primitive",
81
+ "primitive": "string"
82
+ },
83
+ "required": true
84
+ },
85
+ {
86
+ "id": "field_line_part",
87
+ "valueType": {
88
+ "kind": "primitive",
89
+ "primitive": "string"
90
+ },
91
+ "required": true
92
+ },
93
+ {
94
+ "id": "field_line_qty",
95
+ "valueType": {
96
+ "kind": "primitive",
97
+ "primitive": "number"
98
+ },
99
+ "required": true
100
+ }
101
+ ]
102
+ }
103
+ ],
104
+ "fields": {
105
+ "field_user_id": {
106
+ "entityId": "entity_user",
107
+ "field": {
108
+ "id": "field_user_id",
109
+ "valueType": {
110
+ "kind": "primitive",
111
+ "primitive": "string"
112
+ },
113
+ "required": true
114
+ }
115
+ },
116
+ "field_user_role": {
117
+ "entityId": "entity_user",
118
+ "field": {
119
+ "id": "field_user_role",
120
+ "valueType": {
121
+ "kind": "primitive",
122
+ "primitive": "string"
123
+ },
124
+ "required": true
125
+ }
126
+ },
127
+ "field_part_id": {
128
+ "entityId": "entity_part",
129
+ "field": {
130
+ "id": "field_part_id",
131
+ "valueType": {
132
+ "kind": "primitive",
133
+ "primitive": "string"
134
+ },
135
+ "required": true
136
+ }
137
+ },
138
+ "field_part_stock": {
139
+ "entityId": "entity_part",
140
+ "field": {
141
+ "id": "field_part_stock",
142
+ "valueType": {
143
+ "kind": "primitive",
144
+ "primitive": "number"
145
+ },
146
+ "required": true
147
+ }
148
+ },
149
+ "field_line_id": {
150
+ "entityId": "entity_line",
151
+ "field": {
152
+ "id": "field_line_id",
153
+ "valueType": {
154
+ "kind": "primitive",
155
+ "primitive": "string"
156
+ },
157
+ "required": true
158
+ }
159
+ },
160
+ "field_line_part": {
161
+ "entityId": "entity_line",
162
+ "field": {
163
+ "id": "field_line_part",
164
+ "valueType": {
165
+ "kind": "primitive",
166
+ "primitive": "string"
167
+ },
168
+ "required": true
169
+ }
170
+ },
171
+ "field_line_qty": {
172
+ "entityId": "entity_line",
173
+ "field": {
174
+ "id": "field_line_qty",
175
+ "valueType": {
176
+ "kind": "primitive",
177
+ "primitive": "number"
178
+ },
179
+ "required": true
180
+ }
181
+ }
182
+ },
183
+ "states": [
184
+ {
185
+ "id": "state_parts",
186
+ "kind": "state",
187
+ "name": "parts",
188
+ "authority": "server",
189
+ "valueType": {
190
+ "kind": "collection",
191
+ "itemType": {
192
+ "kind": "entity",
193
+ "entityId": "entity_part"
194
+ }
195
+ },
196
+ "initialValue": [
197
+ {
198
+ "field_part_id": "bolt",
199
+ "field_part_stock": 10
200
+ },
201
+ {
202
+ "field_part_id": "nut",
203
+ "field_part_stock": 5
204
+ }
205
+ ]
206
+ },
207
+ {
208
+ "id": "state_ledger",
209
+ "kind": "state",
210
+ "name": "ledger",
211
+ "authority": "server",
212
+ "valueType": {
213
+ "kind": "collection",
214
+ "itemType": {
215
+ "kind": "primitive",
216
+ "primitive": "number"
217
+ }
218
+ },
219
+ "initialValue": []
220
+ },
221
+ {
222
+ "id": "state_total",
223
+ "kind": "state",
224
+ "name": "total",
225
+ "authority": "server",
226
+ "valueType": {
227
+ "kind": "primitive",
228
+ "primitive": "number"
229
+ },
230
+ "derivation": {
231
+ "kind": "call",
232
+ "function": "sum",
233
+ "arguments": [
234
+ {
235
+ "kind": "map",
236
+ "source": {
237
+ "kind": "ref",
238
+ "targetId": "state_parts"
239
+ },
240
+ "scopeId": "scope_total",
241
+ "projection": {
242
+ "kind": "field",
243
+ "source": {
244
+ "kind": "ref",
245
+ "targetId": "scope_total"
246
+ },
247
+ "fieldId": "field_part_stock"
248
+ }
249
+ }
250
+ ]
251
+ }
252
+ }
253
+ ],
254
+ "actions": {
255
+ "action_take": {
256
+ "id": "action_take",
257
+ "kind": "action",
258
+ "name": "take",
259
+ "parameters": [
260
+ {
261
+ "id": "param_part",
262
+ "valueType": {
263
+ "kind": "primitive",
264
+ "primitive": "string"
265
+ },
266
+ "required": true
267
+ },
268
+ {
269
+ "id": "param_qty",
270
+ "valueType": {
271
+ "kind": "primitive",
272
+ "primitive": "number"
273
+ },
274
+ "required": true
275
+ }
276
+ ],
277
+ "guards": [
278
+ {
279
+ "condition": {
280
+ "kind": "binary",
281
+ "operator": "gt",
282
+ "left": {
283
+ "kind": "ref",
284
+ "targetId": "param_qty"
285
+ },
286
+ "right": {
287
+ "kind": "literal",
288
+ "value": 0
289
+ }
290
+ },
291
+ "failureMode": {
292
+ "code": "invalid-quantity",
293
+ "message": "A quantity must be above zero."
294
+ }
295
+ },
296
+ {
297
+ "condition": {
298
+ "kind": "binary",
299
+ "operator": "gte",
300
+ "left": {
301
+ "kind": "field",
302
+ "source": {
303
+ "kind": "find",
304
+ "source": {
305
+ "kind": "ref",
306
+ "targetId": "state_parts"
307
+ },
308
+ "scopeId": "scope_part",
309
+ "predicate": {
310
+ "kind": "binary",
311
+ "operator": "eq",
312
+ "left": {
313
+ "kind": "field",
314
+ "source": {
315
+ "kind": "ref",
316
+ "targetId": "scope_part"
317
+ },
318
+ "fieldId": "field_part_id"
319
+ },
320
+ "right": {
321
+ "kind": "ref",
322
+ "targetId": "param_part"
323
+ }
324
+ }
325
+ },
326
+ "fieldId": "field_part_stock"
327
+ },
328
+ "right": {
329
+ "kind": "ref",
330
+ "targetId": "param_qty"
331
+ }
332
+ },
333
+ "failureMode": {
334
+ "code": "insufficient-stock",
335
+ "message": "Not enough stock."
336
+ }
337
+ }
338
+ ],
339
+ "operations": [
340
+ {
341
+ "kind": "set",
342
+ "target": {
343
+ "kind": "field",
344
+ "target": {
345
+ "kind": "collection-item",
346
+ "collection": {
347
+ "kind": "state",
348
+ "stateId": "state_parts"
349
+ },
350
+ "selector": {
351
+ "kind": "identity",
352
+ "fieldId": "field_part_id",
353
+ "value": {
354
+ "kind": "ref",
355
+ "targetId": "param_part"
356
+ }
357
+ }
358
+ },
359
+ "fieldId": "field_part_stock"
360
+ },
361
+ "value": {
362
+ "kind": "binary",
363
+ "operator": "subtract",
364
+ "left": {
365
+ "kind": "field",
366
+ "source": {
367
+ "kind": "find",
368
+ "source": {
369
+ "kind": "ref",
370
+ "targetId": "state_parts"
371
+ },
372
+ "scopeId": "scope_part",
373
+ "predicate": {
374
+ "kind": "binary",
375
+ "operator": "eq",
376
+ "left": {
377
+ "kind": "field",
378
+ "source": {
379
+ "kind": "ref",
380
+ "targetId": "scope_part"
381
+ },
382
+ "fieldId": "field_part_id"
383
+ },
384
+ "right": {
385
+ "kind": "ref",
386
+ "targetId": "param_part"
387
+ }
388
+ }
389
+ },
390
+ "fieldId": "field_part_stock"
391
+ },
392
+ "right": {
393
+ "kind": "ref",
394
+ "targetId": "param_qty"
395
+ }
396
+ }
397
+ },
398
+ {
399
+ "kind": "insert",
400
+ "target": {
401
+ "kind": "state",
402
+ "stateId": "state_ledger"
403
+ },
404
+ "value": {
405
+ "kind": "ref",
406
+ "targetId": "param_qty"
407
+ }
408
+ }
409
+ ],
410
+ "preconditions": [
411
+ {
412
+ "kind": "binary",
413
+ "operator": "gt",
414
+ "left": {
415
+ "kind": "ref",
416
+ "targetId": "param_qty"
417
+ },
418
+ "right": {
419
+ "kind": "literal",
420
+ "value": 0
421
+ }
422
+ },
423
+ {
424
+ "kind": "binary",
425
+ "operator": "gte",
426
+ "left": {
427
+ "kind": "field",
428
+ "source": {
429
+ "kind": "find",
430
+ "source": {
431
+ "kind": "ref",
432
+ "targetId": "state_parts"
433
+ },
434
+ "scopeId": "scope_part",
435
+ "predicate": {
436
+ "kind": "binary",
437
+ "operator": "eq",
438
+ "left": {
439
+ "kind": "field",
440
+ "source": {
441
+ "kind": "ref",
442
+ "targetId": "scope_part"
443
+ },
444
+ "fieldId": "field_part_id"
445
+ },
446
+ "right": {
447
+ "kind": "ref",
448
+ "targetId": "param_part"
449
+ }
450
+ }
451
+ },
452
+ "fieldId": "field_part_stock"
453
+ },
454
+ "right": {
455
+ "kind": "ref",
456
+ "targetId": "param_qty"
457
+ }
458
+ }
459
+ ],
460
+ "failureModes": [
461
+ {
462
+ "code": "invalid-quantity",
463
+ "message": "A quantity must be above zero."
464
+ },
465
+ {
466
+ "code": "insufficient-stock",
467
+ "message": "Not enough stock."
468
+ }
469
+ ]
470
+ },
471
+ "action_take_many": {
472
+ "id": "action_take_many",
473
+ "kind": "action",
474
+ "name": "takeMany",
475
+ "parameters": [
476
+ {
477
+ "id": "param_lines",
478
+ "valueType": {
479
+ "kind": "collection",
480
+ "itemType": {
481
+ "kind": "entity",
482
+ "entityId": "entity_line"
483
+ }
484
+ },
485
+ "required": true
486
+ }
487
+ ],
488
+ "operations": [
489
+ {
490
+ "kind": "for-each",
491
+ "collection": {
492
+ "kind": "ref",
493
+ "targetId": "param_lines"
494
+ },
495
+ "scopeId": "scope_line",
496
+ "operations": [
497
+ {
498
+ "kind": "set",
499
+ "target": {
500
+ "kind": "field",
501
+ "target": {
502
+ "kind": "collection-item",
503
+ "collection": {
504
+ "kind": "state",
505
+ "stateId": "state_parts"
506
+ },
507
+ "selector": {
508
+ "kind": "identity",
509
+ "fieldId": "field_part_id",
510
+ "value": {
511
+ "kind": "field",
512
+ "source": {
513
+ "kind": "ref",
514
+ "targetId": "scope_line"
515
+ },
516
+ "fieldId": "field_line_part"
517
+ }
518
+ }
519
+ },
520
+ "fieldId": "field_part_stock"
521
+ },
522
+ "value": {
523
+ "kind": "binary",
524
+ "operator": "subtract",
525
+ "left": {
526
+ "kind": "field",
527
+ "source": {
528
+ "kind": "find",
529
+ "source": {
530
+ "kind": "ref",
531
+ "targetId": "state_parts"
532
+ },
533
+ "scopeId": "scope_part",
534
+ "predicate": {
535
+ "kind": "binary",
536
+ "operator": "eq",
537
+ "left": {
538
+ "kind": "field",
539
+ "source": {
540
+ "kind": "ref",
541
+ "targetId": "scope_part"
542
+ },
543
+ "fieldId": "field_part_id"
544
+ },
545
+ "right": {
546
+ "kind": "field",
547
+ "source": {
548
+ "kind": "ref",
549
+ "targetId": "scope_line"
550
+ },
551
+ "fieldId": "field_line_part"
552
+ }
553
+ }
554
+ },
555
+ "fieldId": "field_part_stock"
556
+ },
557
+ "right": {
558
+ "kind": "field",
559
+ "source": {
560
+ "kind": "ref",
561
+ "targetId": "scope_line"
562
+ },
563
+ "fieldId": "field_line_qty"
564
+ }
565
+ }
566
+ }
567
+ ]
568
+ }
569
+ ],
570
+ "preconditions": [],
571
+ "failureModes": []
572
+ },
573
+ "action_set_stock": {
574
+ "id": "action_set_stock",
575
+ "kind": "action",
576
+ "name": "setStock",
577
+ "authorization": {
578
+ "kind": "binary",
579
+ "operator": "eq",
580
+ "left": {
581
+ "kind": "field",
582
+ "source": {
583
+ "kind": "ref",
584
+ "targetId": "axiom_principal"
585
+ },
586
+ "fieldId": "field_user_role"
587
+ },
588
+ "right": {
589
+ "kind": "literal",
590
+ "value": "admin"
591
+ }
592
+ },
593
+ "parameters": [
594
+ {
595
+ "id": "param_part",
596
+ "valueType": {
597
+ "kind": "primitive",
598
+ "primitive": "string"
599
+ },
600
+ "required": true
601
+ },
602
+ {
603
+ "id": "param_stock",
604
+ "valueType": {
605
+ "kind": "primitive",
606
+ "primitive": "number"
607
+ },
608
+ "required": true
609
+ }
610
+ ],
611
+ "operations": [
612
+ {
613
+ "kind": "set",
614
+ "target": {
615
+ "kind": "field",
616
+ "target": {
617
+ "kind": "collection-item",
618
+ "collection": {
619
+ "kind": "state",
620
+ "stateId": "state_parts"
621
+ },
622
+ "selector": {
623
+ "kind": "identity",
624
+ "fieldId": "field_part_id",
625
+ "value": {
626
+ "kind": "ref",
627
+ "targetId": "param_part"
628
+ }
629
+ }
630
+ },
631
+ "fieldId": "field_part_stock"
632
+ },
633
+ "value": {
634
+ "kind": "ref",
635
+ "targetId": "param_stock"
636
+ }
637
+ }
638
+ ],
639
+ "preconditions": [],
640
+ "failureModes": []
641
+ }
642
+ },
643
+ "constraints": [
644
+ {
645
+ "id": "constraint_stock",
646
+ "kind": "constraint",
647
+ "name": "Stock is never negative",
648
+ "entityId": "entity_part",
649
+ "message": "Stock can never fall below zero.",
650
+ "expression": {
651
+ "kind": "binary",
652
+ "operator": "gte",
653
+ "left": {
654
+ "kind": "field",
655
+ "source": {
656
+ "kind": "ref",
657
+ "targetId": "entity_part"
658
+ },
659
+ "fieldId": "field_part_stock"
660
+ },
661
+ "right": {
662
+ "kind": "literal",
663
+ "value": 0
664
+ }
665
+ }
666
+ }
667
+ ],
668
+ "transitionConstraints": [
669
+ {
670
+ "id": "transition_falls",
671
+ "kind": "transition-constraint",
672
+ "name": "Stock only falls",
673
+ "entityId": "entity_part",
674
+ "previousScopeId": "scope_previous",
675
+ "proposedScopeId": "scope_proposed",
676
+ "message": "Stock may not be raised.",
677
+ "expression": {
678
+ "kind": "binary",
679
+ "operator": "lte",
680
+ "left": {
681
+ "kind": "field",
682
+ "source": {
683
+ "kind": "ref",
684
+ "targetId": "scope_proposed"
685
+ },
686
+ "fieldId": "field_part_stock"
687
+ },
688
+ "right": {
689
+ "kind": "field",
690
+ "source": {
691
+ "kind": "ref",
692
+ "targetId": "scope_previous"
693
+ },
694
+ "fieldId": "field_part_stock"
695
+ }
696
+ }
697
+ }
698
+ ],
699
+ "principalEntityId": "entity_user",
700
+ "observableStateIds": [
701
+ "state_parts",
702
+ "state_ledger",
703
+ "state_total"
704
+ ]
705
+ },
706
+ "initialState": [
707
+ {
708
+ "stateId": "state_parts",
709
+ "value": [
710
+ {
711
+ "field_part_id": "bolt",
712
+ "field_part_stock": 10
713
+ },
714
+ {
715
+ "field_part_id": "nut",
716
+ "field_part_stock": 5
717
+ }
718
+ ],
719
+ "revision": 1
720
+ }
721
+ ],
722
+ "invocations": [
723
+ {
724
+ "actionId": "action_take_many",
725
+ "arguments": {
726
+ "param_lines": [
727
+ {
728
+ "field_line_id": "l1",
729
+ "field_line_part": "nut",
730
+ "field_line_qty": 3
731
+ },
732
+ {
733
+ "field_line_id": "l2",
734
+ "field_line_part": "nut",
735
+ "field_line_qty": 3
736
+ }
737
+ ]
738
+ },
739
+ "expect": {
740
+ "ok": false,
741
+ "diagnosticCodes": [
742
+ "CONSTRAINT_VIOLATION"
743
+ ]
744
+ }
745
+ }
746
+ ],
747
+ "expectedState": {
748
+ "state_parts": [
749
+ {
750
+ "field_part_id": "bolt",
751
+ "field_part_stock": 10
752
+ },
753
+ {
754
+ "field_part_id": "nut",
755
+ "field_part_stock": 5
756
+ }
757
+ ]
758
+ }
759
+ }