haystacks-tt
Version:
A simple Haystacks-async based command line typing tutor program for Windows, Mac & Linux.
546 lines (528 loc) • 31.8 kB
JavaScript
/**
* @file tutoringCommands.js
* @module tutoringCommands
* @description Contains all client defined commands for execution of client actions with various operations, specific for typing tutoring.
* @requires module:accountBroker
* @requires module:application.command.constants
* @requires module:application.message.constants
* @requires module:application.system.constants
* @requires {@link https://www.npmjs.com/package/@haystacks/async|@haystacks/async}
* @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants}
* @requires {@link https://www.npmjs.com/package/path|path}
* @author Seth Hollingsead
* @date 2023/02/24
* @copyright Copyright © 2023-… by Seth Hollingsead. All rights reserved
*/
// Internal imports
import accountBroker from '../../brokers/accountBroker.js';
import * as app_cfg from '../../constants/application.configuration.constants.js';
import * as apc from '../../constants/application.constants.js';
import * as app_msg from '../../constants/application.message.constants.js';
import * as app_sys from '../../constants/application.system.constants.js';
// External imports
import haystacks from '@haystacks/async';
import hayConst from '@haystacks/constants';
import path from 'path';
const {bas, msg, wrd} = hayConst;
const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url));
// application.haystacks-tt.commands.clientCommands.tutoringCommands.
const namespacePrefix = wrd.capplication + bas.cDot + apc.cApplicationName + bas.cDot + wrd.ccommands + bas.cDot + wrd.cclient + wrd.cCommands + bas.cDot + baseFileName + bas.cDot;
/**
* @function createAccount
* @description Creates a new account with the given input account name.
* @param {array<string>} inputData The input(s) the user entered into the command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/27
*/
async function createAccount(inputData, inputMetaData) {
let functionName = createAccount.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let accountExists = false;
if (Array.isArray(inputData) && inputData.length === 2) {
// Check first to see if the user already exists.
accountExists = await accountBroker.doesAccountExist(inputData[1]);
if (accountExists === false) {
let newAccount = await accountBroker.createAccount(inputData[1]);
// newAccount is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cnewAccountIs + JSON.stringify(newAccount));
// Now merge the new account with the stored account data.
let storedAccountData = await accountBroker.getAccountData();
// storedAccountData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cstoredAccountDataIs + JSON.stringify(storedAccountData));
let newlyMergedAccountData = Object.assign(storedAccountData, newAccount);
// newlyMergedAccountData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cnewlyMergedAccountDataIs + JSON.stringify(newlyMergedAccountData));
let accountStoredSuccess = await accountBroker.storeAccountData(newlyMergedAccountData);
if (accountStoredSuccess === false) {
// ERROR: Newly created account was not saved, could not create the specified account:
console.log(app_msg.cErrorCreateAccountMessage02 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorCreateAccountMessage02 + inputData[1]);
}
} else {
// ERROR: The user account already exists, please choose a different user name and try again.
console.log(app_msg.cErrorInvalidUserNameCreateAccountMessage02);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorInvalidUserNameCreateAccountMessage02);
}
} else {
// ERROR: Invalid user name, please try again with a valid username.
console.log(app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
}
// let newUserAccount = {userName: }
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function printAccountsData
* @description Prints out all of the accounts data.
* @param {array<string>} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function printAccountsData(inputData, inputMetaData) {
let functionName = printAccountsData.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let storedAccountData = await accountBroker.getAccountData();
console.log(app_msg.cstoredAccountDataIs + JSON.stringify(storedAccountData));
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cstoredAccountDataIs + JSON.stringify(storedAccountData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function printAccountData
* @description Prints out all of the data for a specific account,
* or if no account name is specified, then all account data will be printed out.
* @param {array<string>} inputData The input(s) the user entered into the command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function printAccountData(inputData, inputMetaData) {
let functionName = printAccountData.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
if (Array.isArray(inputData) && inputData.length === 2) {
let userAccountData = await accountBroker.getUserAccountData(inputData[1]);
// userAccountData is:
console.log(app_msg.cuserAccountDataIs + JSON.stringify(userAccountData));
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cuserAccountDataIs + JSON.stringify(userAccountData));
} else {
// User didn't enter any account name for input, so just print all of the data for all accounts!
await printAccountsData();
}
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function deleteAccount
* @description Removes a users account and all account data for a specified account, if the account exists in the system.
* @param {array<string>} inputData The input(s) the user entered into the command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function deleteAccount(inputData, inputMetaData) {
let functionName = deleteAccount.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let accountExists = false;
let confirmedAccountDelete = false;
if (Array.isArray(inputData) && inputData.length === 2) {
// Check first to see if the user already exists.
accountExists = await accountBroker.doesAccountExist(inputData[1]);
if (accountExists === true) {
// Make sure the user really wants to delete the account, add a note that all user data will be lost forever.
// WARNING: All user account data will be lost FOREVER!
// Are you sure you want to delete the account? (yes/y or no/n)
console.log(app_msg.cUserDeleteAccountConfirmedMessage01);
console.log(app_msg.cUserDeleteAccountConfirmedMessage02);
let confirmedDeleteUserResponse = await haystacks.executeBusinessRules([bas.cGreaterThan, ''], [wrd.cprompt]);
// confirmedDeleteUserResponse is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cconfirmedDeleteUserResponseIs + confirmedDeleteUserResponse);
if (confirmedDeleteUserResponse.toUpperCase().trim() === wrd.cYES || confirmedDeleteUserResponse.toUpperCase().trim() === bas.cY) {
confirmedAccountDelete = true;
}
if (confirmedAccountDelete) {
let storedAccountData = await accountBroker.getAccountData();
// storedAccountData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cstoredAccountDataIs + JSON.stringify(storedAccountData));
let cleanedAccountData = await accountBroker.removeAccount(inputData[1], storedAccountData);
// cleanedAccountData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.ccleanedAccountDataIs + JSON.stringify(cleanedAccountData));
let accountStoredSuccess = await accountBroker.storeAccountData(cleanedAccountData);
if (accountStoredSuccess === false) {
// ERROR: Newly created account was not saved, could not create the specified account:
console.log(app_msg.cErrorCreateAccountMessage02 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorCreateAccountMessage02 + inputData[1]);
}
} else {
// INFO: No account was deleted.
console.log(app_msg.cErrorNoDeleteAccountMessage02)
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorNoDeleteAccountMessage02);
}
} else {
// ERROR: Cannot delete user, user does not exist.
console.log(app_msg.cErrorNoUserFoundDeleteAccountMessage01);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorNoUserFoundDeleteAccountMessage01);
}
} else {
// ERROR: Invalid user name, please try again with a valid username.
console.log(app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
}
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function login
* @description Allows the user to login with their username.
* @param {array<string>} inputData The input(s) the user entered into the command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function login(inputData, inputMetaData) {
let functionName = login.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let accountExists = false;
if (Array.isArray(inputData) && inputData.length === 2) {
// Check first to see if the user already exists.
accountExists = await accountBroker.doesAccountExist(inputData[1]);
if (accountExists === true) {
let configSettingSet = await accountBroker.loginUser(inputData[1]);
if (configSettingSet === false) {
// ERROR: Unable to login with the specified user:
console.log(app_msg.cErrorLoginMessage02 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorLoginMessage02 + inputData[1]);
} else {
let manuallySetCurriculumIndex = await haystacks.getConfigurationSetting(wrd.csystem, app_cfg.cmanuallySetCurriculumIndex);
if (manuallySetCurriculumIndex === false) {
// User is successfully logged in, now we need to do a little homework.
// to determine what the current curriculum should be for the current user.
// This should be set, but the user can and will be able to change it manually.
let currentCurriculumIndex = await accountBroker.scanUserDataForCurrentCurriculum();
// currentCurriculumIndex is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.ccurrentCurriculumIndexIs + currentCurriculumIndex);
await accountBroker.setCurrentCurriculum(currentCurriculumIndex);
} else {
// Yes we will manually set the current curriculum, and hard code it first to the 0-index.
await accountBroker.setCurrentCurriculum(0);
}
}
} else {
// ERROR: Cannot login, user does not exist.
console.log(app_msg.cErrorNoUserFoundLoginMessage01);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorNoUserFoundLoginMessage01);
}
} else {
// ERROR: Invalid user name, please try again with a valid username.
// console.log(app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
// If the user didn't specify a username, then we will clear the login configuration setting,
// So nobody is logged in.
await accountBroker.loginUser('');
}
let currentCurriculumIndex = await accountBroker.getCurrentCurriculumIndex();
// currentCurriculumIndex is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.ccurrentCurriculumIndexIs + currentCurriculumIndex);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function logout
* @description Allows the user to remove themselves from the currently logged in user.
* @param {array<string>} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function logout(inputData, inputMetaData) {
let functionName = logout.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let logoutSuccess = false
logoutSuccess = await accountBroker.logoutUser('');
if (logoutSuccess === false) {
// ERROR: Failure to logout.
console.log(app_msg.cErrorFailureToLogOutMessage01);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorFailureToLogOutMessage01);
}
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function startLesson
* @description Allows the user to launch a typing lesson.
* @param {array<string>} inputData The input(s) the user entered into the command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/02/28
*/
async function startLesson(inputData, inputMetaData) {
let functionName = startLesson.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let lessonScoreData = {};
let userExecutedLesson = false;
if (Array.isArray(inputData) && inputData.length === 2) {
if (parseInt(inputData[1]) > 0) {
let currentCurriculumIndex = await accountBroker.getCurrentCurriculumIndex();
// currentCurriculumIndex is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.ccurrentCurriculumIndexIs + currentCurriculumIndex);
let maxLessonNumber = await accountBroker.getHighestLessonCount(currentCurriculumIndex);
// maxLessonNumber is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cmaxLessonNumberIs + maxLessonNumber);
let userLessonNumber = parseInt(inputData[1]);
// userLessonNumber is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cuserLessonNumberIs + userLessonNumber);
if (userLessonNumber > 0 && userLessonNumber <= maxLessonNumber) {
let lessonPassingScoreEnabled = await accountBroker.isLessonAdvancementLimitEnabled();
// lessonPassingScoreEnabled is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.clessonPassingScoreEnabledIs + lessonPassingScoreEnabled);
if (lessonPassingScoreEnabled === true) {
let individualizedLessonSetting = await accountBroker.isIndividualizedLessonPassingScoresEnabled();
// individualizedLessonSetting is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cindividualizedLessonSettingIs + individualizedLessonSetting);
// NOTE: All of the below functions to control if the user is allowed to load the next requested lesson or not,
// should always function the same way if the user is using the individualized lesson passing scores or,
// the universally defined lesson passing scores. The lower level code will have been refactored internally.
// Even the above code may need to be evaluated to be removed from this code here.
let lessonAdvancementScoreLimitAccuracy = await accountBroker.getLessonAdvancementScoreLimitAccuracy(userLessonNumber, currentCurriculumIndex);
// lessonAdvancementScoreLimitAccuracy is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.clessonAdvancementScoreLimitAccuracyIs + lessonAdvancementScoreLimitAccuracy);
let lessonAdvancementScoreLimitSpeed = await accountBroker.getLessonAdvancementScoreLimitSpeed(userLessonNumber, currentCurriculumIndex);
// lessonAdvancementScoreLimitSpeed is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.clessonAdvancementScoreLimitSpeedIs + lessonAdvancementScoreLimitSpeed);
let highestScoringLessonAboveAdvancementLimit = await accountBroker.getHighestLessonNumberAboveAdvancementScoringLimit('', currentCurriculumIndex);
// highestScoringLessonAboveAdvancementLimit is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.chighestScoringLessonAboveAdvancementLimitIs + highestScoringLessonAboveAdvancementLimit);
// Validate that the user is trying to execute a lesson a maximum of 1 lesson above the highest lesson number that has a passing score.
if (userLessonNumber - 1 <= highestScoringLessonAboveAdvancementLimit) {
lessonScoreData = await accountBroker.executeLesson(userLessonNumber);
userExecutedLesson = true;
} else {
// WARNING: You are not aloud to run this lesson,
// please complete the earlier lessons before proceeding.
console.log(app_msg.cWarningStartLessonMessage01 + bas.cSpace + app_msg.cWarningStartLessonMessage02);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cWarningStartLessonMessage01 + bas.cSpace + app_msg.cWarningStartLessonMessage02);
}
} else {
lessonScoreData = await accountBroker.executeLesson(userLessonNumber, currentCurriculumIndex);
userExecutedLesson = true;
}
if (userExecutedLesson === true) {
// lessonScoreData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.clessonScoreDataIs + JSON.stringify(lessonScoreData));
if (lessonScoreData) {
let updatedUserAccountData = await accountBroker.appendUsersLessonScoreData(lessonScoreData, userLessonNumber, currentCurriculumIndex);
// updatedUserAccountData is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cupdatedUserAccountDataIs + JSON.stringify(updatedUserAccountData));
await accountBroker.storeAccountData(updatedUserAccountData);
let userHasPassedLesson = await haystacks.getConfigurationSetting(wrd.csystem, app_cfg.cuserHasPassedLesson);
let userHasCompletedFinalLessonInCurriculum = await haystacks.getConfigurationSetting(wrd.csystem, app_cfg.cuserHasCompletedFinalLessonInCurriculum);
if (userHasPassedLesson === true && userHasCompletedFinalLessonInCurriculum === true) {
let manuallySetCurriculumIndex = await haystacks.getConfigurationSetting(wrd.csystem, app_cfg.cmanuallySetCurriculumIndex);
let newCurrentCurriculumIndex = 0;
if (manuallySetCurriculumIndex === false) {
newCurrentCurriculumIndex = await accountBroker.scanUserDataForCurrentCurriculum();
} else {
// Manually increment the curriculum index and hard code it essentially!
newCurrentCurriculumIndex = currentCurriculumIndex + 1;
}
// newCurrentCurriculumIndex is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cnewCurrentCurriculumIndexIs + newCurrentCurriculumIndex);
await accountBroker.setCurrentCurriculum(newCurrentCurriculumIndex);
// Reset these flags.
await haystacks.setConfigurationSetting(wrd.csystem, app_cfg.cuserHasPassedLesson, false);
await haystacks.setConfigurationSetting(wrd.csystem, app_cfg.cuserHasCompletedFinalLessonInCurriculum, false);
}
}
} // End-if (userExecutedLesson === true)
} else {
// ERROR: The lesson number entered is not available.
console.log(app_msg.cErrorStartLessonMessage03);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorStartLessonMessage03);
// Please enter a lesson number between 1 and:
console.log(app_msg.cErrorStartLessonMessage04 + maxLessonNumber);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorStartLessonMessage04 + maxLessonNumber);
}
} else {
// ERROR: Invalid lesson number entered. Please enter a valid lesson number to execute.
console.log(app_msg.cErrorStartLessonMessage02);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorStartLessonMessage02);
}
} else {
// ERROR: No lesson number entered. Please enter a valid lesson number to execute.
console.log(app_msg.cErrorStartLessonMessage01);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorStartLessonMessage01);
}
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function generateUserReport
* @description Generates a report based on the currently logged in user,
* of the lessons with passing scores and not passing scores to display to the user.
* @param {array<string>} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/03/09
*/
async function generateUserReport(inputData, inputMetaData) {
let functionName = generateUserReport.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let userReportData;
let currentUserName = '';
if (inputData && Array.isArray(inputData) && inputData.length === 2) {
// User specified a username, pass that in as a parameter.
if (await accountBroker.doesAccountExist(inputData[1])) {
userReportData = await accountBroker.generateUserReport(inputData[1]);
currentUserName = inputData[1];
} else {
// ERROR: Invalid user name, please try again with a valid username.
console.log(app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.cErrorInvalidUserNameCreateAccountMessage01 + inputData[1]);
}
} else {
currentUserName = await accountBroker.currentUserAccount();
userReportData = await accountBroker.generateUserReport(currentUserName);
}
// currentUserName is:
await haystacks.consoleLog(namespacePrefix, functionName, app_msg.ccurrentUserNameIs + currentUserName);
if (userReportData) {
// Haystacks Typing Tutor report card for user:
console.log(app_msg.cgenerateUserReportMessage01 + currentUserName);
console.table(userReportData, [wrd.cPass + bas.cDash + wrd.cFail]);
}
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function printRecords
* @description Generates a report that contains the highest passing lesson for all registered users.
* This is useful for teachers who might have multiple students using the system and want to
* get a report on how well their students are doing.
* @param {array<string>} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/03/09
*/
async function printRecords(inputData, inputMetaData) {
let functionName = printRecords.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let allUsersReportData = await accountBroker.generateReportAllUsers();
// Haystacks Typing Tutor users report:
console.log(app_msg.cprintRecordsMessage01);
console.table(allUsersReportData, [app_sys.cLessonNumber])
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function destroyRecords
* @description Completely destroys all user accounts and user account records after prompting the user to confirm.
* @NOTE UPDATE: I'm not actually going to destroy the records in this command.
* Rather I will just provide some basic instructions to the user about how they should manually destroy the records.
* By deleting the users JSON files from the accounts folder.
* This will avoid the risk that a user might destroy records of all the other users on the system.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by an empty string.
* @author Seth Hollingsead
* @date 2023/03/09
*/
async function destroyRecords(inputData, inputMetaData) {
let functionName = destroyRecords.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
// Before you destroy the records, make sure you exit the Haystacks Typing Tutor application,
console.log(app_msg.destroyRecordsInstructionsMessage01);
// or the records will be resaved after you delete them.
console.log(app_msg.destroyRecordsInstructionsMessage02);
// You can destroy all records by going to the application installed path:
console.log(app_msg.destroyRecordsInstructionsMessage03);
// ./src/resources/accounts/
console.log(app_msg.destroyRecordsInstructionsMessage04);
// or
console.log(wrd.cor);
// ./bin/resources/accounts/
console.log(app_msg.destroyRecordsInstructionsMessage05);
// Then delete all of the files with the .JSON file extension.
console.log(app_msg.destroyRecordsInstructionsMessage06);
// This will remove all account data from the system forever.
console.log(app_msg.destroyRecordsInstructionsMessage07);
// If you wish to back-up the account data,
console.log(app_msg.destroyRecordsInstructionsMessage08);
// you can copy these files to another storage location before deleting them.
console.log(app_msg.destroyRecordsInstructionsMessage09);
// ****************************************************************************************************
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
export default {
createAccount,
printAccountsData,
printAccountData,
deleteAccount,
login,
logout,
startLesson,
generateUserReport,
printRecords,
destroyRecords
}