fcsc_ipi_backend/ipi-methodology-cross-verification.md

148 lines
4.2 KiB
Markdown

# IPI Methodology Cross Verification (Updated)
## Scope
Cross-verification between:
- `Annex V - IPI Calculation Methodology.pptx`
- Current implementation in `app/services/ipi_calculation_service.js`
- Runtime trigger/orchestration in `server.js` and `app/services/scheduler.service.js`
## Trigger Path Verification
Verified start path:
- `server.js` boots scheduler via `scheduler.start()`.
- Cron `0 2 * * *` executes `runScheduledTask()`.
- `runScheduledTask()` calls `executeCalculateQuarter(year, quarter)`.
- `executeCalculateQuarter()` runs `runCompleteCalculation(year, month)` for each month.
- Manual endpoint `POST /api/admin/trigger-scheduler` triggers same scheduler flow.
Status: **MATCH**
---
## Overall Conclusion
Current code is **largely aligned on formula chain**, with **two remaining methodology gaps**:
1. product-to-ISIC4 mapping source is still an approximation (derived from establishment submissions, not a fixed official mapping table),
2. non-response imputation rules from PPT are not implemented in this service.
---
## Verification Matrix (Current Code vs PPT)
## 1) Base-year average production
PPT (Slides 9-10):
- Base year average uses arithmetic mean of 12 months.
Implementation:
- `calculateBaseYearProduction()` computes average across Jan-Dec and stores in `base_year_production.avg_by_production`.
Status: **MATCH**
---
## 2) Item-level index formula
PPT (Slides 8-10):
- `Ri = CurrentProduction / BaseYearAverage`
- `Ii = Ri * 100`
Implementation:
- `calculateItemLevelIndices()`:
- `production_relative = current_production / base_year_avg_production`
- `item_index = production_relative * 100`
Status: **MATCH**
---
## 3) ISIC 4-digit aggregation
PPT (Slides 11-12):
- Laspeyres weighted aggregation:
- `ISIC4 = SUM(w_i * I_i) / SUM(w_i)`
Implementation (current):
- Uses weighted formula with `products.weight_in_ib`:
- `total_weight = SUM(weight_in_ib)`
- `weighted_index_sum = SUM(weight_in_ib * item_index)`
- `isic_4digit_index = weighted_index_sum / total_weight`
- Prevents row multiplication by selecting one ISIC4 per product in-period using ranked mapping.
Status: **PARTIAL MATCH (Formula MATCH, Mapping APPROXIMATION)**
Reason for partial:
- Formula is aligned.
- Mapping source is not a fixed product master/official bridge; it is inferred from establishment-level submissions.
---
## 4) ISIC 3-digit aggregation
PPT (Slide 13):
- Weighted roll-up from ISIC4.
Implementation:
- `ISIC3 = SUM(total_weight_4 * isic_4digit_index) / SUM(total_weight_4)`
Status: **MATCH** (depends on ISIC4 inputs)
---
## 5) ISIC 2-digit aggregation
PPT (Slide 14):
- Weighted roll-up from ISIC3.
Implementation:
- `ISIC2 = SUM(total_weight_3 * isic_3digit_index) / SUM(total_weight_3)`
Status: **MATCH** (depends on ISIC3 inputs)
---
## 6) Manufacturing IPI (headline)
PPT (Slide 15):
- Weighted roll-up from ISIC2.
Implementation:
- `ManufacturingIPI = SUM(total_weight_2 * isic_2digit_index) / SUM(total_weight_2)`
Status: **MATCH**
Note:
- Current code includes defensive handling when no valid ISIC2 aggregates exist for a month.
---
## 7) Growth rates
PPT (Slide 16):
- YoY: `((Current - SameMonthLastYear) / SameMonthLastYear) * 100`
Implementation:
- YoY formula matches.
- MoM is also computed additionally.
Status:
- **YoY MATCH**
- **MoM Additional (not conflicting)**
---
## 8) Missing/non-response data treatment
PPT (Slide 3):
- For missing data, estimate using:
- previous month repeat, or
- average of last 3 months, or
- same month previous year.
Implementation:
- This imputation logic is not implemented in the IPI service pipeline.
- Pipeline uses available approved records.
Status: **MISMATCH**
---
## Final Assessment (Current Code)
If Annex V is interpreted strictly:
- **Formula chain:** mostly aligned now (item -> ISIC4 -> ISIC3 -> ISIC2 -> headline).
- **Remaining non-compliance points:** official deterministic item/product-to-ISIC mapping source and missing-data imputation policy.
Practical statement for stakeholders:
- Current implementation is **operationally correct and mathematically aligned for weighted aggregation**, but still requires **data governance alignment** (official mapping + imputation policy) for full Annex V compliance.