easier takt time computation

This commit is contained in:
Julien Calixte
2023-07-27 01:10:15 +02:00
parent 8d0d3dc7f9
commit e218ae5447
5 changed files with 33 additions and 22 deletions

View File

@@ -4,22 +4,25 @@ import { featureSteps } from '@/modules/feature/feature-steps'
import { useFeatureStore } from '@/modules/feature/feature-store' import { useFeatureStore } from '@/modules/feature/feature-store'
import { onMounted } from 'vue' import { onMounted } from 'vue'
const NUMBER_OF_FEATURES = 20
const featureStore = useFeatureStore() const featureStore = useFeatureStore()
onMounted(() => featureStore.initBoard()) onMounted(() => featureStore.initBoard(NUMBER_OF_FEATURES))
</script> </script>
<template> <template>
<div class="dashboard"> <div class="dashboard">
<div> <div>
{{ featureStore.features.length }} features | mean complexity : {{ featureStore.features.length }} / {{ NUMBER_OF_FEATURES }} features in
{{ featureStore.meanComplexity }} | mean lead time : the board | mean complexity : {{ featureStore.meanComplexity }} | mean
{{ featureStore.meanLeadTime }} days | Total days: lead time : {{ featureStore.meanLeadTime }} days | Total days:
{{ featureStore.meta.totalDays }} | Team work experience: {{ featureStore.meta.totalDays }} | Team work experience:
{{ featureStore.meta.teamWorkExperience }} {{ featureStore.meta.teamWorkExperience }}
</div> </div>
<div class="row"> <div class="row">
New feature live every {{ featureStore.taktTime }} days. New feature live every {{ featureStore.taktTime }} days. Finishing in
{{ featureStore.eat }} days.
</div> </div>
<div class="row">Strategy of the day:</div> <div class="row">Strategy of the day:</div>
<div class="row"> <div class="row">

View File

