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