Skip to content

Linh - Material Usage Insights Backend APIs and Calculations#2019

Open
linh2020 wants to merge 4 commits into
developmentfrom
linh_materials_usage_insights_visual_indicators_be
Open

Linh - Material Usage Insights Backend APIs and Calculations#2019
linh2020 wants to merge 4 commits into
developmentfrom
linh_materials_usage_insights_visual_indicators_be

Conversation

@linh2020

@linh2020 linh2020 commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

Description

image

This PR adds backend support for the Material Usage Insights & Visual Indicators feature in the BM Dashboard by introducing reusable calculation utilities and new API endpoints for material insights and summary metrics.

These APIs provide structured data for:

  • Usage percentage
  • Stock ratio
  • Stock health classification
  • Aggregated summary statistics
  • Lists of critical/low stock items and high-usage items

This work enables the frontend to consume consistent, server-side calculated insights instead of duplicating logic in the UI.

Implements:
(WBS: Add Material Usage Insights & Visual Indicators – Backend Support)

Related PRS (if any):

Related frontend PR: #4736 (Material Usage Insights & Visual Indicators – Frontend)

Main changes explained:

Added reusable calculation utilities for usage percentage, stock ratio, stock health status, and summary metrics with proper edge-case handling.
Implemented new API handlers to provide:

  • Insights for all materials and by project
  • Global and per-project summary metrics
  • Lists of critical/low stock items and high-usage items
  • Detailed insights for a single material

Added a new Material Insights router and registered it under /api/bm/materials/insights/* in startup/routes.js.

How to test:

  1. Check out this branch: linh_materials_usage_insights_visual_indicators_be
  2. Run: npm install, npm run dev (or equivalent backend start command)
  3. Clear site data/cache if needed.
  4. Verify endpoints via Postman / browser:

Example checks:

  • GET /api/bm/materials/insights/all → returns materials + summary
  • GET /api/bm/materials/insights/summary → returns aggregated metrics
  • GET /api/bm/materials/insights/critical-items → returns low/critical items
  • GET /api/bm/materials/insights/high-usage-items → returns ≥80% used items

Note:

Include the information the reviewers need to know.

Split controller into calculations, handlers, and composition layers
to resolve ESLint violations and improve maintainability.
@linh2020 linh2020 changed the title Linh - Material Usage Insights Backend APIs and Calculations [WIP] Linh - Material Usage Insights Backend APIs and Calculations Feb 3, 2026
@one-community one-community added the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Apr 24, 2026

@handikaharianto handikaharianto left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi, after reviewing this PR, every single API endpoint is working properly and displaying correct data.

Worked well

/api/bm/insights/all is working as expected✅

As can be seen from the two images below, this API endpoint successfully returns the materials + summary data.
Image

Image

/api/bm/insights/summary is working as expected✅

As can be seen from the image below, this API endpoint successfully returns the aggregated metrics.
Image

/api/bm/insights/critical-items is working as expected✅

As can be seen from the image below, this API endpoint successfully returns the low/critical items.
Image

/api/bm/insights/high-usage-items is working as expected✅

As can be seen from the image below, this API endpoint successfully returns the ≥80% used items.
Image

@pixelpix13 pixelpix13 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi, @linh2020 just reviewed this pr and following were my observations

PR #2019 Test Report — Material Usage Insights Backend

Field Value
Branch linh_materials_usage_insights_visual_indicators_be
Related frontend PR #4736
Tested 2026-06-18
Environment npm run dev on port 4500 + hgnData_dev MongoDB
Result 46/46 checks passed (22 unit + 24 API)

Summary

All material insights endpoints work correctly on the actual route base /api/bm/insights/*. Calculations for usage percentage, stock ratio, and health classification match the spec. Summary, critical-items, and high-usage filters behave as expected against live data (127 materials in dev DB).

Recommendation: Approve with minor documentation fixes (URL path mismatch in PR description).


Unit tests — 22/22 passed

npm test -- src/controllers/bmdashboard/__tests__/bmMaterialInsightsController.test.js

Covers:

  • calculateMaterialInsights (complete data, no purchases, critical/healthy thresholds)
  • calculateUsagePercentage, calculateStockRatio, getStockHealthStatus
  • calculateSummaryMetrics (low stock %, over-usage %, on-hold count)
  • API handlers: all materials, by project, summary, error handling

API tests — 24/24 passed

Endpoint Result Live data notes
GET /api/bm/insights/all Pass 127 materials + summary
GET /api/bm/insights/summary Pass Lightweight metrics only
GET /api/bm/insights/critical-items Pass 65 low/critical items, sorted by stock ratio
GET /api/bm/insights/high-usage-items Pass 7 items ≥ 80% usage, sorted desc
GET /api/bm/insights/by-project/:projectId Pass 42 materials for sample project
GET /api/bm/insights/summary/by-project/:projectId Pass Project-scoped summary
GET /api/bm/insights/:materialId Pass Detail with health=critical, usage=75%
No auth Pass 401
Invalid material ID Pass 400
Non-existent material Pass 404
Invalid project ID Pass 400

Calculation rules verified

Metric Formula Thresholds
Usage % (used / bought) × 100 null if bought ≤ 0
Stock ratio available / bought null if bought ≤ 0
Health From stock ratio Critical ≤ 20%, Low ≤ 40%, Healthy > 40%
High usage filter usagePct >= 80 7 items in dev DB
Low stock in summary low + critical counts 65 items in dev DB

Issues found (non-blocking)

1. URL path mismatch in PR docs (Medium — documentation)

PR description says /api/bm/materials/insights/* but actual routes are:

GET /api/bm/insights/all
GET /api/bm/insights/summary
GET /api/bm/insights/critical-items
GET /api/bm/insights/high-usage-items
GET /api/bm/insights/by-project/:projectId
GET /api/bm/insights/summary/by-project/:projectId
GET /api/bm/insights/:materialId

Confirmed: /api/bm/materials/insights/all returns 404.

2. onHoldCount always 0 (Low)

calculateSummaryMetrics checks stockHold, but buildingMaterial schema on this branch has no stockHold field (that field is on the bulk-actions branch). onHoldCount will always be 0 unless the field exists in DB documents.

3. Frontend PR #4736 uses client-side calculations (Informational)

Frontend duplicates logic in src/utils/materialInsights.js and does not call these backend endpoints yet. Backend APIs are ready but may be unused by the current frontend PR.

4. Router comments vs code (Informational)

Comments in bmMaterialInsightsRouter.js say /materials/insights/... but route definitions use /insights/....


Files tested

File Role
src/controllers/bmdashboard/materialInsightsCalculations.js Pure calculation utilities
src/controllers/bmdashboard/materialInsightsHandlers.js API endpoint handlers
src/controllers/bmdashboard/bmMaterialInsightsController.js Controller factory
src/routes/bmdashboard/bmMaterialInsightsRouter.js Route definitions
src/startup/routes.js Mounted at /api/bm

Verdict

LGTM — All endpoints and calculations work correctly. Fix PR documentation to use /api/bm/insights/* instead of /api/bm/materials/insights/*.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants