AOSSIE-Org / AOSSIE-Org/OrgExplorer
[BUG]: Bus Factor metric on Contributors page always evaluates to 0 (UNKNOWN) due to property mismatch
- Linguagem predominante
- JavaScript
- Estrelas
- 34
- Forks
- 92
- Merge médio
- 8d 7h
- PRs com merge (30d)
- 12
Descrição
### Bug Description
On the Contributors page (`/contributors`), the **Bus Factor Risk** metric card always evaluates to `Bus Factor: 0` with risk level `UNKNOWN` and subtitle `0 contributors own over 50% of total commits. Knowledge distribution is heavily skewed.`, regardless of the organization analyzed.
This is caused by a property name mismatch between `model.contributors` and `computeBusFactor`:
- `computeBusFactor` in `src/services/analytics.js` expects contributor objects to have a `.contributions` property:
```javascript
const total = contributors.reduce((s, c) => s + c.contributions, 0)
```
- However, in `buildAnalyticalModel` (`src/services/analytics.js`), aggregate contributor objects in `model.contributors` store their commit counts under `.totalContribs`:
```javascript
contributorMap[c.login] = {
login: c.login,
totalContribs: 0,
...
}
```
- When `ContributorsPage.jsx` passes `scopedContributors` (from `model.contributors`) into `computeBusFactor(scopedContributors)`, `c.contributions` is `undefined`.
- As a result, `0 + undefined` results in `NaN`. Since `!NaN` evaluates to `true`, `if (!total)` immediately triggers and returns `{ factor: 0, risk: 'unknown' }` on every run.
### Steps to Reproduce
1. Open OrgExplorer and analyze any organization (e.g. `AOSSIE-Org`).
2. Navigate to the Contributors page (`/contributors`).
3. Look at the Bus Factor Risk card at the top left.
4. Note that it displays `Bus Factor: 0` and `UNKNOWN` instead of calculating the contributor concentration.
### Logs and Screenshots
Observed behavior in the UI:
- Title: `Bus Factor: 0`
- Badge: `UNKNOWN`
- Subtitle: `0 contributors own over 50% of total commits. Knowledge distribution is heavily skewed.`
- Risk Level: `UNKNOWN`
- Progress bar: `25%`
Proposed fix in `src/services/analytics.js`:
```javascript
export function computeBusFactor(contributors = []) {
if (!contributors.length) return { factor: 0, risk: 'unknown' }
const getCount = c => (typeof c === 'number' ? c : (c.contributions ?? c.totalContribs ?? 0))
const total = contributors.reduce((s, c) => s + getCount(c), 0)
if (!total) return { factor: 0, risk: 'unknown' }
let cum = 0
for (let i = 0; i < contributors.length; i++) {
cum += getCount(contributors[i])
if (cum / total > 0.5) {
const f = i + 1
return { factor: f, risk: f <= 1 ? 'critical' : f <= 2 ? 'high' : 'healthy' }
}
}
return { factor: contributors.length, risk: 'healthy' }
}
```
### Environment Details
- OS: macOS / Linux / Windows
- Browser: Chrome / Firefox / Safari
- Application version: 1.0.0 (main branch)
### Impact
High - Major feature is broken
### Code of Conduct
- [x] I have joined the [Discord server](https://discord.gg/hjUhu33uAn) and will post updates there
- [x] I have searched existing issues to avoid duplicates
Guia de contribuição
Direção de pesquisa
Start in src/services/analytics.js by reading computeBusFactor and buildAnalyticalModel, then follow the call from ContributorsPage.jsx using scopedContributors. Reproduce the metric on /contributors with an analyzed organization and verify the Bus Factor Risk card reports a calculated factor and risk instead of 0 and UNKNOWN.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- javascript
- Domínio
- analytics, frontend
- Tipo de issue
- Bug
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Status de atividade
- Ativa
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 88/100