Skip to content

feat(metrics): Legislative Efficiency Score Calculator (BRU-878) - #331

Open
bcamarneiro wants to merge 3 commits into
mainfrom
aragorn/bru-878
Open

feat(metrics): Legislative Efficiency Score Calculator (BRU-878)#331
bcamarneiro wants to merge 3 commits into
mainfrom
aragorn/bru-878

Conversation

@bcamarneiro

Copy link
Copy Markdown
Owner

Summary

Adds a Legislative Efficiency Score (calculateEfficiencyScore) to the Adamastor transparency platform.

The metric distinguishes parliamentary activity (proposals submitted, interventions made, questions asked, attendance) from output (vote participation, session attendance) and assigns a qualitative Portuguese-language grade, providing deeper assessment beyond raw activity counts.

Changes

  • apps/web/src/services/metrics/EfficiencyScoreCalculator.ts — Core calculator with types (ActivityMetrics, OutputMetrics, EfficiencyScore, EfficiencyGrade), exported weight constants, and helper functions (calculateEfficiencyScore, scoreToGrade, scoreToLabel).
  • apps/web/src/services/metrics/EfficiencyScoreCalculator.test.ts — 23 unit tests covering normal ranges, edge cases (zero, max, missing data), division-by-zero safety, NaN safety, weight validation, grade classification, label classification, and activity-vs-output distinction.

Design Decisions

  • Plain functions, not a static class — per Biome lint rule noStaticOnlyClass.
  • Portuguese labels for grades (Excecional, Elevada, Moderada, Baixa, Mínima).
  • Output/Activity ratio scaled so 1:1 maps to 50 (balanced), >1 gets higher efficiency.
  • All weights exported as as const for downstream reuse.

Hermes Coder added 2 commits July 30, 2026 11:46
Implements EfficiencyScoreCalculator that distinguishes parliamentary
'activity' (proposals, interventions, questions, attendance) from
'output' (vote participation, session attendance) — adding a
qualitative efficiency dimension to the transparency platform.

- New service: apps/web/src/services/metrics/
- 23 unit tests verifying activity vs output distinction
- Portuguese-language grade labels (Excecional → Mínima)
- All 564 tests pass, zero regressions

BRU-878
- Distinguishes parliamentary activity (proposals, interventions, questions,
  attendance) from output (vote participation, session attendance).
- Converts static-class method API to plain exported functions per Biome lint.
- All 23 unit tests pass: normal ranges, edge cases (zero, max, missing data),
  and activity-vs-output distinction verified.
Copilot AI review requested due to automatic review settings July 30, 2026 10:49
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
adamastor-web Ignored Ignored Preview Jul 30, 2026 11:04am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@bcamarneiro

Copy link
Copy Markdown
Owner Author

Code Review Summary

Verdict: Concerns (1 real issue found)

Issue

  • apps/web/src/services/metrics/index.ts:3 — Broken barrel export: re-exports EfficiencyScoreCalculator which doesn't exist in the source module (EfficiencyScoreCalculator.ts). The source exports calculateEfficiencyScore (a function), not EfficiencyScoreCalculator. This is a leftover from the static-class-to-plain-functions refactor (mentioned in the PR's design decisions). Any consumer importing from @/services/metrics will get a build error.

In Scope / Good

  • Core calculator implemented correctly (activity vs output, ratio scaling, grade/label mappings)
  • Unit tests (23 tests) verify the activity-vs-output distinction explicitly
  • Score object shape is dashboard-ready
  • No scope violations (no UI, no ingestion, no historical scoring)

Quality Highlights

  • Division-by-zero handled in all code paths
  • NaN safety covered in tests
  • Weight validation (sum to 1.0) present
  • Code is well-documented with JSDoc and inline comments
  • Proper as const for exported constants

Fix suggestion

Remove the EfficiencyScoreCalculator, line from the barrel export — the individual exports (calculateEfficiencyScore, constants, types) are already correct and sufficient.


Reviewed by Hermes Agent

@bcamarneiro

Copy link
Copy Markdown
Owner Author

Review verdict: needs-work

1. BLOCKING — Barrel export references non-existent symbol

File: apps/web/src/services/metrics/index.ts

The barrel file re-exports EfficiencyScoreCalculator from ./EfficiencyScoreCalculator, but that symbol was never exported from the implementation module. The actual public function is called calculateEfficiencyScore. Additionally, the barrel is missing re-exports of the core public API functions: calculateEfficiencyScore, scoreToGrade, scoreToLabel.

// Current (broken):
export {
  EfficiencyScoreCalculator,  // does not exist - TS compile error
  ...
}

// Should be:
export {
  calculateEfficiencyScore,
  scoreToGrade,
  scoreToLabel,
  ...
}

Any consumer importing from the ./metrics barrel will hit a TypeScript compilation error. The tests pass because they import directly from ./EfficiencyScoreCalculator, bypassing this barrel entirely, which is also why this was not caught at test time.

Impact: The acceptance criterion "score integrates with transparency dashboard API" is blocked - the dashboard cannot import the calculator through the modules public entry point.

What looks good

  • Clear separation of activity vs output metrics with documented rationale
  • Excellent test coverage (23 tests): edge cases, zero-division, NaN safety, grade boundaries, weight sums
  • Well-typed interfaces and as const exports for weights
  • Function-scoped helpers instead of a static class (consistent with Biome lint rules)
  • Division-by-zero guards on totalVotes, totalSessions, and activityScore

Verdict

needs-work - one blocking issue (broken barrel). The core implementation logic is sound, but the barrel export needs to reference the actual exported symbols for this to merge.

…eCalculator with actual exports calculateEfficiencyScore, scoreToGrade, scoreToLabel

Addresses review concern on PR #331: the barrel index.ts re-exported
EfficiencyScoreCalculator which was never exported from the source module.
Replaced with the three actual function exports. TypeScript typecheck passes
clean, all 23 tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants