///
import { featureSteps } from '@/modules/pull-system/feature/feature-steps'
import type { Strategy } from '@/modules/pull-system/lean/strategy'
import type { Dashboard, Meta } from '@/store-type'
import { getRound } from '@/utils'
import { defineStore } from 'pinia'
type Mean = {
leadTimeSum: number
minLeadTime: number
maxLeadTime: number
cycleTimeSum: number
complexitySum: number
qualityIssueSum: number
teamWorkExperienceSum: number
totalDaysSum: number
simulations: number
}
type State = {
dashboards: Dashboard[]
requestedSimulation: number
simulationsDone: number
mean: Record
}
const initMean = (): Mean => ({
leadTimeSum: 0,
minLeadTime: Infinity,
maxLeadTime: 0,
cycleTimeSum: 0,
complexitySum: 0,
qualityIssueSum: 0,
teamWorkExperienceSum: 0,
totalDaysSum: 0,
simulations: 0
})
const instance = new ComlinkWorker(
new URL('../feature/feature-board', import.meta.url)
)
const resetMeta = (): Meta => ({
totalDays: 0,
teamWorkExperience: 0,
featuresDonePerDay: [],
strategy: {
push: 0,
pull: 0,
'pull-dps': 0,
'push-dps': 0
}
})
export const useSimulationStore = defineStore('dashboard', {
state: (): State => {
return {
dashboards: [],
requestedSimulation: 0,
simulationsDone: 0,
mean: {
push: initMean(),
pull: initMean(),
'pull-dps': initMean(),
'push-dps': initMean()
}
}
},
actions: {
async simulate(strategy: Strategy) {
const steps = featureSteps
const backlog = await instance.newBacklog('mobile-app')
const features = await instance.initBoard(steps, backlog, true)
const newState = await instance.simulate(
{
backlog,
steps,
features,
meta: resetMeta()
},
strategy
)
const [worstFeature] = newState.features.sort((a, b) =>
a.qualityIssue > b.qualityIssue ? -1 : 1
)
const dashboard: Dashboard = {
uuid: new Date().getTime().toString(),
meta: newState.meta,
analysis: {
meanComplexity: await instance.getMeanComplexity(newState.features),
meanLeadTime: await instance.getMeanLeadTime(newState.features),
meanQualityIssue: await instance.getMeanQualityIssue(
newState.features
),
worstFeature,
strategy
}
}
this.dashboards.push(dashboard)
this.mean[strategy].leadTimeSum += dashboard.analysis.meanLeadTime
this.mean[strategy].minLeadTime = Math.min(
this.mean[strategy].minLeadTime,
...newState.features.map((f) => f.leadTime)
)
this.mean[strategy].maxLeadTime = Math.max(
this.mean[strategy].maxLeadTime,
...newState.features.map((f) => f.leadTime)
)
this.mean[strategy].cycleTimeSum +=
dashboard.meta.totalDays / newState.features.length
this.mean[strategy].complexitySum += dashboard.analysis.meanComplexity
this.mean[strategy].qualityIssueSum += dashboard.analysis.meanQualityIssue
// this.mean[strategy].teamWorkExperienceSum +=
// dashboard.meta.teamWorkExperience
this.mean[strategy].totalDaysSum += dashboard.meta.totalDays
this.mean[strategy].simulations++
},
async multiSimulation(simulations: number, strategy: Strategy) {
this.requestedSimulation += simulations
for (let i = 0; i < simulations; i++) {
await this.simulate(strategy)
this.simulationsDone++
}
},
clearDashboard() {
this.dashboards = []
this.mean.push = initMean()
this.mean.pull = initMean()
this.mean['pull-dps'] = initMean()
this.mean['push-dps'] = initMean()
this.simulationsDone = 0
this.requestedSimulation = 0
}
},
getters: {
meanLeadTime: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].leadTimeSum,
state.mean[strategy].simulations
),
minLeadTime: (state) => (strategy: Strategy) =>
state.mean[strategy].minLeadTime,
maxLeadTime: (state) => (strategy: Strategy) =>
state.mean[strategy].maxLeadTime,
meanCycleTime: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].cycleTimeSum,
state.mean[strategy].simulations
),
meanComplexity: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].complexitySum,
state.mean[strategy].simulations
),
meanQuality: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].qualityIssueSum,
state.mean[strategy].simulations
),
meanTeamWorkExperience: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].teamWorkExperienceSum,
state.mean[strategy].simulations
),
meanTotalDays: (state) => (strategy: Strategy) =>
getRound(
state.mean[strategy].totalDaysSum,
state.mean[strategy].simulations
),
hasSimulationFinished: (state) =>
state.requestedSimulation > 0 &&
state.requestedSimulation === state.simulationsDone
}
})