turash/models/team/team.go
Damir Mukimov cdca1ea1a7
Reorganize funding programs and create application documents
- Reorganized funding program structure: moved standalone .md files into organized directories with PROGRAM_INFO.md and APPLICATION_SCOPE.md
- Created budget files for selected priority programs:
  * EIC Accelerator: budget_breakdown.csv and budget_justification.md (€1.815M)
  * ZIM: budget_breakdown.csv and budget_justification.md (€465k)
  * DBU: budget_breakdown.csv and budget_justification.md (€152.5k)
  * LIFE Programme: budget_breakdown.csv and budget_justification.md (€1.815M)
- Created team CV files for all selected programs (CV_Damir_Mukimov.md)
- Added application documents structure:
  * funding/applications/budget/ - Master budget files and templates
  * funding/applications/team_cvs/ - Master CV and team expertise summary
- Updated FUNDING_GAP_ANALYSIS.md to reflect completed documents
- Added APPLICATION_REQUIREMENTS_REPORT.md with detailed requirements
- Added PREPARATION_PRIORITY.md for application preparation workflow
2025-11-01 09:59:48 +01:00

125 lines
6.1 KiB
Go

package team
import (
"github.com/damirmukimov/city_resource_graph/models/params"
)
// TeamMember represents a single team member with role and salary.
type TeamMember struct {
Role string `json:"role" yaml:"role"` // e.g., "backend_engineer", "frontend_engineer"
Salary float64 `json:"salary" yaml:"salary"` // Annual salary in EUR
}
// TeamComposition defines team composition for a given year.
type TeamComposition struct {
BackendEngineers int `json:"backend_engineers" yaml:"backend_engineers"` // Number of backend engineers
FrontendEngineers int `json:"frontend_engineers" yaml:"frontend_engineers"` // Number of frontend engineers
DevOpsEngineers int `json:"devops_engineers" yaml:"devops_engineers"` // Number of DevOps engineers
DataEngineers int `json:"data_engineers" yaml:"data_engineers"` // Number of data engineers
CTO int `json:"cto" yaml:"cto"` // Number of CTOs (typically 1)
BDSales int `json:"bd_sales" yaml:"bd_sales"` // Number of BD/Sales managers
DomainExperts int `json:"domain_experts" yaml:"domain_experts"` // Number of domain experts
CustomerSuccess int `json:"customer_success" yaml:"customer_success"` // Number of customer success
Operations int `json:"operations" yaml:"operations"` // Number of operations staff
Total int `json:"total" yaml:"total"` // Total team size
}
// Salaries defines annual salary for each role.
type Salaries struct {
BackendEngineer float64 `json:"backend_engineer" yaml:"backend_engineer"` // Annual salary in EUR
FrontendEngineer float64 `json:"frontend_engineer" yaml:"frontend_engineer"` // Annual salary in EUR
DevOpsEngineer float64 `json:"devops_engineer" yaml:"devops_engineer"` // Annual salary in EUR
DataEngineer float64 `json:"data_engineer" yaml:"data_engineer"` // Annual salary in EUR
CTO float64 `json:"cto" yaml:"cto"` // Annual salary in EUR
BDSales float64 `json:"bd_sales" yaml:"bd_sales"` // Annual salary in EUR
DomainExpert float64 `json:"domain_expert" yaml:"domain_expert"` // Annual salary in EUR
CustomerSuccess float64 `json:"customer_success" yaml:"customer_success"` // Annual salary in EUR
Operations float64 `json:"operations" yaml:"operations"` // Annual salary in EUR
}
// DefaultSalaries returns default salaries for each role.
func DefaultSalaries() Salaries {
return Salaries{
BackendEngineer: 100000, // €100k/year
FrontendEngineer: 100000, // €100k/year
DevOpsEngineer: 100000, // €100k/year
DataEngineer: 100000, // €100k/year
CTO: 120000, // €120k/year
BDSales: 100000, // €100k/year
DomainExpert: 90000, // €90k/year
CustomerSuccess: 70000, // €70k/year
Operations: 70000, // €70k/year
}
}
// CalculateTeamCosts computes total personnel costs for a team composition.
func CalculateTeamCosts(composition TeamComposition, salaries Salaries) float64 {
var total float64
total += float64(composition.BackendEngineers) * salaries.BackendEngineer
total += float64(composition.FrontendEngineers) * salaries.FrontendEngineer
total += float64(composition.DevOpsEngineers) * salaries.DevOpsEngineer
total += float64(composition.DataEngineers) * salaries.DataEngineer
total += float64(composition.CTO) * salaries.CTO
total += float64(composition.BDSales) * salaries.BDSales
total += float64(composition.DomainExperts) * salaries.DomainExpert
total += float64(composition.CustomerSuccess) * salaries.CustomerSuccess
total += float64(composition.Operations) * salaries.Operations
return total
}
// CalculateTeamCostsFromParams computes team costs using params structure.
// This bridges the old CostParams (engineers count + salary) to new team structure.
func CalculateTeamCostsFromParams(year int, p *params.Params, salaries Salaries) (float64, TeamComposition) {
// Get total engineers from params
totalEngineers := p.Costs.Engineers.GetYear(year)
// Default distribution (can be overridden in params.yaml)
composition := TeamComposition{
BackendEngineers: int(float64(totalEngineers) * 0.5), // 50% backend
FrontendEngineers: int(float64(totalEngineers) * 0.25), // 25% frontend
DevOpsEngineers: int(float64(totalEngineers) * 0.125), // 12.5% DevOps
DataEngineers: int(float64(totalEngineers) * 0.125), // 12.5% data
CTO: 1, // 1 CTO
BDSales: 1, // 1 BD/Sales
DomainExperts: 2, // 2 domain experts
CustomerSuccess: 0, // 0 initially, grows over time
Operations: 0, // 0 initially
}
// Adjust to match total engineers (distribute remaining)
allocated := composition.BackendEngineers + composition.FrontendEngineers +
composition.DevOpsEngineers + composition.DataEngineers
if allocated < totalEngineers {
// Add remaining to backend engineers
composition.BackendEngineers += totalEngineers - allocated
}
composition.Total = totalEngineers + composition.CTO + composition.BDSales +
composition.DomainExperts + composition.CustomerSuccess + composition.Operations
// Calculate costs
totalCost := CalculateTeamCosts(composition, salaries)
return totalCost, composition
}
// GetYearlyTeamComposition returns team composition for a given year.
// This can be extended to read from params.yaml if team structure is defined there.
func GetYearlyTeamComposition(year int, p *params.Params) TeamComposition {
salaries := DefaultSalaries()
_, composition := CalculateTeamCostsFromParams(year, p, salaries)
// Adjust based on year (team grows over time)
if year >= 2 {
composition.CustomerSuccess = 1 // Add customer success in year 2+
}
if year >= 3 {
composition.Operations = 1 // Add operations in year 3+
}
return composition
}