Untitled
unknown
plain_text
a year ago
19 kB
1
Indexable
Never
const { sanitizeEntity } = require("strapi-utils"); const { respond, respondWithError, translation } = require("@macromo/tools"); const { TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_ANCESTRY, TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_DISEASES, TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_TRAITS, TRANSLATION_INSIGHTS_SYSTEMS_DESCRIPTION_ANCESTRY, } = require("@macromo/enums"); const { responses: { FORBIDDEN, INTERNAL_SERVER_ERROR }, } = strapi.config.get("server"); const { responses: { INSIGHTS_DISEASE_NOT_FOUND, INSIGHTS_MACROMO_ID_NOT_DEFINED, INSIGHTS_MEDICATION_NOT_FOUND, INSIGHTS_SYSTEM_ID_NOT_DEFINED, INSIGHTS_SYSTEM_NOT_FOUND, INSIGHTS_TRAIT_NOT_FOUND, }, } = strapi.config.get("insights"); module.exports = { async getAncestry(ctx) { const { state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const { ancestry: ancestryGroups = {} } = medicalResultsState.toJSON(); const ancestryIds = Object.keys(ancestryGroups); const ancestryState = await strapi .query("ancestry") .model.fetchAll(strapi.services["insights-schema"].ancestryBasic); const ancestry = ancestryState.toJSON(); const payload = { description: { key: TRANSLATION_INSIGHTS_SYSTEMS_DESCRIPTION_ANCESTRY, }, origins: ancestry.reduce((acc, { displayName, macromoId }) => { if (ancestryIds.includes(macromoId)) { acc.push( sanitizeEntity( { displayName, value: ancestryGroups[macromoId] }, { model: strapi.models.ancestry } ) ); } return acc; }, []), }; respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getDiseases(ctx) { const { state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const diseasesState = await strapi .query("disease") .model.fetchAll(strapi.services["insights-schema"].diseasesBasic); const diseases = diseasesState.toJSON(); const medicalResultsIds = medicalResults.results?.insights?.map(({ macromoId }) => macromoId) || []; const payload = diseases.reduce((acc, cur) => { if (medicalResultsIds.includes(cur.macromoId)) { const level = medicalResults.results?.insights?.find( ({ macromoId }) => macromoId === cur.macromoId )?.riskScore; return [ ...acc, sanitizeEntity({ ...cur, level }, { model: strapi.models.disease }), ]; } return acc; }, []); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getDiseaseById(ctx) { const { params: { macromoId }, state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); if (!macromoId) { return respondWithError({ ctx, data: INSIGHTS_MACROMO_ID_NOT_DEFINED }); } try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const diseaseState = await strapi .query("disease") .model.query((q) => { q.where("macromoId", macromoId); }) .fetch(strapi.services["insights-schema"].diseaseDetails); if (!diseaseState) { return respondWithError({ ctx, data: INSIGHTS_DISEASE_NOT_FOUND }); } const { ...disease } = diseaseState.toJSON(); const level = medicalResults.results?.insights?.find( (insight) => insight.macromoId === macromoId )?.riskScore; const payload = sanitizeEntity( { ...disease, level, }, { model: strapi.models.disease } ); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getInsightsOverview(ctx) { const { state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); try { const questionnairesState = await strapi .query("questionnaire") .model.query((q) => q.where("userId", userId).whereNotNull("questionnaireId") ) .fetchAll(); const questionnaires = questionnairesState.toJSON(); const questionnaireTemplateState = await strapi .query("questionnaire_template") .model.fetchAll(); const questionnaireTemplate = questionnaireTemplateState.toJSON(); const kitsState = await strapi .query("kit") .model.query((q) => q.where("userId", userId)) .fetchAll(); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const onboarding = { "health-profile": questionnaireTemplate.length ? Math.round( (questionnaires.length / questionnaireTemplate.length + Number.EPSILON) * 100 ) / 100 : 0, insights: 0, kit: +!!kits.length, }; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx, data: { payload: { categories: [], diseases: [], onboarding, }, }, }); } const medicalResults = medicalResultsState.toJSON(); const medicalResultsIds = medicalResults.results?.insights?.map(({ macromoId }) => macromoId) || []; const ancestryIds = Object.keys(medicalResults.ancestry || {}); const ancestryState = await strapi .query("ancestry") .model.fetchAll(strapi.services["insights-schema"].ancestryBasic); const diseasesState = await strapi .query("disease") .model.fetchAll(strapi.services["insights-schema"].diseasesBasic); const diseases = diseasesState.toJSON(); const traitsState = await strapi .query("trait") .model.fetchAll(strapi.services["insights-schema"].traitsBasic); const traits = traitsState.toJSON(); const ancestry = ancestryState.toJSON(); const payload = { categories: [ { count: ancestry.filter(({ macromoId }) => ancestryIds.includes(macromoId) ).length, displayName: { key: TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_ANCESTRY, }, }, { count: traits.filter(({ macromoId }) => medicalResultsIds.includes(macromoId) ).length, displayName: { key: TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_TRAITS, }, }, { count: diseases.filter(({ macromoId }) => medicalResultsIds.includes(macromoId) ).length, displayName: { key: TRANSLATION_INSIGHTS_SYSTEMS_CATEGORY_DISEASES, }, }, ], diseases: diseases.reduce((acc, cur) => { if (medicalResultsIds.includes(cur.macromoId)) { const level = medicalResults.results?.insights?.find( (insight) => insight.macromoId === cur.macromoId )?.riskScore; return [ ...acc, sanitizeEntity( { ...cur, level }, { model: strapi.models.disease } ), ]; } return acc; }, []), onboarding: { ...onboarding, insights: +!!medicalResults, }, }; respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getMedications(ctx) { const { state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const medicationsState = await strapi .query("medication") .model.fetchAll(strapi.services["insights-schema"].medicationsBasic); const medications = medicationsState.toJSON(); const medicalResultsIds = medicalResults?.results?.insights?.map(({ macromoId }) => macromoId) || []; const payload = medications.reduce((acc, cur) => { if (medicalResultsIds.includes(cur.macromoId)) { const level = medicalResults?.results?.insights?.find( (insight) => insight.macromoId === cur.macromoId )?.riskScore; return [ ...acc, sanitizeEntity( { ...cur, level }, { model: strapi.models.medication } ), ]; } return acc; }, []); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getMedicationById(ctx) { const { params: { macromoId }, state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); if (!macromoId) { return respondWithError({ ctx, data: INSIGHTS_MACROMO_ID_NOT_DEFINED }); } try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const medicationState = await strapi .query("medication") .model.query((q) => { q.where("macromoId", macromoId); }) .fetch(strapi.services["insights-schema"].medicationDetails); if (!medicationState) { return respondWithError({ ctx, data: INSIGHTS_MEDICATION_NOT_FOUND }); } const medication = medicationState.toJSON(); const level = medicalResults?.results?.insights?.find( (insight) => insight.macromoId === macromoId )?.riskScore; const payload = sanitizeEntity( { ...medication, level, }, { model: strapi.models.medication } ); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getTraits(ctx) { const { state: { user }, } = ctx; const { id: userId } = user; if (!userId) return respondWithError({ ctx, data: FORBIDDEN }); try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const traitsState = await strapi .query("trait") .model.fetchAll(strapi.services["insights-schema"].traitsBasic); const traits = traitsState.toJSON(); const medicalResultsIds = medicalResults.results?.insights?.map(({ macromoId }) => macromoId) || []; const payload = traits.reduce((acc, cur) => { if (medicalResultsIds.includes(cur.macromoId)) { const level = medicalResults.results?.insights?.find( (insight) => insight.macromoId === cur.macromoId )?.riskScore; return [ ...acc, sanitizeEntity({ ...cur, level }, { model: strapi.models.trait }), ]; } return acc; }, []); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, async getTraitById(ctx) { const { params: { macromoId }, state: { user }, } = ctx; const { id: userId } = user; if (!macromoId) { return respondWithError({ ctx, data: INSIGHTS_MACROMO_ID_NOT_DEFINED }); } try { const kitsState = await strapi .query("kit") .model.query((q) => { q.where("userId", userId); }) .fetchAll(strapi.services["insights-schema"].kits); const kits = kitsState.toJSON(); const kitId = kits[0]?.id; const medicalResultsState = kitId ? await strapi .query("medical_result") .model.query((q) => { q.where("kit", kitId).andWhere("completed", true); }) .fetch(strapi.services["insights-schema"].medicalResults) : undefined; if (!medicalResultsState) { return respond({ ctx }); } const medicalResults = medicalResultsState.toJSON(); const traitState = await strapi .query("trait") .model.query((q) => { q.where("macromoId", macromoId); }) .fetch(strapi.services["insights-schema"].traitDetails); if (!traitState) { return respondWithError({ ctx, data: INSIGHTS_TRAIT_NOT_FOUND }); } const trait = traitState.toJSON(); const level = medicalResults?.results?.insights?.find( (insight) => insight.macromoId === macromoId )?.riskScore; const payload = sanitizeEntity( { ...trait, level, }, { model: strapi.models.trait } ); respond({ ctx, data: { payload } }); } catch (error) { respondWithError({ ctx, data: INTERNAL_SERVER_ERROR, error }); } }, // TODO - check, update errors // CAUTION - doesn't work now!!! async isUserInsightReady(ctx) { const userId = ctx.state.user.id; const user = await strapi .query("user", "users-permissions") .findOne({ id: userId }); if (!user) { return ctx.badRequest("User not found"); } try { const insight = await strapi .query("medical_result") .findOne({ userId, completed: true }); if (!insight) { return (ctx.body = { statusCode: 200, message: "Insights are not ready.", }); } else { // TODO: lang is missing, AWS is calling this route, wrong email template. if (user.email) { await strapi.services.user.sendInsightReadyEmail(user); } else { await strapi.services.sms.send( "Your insights are ready! Please open Macromo" + " application. https://www.macromo.org", user.phone ); } ctx.body = { statusCode: 200, insightId: insight.id, isReady: insight.completed, }; } } catch (e) { console.error(e); ctx.status = 500; ctx.body = { statusCode: 500, error: "Internal server error", }; } }, };