feat: 🎸 simulation
fix dps and add the push and DPS strategy
This commit is contained in:
@@ -8,6 +8,20 @@
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
padding: 0 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
dl dl,
|
||||
dl ol,
|
||||
dl ul,
|
||||
ol dl,
|
||||
ol ol,
|
||||
ol ul,
|
||||
ul dl,
|
||||
ul ol,
|
||||
ul ul {
|
||||
font-size: 90%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
||||
@@ -58,7 +58,14 @@ const isLive = computed(
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isLive" class="live">
|
||||
{{ featuresDone.length }} features live!
|
||||
<span v-if="featuresDone.length === 0">No features live yet</span>
|
||||
<span v-else>
|
||||
{{ featuresDone.length }} feature<template
|
||||
v-if="featuresDone.length > 1"
|
||||
>s</template
|
||||
>
|
||||
live!
|
||||
</span>
|
||||
</div>
|
||||
<ul class="done-list">
|
||||
<li v-for="feature in featuresDone" :key="feature.name">
|
||||
|
||||
@@ -10,16 +10,17 @@ onMounted(() => featureStore.initBoard())
|
||||
|
||||
const pullAndProblemSolving20Percent = () => {
|
||||
if (featureStore.meta.totalDays % 5 === 0) {
|
||||
featureStore.nextDay('problem-solving')
|
||||
featureStore.nextDay('pull-dps')
|
||||
} else {
|
||||
featureStore.nextDay('pull')
|
||||
}
|
||||
}
|
||||
|
||||
const pushAndProblemSolving20Percent = () => {
|
||||
if (featureStore.meta.totalDays % 5 === 0) {
|
||||
featureStore.nextDay('problem-solving')
|
||||
featureStore.nextDay('push-dps')
|
||||
} else {
|
||||
featureStore.nextDay('pull')
|
||||
featureStore.nextDay('push')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -57,7 +57,7 @@ export const getFeaturesForNextDay = ({
|
||||
features: Feature[]
|
||||
steps: FeatureStep[]
|
||||
initialStep: number
|
||||
strategy: Strategy
|
||||
strategy: Strategy | 'problem-solving'
|
||||
daysWithProblemSolving: number
|
||||
}): [Feature[], Feature[]] => {
|
||||
features
|
||||
@@ -78,6 +78,7 @@ export const getFeaturesForNextDay = ({
|
||||
const nextStep = steps.find(
|
||||
(step) => step.stepIndex === feature.step - 1
|
||||
)
|
||||
|
||||
if (!nextStep) {
|
||||
break
|
||||
}
|
||||
@@ -96,21 +97,23 @@ export const getFeaturesForNextDay = ({
|
||||
feature.status = 'doing'
|
||||
}
|
||||
|
||||
if (feature.status === 'doing') {
|
||||
if (
|
||||
hasQualityIssue({
|
||||
complexity: feature.complexity,
|
||||
tasksInParallel: features.filter(
|
||||
(f) => f.status === 'doing' && f.step === feature.step
|
||||
).length,
|
||||
daysWithProblemSolving
|
||||
})
|
||||
) {
|
||||
feature.step = Math.min(4, feature.step + 1)
|
||||
feature.qualityIssue++
|
||||
} else {
|
||||
feature.step--
|
||||
}
|
||||
if (feature.status === 'done') {
|
||||
break
|
||||
}
|
||||
|
||||
if (
|
||||
hasQualityIssue({
|
||||
complexity: feature.complexity,
|
||||
tasksInParallel: features.filter(
|
||||
(f) => f.status === 'doing' && f.step === feature.step
|
||||
).length,
|
||||
daysWithProblemSolving
|
||||
})
|
||||
) {
|
||||
feature.step = Math.min(4, feature.step + 1)
|
||||
feature.qualityIssue++
|
||||
} else {
|
||||
feature.step--
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -119,11 +122,12 @@ export const getFeaturesForNextDay = ({
|
||||
if (features.length < MAX_FEATURES) {
|
||||
switch (strategy) {
|
||||
case 'push': {
|
||||
const [newFeature] = popNElement(backlog, 1)
|
||||
const [nextFeature] = popNElement(backlog, 1)
|
||||
|
||||
if (newFeature) {
|
||||
features.push({ ...newFeature, step: initialStep })
|
||||
if (nextFeature) {
|
||||
features.push({ ...nextFeature, step: initialStep })
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
case 'pull': {
|
||||
@@ -158,21 +162,21 @@ const getOverburdenMultiplicator = (tasksInParallel: number) => {
|
||||
case 1:
|
||||
return 1
|
||||
case 2:
|
||||
return 1.05
|
||||
case 3:
|
||||
return 1.08
|
||||
case 4:
|
||||
return 1.1
|
||||
case 3:
|
||||
return 1.3
|
||||
case 4:
|
||||
return 1.6
|
||||
case 5:
|
||||
return 1.15
|
||||
return 2.2
|
||||
case 6:
|
||||
return 1.25
|
||||
return 3.2
|
||||
case 7:
|
||||
return 1.35
|
||||
return 4.5
|
||||
case 8:
|
||||
return 1.4
|
||||
return 6
|
||||
default:
|
||||
return 1.5
|
||||
return 8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,13 +213,14 @@ const getQualityProbability = (
|
||||
|
||||
export const nextDay = (
|
||||
state: FeatureState,
|
||||
strategy: Strategy
|
||||
strategy: Strategy | 'problem-solving'
|
||||
): FeatureState => {
|
||||
state.meta.totalDays++
|
||||
state.meta.strategy[strategy]++
|
||||
|
||||
if (strategy === 'problem-solving') {
|
||||
state.meta.daysWithProblemSolving++
|
||||
} else {
|
||||
state.meta.strategy[strategy]++
|
||||
}
|
||||
|
||||
const [backlog, features] = getFeaturesForNextDay({
|
||||
@@ -226,7 +231,6 @@ export const nextDay = (
|
||||
strategy,
|
||||
daysWithProblemSolving: state.meta.daysWithProblemSolving
|
||||
})
|
||||
|
||||
state.backlog = backlog
|
||||
state.features = features
|
||||
|
||||
@@ -255,11 +259,11 @@ export const simulate = (
|
||||
let i = 0
|
||||
|
||||
while (!isProjectFinished(state.features) && i++ < HARD_STOP) {
|
||||
if (strategy === 'problem-solving') {
|
||||
if (strategy === 'pull-dps' || strategy === 'push-dps') {
|
||||
if (state.meta.totalDays % 5 === 0) {
|
||||
state = nextDay(state, 'problem-solving')
|
||||
} else {
|
||||
state = nextDay(state, 'pull')
|
||||
state = nextDay(state, strategy.split('-')[0] as Strategy)
|
||||
}
|
||||
} else {
|
||||
state = nextDay(state, strategy)
|
||||
|
||||
@@ -19,7 +19,8 @@ const resetMeta = (): Meta => ({
|
||||
strategy: {
|
||||
push: 0,
|
||||
pull: 0,
|
||||
'problem-solving': 0
|
||||
'pull-dps': 0,
|
||||
'push-dps': 0
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
export type Strategy = 'push' | 'pull' | 'problem-solving'
|
||||
export type Strategy = 'push' | 'pull' | 'pull-dps' | 'push-dps'
|
||||
|
||||
@@ -21,10 +21,16 @@ const NUMBER_OF_SIMULATION = 1000
|
||||
</button>
|
||||
<button
|
||||
class="button button-outline"
|
||||
@click="simulationStore.simulate('problem-solving')"
|
||||
@click="simulationStore.simulate('pull-dps')"
|
||||
>
|
||||
simulate pull and problem solving
|
||||
</button>
|
||||
<button
|
||||
class="button button-outline"
|
||||
@click="simulationStore.simulate('push-dps')"
|
||||
>
|
||||
simulate push and problem solving
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button
|
||||
@@ -42,14 +48,19 @@ const NUMBER_OF_SIMULATION = 1000
|
||||
<button
|
||||
class="button button-outline"
|
||||
@click="
|
||||
simulationStore.multiSimulation(
|
||||
NUMBER_OF_SIMULATION,
|
||||
'problem-solving'
|
||||
)
|
||||
simulationStore.multiSimulation(NUMBER_OF_SIMULATION, 'pull-dps')
|
||||
"
|
||||
>
|
||||
simulate {{ NUMBER_OF_SIMULATION }} pull and problem solving
|
||||
</button>
|
||||
<button
|
||||
class="button button-outline"
|
||||
@click="
|
||||
simulationStore.multiSimulation(NUMBER_OF_SIMULATION, 'push-dps')
|
||||
"
|
||||
>
|
||||
simulate {{ NUMBER_OF_SIMULATION }} push and problem solving
|
||||
</button>
|
||||
<button
|
||||
class="button button-clear"
|
||||
@click="simulationStore.clearDashboard()"
|
||||
|
||||
@@ -6,7 +6,7 @@ const simulationStore = useSimulationStore()
|
||||
|
||||
<template>
|
||||
<div class="simulation-dashboard">
|
||||
<h3>Dashboard</h3>
|
||||
<h3>Simulation dashboard</h3>
|
||||
<h4>
|
||||
({{ simulationStore.simulationsDone }} /
|
||||
{{ simulationStore.requestedSimulation }}
|
||||
@@ -19,6 +19,7 @@ const simulationStore = useSimulationStore()
|
||||
<th>push</th>
|
||||
<th>pull</th>
|
||||
<th>pull and DPS</th>
|
||||
<th>push and DPS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -33,6 +34,9 @@ const simulationStore = useSimulationStore()
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPullDPSLeadTime }}
|
||||
</td>
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPushDPSLeadTime }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Complexity</td>
|
||||
@@ -45,6 +49,9 @@ const simulationStore = useSimulationStore()
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPullDPSComplexity }}
|
||||
</td>
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPushDPSComplexity }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Quality issue</td>
|
||||
@@ -57,6 +64,9 @@ const simulationStore = useSimulationStore()
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPullDPSQuality }}
|
||||
</td>
|
||||
<td class="numeric">
|
||||
{{ simulationStore.meanPushDPSQuality }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Dashboard, Meta } from '@/store-type'
|
||||
import { getRound } from '@/utils'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
// Get features done per day to plot it
|
||||
|
||||
type Mean = {
|
||||
leadTimeSum: number
|
||||
complexitySum: number
|
||||
@@ -35,7 +37,8 @@ const resetMeta = (): Meta => ({
|
||||
strategy: {
|
||||
push: 0,
|
||||
pull: 0,
|
||||
'problem-solving': 0
|
||||
'pull-dps': 0,
|
||||
'push-dps': 0
|
||||
}
|
||||
})
|
||||
|
||||
@@ -48,7 +51,8 @@ export const useSimulationStore = defineStore('dashboard', {
|
||||
mean: {
|
||||
push: newMean(),
|
||||
pull: newMean(),
|
||||
'problem-solving': newMean()
|
||||
'pull-dps': newMean(),
|
||||
'push-dps': newMean()
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -106,7 +110,8 @@ export const useSimulationStore = defineStore('dashboard', {
|
||||
this.dashboards = []
|
||||
this.mean.push = newMean()
|
||||
this.mean.pull = newMean()
|
||||
this.mean['problem-solving'] = newMean()
|
||||
this.mean['pull-dps'] = newMean()
|
||||
this.mean['push-dps'] = newMean()
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@@ -118,8 +123,14 @@ export const useSimulationStore = defineStore('dashboard', {
|
||||
},
|
||||
meanPullDPSLeadTime: (state) => {
|
||||
return getRound(
|
||||
state.mean['problem-solving'].leadTimeSum,
|
||||
state.mean['problem-solving'].simulations
|
||||
state.mean['pull-dps'].leadTimeSum,
|
||||
state.mean['pull-dps'].simulations
|
||||
)
|
||||
},
|
||||
meanPushDPSLeadTime: (state) => {
|
||||
return getRound(
|
||||
state.mean['push-dps'].leadTimeSum,
|
||||
state.mean['push-dps'].simulations
|
||||
)
|
||||
},
|
||||
meanPushComplexity: (state) => {
|
||||
@@ -136,8 +147,14 @@ export const useSimulationStore = defineStore('dashboard', {
|
||||
},
|
||||
meanPullDPSComplexity: (state) => {
|
||||
return getRound(
|
||||
state.mean['problem-solving'].complexitySum,
|
||||
state.mean['problem-solving'].simulations
|
||||
state.mean['pull-dps'].complexitySum,
|
||||
state.mean['pull-dps'].simulations
|
||||
)
|
||||
},
|
||||
meanPushDPSComplexity: (state) => {
|
||||
return getRound(
|
||||
state.mean['push-dps'].complexitySum,
|
||||
state.mean['push-dps'].simulations
|
||||
)
|
||||
},
|
||||
meanPushQuality: (state) => {
|
||||
@@ -154,8 +171,14 @@ export const useSimulationStore = defineStore('dashboard', {
|
||||
},
|
||||
meanPullDPSQuality: (state) => {
|
||||
return getRound(
|
||||
state.mean['problem-solving'].qualityIssueSum,
|
||||
state.mean['problem-solving'].simulations
|
||||
state.mean['pull-dps'].qualityIssueSum,
|
||||
state.mean['pull-dps'].simulations
|
||||
)
|
||||
},
|
||||
meanPushDPSQuality: (state) => {
|
||||
return getRound(
|
||||
state.mean['push-dps'].qualityIssueSum,
|
||||
state.mean['push-dps'].simulations
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user