feat: added learningPaths.ts
This commit is contained in:
parent
cfaae9ebe4
commit
e8e1d94e5b
5 changed files with 193 additions and 8 deletions
|
@ -18,6 +18,7 @@
|
|||
"@mikro-orm/postgresql": "^6.4.6",
|
||||
"@mikro-orm/reflection": "^6.4.6",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"axios": "^1.8.1",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.0.1",
|
||||
"js-yaml": "^4.1.0"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import express, { Express, Response } from 'express';
|
||||
import initORM from './orm.js';
|
||||
import themeRoutes from './routes/themes.js';
|
||||
import learningPathRoutes from './routes/learningPaths.js'
|
||||
|
||||
const app: Express = express();
|
||||
const port: string | number = process.env.PORT || 3000;
|
||||
|
@ -13,6 +14,7 @@ app.get('/', (_, res: Response) => {
|
|||
});
|
||||
|
||||
app.use('/theme', themeRoutes);
|
||||
app.use('/learningPath', learningPathRoutes);
|
||||
|
||||
async function startServer() {
|
||||
await initORM();
|
||||
|
|
134
backend/src/controllers/learningPaths.ts
Normal file
134
backend/src/controllers/learningPaths.ts
Normal file
|
@ -0,0 +1,134 @@
|
|||
import { Request, Response } from "express";
|
||||
import axios from "axios";
|
||||
import { themes } from "../data/themes.js";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
// Load environment variables
|
||||
dotenv.config();
|
||||
|
||||
// Get API base URL from environment variables
|
||||
const DWENGO_API_BASE = process.env.DWENGO_API_BASE as string;
|
||||
if (!DWENGO_API_BASE) {
|
||||
throw new Error("DWENGO_API_BASE is not defined in the .env file");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch learning paths for a given list of HRUIDs.
|
||||
* This function sends a request to the Dwengo API with the provided HRUIDs.
|
||||
*/
|
||||
export async function getLearningPathsFromIds(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { hruids } = req.query;
|
||||
const language = (req.query.language as string) || "nl"; // Default to Dutch
|
||||
|
||||
if (!hruids) {
|
||||
res.status(400).json({ error: "Missing required parameter: hruids" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the input to an array if it's a string
|
||||
const hruidList = Array.isArray(hruids) ? hruids : [hruids];
|
||||
|
||||
// Request learning paths from Dwengo API
|
||||
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, {
|
||||
params: {
|
||||
pathIdList: JSON.stringify({ hruids: hruidList }),
|
||||
language
|
||||
}
|
||||
});
|
||||
|
||||
res.json(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching learning paths:", error);
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all learning paths for a specific theme.
|
||||
* First retrieves the HRUIDs associated with the theme,
|
||||
* then fetches the corresponding learning paths from the Dwengo API.
|
||||
*/
|
||||
export async function getLearningPathsByTheme(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const themeKey = req.params.theme;
|
||||
const language = (req.query.language as string) || "nl"; // Default to Dutch
|
||||
|
||||
// Find the theme by its title
|
||||
const theme = themes.find((t) => t.title === themeKey);
|
||||
|
||||
if (!theme) {
|
||||
res.status(404).json({ error: "Theme not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract HRUIDs from the theme
|
||||
const hruidList = theme.hruids;
|
||||
|
||||
// Request learning paths from Dwengo API using the extracted HRUIDs
|
||||
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, {
|
||||
params: {
|
||||
pathIdList: JSON.stringify({ hruids: hruidList }),
|
||||
language
|
||||
}
|
||||
});
|
||||
|
||||
res.json({
|
||||
theme: themeKey,
|
||||
hruids: hruidList,
|
||||
learningPaths: response.data
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching learning paths for theme:", error);
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
}
|
||||
|
||||
export async function searchLearningPaths(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const query = req.query.query as string;
|
||||
const language = (req.query.language as string) || "nl";
|
||||
|
||||
if (!query) {
|
||||
res.status(400).json({ error: "Missing search query" });
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/search`, {
|
||||
params: { all: query, language }
|
||||
});
|
||||
|
||||
res.json(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error searching learning paths:", error);
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllLearningPaths(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const language = (req.query.language as string) || "nl"; // Default to Dutch
|
||||
|
||||
// Collect all HRUIDs from all themes
|
||||
const allHruids: string[] = themes.flatMap(theme => theme.hruids);
|
||||
|
||||
if (allHruids.length === 0) {
|
||||
res.status(404).json({ error: "No HRUIDs found in themes" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Call the Dwengo API with all HRUIDs combined
|
||||
const response = await axios.get(`${DWENGO_API_BASE}/learningPath/getPathsFromIdList`, {
|
||||
params: {
|
||||
pathIdList: JSON.stringify({ hruids: allHruids }),
|
||||
language
|
||||
}
|
||||
});
|
||||
|
||||
res.json(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching all learning paths:", error);
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
}
|
18
backend/src/routes/learningPaths.ts
Normal file
18
backend/src/routes/learningPaths.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import express from "express";
|
||||
import { getLearningPathsFromIds, getLearningPathsByTheme, getAllLearningPaths, searchLearningPaths } from "../controllers/learningPaths.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Route to fetch learning paths based on a list of HRUIDs
|
||||
router.get("/", getLearningPathsFromIds);
|
||||
|
||||
// Route to fetch all possible learning paths
|
||||
router.get("/all", getAllLearningPaths);
|
||||
|
||||
// Route to fetch learning paths based on a searchterm
|
||||
router.get("/search", searchLearningPaths);
|
||||
|
||||
// Route to fetch learning paths based on a theme
|
||||
router.get("/theme/:theme", getLearningPathsByTheme);
|
||||
|
||||
export default router;
|
46
package-lock.json
generated
46
package-lock.json
generated
|
@ -35,6 +35,7 @@
|
|||
"@mikro-orm/postgresql": "^6.4.6",
|
||||
"@mikro-orm/reflection": "^6.4.6",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"axios": "^1.8.1",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.0.1",
|
||||
"js-yaml": "^4.1.0"
|
||||
|
@ -3152,9 +3153,19 @@
|
|||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz",
|
||||
"integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
|
@ -3520,7 +3531,6 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
|
@ -3788,7 +3798,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
|
@ -4003,7 +4012,6 @@
|
|||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
|
@ -4745,6 +4753,26 @@
|
|||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
|
||||
|
@ -4766,7 +4794,6 @@
|
|||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
|
||||
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
|
@ -4782,7 +4809,6 @@
|
|||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
|
@ -4792,7 +4818,6 @@
|
|||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
|
@ -5077,7 +5102,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
|
@ -6772,6 +6796,12 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue