@company-semantics/contracts 0.89.0 → 0.90.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "0.89.0",
3
+ "version": "0.90.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -107,6 +107,20 @@ describe('decision table key consistency', () => {
107
107
  const decisionKeys = Object.keys(LIFECYCLE_DECISIONS.confirm).sort()
108
108
  expect(decisionKeys).toEqual(transitionKeys)
109
109
  })
110
+
111
+ it('LIFECYCLE_DECISIONS.reject keys match VALID_TRANSITIONS keys', () => {
112
+ const transitionKeys = Object.keys(VALID_TRANSITIONS).sort()
113
+ const decisionKeys = Object.keys(LIFECYCLE_DECISIONS.reject).sort()
114
+ expect(decisionKeys).toEqual(transitionKeys)
115
+ })
116
+
117
+ it('all intent rows have the same set of state keys', () => {
118
+ const intents = Object.keys(LIFECYCLE_DECISIONS) as Array<keyof typeof LIFECYCLE_DECISIONS>
119
+ const referenceKeys = Object.keys(LIFECYCLE_DECISIONS[intents[0]]).sort()
120
+ for (const intent of intents) {
121
+ expect(Object.keys(LIFECYCLE_DECISIONS[intent]).sort()).toEqual(referenceKeys)
122
+ }
123
+ })
110
124
  })
111
125
 
112
126
  // ---------------------------------------------------------------------------
@@ -157,6 +171,30 @@ describe('applyIntent', () => {
157
171
  it('undone + confirm = conflict', () => {
158
172
  expect(applyIntent('undone', 'confirm')).toBe('conflict')
159
173
  })
174
+
175
+ it('pending_confirmation + reject = approve', () => {
176
+ expect(applyIntent('pending_confirmation', 'reject')).toBe('approve')
177
+ })
178
+
179
+ it('expired + reject = expired', () => {
180
+ expect(applyIntent('expired', 'reject')).toBe('expired')
181
+ })
182
+
183
+ it('cancelled + reject = conflict', () => {
184
+ expect(applyIntent('cancelled', 'reject')).toBe('conflict')
185
+ })
186
+
187
+ it('ready + reject = conflict', () => {
188
+ expect(applyIntent('ready', 'reject')).toBe('conflict')
189
+ })
190
+
191
+ it('executing + reject = conflict', () => {
192
+ expect(applyIntent('executing', 'reject')).toBe('conflict')
193
+ })
194
+
195
+ it('completed + reject = conflict', () => {
196
+ expect(applyIntent('completed', 'reject')).toBe('conflict')
197
+ })
160
198
  })
161
199
 
162
200
  // ---------------------------------------------------------------------------
@@ -10,5 +10,4 @@ export interface ExecutionError {
10
10
  readonly name: 'ExecutionError';
11
11
  readonly code: ExecutionErrorCode;
12
12
  readonly message: string;
13
- readonly httpStatus?: number;
14
13
  }
@@ -1,6 +1,6 @@
1
1
  import type { ExecutionState } from './status';
2
2
 
3
- export type ExecutionIntent = 'confirm';
3
+ export type ExecutionIntent = 'confirm' | 'reject';
4
4
 
5
5
  export type LifecycleDecision =
6
6
  | 'approve'
@@ -29,6 +29,20 @@ export const LIFECYCLE_DECISIONS: DecisionTable = {
29
29
  failed_with_partial_execution: 'conflict',
30
30
  undone: 'conflict',
31
31
  },
32
+ reject: {
33
+ pending_confirmation: 'approve',
34
+ expired: 'expired',
35
+ cancelled: 'conflict',
36
+ blocked_pending_approval: 'conflict',
37
+ ready: 'conflict',
38
+ executing: 'conflict',
39
+ completed: 'conflict',
40
+ completed_with_rollbacks: 'conflict',
41
+ failed_retryable: 'conflict',
42
+ failed_terminal: 'conflict',
43
+ failed_with_partial_execution: 'conflict',
44
+ undone: 'conflict',
45
+ },
32
46
  };
33
47
 
34
48
  export function applyIntent(