diff --git a/src/modules/feature/FeatureSteps.vue b/src/modules/feature/FeatureSteps.vue index 092fb5c..2098129 100644 --- a/src/modules/feature/FeatureSteps.vue +++ b/src/modules/feature/FeatureSteps.vue @@ -1,68 +1,24 @@ diff --git a/src/modules/feature/feature-board.ts b/src/modules/feature/feature-board.ts index abdf7ef..8ccc2a4 100644 --- a/src/modules/feature/feature-board.ts +++ b/src/modules/feature/feature-board.ts @@ -53,64 +53,71 @@ const hasQualityIssue = ( return Math.random() > probabilityOfQualityIssue / multiplicator } -export const createFeatureBoard = () => { - const boardFeatures = shuffleArray(features) +export const newBoard = () => shuffleArray(features) - const initBoard = (steps: FeatureStep[]): Feature[] => { - const initialFeatures = popNElement(boardFeatures, 10) +export const initBoard = ( + steps: FeatureStep[], + features: Feature[] +): Feature[] => { + const initialFeatures = popNElement(features, 10) - initialFeatures.forEach((feature) => { - const step = pickRandomElement(steps) - feature.status = pickRandomElement(['doing', 'done']) - feature.step = step.stepIndex - }) + initialFeatures.forEach((feature) => { + const step = pickRandomElement(steps) + feature.status = pickRandomElement(['doing', 'done']) + feature.step = step.stepIndex + }) - return initialFeatures - } + return initialFeatures +} - const nextDay = (features: Feature[], initialStep: number): Feature[] => { - features.forEach((feature) => { - const isFeatureLive = feature.step === 0 && feature.status === 'done' - if (isFeatureLive) { - return - } - - feature.leadTime++ - - switch (feature.status) { - case 'doing': - feature.status = 'done' - break - case 'done': - feature.status = 'doing' - - if ( - hasQualityIssue( - feature.complexity, - features.filter( - (f) => f.status === 'doing' && f.step === feature.step - ).length - ) - ) { - feature.step = Math.min(4, feature.step + 1) - feature.qualityIssue++ - } else { - feature.step-- - } - break - } - }) - - if (features.length < MAX_FEATURES) { - const [newFeature] = popNElement(boardFeatures, 1) - - if (newFeature) { - features.push({ ...newFeature, step: initialStep }) - } +export const nextDay = ({ + backlog, + features, + initialStep +}: { + backlog: Feature[] + features: Feature[] + initialStep: number +}): Feature[] => { + features.forEach((feature) => { + const isFeatureLive = feature.step === 0 && feature.status === 'done' + if (isFeatureLive) { + return } - return features + feature.leadTime++ + + switch (feature.status) { + case 'doing': + feature.status = 'done' + break + case 'done': + feature.status = 'doing' + + if ( + hasQualityIssue( + feature.complexity, + features.filter( + (f) => f.status === 'doing' && f.step === feature.step + ).length + ) + ) { + feature.step = Math.min(4, feature.step + 1) + feature.qualityIssue++ + } else { + feature.step-- + } + break + } + }) + + if (features.length < MAX_FEATURES) { + const [newFeature] = popNElement(backlog, 1) + + if (newFeature) { + features.push({ ...newFeature, step: initialStep }) + } } - return { initBoard, nextDay } + return features } diff --git a/src/modules/feature/store.ts b/src/modules/feature/store.ts index 6fe397f..a8d17e8 100644 --- a/src/modules/feature/store.ts +++ b/src/modules/feature/store.ts @@ -1,15 +1,74 @@ import { Feature } from '@/modules/feature/feature' -import { FeatureStep } from '@/modules/feature/feature-steps' +import { initBoard, newBoard, nextDay } from '@/modules/feature/feature-board' +import { FeatureStep, featureSteps } from '@/modules/feature/feature-steps' +import { sumElements } from '@/utils' import { defineStore } from 'pinia' type State = { steps: FeatureStep[] features: Feature[] + backlog: Feature[] + meta: { + totalDays: number + } } -export const featureStore = defineStore('feature', { +export const useFeatureStore = defineStore('feature', { state: (): State => ({ steps: [], - features: [] - }) + features: [], + backlog: [], + meta: { + totalDays: 0 + } + }), + actions: { + initBoard() { + this.backlog = newBoard() + this.steps = featureSteps + this.features = initBoard(this.steps, this.backlog) + this.meta.totalDays = 0 + }, + nextDay() { + this.features = nextDay({ + backlog: this.backlog, + features: this.features, + initialStep: this.steps[0].stepIndex + }) + this.meta.totalDays++ + } + }, + getters: { + meanComplexity: (state) => { + return ( + Math.round( + 100 * + (sumElements(state.features.map((feature) => feature.complexity)) / + state.features.length) + ) / 100 + ) + }, + meanLeadTime: (state) => { + return ( + Math.round( + 100 * + (sumElements(state.features.map((feature) => feature.leadTime)) / + state.features.length) + ) / 100 + ) + }, + featuresGroupedByStep: (state) => { + const groupedByStep: Record = {} + + state.features.forEach((feature) => { + if (!groupedByStep[feature.step]) { + groupedByStep[feature.step] = [feature] + } else { + groupedByStep[feature.step].push(feature) + } + }) + + return groupedByStep + } + } })