-
Notifications
You must be signed in to change notification settings - Fork 1
Feat/ahp #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/ahp #18
Changes from all commits
2154c05
c3c9966
416635d
a8a943a
035d508
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||||
| import { computeDataDrivenAHP } from "../utils/pairwiseMatrix.js"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const dataDrivenAHP = (req, res) => { | ||||||||||||||||||||||||||
| const { criteriaNames, alternativeNames, dataMatrix, benefitFlags } = req.body || {}; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (!req.body) { | ||||||||||||||||||||||||||
| return res.status(400).json({ error: 'Request body is required. Please send JSON with dataMatrix, criteriaNames, alternativeNames, and benefitFlags.' }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+4
to
+9
|
||||||||||||||||||||||||||
| const { criteriaNames, alternativeNames, dataMatrix, benefitFlags } = req.body || {}; | |
| if (!req.body) { | |
| return res.status(400).json({ error: 'Request body is required. Please send JSON with dataMatrix, criteriaNames, alternativeNames, and benefitFlags.' }); | |
| } | |
| const body = req.body; | |
| if (!body || typeof body !== 'object') { | |
| return res.status(400).json({ error: 'Request body is required. Please send JSON with dataMatrix, criteriaNames, alternativeNames, and benefitFlags.' }); | |
| } | |
| const { criteriaNames, alternativeNames, dataMatrix, benefitFlags } = body; |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete input validation. The controller only validates that dataMatrix is an array but doesn't validate other required parameters (criteriaNames, alternativeNames). These are required by computeDataDrivenAHP and will cause unclear error messages if missing. Add validation for all required parameters.
| if (!Array.isArray(criteriaNames) || criteriaNames.length === 0) { | |
| return res.status(400).json({ error: 'criteriaNames must be a non-empty array.' }); | |
| } | |
| if (!Array.isArray(alternativeNames) || alternativeNames.length === 0) { | |
| return res.status(400).json({ error: 'alternativeNames must be a non-empty array.' }); | |
| } |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug console.log statement should be removed from production code. Consider using a proper logging library consistent with the rest of the application, or remove this debug statement.
| console.log("Start running AHP computation"); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||||||||||
| import express from 'express'; | ||||||||||||||||||
| import { dataDrivenAHP } from '../controllers/ahpController.js'; | ||||||||||||||||||
|
|
||||||||||||||||||
| const router = express.Router(); | ||||||||||||||||||
|
Comment on lines
+1
to
+4
|
||||||||||||||||||
| import express from 'express'; | |
| import { dataDrivenAHP } from '../controllers/ahpController.js'; | |
| const router = express.Router(); | |
| import { Router } from 'express'; | |
| import { dataDrivenAHP } from '../controllers/ahpController.js'; | |
| const router = Router(); |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon at the end of the statement. While JavaScript has automatic semicolon insertion, the codebase appears to use semicolons consistently (see other route files). This should include a semicolon for consistency.
| router.post('/', dataDrivenAHP) | |
| router.post('/', dataDrivenAHP); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,116 @@ | ||||||||||||||||||||
| import { create, all } from "mathjs"; | ||||||||||||||||||||
| import matrixValidation from "./validateMatrix.js"; | ||||||||||||||||||||
| import weightVectorGeometricMean from "./computePriorityVector.js"; | ||||||||||||||||||||
| import { consistencyRatio } from "./computeConsistancyRatio.js"; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const math = create(all, {}); | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
Comment on lines
+1
to
+7
|
||||||||||||||||||||
| import { create, all } from "mathjs"; | |
| import matrixValidation from "./validateMatrix.js"; | |
| import weightVectorGeometricMean from "./computePriorityVector.js"; | |
| import { consistencyRatio } from "./computeConsistancyRatio.js"; | |
| const math = create(all, {}); | |
| import matrixValidation from "./validateMatrix.js"; | |
| import weightVectorGeometricMean from "./computePriorityVector.js"; | |
| import { consistencyRatio } from "./computeConsistancyRatio.js"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { create, all } from "mathjs"; | ||
|
||
|
|
||
| const math = create(all, {}); | ||
|
Comment on lines
+1
to
+3
|
||
|
|
||
| const RI = { | ||
| 1: 0.00, 2: 0.00, 3: 0.58, 4: 0.90, 5: 1.12, | ||
| 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49, | ||
| 11: 1.51, 12: 1.48, 13: 1.56, 14: 1.57, 15: 1.59 | ||
| }; | ||
|
|
||
|
|
||
| /** Consistency Ratio for a pairwise matrix M with weights w */ | ||
| export function lambdaMax(M, w) { | ||
| const Aw = math.multiply(M, w); // vector | ||
| let sum = 0; | ||
| for (let i = 0; i < w.length; i++) { | ||
| sum += (Aw[i] / w[i]); | ||
| } | ||
| return sum / w.length; | ||
| } | ||
|
|
||
| /** Consistency Ratio for a pairwise matrix M with weights w */ | ||
| export function consistencyRatio(M, w) { | ||
| const n = M.length; | ||
| if (n <= 2) return 0; // CR undefined but effectively 0 | ||
| const lam = lambdaMax(M, w); | ||
| const CI = (lam - n) / (n - 1); | ||
| const ri = RI[n] ?? RI[15]; // cap if very large n | ||
| return ri === 0 ? 0 : CI / ri; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new AHP controller lacks test coverage. All other controllers in the codebase (branchController, messageController, thirdPartiesController, etc.) have corresponding test files in src/tests/. Consider adding comprehensive tests for the AHP controller covering successful computation, validation errors, and error handling.