v1.1.0/number values and efficacy

This commit is contained in:
2021-04-20 20:16:21 -04:00
parent 2eabb6807f
commit 5c39e8a628
10 changed files with 581 additions and 435 deletions
+138 -132
View File
@@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPastResult = exports.saveResult = void 0;
exports.getPastResult = exports.saveResult = exports.getStats = void 0;
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const firebaseSecret = require("./firebaseSecret.json");
@@ -19,152 +19,120 @@ const params = {
admin.initializeApp({
credential: admin.credential.cert(params),
});
const VAX_NAMES = {
PB: "Pfizer-BioNTech",
MD: "Moderna",
JJ: "J&J Janssen",
};
const VAX_DOSES = {
ONE: "Dose 1",
TWO: "Dose 2",
};
const serializeGaId = (_gaid) => {
if (_gaid) {
return _gaid.split(".").join("|");
}
return "";
};
const addResultToStats = async (data) => {
const cleanData = Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
delete cleanData.gid;
const updateDoc = {
count: admin.firestore.FieldValue.increment(1),
};
if (data.name === VAX_NAMES.PB || data.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey) => {
const dose = VAX_DOSES[doseKey];
Object.keys(cleanData[dose]).forEach((symptom) => {
if (cleanData[dose][symptom]) {
updateDoc[`${dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
});
});
}
else {
Object.keys(cleanData).forEach((symptom) => {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
});
}
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
};
const removeResultFromStats = async (data) => {
const cleanData = Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
delete cleanData.gid;
const updateDoc = {
count: admin.firestore.FieldValue.increment(-1),
};
if (data.name === VAX_NAMES.PB || data.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey) => {
const dose = VAX_DOSES[doseKey];
Object.keys(cleanData[dose]).forEach((symptom) => {
if (cleanData[dose][symptom]) {
updateDoc[`${dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
}
});
});
}
else {
Object.keys(cleanData).forEach((symptom) => {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
});
}
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
};
exports.getStats = functions.https.onCall(async () => {
const stats = await admin.firestore().collection("stats").get();
const docs = stats.docs
.map((docSnap) => ({ name: docSnap.id, result: docSnap.data() }));
const returnData = {};
docs.forEach((vaxResult) => {
returnData[vaxResult.name] = {};
returnData[vaxResult.name] = vaxResult.result;
});
return returnData;
});
exports.saveResult = functions.https.onCall(async (data, context) => {
if (!!data && !!context) {
const { gid } = data;
const docId = serializeGaId(gid);
const docData = Object.assign({}, data);
delete docData.gid;
const existingData = await admin
// Get existing result
const existingResult = await admin
.firestore()
.collection("results")
.doc(docId)
.doc(serializeGaId(gid))
.get()
.then((doc) => doc.data());
if (existingData !== undefined && existingData !== docData &&
existingData.name === docData.name) {
// DATA EXISTS FOR USER
// BUT DIFF DATA SENT FOR UPDATE
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
const updateDoc = {};
Object.keys(docData).forEach((symptom) => {
// IF WAS TRUE, NOW FALSE = -1
// IF WAS TRUE, NOW TRUE = 0
// IF WAS FALSE, NOW TRUE = +1
// IF WAS FALSE, NOW FALSE = 0
let incrementValue = 0;
if (existingData[symptom] === true && docData[symptom] === false) {
incrementValue = -1;
}
else if (existingData[symptom] === false &&
docData[symptom] === true) {
incrementValue = 1;
}
if (data.dose) {
updateDoc[`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(incrementValue);
}
else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(incrementValue);
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
.then((docSnap) => docSnap.data());
// Update user result
const cleanData = Object.assign({}, data);
delete cleanData.gid;
await admin
.firestore()
.collection("results")
.doc(serializeGaId(gid))
.set(cleanData);
// No existing result
if (existingResult === undefined) {
await addResultToStats(data);
}
else if (existingData !== undefined && existingData !== docData &&
existingData.name !== docData.name) {
// UNDO DATA FOR OLD VAX
// DECREMENT VALUES FOR EACH SYMPTOM ON OLD VAX
const undoDoc = {
count: admin.firestore.FieldValue.increment(-1),
};
Object.keys(existingData).forEach((symptom) => {
if (symptom !== "name" && symptom !== "dose" &&
symptom !== "age") {
if (existingData[symptom] === true) {
if (existingData.dose) {
undoDoc[`${existingData.dose}.${existingData.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
}
else {
undoDoc[`${existingData.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
}
}
}
});
admin
.firestore()
.collection("stats")
.doc(existingData.name)
.update(undoDoc);
// PROCESS NEW DATA FOR USE
// SAVE USER DATA
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
// INCREMENT TOTAL RESPONSE COUNT
const updateDoc = {
count: admin.firestore.FieldValue.increment(1),
};
// INCREMENT VALUES FOR EACH SYMPTOM
Object.keys(docData).forEach((symptom) => {
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
}
else if (existingData === undefined) {
// DATA DOESN'T EXIST FOR USER
// SAVE USER DATA
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
// INCREMENT TOTAL RESPONSE COUNT
const updateDoc = {
count: admin.firestore.FieldValue.increment(1),
};
// INCREMENT VALUES FOR EACH SYMPTOM
Object.keys(docData).forEach((symptom) => {
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
else {
await removeResultFromStats(existingResult);
await addResultToStats(data);
}
}
});
exports.getPastResult = functions.https.onCall(async (data, context) => {
if (!!data && !!context) {
const { gid } = data;
let hasToUpdateDb = false;
const existingData = await admin
.firestore()
.collection("results")
@@ -172,11 +140,49 @@ exports.getPastResult = functions.https.onCall(async (data, context) => {
.get()
.then((doc) => doc.data());
if (existingData) {
if (existingData["NAUSEA / VOMITING"]) {
existingData["NAUSEA OR VOMITING"] =
existingData["NAUSEA / VOMITING"];
const returnData = Object.assign({}, existingData);
if (existingData.name === VAX_NAMES.PB ||
existingData.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey) => {
const dose = VAX_DOSES[doseKey];
if (!existingData[dose]) {
hasToUpdateDb = true;
const temp = {};
Object.keys(existingData).forEach((symptom) => {
if (symptom !== "name" &&
symptom !== "age" &&
symptom !== "dose") {
if (existingData.dose === dose) {
temp[symptom] = existingData[symptom];
delete returnData[symptom];
}
else {
temp[symptom] = false;
}
}
});
returnData[dose] = temp;
}
if (returnData[dose]["NAUSEA / VOMITING"]) {
returnData["NAUSEA OR VOMITING"] =
returnData["NAUSEA / VOMITING"];
}
});
}
return existingData;
else {
if (returnData["NAUSEA / VOMITING"]) {
returnData["NAUSEA OR VOMITING"] =
returnData["NAUSEA / VOMITING"];
}
}
if (hasToUpdateDb) {
await admin
.firestore()
.collection("results")
.doc(serializeGaId(gid))
.set(returnData);
}
return returnData;
}
}
return undefined;
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -3,7 +3,7 @@
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
"serve": "npm run devenv && npm run build && $env:NODE_ENV=DEV && firebase emulators:start",
"serve": "npm run devenv && npm run build && firebase emulators:start --import ./exportDB",
"devenv": "SET NODE_ENV=dev",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
+169 -197
View File
@@ -19,14 +19,15 @@ admin.initializeApp({
credential: admin.credential.cert(params),
});
type SideEffect = Record<string, boolean>;
type DoseToSideEffect = Record<string, SideEffect>;
type DBResult = {
name : string;
age : string;
"J&J Janssen"? : SideEffect;
"Moderna"? : DoseToSideEffect;
"Pfizer-BioNTech"? : DoseToSideEffect;
const VAX_NAMES : Record<string, string> = {
PB: "Pfizer-BioNTech",
MD: "Moderna",
JJ: "J&J Janssen",
};
const VAX_DOSES : Record<string, string> = {
ONE: "Dose 1",
TWO: "Dose 2",
};
type SaveResultRequestData = {
@@ -44,34 +45,93 @@ const serializeGaId = (_gaid: string): string => {
}
return "";
};
const requestDataToDbData = (data: SaveResultRequestData) : DBResult => {
console.log(data);
return {name: "a", age: "d"};
};
const addResultToStats = async (data : DBResult) => {
console.log(data);
};
const removeResultFromStats = async (data : DBResult) => {
console.log(data);
};
const setResultInDb = async (data: SaveResultRequestData) => {
const {name, age, dose} = data;
const result : DBResult = {name, age};
const rawResult : Record<string, boolean> = {};
Object.keys(data).filter(k => data[k] === true || data[k] === false).forEach(k => {
rawResult[k] = data[k];
});
if (!!dose.replace(/\s/g, "")) {
result[name][dose][age] =
const addResultToStats = async (data : SaveResultRequestData) => {
const cleanData : Record<string, any> =
Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
delete cleanData.gid;
const updateDoc : Record<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(1),
};
if (data.name === VAX_NAMES.PB || data.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey : string) => {
const dose : string = VAX_DOSES[doseKey];
Object.keys(cleanData[dose]).forEach((symptom : string) => {
if (cleanData[dose][symptom]) {
let updateDocSymptom = symptom.replace("/", "OR");
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${dose}.${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(1);
}
});
});
} else {
Object.keys(cleanData).forEach((symptom : string) => {
let updateDocSymptom = symptom.replace("/", "OR");
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(1);
});
}
await addResultToStats(requestDataToDbData(data));
return result;
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
};
const removeResultFromStats = async (data : FirebaseFirestore.DocumentData) => {
const cleanData : Record<string, any> =
Object.assign({}, data);
delete cleanData.name;
delete cleanData.dose;
delete cleanData.age;
delete cleanData.gid;
const updateDoc : Record<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(-1),
};
if (data.name === VAX_NAMES.PB || data.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey : string) => {
const dose : string = VAX_DOSES[doseKey];
Object.keys(cleanData[dose]).forEach((symptom : string) => {
if (cleanData[dose][symptom]) {
let updateDocSymptom = symptom.replace("/", "OR");
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${dose}.${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(-1);
}
});
});
} else {
Object.keys(cleanData).forEach((symptom : string) => {
let updateDocSymptom = symptom.replace("/", "OR");
if (symptom === "DIARRHEA") {
updateDocSymptom = "DIRRHEA";
}
updateDoc[`${data.age}.${updateDocSymptom}`] =
admin.firestore.FieldValue.increment(-1);
});
}
admin.firestore().collection("stats").doc(data.name).update(updateDoc);
};
export const getStats = functions.https.onCall(
async () => {
const stats = await admin.firestore().collection("stats").get();
const docs = stats.docs
.map((docSnap) => ({name: docSnap.id, result: docSnap.data()}));
const returnData : Record<string, unknown> = {};
docs.forEach((vaxResult) => {
returnData[vaxResult.name] = {};
returnData[vaxResult.name] = vaxResult.result;
});
return returnData;
});
export const saveResult = functions.https.onCall(
async (data: SaveResultRequestData, context) => {
if (!!data && !!context) {
@@ -83,175 +143,87 @@ export const saveResult = functions.https.onCall(
.doc(serializeGaId(gid))
.get()
.then((docSnap) => docSnap.data());
// No existing result
if (existingResult === undefined) {
// Set result
setResultInDb(data);
} else {
const {dose, name, age} = data;
if (existingResult.name === name && // Same vax
existingResult.age === age && // Same age group
!!dose.replace(/\s/g, "") && // Has dose sub category
!existingResult[name][age][dose]) { // Dose not existing
setResultInDb(data);
} else {
await removeResultFromStats(existingResult);
}
}
}
if (!!data && !!context) {
const {gid} = data;
const docId: string = serializeGaId(gid);
const docData: Record<string, string | boolean> =
Object.assign({}, data);
delete docData.gid;
const existingData = await admin
// Update user result
const cleanData : Record<string, any> =
Object.assign({}, data);
delete cleanData.gid;
await admin
.firestore()
.collection("results")
.doc(docId)
.get()
.then((doc) => doc.data());
if (existingData !== undefined && existingData !== docData &&
existingData.name === docData.name) {
// DATA EXISTS FOR USER
// BUT DIFF DATA SENT FOR UPDATE
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
const updateDoc : Record<string, admin.firestore.FieldValue> = {};
Object.keys(docData).forEach((symptom : string) => {
// IF WAS TRUE, NOW FALSE = -1
// IF WAS TRUE, NOW TRUE = 0
// IF WAS FALSE, NOW TRUE = +1
// IF WAS FALSE, NOW FALSE = 0
let incrementValue = 0;
if (existingData[symptom] === true && docData[symptom] === false) {
incrementValue = -1;
} else if (existingData[symptom] === false &&
docData[symptom] === true) {
incrementValue = 1;
}
if (data.dose) {
updateDoc[
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(incrementValue);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(incrementValue);
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
} else if (existingData !== undefined && existingData !== docData &&
existingData.name !== docData.name) {
// UNDO DATA FOR OLD VAX
// DECREMENT VALUES FOR EACH SYMPTOM ON OLD VAX
const undoDoc : Record<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(-1),
};
Object.keys(existingData).forEach((symptom : string) => {
if (symptom !== "name" && symptom !== "dose" &&
symptom !== "age" ) {
if (existingData[symptom] === true) {
if (existingData.dose) {
undoDoc[
`${existingData.dose}.${existingData.age}.${
symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
} else {
undoDoc[`${existingData.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(-1);
}
}
}
});
admin
.firestore()
.collection("stats")
.doc(existingData.name)
.update(undoDoc);
// PROCESS NEW DATA FOR USE
// SAVE USER DATA
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
// INCREMENT TOTAL RESPONSE COUNT
const updateDoc : Record<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(1),
};
// INCREMENT VALUES FOR EACH SYMPTOM
Object.keys(docData).forEach((symptom : string) => {
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
} else if (existingData === undefined) {
// DATA DOESN'T EXIST FOR USER
// SAVE USER DATA
await admin.firestore().collection("results").doc(docId).set(docData);
delete docData.age;
delete docData.name;
delete docData.dose;
// INCREMENT TOTAL RESPONSE COUNT
const updateDoc : Record<string, admin.firestore.FieldValue> = {
count: admin.firestore.FieldValue.increment(1),
};
// INCREMENT VALUES FOR EACH SYMPTOM
Object.keys(docData).forEach((symptom : string) => {
if (docData[symptom] === true) {
if (data.dose) {
updateDoc[
`${data.dose}.${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
} else {
updateDoc[`${data.age}.${symptom.replace("/", "OR")}`] =
admin.firestore.FieldValue.increment(1);
}
}
});
admin
.firestore()
.collection("stats")
.doc(data.name)
.update(updateDoc);
.doc(serializeGaId(gid))
.set(cleanData);
// No existing result
if (existingResult === undefined) {
await addResultToStats(data);
} else {
await removeResultFromStats(existingResult);
await addResultToStats(data);
}
}
});
export const getPastResult = functions.https.onCall(async (data : {gid:string}, context) => {
if (!!data && !!context) {
const {gid} = data;
const existingData : admin.firestore.DocumentData | undefined = await admin
.firestore()
.collection("results")
.doc(serializeGaId(gid))
.get()
.then((doc) => doc.data());
if (existingData) {
if (existingData["NAUSEA / VOMITING"]) {
existingData["NAUSEA OR VOMITING"] =
existingData["NAUSEA / VOMITING"];
export const getPastResult =
functions.https.onCall(async (data : {gid:string}, context) => {
if (!!data && !!context) {
const {gid} = data;
let hasToUpdateDb = false;
const existingData : admin.firestore.DocumentData | undefined =
await admin
.firestore()
.collection("results")
.doc(serializeGaId(gid))
.get()
.then((doc) => doc.data());
if (existingData) {
const returnData : admin.firestore.DocumentData | undefined =
Object.assign({}, existingData);
if (existingData.name === VAX_NAMES.PB ||
existingData.name === VAX_NAMES.MD) {
Object.keys(VAX_DOSES).forEach((doseKey : string) => {
const dose : string = VAX_DOSES[doseKey];
if (!existingData[dose]) {
hasToUpdateDb = true;
const temp : Record<string, unknown> = {};
Object.keys(existingData).forEach((symptom) => {
if (symptom !== "name" &&
symptom !== "age" &&
symptom !== "dose") {
if (existingData.dose === dose) {
temp[symptom] = existingData[symptom];
delete returnData[symptom];
} else {
temp[symptom] = false;
}
}
});
returnData[dose] = temp;
}
if (returnData[dose]["NAUSEA / VOMITING"]) {
returnData["NAUSEA OR VOMITING"] =
returnData["NAUSEA / VOMITING"];
}
if (returnData["DIRRHEA"]) {
returnData["DIARRHEA"] = returnData["DIRRHEA"];
}
});
} else {
if (returnData["NAUSEA / VOMITING"]) {
returnData["NAUSEA OR VOMITING"] =
returnData["NAUSEA / VOMITING"];
}
if (returnData["DIRRHEA"]) {
returnData["DIARRHEA"] = returnData["DIRRHEA"];
}
}
if (hasToUpdateDb) {
await admin
.firestore()
.collection("results")
.doc(serializeGaId(gid))
.set(returnData);
}
return returnData;
}
return existingData;
}
}
return undefined;
});
return undefined;
});