@@ -11,7 +11,6 @@ import {
sumElements sumElements
} from '@/utils' } from '@/utils'
const MAX_FEATURES = 200
const HARD_STOP = 5000 const HARD_STOP = 5000
const hasQualityIssue = ({ const hasQualityIssue = ({
@@ -34,7 +33,10 @@ const hasQualityIssue = ({
return quality > qualityProbability / multiplicator return quality > qualityProbability / multiplicator
} }
export const newBacklog = () => shuffleArray(initialFeatures) export const newBacklog = (limit?: number) =>
limit !== undefined
? popNElement(shuffleArray(initialFeatures), limit)
: shuffleArray(initialFeatures)
export const initBoard = ( export const initBoard = (
steps: FeatureStep[], steps: FeatureStep[],
@@ -125,7 +127,7 @@ export const getFeaturesForNextDay = ({
} }
}) })
if (features.length < MAX_FEATURES) { if (backlog.length > 0) {
switch (strategy) { switch (strategy) {
case 'push': { case 'push': {
const [nextFeature] = popNElement(backlog, 1) const [nextFeature] = popNElement(backlog, 1)
@@ -217,7 +219,7 @@ const getQualityProbability = (
return probabilityOfGoodQuality return probabilityOfGoodQuality
} }
const isFeatureDone = (feature: Feature) => export const isFeatureDone = (feature: Feature) =>
feature.step === 0 && feature.status === 'done' feature.step === 0 && feature.status === 'done'
export const nextDay = ( export const nextDay = (
@@ -276,7 +278,7 @@ 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 === 'pull-dps' || strategy === 'push-dps') { if (strategy.includes('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 {

View File

@@ -4,13 +4,13 @@ import {
getMeanLeadTime, getMeanLeadTime,
getMeanQualityIssue, getMeanQualityIssue,
initBoard, initBoard,
isFeatureDone,
newBacklog, newBacklog,
nextDay nextDay
} from '@/modules/feature/feature-board' } from '@/modules/feature/feature-board'
import { featureSteps } from '@/modules/feature/feature-steps' import { featureSteps } from '@/modules/feature/feature-steps'
import { Strategy } from '@/modules/lean/strategy' import { Strategy } from '@/modules/lean/strategy'
import { FeatureState, Meta } from '@/store-type' import { FeatureState, Meta } from '@/store-type'
import { sumElements } from '@/utils'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
const resetMeta = (): Meta => ({ const resetMeta = (): Meta => ({
@@ -33,9 +33,9 @@ export const useFeatureStore = defineStore('feature', {
meta: resetMeta() meta: resetMeta()
}), }),
actions: { actions: {
// set the number of feature we want // todo set the number of feature we want
async initBoard() { async initBoard(limit: number) {
this.backlog = newBacklog() this.backlog = newBacklog(limit)
this.steps = featureSteps this.steps = featureSteps
this.features = initBoard(this.steps, this.backlog) this.features = initBoard(this.steps, this.backlog)
@@ -56,10 +56,10 @@ export const useFeatureStore = defineStore('feature', {
meanComplexity: (state) => getMeanComplexity(state.features), meanComplexity: (state) => getMeanComplexity(state.features),
meanLeadTime: (state) => getMeanLeadTime(state.features), meanLeadTime: (state) => getMeanLeadTime(state.features),
meanQualityIssue: (state) => getMeanQualityIssue(state.features), meanQualityIssue: (state) => getMeanQualityIssue(state.features),
taktTime: (state) => taktTime: (state): string =>
( (
state.meta.totalDays / sumElements(state.meta.featuresDonePerDay) state.meta.totalDays / state.features.filter(isFeatureDone).length
).toFixed(2) ?? 0, ).toFixed(2) ?? `0`,
featuresGroupedByStep: (state) => { featuresGroupedByStep: (state) => {
const groupedByStep: Record<number, Feature[]> = {} const groupedByStep: Record<number, Feature[]> = {}
@@ -72,6 +72,13 @@ export const useFeatureStore = defineStore('feature', {
}) })
return groupedByStep return groupedByStep
},
eat(): string {
return (
parseFloat(this.taktTime) *
(this.features.filter((feature) => !isFeatureDone(feature)).length +
this.backlog.length)
).toFixed(2)
} }
} }
}) })

View File

@@ -21,8 +21,8 @@ const strategies: Strategy[] = ['push', 'pull', 'push-dps', 'pull-dps']
<th>#</th> <th>#</th>
<th class="numeric">push</th> <th class="numeric">push</th>
<th class="numeric">pull</th> <th class="numeric">pull</th>
<th class="numeric">pull and DPS</th>
<th class="numeric">push and DPS</th> <th class="numeric">push and DPS</th>
<th class="numeric">pull and DPS</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@@ -1,7 +1,7 @@
import { featureSteps } from '@/modules/feature/feature-steps' import { featureSteps } from '@/modules/feature/feature-steps'
import { Strategy } from '@/modules/lean/strategy' import { Strategy } from '@/modules/lean/strategy'
import { Dashboard, Meta } from '@/store-type' import { Dashboard, Meta } from '@/store-type'
import { getRound, sumElements } from '@/utils' import { getRound } from '@/utils'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
// Get features done per day to plot it // Get features done per day to plot it
@@ -64,6 +64,7 @@ export const useSimulationStore = defineStore('dashboard', {
this.dashboards.push(dashboard) this.dashboards.push(dashboard)
}, },
async simulate(strategy: Strategy) { async simulate(strategy: Strategy) {
this.requestedSimulation++
const steps = featureSteps const steps = featureSteps
const backlog = await instance.newBacklog() const backlog = await instance.newBacklog()
const features = await instance.initBoard(steps, backlog) const features = await instance.initBoard(steps, backlog)
@@ -98,10 +99,8 @@ export const useSimulationStore = defineStore('dashboard', {
this.newDashboard(dashboard) this.newDashboard(dashboard)
this.mean[strategy].leadTimeSum += dashboard.analysis.meanLeadTime this.mean[strategy].leadTimeSum += dashboard.analysis.meanLeadTime
// todo: set directly the number of features
this.mean[strategy].taktTimeSum += this.mean[strategy].taktTimeSum +=
dashboard.meta.totalDays / dashboard.meta.totalDays / newState.features.length
sumElements(dashboard.meta.featuresDonePerDay)
this.mean[strategy].complexitySum += dashboard.analysis.meanComplexity this.mean[strategy].complexitySum += dashboard.analysis.meanComplexity
this.mean[strategy].qualityIssueSum += dashboard.analysis.meanQualityIssue this.mean[strategy].qualityIssueSum += dashboard.analysis.meanQualityIssue
this.mean[strategy].simulations++ this.mean[strategy].simulations++