Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: source wfis with log to fix random sorting of workflowitems #1565

Merged
merged 1 commit into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 3 additions & 73 deletions api/src/service/domain/workflow/workflowitem_eventsourcing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as WorkflowitemUpdated from "./workflowitem_updated";
export function sourceWorkflowitemFromSnapshot(
ctx: Ctx,
events: BusinessEvent[],
withLog: boolean,
_withLog: boolean,
workflowitemJson?,
): Result.Type<Workflowitem.Workflowitem> {
let workflowitem;
Expand All @@ -36,9 +36,7 @@ export function sourceWorkflowitemFromSnapshot(
}
const workflowitemResult = sourceEventFromSnapshot(ctx, event, workflowitem);
if (Result.isOk(workflowitemResult)) {
if (withLog) {
workflowitemResult.log.push(newTraceEvent(workflowitemResult, event));
}
workflowitemResult.log.push(newTraceEvent(workflowitemResult, event));
workflowitem = workflowitemResult;
}
}
Expand Down Expand Up @@ -108,35 +106,6 @@ export function parseWorkflowitemFromSnapshot(workflowitemJson): Workflowitem.Wo
};
}

export function sourceWorkflowitems(
ctx: Ctx,
events: BusinessEvent[],
origin?: Map<Workflowitem.Id, Workflowitem.Workflowitem>,
): { workflowitems: Workflowitem.Workflowitem[]; errors: Error[] } {
const items =
origin === undefined
? new Map<Workflowitem.Id, Workflowitem.Workflowitem>()
: new Map<Workflowitem.Id, Workflowitem.Workflowitem>(origin);
const errors: Error[] = [];

for (const event of events) {
logger.trace({ event }, "Validating workflowitem event by applying it");
if (!event.type.startsWith("workflowitem_")) {
continue;
}

const workflowitem = sourceEvent(ctx, event, items);
if (Result.isErr(workflowitem)) {
errors.push(workflowitem);
} else {
workflowitem.log.push(newTraceEvent(workflowitem, event));
items.set(workflowitem.id, workflowitem);
}
}

return { workflowitems: [...items.values()], errors };
}

function newTraceEvent(
workflowitem: Workflowitem.Workflowitem,
event: BusinessEvent,
Expand All @@ -154,46 +123,6 @@ function newTraceEvent(
};
}

function sourceEvent(
ctx: Ctx,
event: BusinessEvent,
workflowitems: Map<Workflowitem.Id, Workflowitem.Workflowitem>,
): Result.Type<Workflowitem.Workflowitem> {
const workflowitemId = getWorkflowitemId(event);
let workflowitem: Result.Type<Workflowitem.Workflowitem>;
if (Result.isOk(workflowitemId)) {
// The event refers to an existing workflowitem, so
// the workflowitem should have been initialized already.

workflowitem = get(workflowitems, workflowitemId);
if (Result.isErr(workflowitem)) {
return new VError(
`workflowitem ID ${workflowitemId} found in event ${event.type} is invalid`,
);
}

workflowitem = newWorkflowitemFromEvent(ctx, workflowitem, event);
if (Result.isErr(workflowitem)) {
return workflowitem; // <- event-sourcing error
}
} else {
// The event does not refer to a workflowitem ID, so it must be a creation event:
if (event.type !== "workflowitem_created") {
return new VError(
`event ${event.type} is not of type "workflowitem_created" but also ` +
"does not include a workflowitem ID",
);
}

workflowitem = WorkflowitemCreated.createFrom(ctx, event);
if (Result.isErr(workflowitem)) {
return new VError(workflowitem, "could not create workflowitem from event");
}
}

return workflowitem;
}

function get(
workflowitems: Map<Workflowitem.Id, Workflowitem.Workflowitem>,
workflowitemId: Workflowitem.Id,
Expand Down Expand Up @@ -264,6 +193,7 @@ export function newWorkflowitemFromEvent(
type EventModule = {
mutate: (workflowitem: Workflowitem.Workflowitem, event: BusinessEvent) => Result.Type<void>;
};

function getEventModule(event: BusinessEvent): Result.Type<EventModule> {
switch (event.type) {
case "workflowitem_document_validated":
Expand Down
7 changes: 6 additions & 1 deletion api/src/service/domain/workflow/workflowitem_ordering.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AssertionError } from "assert";
import * as Workflowitem from "./workflowitem";
import logger from "../../../lib/logger";

export type WorkflowitemOrdering = Workflowitem.Id[];

Expand Down Expand Up @@ -73,7 +74,11 @@ function closedAt(item: Workflowitem.ScrubbedWorkflowitem): string | AssertionEr
const traceEvent = item.log.find((e) => e.businessEvent.type === "workflowitem_closed");

if (traceEvent === undefined || traceEvent.businessEvent.type !== "workflowitem_closed") {
return new AssertionError({ message: `Expected close event for workflowitem ${item.id}` });
const error = new AssertionError({
message: `Expected close event for workflowitem ${item.id}`,
});
logger.error(error, error.message);
return error;
}
const closeEvent = traceEvent.businessEvent;

Expand Down
Loading