Files
T
Bill 3a5ebaa17a v1.5.0: External credits per specialization
Students can now record credits earned in courses taken outside the J27
program via an inline editable amber chip on each spec card. Values flow
through the LP (per-spec demand reduces by external amount), upper-bound
math, decision-tree search, and the credit bar visualization. The 9-credit
threshold and the 3-spec achievement cap are unchanged; required-course
gates remain authoritative — external credits never satisfy them.
2026-05-10 11:47:22 -04:00

4.9 KiB

ADDED Requirements

Requirement: Inline editable external-credits chip on each spec card

Each specialization in the ranking panel SHALL include an inline editable chip for entering an external credit value. The chip SHALL display blank or +0 when the spec's externalCredits value is 0, and SHALL display +<value> (e.g., +2.5) when non-zero. Clicking or tapping the chip SHALL switch it to a numeric input field; pressing Enter or blurring the input SHALL commit the value. The chip SHALL be present on both the desktop chip layout and the mobile row layout, sized so it does not displace existing affordances (drag handle, status badge, credit bar).

Scenario: Chip shows the current value

  • WHEN a specialization has externalCredits[specId] === 2.5
  • THEN the chip SHALL display +2.5

Scenario: Chip is blank when value is zero

  • WHEN a specialization has externalCredits[specId] === 0 (or no entry)
  • THEN the chip SHALL render in its blank/placeholder state (e.g., +0 or an unobtrusive add-icon)

Scenario: Click activates input

  • WHEN the user clicks or taps the chip
  • THEN the chip SHALL switch to a numeric input pre-filled with the current value

Scenario: Enter commits the value

  • WHEN the user types a valid non-negative number into the input and presses Enter
  • THEN the value SHALL be saved to externalCredits[specId] and the chip SHALL return to display mode showing the new value

Scenario: Blur commits the value

  • WHEN the user types a valid non-negative number into the input and clicks elsewhere
  • THEN the value SHALL be saved and the chip SHALL return to display mode

Scenario: Invalid input clamps to zero

  • WHEN the user commits an empty string, NaN, or a negative number
  • THEN the value SHALL be saved as 0 and the chip SHALL return to its blank state

Requirement: Credit bar renders external segment

CreditBar SHALL accept an external prop (a non-negative number). When external > 0, the bar SHALL render an amber stripe (#f59e0b) at the leftmost edge whose width is proportional to external / maxWidth. The existing in-program allocated stripe SHALL stack on top, starting at external / maxWidth and ending at (external + allocated) / maxWidth. The potential stripe SHALL stack next, starting at (external + allocated) / maxWidth and ending at (external + potential) / maxWidth. maxWidth SHALL be Math.max(potential + external, threshold) so that the threshold tick remains correctly positioned.

Scenario: External segment renders for non-zero value

  • WHEN a spec has external = 2.5, allocated = 5.0, potential = 7.5, threshold = 9
  • THEN the bar SHALL render an amber segment from 0% to 2.5/10 = 25% of the bar width, an allocated segment from 25% to 75%, and a potential segment from 75% to 100% (where maxWidth = 10)

Scenario: No external segment when value is zero

  • WHEN a spec has external = 0
  • THEN the bar SHALL render with the same layout as before this change (no amber segment)

Scenario: External alone exceeds threshold

  • WHEN a spec has external = 10 and threshold = 9
  • THEN the threshold tick SHALL still appear at the 9 / maxWidth position, with the amber segment crossing it

Requirement: Achievement coloring keys off combined credit

The credit bar's "achieved" green color (#22c55e) SHALL switch on when allocated + external ≥ threshold. Otherwise the in-program allocated stripe SHALL render in the existing in-progress blue (#3b82f6).

Scenario: Combined credit reaches threshold via external

  • WHEN allocated = 7.0 and external = 2.5
  • THEN the in-program allocated stripe SHALL render in green

Scenario: Combined credit below threshold

  • WHEN allocated = 4.0 and external = 2.5
  • THEN the in-program allocated stripe SHALL render in blue

Requirement: Allocation breakdown shows External line

AllocationBreakdown SHALL prepend an External line when externalCredits[specId] > 0, displaying the credit value (e.g., External — 2.5). The line SHALL be visually distinguishable from in-program contributions (e.g., italic label, amber accent, or other lightweight treatment) so the reader can identify it without explanation.

Scenario: External line appears for non-zero value

  • WHEN a specialization has external = 2.5 and one in-program contribution of 2.0 from "Real Estate Finance"
  • THEN the breakdown SHALL list External — 2.5 followed by Real Estate Finance — 2.0

Scenario: External line absent for zero value

  • WHEN a specialization has external = 0
  • THEN the breakdown SHALL render exactly as before this change (no External line)

Scenario: External-only spec shows only the External line

  • WHEN a specialization has external = 9 and no in-program contributions
  • THEN the breakdown SHALL contain a single External — 9.0 line