Problem
Crime type labels, danger weights, and severity mappings are duplicated across 5+ locations:
crime-reports.service.ts — inline dangerLevels objects (×3 occurrences)
ai/ai.service.ts — typeLabels record
- Frontend:
use-map-crime-markers.ts, use-notifications.ts, map/page.tsx each define their own label/color maps
Two divergent danger scales coexist: getDefaultSeverityByType used 1–5, heatmap used 3–10. Any new crime type requires edits in 5+ files.
Proposed Solution — Two co-located constant files
Backend: src/shared/crime-types.constants.ts
export const CRIME_DANGER_WEIGHT: Record<CrimeType, number> = { ... } // single 1–10 scale
export const CRIME_TYPE_LABEL: Record<CrimeType, string> = { ... }
export function weightToSeverity(weight: number): number { ... } // maps to 1–5 for DB column
Frontend: src/constants/crime-constants.ts
export const CRIME_TYPE_LABEL: Record<CrimeType, string> = { ... }
export const CRIME_TYPE_COLOR: Record<CrimeType, string> = { ... }
export const CRIME_TYPE_OPTIONS = [ ... ]
export const SEVERITY_COLOR: Record<number, string> = { ... }
Files to migrate
| File |
Action |
src/crime-reports/crime-reports.service.ts |
Remove 3× inline dangerLevels, import CRIME_DANGER_WEIGHT |
src/ai/ai.service.ts |
Remove typeLabels, import CRIME_TYPE_LABEL |
src/app/(protected)/map/hooks/use-map-crime-markers.ts |
Remove local label map, import from constants |
src/hooks/use-notifications.ts |
Remove crimeTypeLabels, import from constants |
src/app/(protected)/map/page.tsx |
Remove CRIME_TYPE_OPTIONS definition, import from constants |
Benefits
- Adding a new crime type = edit 2 files, not 7
- Heatmap danger score and DB severity column stay in sync via
weightToSeverity()
- Single source of truth for UI labels and colors
References
Architecture RFC session — 2026-04-12
Problem
Crime type labels, danger weights, and severity mappings are duplicated across 5+ locations:
crime-reports.service.ts— inlinedangerLevelsobjects (×3 occurrences)ai/ai.service.ts—typeLabelsrecorduse-map-crime-markers.ts,use-notifications.ts,map/page.tsxeach define their own label/color mapsTwo divergent danger scales coexist:
getDefaultSeverityByTypeused 1–5, heatmap used 3–10. Any new crime type requires edits in 5+ files.Proposed Solution — Two co-located constant files
Backend:
src/shared/crime-types.constants.tsFrontend:
src/constants/crime-constants.tsFiles to migrate
src/crime-reports/crime-reports.service.tsdangerLevels, importCRIME_DANGER_WEIGHTsrc/ai/ai.service.tstypeLabels, importCRIME_TYPE_LABELsrc/app/(protected)/map/hooks/use-map-crime-markers.tssrc/hooks/use-notifications.tscrimeTypeLabels, import from constantssrc/app/(protected)/map/page.tsxCRIME_TYPE_OPTIONSdefinition, import from constantsBenefits
weightToSeverity()References
Architecture RFC session — 2026-04-12