Created
May 7, 2025 21:50
-
-
Save 0xack13/83b3b00884251b3fcdbe1022c224fd5f to your computer and use it in GitHub Desktop.
FSM-escalation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const THRESHOLDS = { | |
ESCALATE_TO_BUG: 5, | |
ESCALATE_TO_P2: 10, | |
}; | |
const PRIORITY = { | |
P1: 'P1', | |
P2: 'P2', | |
P3: 'P3', | |
}; | |
const ISSUE_TYPE = { | |
STORY: 'story', | |
BUG: 'bug', | |
}; | |
class TicketEscalationFSM { | |
constructor(context) { | |
this.context = { | |
...context, | |
type: ISSUE_TYPE.STORY, | |
priority: PRIORITY.P3, | |
}; | |
this.machine = this._createMachine({ | |
initialState: 'created', | |
states: { | |
created: { | |
actions: { | |
onEnter: (ctx) => | |
console.log(`[${ctx.issueId}] Created as STORY (P3)`), | |
onExit: (ctx) => | |
console.log(`[${ctx.issueId}] Exiting 'created' state`), | |
}, | |
transitions: { | |
escalateToBug: { | |
condition: (ctx) => ctx.occurrences > THRESHOLDS.ESCALATE_TO_BUG, | |
target: 'bugP3', | |
action: (ctx) => { | |
ctx.type = ISSUE_TYPE.BUG; | |
console.log(`[${ctx.issueId}] Escalated to BUG (P3)`); | |
}, | |
}, | |
}, | |
}, | |
bugP3: { | |
actions: { | |
onEnter: (ctx) => | |
console.log(`[${ctx.issueId}] Entered Bug P3`), | |
onExit: (ctx) => | |
console.log(`[${ctx.issueId}] Exiting 'bugP3' state`), | |
}, | |
transitions: { | |
escalateToP2: { | |
condition: (ctx) => ctx.occurrences > THRESHOLDS.ESCALATE_TO_P2, | |
target: 'bugP2', | |
action: (ctx) => { | |
ctx.priority = PRIORITY.P2; | |
console.log(`[${ctx.issueId}] Escalated priority to P2`); | |
}, | |
}, | |
}, | |
}, | |
bugP2: { | |
actions: { | |
onEnter: (ctx) => | |
console.log(`[${ctx.issueId}] Final state: Bug P2`), | |
}, | |
transitions: {}, | |
}, | |
}, | |
}); | |
} | |
_createMachine(definition) { | |
const machine = { | |
value: definition.initialState, | |
transition: () => { | |
const stateDef = definition.states[machine.value]; | |
for (const [_, transition] of Object.entries(stateDef.transitions)) { | |
if (!transition.condition || transition.condition(this.context)) { | |
stateDef.actions?.onExit?.(this.context); | |
transition.action?.(this.context); | |
machine.value = transition.target; | |
definition.states[machine.value].actions?.onEnter?.(this.context); | |
return machine.value; | |
} | |
} | |
return machine.value; | |
}, | |
}; | |
// Initial entry action | |
definition.states[machine.value].actions?.onEnter?.(this.context); | |
return machine; | |
} | |
escalate(occurrences) { | |
this.context.occurrences = occurrences; | |
return this.machine.transition(); | |
} | |
getState() { | |
return this.machine.value; | |
} | |
getContext() { | |
return this.context; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ticket1 = new TicketEscalationFSM({ issueId: 'TICKET-001' }); | |
ticket1.escalate(6); // Escalates to bugP3 | |
ticket1.escalate(11); // Escalates to bugP2 | |
console.log(ticket1.getState()); // 'bugP2' | |
console.log('\n----\n'); | |
const ticket2 = new TicketEscalationFSM({ issueId: 'TICKET-002' }); | |
ticket2.escalate(3); // No escalation | |
console.log(ticket2.getState()); // 'created' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment