refactor: enhance routing and state management in CoopBuilder, add migration checks on startup, and update Tailwind configuration for improved component styling
This commit is contained in:
parent
848386e3dd
commit
4cea1f71fe
55 changed files with 4053 additions and 1486 deletions
109
composables/useScenarios.ts
Normal file
109
composables/useScenarios.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import { monthlyPayroll } from '~/types/members'
|
||||
|
||||
export function useScenarios() {
|
||||
const membersStore = useMembersStore()
|
||||
const streamsStore = useStreamsStore()
|
||||
const policiesStore = usePoliciesStore()
|
||||
const budgetStore = useBudgetStore()
|
||||
const cashStore = useCashStore()
|
||||
|
||||
// Base runway calculation
|
||||
function calculateScenarioRunway(
|
||||
members: any[],
|
||||
streams: any[],
|
||||
operatingMode: 'minimum' | 'target' = 'minimum'
|
||||
) {
|
||||
// Calculate payroll for scenario
|
||||
const payrollCost = monthlyPayroll(members, operatingMode)
|
||||
const oncostPct = policiesStore.payrollOncostPct || 0
|
||||
const totalPayroll = payrollCost * (1 + oncostPct / 100)
|
||||
|
||||
// Calculate revenue
|
||||
const totalRevenue = streams.reduce((sum, s) => sum + (s.targetMonthlyAmount || 0), 0)
|
||||
|
||||
// Add overhead
|
||||
const overheadCost = budgetStore.overheadCosts.reduce((sum, cost) => sum + (cost.amount || 0), 0)
|
||||
|
||||
// Net monthly
|
||||
const monthlyNet = totalRevenue - totalPayroll - overheadCost
|
||||
|
||||
// Cash + savings
|
||||
const cash = cashStore.currentCash || 50000
|
||||
const savings = cashStore.currentSavings || 15000
|
||||
const totalLiquid = cash + savings
|
||||
|
||||
// Runway calculation
|
||||
const monthlyBurn = totalPayroll + overheadCost
|
||||
const runway = monthlyBurn > 0 ? totalLiquid / monthlyBurn : Infinity
|
||||
|
||||
return {
|
||||
runway: Math.max(0, runway),
|
||||
monthlyNet,
|
||||
monthlyBurn,
|
||||
totalRevenue,
|
||||
totalPayroll
|
||||
}
|
||||
}
|
||||
|
||||
// Scenario transformations per CLAUDE.md
|
||||
const scenarioTransforms = {
|
||||
current: () => ({
|
||||
members: [...membersStore.members],
|
||||
streams: [...streamsStore.streams]
|
||||
}),
|
||||
|
||||
quitJobs: () => ({
|
||||
// Set external income to 0 for members who have day jobs
|
||||
members: membersStore.members.map(m => ({
|
||||
...m,
|
||||
externalMonthlyIncome: 0 // Assume everyone quits their day job
|
||||
})),
|
||||
streams: [...streamsStore.streams]
|
||||
}),
|
||||
|
||||
startProduction: () => ({
|
||||
members: [...membersStore.members],
|
||||
// Reduce service revenue, increase production costs
|
||||
streams: streamsStore.streams.map(s => {
|
||||
// Reduce service contracts by 30%
|
||||
if (s.category?.toLowerCase().includes('service') || s.name.toLowerCase().includes('service')) {
|
||||
return { ...s, targetMonthlyAmount: (s.targetMonthlyAmount || 0) * 0.7 }
|
||||
}
|
||||
return s
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Calculate all scenarios
|
||||
const scenarios = computed(() => {
|
||||
const currentMode = policiesStore.operatingMode || 'minimum'
|
||||
|
||||
const current = scenarioTransforms.current()
|
||||
const quitJobs = scenarioTransforms.quitJobs()
|
||||
const startProduction = scenarioTransforms.startProduction()
|
||||
|
||||
return {
|
||||
current: {
|
||||
name: 'Operate Current',
|
||||
status: 'Active',
|
||||
...calculateScenarioRunway(current.members, current.streams, currentMode)
|
||||
},
|
||||
quitJobs: {
|
||||
name: 'Quit Day Jobs',
|
||||
status: 'Scenario',
|
||||
...calculateScenarioRunway(quitJobs.members, quitJobs.streams, currentMode)
|
||||
},
|
||||
startProduction: {
|
||||
name: 'Start Production',
|
||||
status: 'Scenario',
|
||||
...calculateScenarioRunway(startProduction.members, startProduction.streams, currentMode)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
scenarios,
|
||||
calculateScenarioRunway,
|
||||
scenarioTransforms
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue