22 branches 3 (#13181)
This PR does not produce any functional changes for our users. It prepares the branches for workflows by: - decommissioning `output` and `context` fields or `workflowRun` records and use newly created `state` field from front-end and back-end - use `stepStatus` computed by `back-end` in `front-end` - add utils and types in `twenty-shared/workflow` (not completed, a follow-up is scheduled https://github.com/twentyhq/core-team-issues/issues/1211) - add concurrency to `workflowQueue` message queue to avoid weird branch execution when using forms in workflow branches - add a WithLock decorator for better dev experience of `CacheLockService.withLock` usage Here is an example of such a workflow running (front branch display is not yet done that's why it looks ugly) -> https://discord.com/channels/1130383047699738754/1258024460238192691/1392897615171158098
This commit is contained in:
15
packages/twenty-shared/src/workflow/index.ts
Normal file
15
packages/twenty-shared/src/workflow/index.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* _____ _
|
||||
*|_ _|_ _____ _ __ | |_ _ _
|
||||
* | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
|
||||
* | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
|
||||
* |_| \_/\_/ \___|_| |_|\__|\__, |
|
||||
* |___/
|
||||
*/
|
||||
|
||||
export type {
|
||||
WorkflowRunStepInfo,
|
||||
WorkflowRunStepInfos,
|
||||
} from './types/WorkflowRunStateStepInfos';
|
||||
export { StepStatus } from './types/WorkflowRunStateStepInfos';
|
||||
export { getWorkflowRunContext } from './utils/getWorkflowRunContext';
|
||||
@ -0,0 +1,15 @@
|
||||
export enum StepStatus {
|
||||
NOT_STARTED = 'NOT_STARTED',
|
||||
RUNNING = 'RUNNING',
|
||||
SUCCESS = 'SUCCESS',
|
||||
FAILED = 'FAILED',
|
||||
PENDING = 'PENDING',
|
||||
}
|
||||
|
||||
export type WorkflowRunStepInfo = {
|
||||
result?: object;
|
||||
error?: string;
|
||||
status: StepStatus;
|
||||
};
|
||||
|
||||
export type WorkflowRunStepInfos = Record<string, WorkflowRunStepInfo>;
|
||||
@ -0,0 +1,37 @@
|
||||
import { getWorkflowRunContext } from '@/workflow/utils/getWorkflowRunContext';
|
||||
import {
|
||||
StepStatus,
|
||||
WorkflowRunStepInfos,
|
||||
} from '@/workflow/types/WorkflowRunStateStepInfos';
|
||||
|
||||
describe('getWorkflowRunContext', () => {
|
||||
it('returns a context with only steps that have a defined result', () => {
|
||||
const stepInfos: WorkflowRunStepInfos = {
|
||||
step1: { result: { res: 'value1' }, status: StepStatus.SUCCESS },
|
||||
step2: { result: {}, status: StepStatus.SUCCESS },
|
||||
step3: { status: StepStatus.NOT_STARTED },
|
||||
step4: { result: { res: 0 }, status: StepStatus.SUCCESS },
|
||||
step5: { result: { res: undefined }, status: StepStatus.SUCCESS },
|
||||
};
|
||||
|
||||
const context = getWorkflowRunContext(stepInfos);
|
||||
|
||||
expect(context).toEqual({
|
||||
step1: { res: 'value1' },
|
||||
step2: {},
|
||||
step4: { res: 0 },
|
||||
step5: { res: undefined },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an empty object when no step has a defined result', () => {
|
||||
const stepInfos: WorkflowRunStepInfos = {
|
||||
step1: { status: StepStatus.NOT_STARTED },
|
||||
step2: { status: StepStatus.NOT_STARTED },
|
||||
};
|
||||
|
||||
const context = getWorkflowRunContext(stepInfos);
|
||||
|
||||
expect(context).toEqual({});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,12 @@
|
||||
import { isDefined } from '@/utils';
|
||||
import { WorkflowRunStepInfos } from '@/workflow/types/WorkflowRunStateStepInfos';
|
||||
|
||||
export const getWorkflowRunContext = (
|
||||
stepInfos: WorkflowRunStepInfos,
|
||||
): Record<string, unknown> => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(stepInfos)
|
||||
.filter(([, value]) => isDefined(value?.['result']))
|
||||
.map(([key, value]) => [key, value?.['result']]),
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user