Inconsistency Resolution Log
Every inconsistency found in the audit, what was chosen as canonical, and why.
prometheus/prometheus, they will be linked here.Upstream PRs: StatusBadge unification (proposed) ยท Filter bar consolidation (proposed) ยท localStorage key fix (proposed)
This page documents every inconsistency found during the codebase audit, the resolution chosen, and the reasoning behind each decision.
1. Health Badge Fragmentation
What was inconsistent
Three different approaches to health status badges across pages:
- AlertsPage:
Badge.module.cssclasses (badgeClasses.healthErr) - RulesPage: Mantine Badge with
color="red"prop - ScrapePoolsList: Conditional color prop (
color={health === "up" ? "green" : "red"})
Variants that existed
| Page | Implementation | Color Steps |
|---|---|---|
| AlertsPage | CSS module classes | green-1/green-9, red-1/red-9 (with light-dark()) |
| RulesPage | Mantine color prop | Mantine default shade (step-6 filled) |
| ScrapePoolsList | Conditional color prop | Mantine default "green"/"red" |
Canonical choice
The AlertsPage approach (CSS module classes with explicit light-dark() step-1/step-9 colors) was chosen as canonical because it provides the most precise dark mode support.
Reasoning
- Step-1 bg / step-9 text provides maximum contrast in both modes
- CSS module approach avoids Mantine Badge overhead for performance-critical label badges
light-dark()is the modern standard for mode-aware colors
Migration
Replace all three patterns with <StatusBadge status="..." />. The component internally normalizes all status vocabularies.
2. Panel Border Inconsistency
What was inconsistent
AlertsPage and RulesPage both display accordion items with health-colored left borders, but used different color steps.
Variants that existed
| Page | Implementation | Light Mode Steps |
|---|---|---|
| AlertsPage | Panel.module.css classes | green-3, red-3, orange-3, gray-3 |
| RulesPage | Inline styles | green-4, red-4, gray-5 |
Canonical choice
Step-3 (light) / Step-8 (dark) from the AlertsPage implementation.
Reasoning
- AlertsPage was the more established implementation (CSS modules, not inline styles)
- Step-3 is lighter and more subtle than step-4, appropriate for a border accent
- Dark mode step-8 provides good visibility without being overpowering
- CSS module approach is more maintainable than inline styles
Migration
Replace both patterns with <HealthPanel status="..." />.
3. Duplicate Filter Bars
What was inconsistent
Four pages (AlertsPage, RulesPage, TargetsPage, ServiceDiscoveryPage) each had their own copy of the filter bar pattern: Group + StateMultiSelect + TextInput + optional ActionIcon.
Variants that existed
- AlertsPage / RulesPage: StateMultiSelect + TextInput (2 controls)
- TargetsPage / ServiceDiscoveryPage: StateMultiSelect + TextInput + collapse ActionIcon (3 controls)
Canonical choice
A single FilterToolbar component with optional showCollapseAll prop.
Reasoning
The pattern is identical across all four pages. The only difference is whether a collapse/expand button is shown. A single component with a boolean flag is simpler than four separate implementations.
4. localStorage Key Collision (Bug)
What was inconsistent
Both AlertsPage and RulesPage used the key "alertsPage.showEmptyGroups". Toggling "show empty groups" on one page affected the other.
Resolution
RulesPage key changed to "rulesPage.showEmptyGroups".
Impact
Existing users lose their RulesPage toggle state on upgrade. The default value (false) is the correct initial state, so this is acceptable.
5. SeriesName Hover Colors
What was inconsistent
SeriesName label pair hover used hardcoded light-mode-only values:
/* Before โ light mode only */
.labelPair:hover {
background: #add6ffa0; /* hardcoded light blue */
color: #495057; /* hardcoded dark gray */
}
Resolution
/* After โ dark mode support */
.labelPair:hover {
background-color: light-dark(rgba(173, 214, 255, 0.63), rgba(100, 149, 200, 0.3));
color: light-dark(#495057, var(--mantine-color-gray-3));
}
Reasoning
The light mode values were preserved exactly. Dark mode values were derived by reducing opacity and using an appropriate gray for text.
6. Logo Font Size
What was inconsistent
The logo text used fz={20} โ a unitless number that doesn't scale with user font preferences.
Resolution
Changed to var(--prom-logo-font-size): 1.25rem (equivalent to 20px at default 16px root, but scales with user preferences).
7. Icon Style Duplication
What was inconsistent
The same icon style { width: "0.9rem", height: "0.9rem" } was defined locally in 3+ files. The source code even had a TODO: This is duplicated everywhere, unify it. comment.
Resolution
FilterToolbar and other components internally use the consistent icon size. For custom usage, the design system documents the standard sizes.
8. Pool Display Limit
What was inconsistent
targetPoolDisplayLimit = 20 was defined independently in both TargetsPage.tsx and ServiceDiscoveryPage.tsx.
Resolution
Moved to PoolAccordion as a shared constant. Both pages reference the same value.
9. Navbar Text Visibility Gap
What was inconsistent
Two separate Text elements controlled logo visibility:
<Text hiddenFrom="sm">Prometheus</Text> // visible: xs only
<Text visibleFrom="md">Prometheus</Text> // visible: md+
Between breakpoints sm and md, neither text was visible โ the "Prometheus" label disappeared.
Resolution
PrometheusAppShell uses a single Text element with correct responsive visibility that avoids the gap.