Source

utils/lessonsFactory.js

import { Metadata } from "@models/Metadata.model";
/**
 * Retrieves lesson metadata for a given unit and formats it as a string.
 *
 * Can optionally filter lessons based on whether they have an associated investigation.
 * The returned string includes the unit name and a list of lessons with their numbers,
 * titles, and optionally whether they have an investigation.
 * @category Utils
 * @param {string} unit - The unit identifier to fetch lessons for.
 * @param {boolean | null} hasInvestigation - Optional filter to only include lessons that do (true) or do not (false) have an investigation. If `null`, includes all lessons and shows their investigation status.
 * @returns {Promise<string>} - A formatted string containing the unit and lesson information.
 */
export async function getLessonData(unit, hasInvestigation = null) {
    let query;
    if (hasInvestigation === true || hasInvestigation === false) {
        query = { unit: unit, hasInvestigation: hasInvestigation };
    }
    else {
        query = { unit: unit };
    }
    const unitMetadata = await Metadata.find(query).sort({ lessonNumber: 1 });
    let lessonMetadata = "";
    if (unitMetadata) {
        lessonMetadata += `Unit: ${unit} - ${unitMetadata[0]?.unitName}\n`;
    }
    for (const metadata of unitMetadata) {
        lessonMetadata += `Lesson ${metadata.lessonNumber} - ${metadata.lessonTitle}`;
        if (hasInvestigation === null) {
            lessonMetadata += `: hasInvestigation - ${metadata.hasInvestigation}\n`;
        }
        else {
            lessonMetadata += "\n";
        }
    }
    return lessonMetadata;
}
/**
 * Retrieves all unique units with their names and descriptions, grouped by grade.
 * Formats the output similar to the detect_unit_from_message prompt format.
 * @category Utils
 * @returns {Promise<string>} - A formatted string containing all units grouped by grade.
 */
export async function getUnitNames() {
    // Get all unique units with their metadata
    const allMetadata = await Metadata.find({}).sort({ grade: 1, unit: 1 });
    // Group by grade and collect unique units
    const gradeMap = new Map();
    for (const metadata of allMetadata) {
        const grade = metadata.grade;
        const unit = metadata.unit;
        const unitName = metadata.unitName;
        if (!gradeMap.has(grade)) {
            gradeMap.set(grade, new Map());
        }
        const unitMap = gradeMap.get(grade);
        if (!unitMap.has(unit)) {
            unitMap.set(unit, { unit, unitName });
        }
    }
    // Format the output - group by grade
    let unitNames = "";
    const sortedGrades = Array.from(gradeMap.keys()).sort();
    for (const grade of sortedGrades) {
        const unitMap = gradeMap.get(grade);
        const units = Array.from(unitMap.values()).sort((a, b) => a.unit.localeCompare(b.unit));
        if (units.length > 0) {
            unitNames += `${grade} Units\n`;
            for (const { unit, unitName } of units) {
                unitNames += `${unit} - ${unitName}\n`;
            }
            unitNames += "\n";
        }
    }
    return unitNames.trim();
}