Skip to content

Commit

Permalink
#1 adds training events and reducer
Browse files Browse the repository at this point in the history
  • Loading branch information
georgeenciu committed Jun 20, 2023
1 parent 8208a03 commit ad40e41
Show file tree
Hide file tree
Showing 20 changed files with 678 additions and 0 deletions.
18 changes: 18 additions & 0 deletions libs/training-events/src/events/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export { trainingCompleted } from "./training-completed"
export { trainingCptPerformed } from "./training-cpt-performed"
export { trainingCptRequested } from "./training-cpt-requested"
export { trainingCptScheduled } from "./training-cpt-scheduled"
export { trainingIntent } from "./training-intent";
export { trainingIntentConfirmationExpired } from "./training-intent-confirmation-expired";
export { trainingIntentConfirmationRejected } from "./training-intent-confirmation-rejected";
export { trainingIntentConfirmationRequested } from "./training-intent-confirmation-requested";
export { trainingIntentConfirmationResponded } from "./training-intent-confirmation-responded";
export { trainingMentorAssigned } from "./training-mentor-assigned";
export { trainingMentorReassigned } from "./training-mentor-reassigned";
export { trainingSessionPerformed } from "./training-session-performed";
export { trainingSessionScheduled } from "./training-session-scheduled";
export { trainingSoloPerformed } from "./training-solo-performed"
export { trainingSoloRequested } from "./training-solo-requested"
export { trainingSoloScheduled } from "./training-solo-scheduled"
export { trainingTestAssigned } from "./training-test-assigned";
export { trainingTestCompleted } from "./training-test-completed";
60 changes: 60 additions & 0 deletions libs/training-events/src/events/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { IsEmitted, Reducer, Training, TrainingEvent } from "../types";
import { trainingCompleted } from "./training-completed";
import { trainingCptPerformed } from "./training-cpt-performed";
import { trainingCptRequested } from "./training-cpt-requested";
import { trainingCptScheduled } from "./training-cpt-scheduled";
import { trainingIntent } from "./training-intent";
import { trainingIntentConfirmationExpired } from "./training-intent-confirmation-expired";
import { trainingIntentConfirmationRejected } from "./training-intent-confirmation-rejected";
import { trainingIntentConfirmationRequested } from "./training-intent-confirmation-requested";
import { trainingIntentConfirmationResponded } from "./training-intent-confirmation-responded";
import { trainingMentorAssigned } from "./training-mentor-assigned";
import { trainingMentorReassigned } from "./training-mentor-reassigned";
import { trainingSessionPerformed } from "./training-session-performed";
import { trainingSessionScheduled } from "./training-session-scheduled";
import { trainingSoloPerformed } from "./training-solo-performed";
import { trainingSoloRequested } from "./training-solo-requested";
import { trainingSoloScheduled } from "./training-solo-scheduled";
import { trainingTestAssigned } from "./training-test-assigned";
import { trainingTestCompleted } from "./training-test-completed";

const events = [
trainingCompleted,
trainingCptPerformed,
trainingCptRequested,
trainingCptScheduled,
trainingIntent,
trainingIntentConfirmationExpired,
trainingIntentConfirmationRejected,
trainingIntentConfirmationRequested,
trainingIntentConfirmationResponded,
trainingMentorAssigned,
trainingMentorReassigned,
trainingSessionPerformed,
trainingSessionScheduled,
trainingSoloPerformed,
trainingSoloRequested,
trainingSoloScheduled,
trainingTestAssigned,
trainingTestCompleted,
] as const

type Names = typeof events[number]['name']

const { reducer, isEmitted } = events.reduce(
(acc, event) => ({
reducer: { ...acc.reducer, [event.name]: event.reducer },
isEmitted: { ...acc.isEmitted, [event.name]: event.isEmitted }
}), { reducer: {} as Record<Names, Reducer>, isEmitted: {} as Record<Names, IsEmitted> })

export const applyReducer = (training: Training | null, event: TrainingEvent): Training | null => {
if (!reducer[event.name]) {
console.log('Event not found', event)
return training
} else {
return !isEmitted[event.name](training, event)
? reducer[event.name](training, event)
: training
}
}

31 changes: 31 additions & 0 deletions libs/training-events/src/events/training-completed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import { OutcomeReason, OutcomeReasonDetailed, Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-completed'

export type TrainingCompletedEventData = {
trainingId: string,
name: typeof name
payload: {
reason: OutcomeReason
reasonDetailed: OutcomeReasonDetailed
}
}

export type TrainingCompletedEvent = TrainingEventMetadata & TrainingCompletedEventData

const reducer: Reducer<TrainingCompletedEvent> = (
training: Training | null,
event: TrainingCompletedEvent
): Training => ({
...training,
trainingId: event.trainingId,
status: event.payload.reason === 'completed' ? 'COMPLETED' : 'TERMINATED',
...event.payload,
completedAt: event.emittedAt,
})

const isEmitted = (training: Training | null) => !!training?.completedAt

export const trainingCompleted = { name, reducer, isEmitted } as const

34 changes: 34 additions & 0 deletions libs/training-events/src/events/training-cpt-performed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import { Member, Reducer, Training, TrainingEventMetadata, TrainingReport } from "../types";

const name = 'training-cpt-performed'

export type TrainingCptPerformedEventData = {
trainingId: string,
name: typeof name
payload: {
assessedBy: Member
report: TrainingReport
passed: boolean
}
}

export type TrainingCptPerformedEvent = TrainingEventMetadata & TrainingCptPerformedEventData

const reducer: Reducer<TrainingCptPerformedEvent> = (
training: Training | null,
event: TrainingCptPerformedEvent
): Training => ({
...training,
trainingId: event.trainingId,
status: event.payload.passed ? 'COMPLETED' : 'AWAITING_CPT',
cpt: {
...training?.cpt,
...event.payload
}
})

const isEmitted = (training: Training | null) => !!training?.cpt && !!training?.cpt.assessedBy

export const trainingCptPerformed = { name, reducer, isEmitted } as const

33 changes: 33 additions & 0 deletions libs/training-events/src/events/training-cpt-requested.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import { Member, Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-cpt-requested'

export type TrainingCptRequestedEventData = {
trainingId: string,
name: typeof name
payload: {
requestedBy: Member
}
}

export type TrainingCptRequestedEvent = TrainingEventMetadata & TrainingCptRequestedEventData

const reducer: Reducer<TrainingCptRequestedEvent> = (
training: Training | null,
event: TrainingCptRequestedEvent
): Training => ({
...training,
trainingId: event.trainingId,
status: 'AWAITING_CPT',
cpt: {
...training?.cpt,
...event.payload,
requestedAt: event.emittedAt,
}
})

const isEmitted = (training: Training | null) => !!training?.cpt && !!training?.cpt.requestedAt

export const trainingCptRequested = { name, reducer, isEmitted } as const

32 changes: 32 additions & 0 deletions libs/training-events/src/events/training-cpt-scheduled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

import { Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-cpt-scheduled'

export type TrainingCptScheduledEventData = {
trainingId: string,
name: typeof name
payload: {
scheduledAt: Date
}
}

export type TrainingCptScheduledEvent = TrainingEventMetadata & TrainingCptScheduledEventData

const reducer: Reducer<TrainingCptScheduledEvent> = (
training: Training | null,
event: TrainingCptScheduledEvent
): Training => ({
...training,
trainingId: event.trainingId,
status: 'AWAITING_CPT',
cpt: {
...training?.cpt,
scheduledAt: event.payload.scheduledAt
}
})

const isEmitted = (training: Training | null) => !!training?.cpt && !!training?.cpt.scheduledAt

export const trainingCptScheduled = { name, reducer, isEmitted } as const

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

import { Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-intent-confirmation-expired';

export type TrainingIntentConfirmationExpiredData = {
name: typeof name
trainingId: string
payload: Record<string, never>
}

export type TrainingIntentConfirmationExpiredEvent = TrainingEventMetadata & TrainingIntentConfirmationExpiredData

const reducer: Reducer<TrainingIntentConfirmationExpiredEvent> = (
training: Training | null,
event: TrainingIntentConfirmationExpiredEvent
): Training => ({
...training,
status: 'QUEUED',
trainingId: event.trainingId,
intentConfirmation: {
...training?.intentConfirmation,
expiredAt: event.emittedAt,
}
})

const isEmitted =
(training: Training | null) =>
training && training?.intentConfirmation && !!training.intentConfirmation.expiredAt

export const trainingIntentConfirmationExpired = { name, reducer, isEmitted } as const

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-intent-confirmation-rejected';

export type TrainingIntentConfirmationRejectedData = {
name: typeof name
trainingId: string
payload: Record<string, never>
}

export type TrainingIntentConfirmationRejectedEvent = TrainingEventMetadata & TrainingIntentConfirmationRejectedData

const reducer: Reducer<TrainingIntentConfirmationRejectedEvent> = (
training: Training | null,
event: TrainingIntentConfirmationRejectedEvent
): Training => ({
...training,
status: 'QUEUED',
trainingId: event.trainingId,
intentConfirmation: {
...training?.intentConfirmation,
rejectedAt: event.emittedAt,
}
})

const isEmitted =
(training: Training | null) =>
training && training?.intentConfirmation && training.intentConfirmation.rejectedAt

export const trainingIntentConfirmationRejected = { name, reducer, isEmitted } as const

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import { Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-intent-confirmation-requested';

export type TrainingIntentConfirmationRequestedData = {
name: typeof name
trainingId: string
payload: Record<string, never>
}

export type TrainingIntentConfirmationRequestedEvent = TrainingEventMetadata & TrainingIntentConfirmationRequestedData

const reducer: Reducer<TrainingIntentConfirmationRequestedEvent> = (
training: Training | null,
event: TrainingIntentConfirmationRequestedEvent
): Training => ({
...training,
status: 'QUEUED',
trainingId: event.trainingId,
intentConfirmation: {
requestedAt: event.emittedAt,
}
})

const isEmitted =
(training: Training | null) =>
training && training?.intentConfirmation && !!training.intentConfirmation.requestedAt

export const trainingIntentConfirmationRequested = { name, reducer, isEmitted } as const

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import { Reducer, Training, TrainingEventMetadata } from "../types";

const name = 'training-intent-confirmation-responded';

export type TrainingIntentConfirmationRespondedData = {
name: typeof name
trainingId: string
payload: Record<string, never>
}

export type TrainingIntentConfirmationRespondedEvent = TrainingEventMetadata & TrainingIntentConfirmationRespondedData

const reducer: Reducer<TrainingIntentConfirmationRespondedEvent> = (
training: Training | null,
event: TrainingIntentConfirmationRespondedEvent
): Training => ({
...training,
status: 'QUEUED',
trainingId: event.trainingId,
intentConfirmation: {
...training?.intentConfirmation,
respondedAt: event.emittedAt,

}
})

const isEmitted =
(training: Training | null) =>
training && training?.intentConfirmation && training.intentConfirmation.respondedAt

export const trainingIntentConfirmationResponded = { name, reducer, isEmitted } as const

34 changes: 34 additions & 0 deletions libs/training-events/src/events/training-intent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import { Reducer, Training, TrainingEventMetadata, TrainingPurpose } from "../types";

const name = 'training-intent';

export type TrainingIntentEventData = {
trainingId: string,
name: typeof name
payload: {
student: number
rating: number
purpose: TrainingPurpose
}
}

export type TrainingIntentEvent = TrainingEventMetadata & TrainingIntentEventData

const reducer: Reducer<TrainingIntentEvent> = (
training: Training | null,
event: TrainingIntentEvent
): Training => ({
...training,
trainingId: event.trainingId,
status: 'QUEUED',
purpose: event.payload.purpose,
rating: event.payload.rating,
student: event.payload.student,
requestedAt: event.emittedAt,
})

const isEmitted = (training: Training | null) => !!training?.student

export const trainingIntent = { name, reducer, isEmitted } as const

Loading

0 comments on commit ad40e41

Please sign in to comment.