Add Bible verse highlights and notes API
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
const DBName = "EMI_SOCIAL";
|
||||
|
||||
const toProfileIds = (DB, profileIds = []) => {
|
||||
return profileIds
|
||||
.filter((profileId) => DB.ObjectID.isValid(profileId))
|
||||
.map((profileId) => DB.ObjectID(profileId));
|
||||
};
|
||||
|
||||
const publicProfile = (profile) => {
|
||||
if (!profile) return null;
|
||||
return {
|
||||
_id: profile._id,
|
||||
profile: profile.profile,
|
||||
username: profile.username,
|
||||
isGroup: profile.isGroup,
|
||||
isCourse: profile.isCourse,
|
||||
};
|
||||
};
|
||||
|
||||
const bibleDB = (DB) => {
|
||||
DB.bibleVerseCols = DB.db.db(DBName).collection("bible_verses");
|
||||
DB.bibleVerseCols.createIndex({ highlightedBy: 1 }).catch(console.error);
|
||||
DB.bibleVerseCols.createIndex({ notedBy: 1 }).catch(console.error);
|
||||
|
||||
const getVerseDoc = async (verseKey) => {
|
||||
return DB.bibleVerseCols.findOne({ _id: verseKey }).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
DB.getBibleProfileData = async (profileid) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const profile = await DB.profileCols.findOne(
|
||||
{ _id: DB.ObjectID(profileid) },
|
||||
{ projection: { bibleHighlights: 1, bibleNotes: 1 } }
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
highlights: profile?.bibleHighlights || [],
|
||||
notes: profile?.bibleNotes || [],
|
||||
};
|
||||
};
|
||||
|
||||
DB.getBibleVerseCounters = async (verseKey) => {
|
||||
const verse = await getVerseDoc(verseKey);
|
||||
const highlightedBy = Array.isArray(verse?.highlightedBy) ? verse.highlightedBy : [];
|
||||
const notedBy = Array.isArray(verse?.notedBy) ? verse.notedBy : [];
|
||||
return {
|
||||
verseKey,
|
||||
highlightCount: highlightedBy.length,
|
||||
noteProfileCount: notedBy.length,
|
||||
notesCount: verse?.notesCount || 0,
|
||||
};
|
||||
};
|
||||
|
||||
DB.getBibleVerseActivity = async (verseKey, limit = 10) => {
|
||||
const verse = await getVerseDoc(verseKey);
|
||||
const highlightedBy = Array.isArray(verse?.highlightedBy) ? verse.highlightedBy : [];
|
||||
const notedBy = Array.isArray(verse?.notedBy) ? verse.notedBy : [];
|
||||
const highlightProfiles = toProfileIds(DB, highlightedBy);
|
||||
const noteProfiles = toProfileIds(DB, notedBy);
|
||||
|
||||
const [highlights, noteUsers, notes] = await Promise.all([
|
||||
highlightProfiles.length
|
||||
? DB.profileCols.find({ _id: { $in: highlightProfiles } }).project({
|
||||
profile: 1,
|
||||
username: 1,
|
||||
isGroup: 1,
|
||||
isCourse: 1,
|
||||
}).toArray()
|
||||
: [],
|
||||
noteProfiles.length
|
||||
? DB.profileCols.find({ _id: { $in: noteProfiles } }).project({
|
||||
profile: 1,
|
||||
username: 1,
|
||||
isGroup: 1,
|
||||
isCourse: 1,
|
||||
}).toArray()
|
||||
: [],
|
||||
DB.profileCols.aggregate([
|
||||
{ $match: { "bibleNotes.verseKey": verseKey } },
|
||||
{ $unwind: "$bibleNotes" },
|
||||
{ $match: { "bibleNotes.verseKey": verseKey } },
|
||||
{ $sort: { "bibleNotes.updatedAt": -1, "bibleNotes.createdAt": -1 } },
|
||||
{ $limit: limit },
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
note: "$bibleNotes",
|
||||
profile: {
|
||||
_id: "$_id",
|
||||
profile: "$profile",
|
||||
username: "$username",
|
||||
isGroup: "$isGroup",
|
||||
isCourse: "$isCourse",
|
||||
}
|
||||
}
|
||||
}
|
||||
]).toArray(),
|
||||
]);
|
||||
|
||||
return {
|
||||
counters: await DB.getBibleVerseCounters(verseKey),
|
||||
highlightedBy: highlights.map(publicProfile),
|
||||
notedBy: noteUsers.map(publicProfile),
|
||||
notes,
|
||||
};
|
||||
};
|
||||
|
||||
DB.addBibleHighlight = async (profileid, verseKey) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const now = new Date();
|
||||
const _id = DB.ObjectID(profileid);
|
||||
const profileUpdate = await DB.profileCols.updateOne(
|
||||
{ _id, "bibleHighlights.verseKey": { $ne: verseKey } },
|
||||
{
|
||||
$push: {
|
||||
bibleHighlights: {
|
||||
verseKey,
|
||||
createdAt: now,
|
||||
}
|
||||
},
|
||||
$set: { lastUpdate: now }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
await DB.bibleVerseCols.updateOne(
|
||||
{ _id: verseKey },
|
||||
{
|
||||
$setOnInsert: { createdAt: now },
|
||||
$set: { updatedAt: now },
|
||||
$addToSet: { highlightedBy: profileid + "" }
|
||||
},
|
||||
{ upsert: true }
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (DB.clearProfileCache) DB.clearProfileCache(profileid);
|
||||
return profileUpdate;
|
||||
};
|
||||
|
||||
DB.removeBibleHighlight = async (profileid, verseKey) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const now = new Date();
|
||||
const _id = DB.ObjectID(profileid);
|
||||
const profileUpdate = await DB.profileCols.updateOne(
|
||||
{ _id },
|
||||
{
|
||||
$pull: { bibleHighlights: { verseKey } },
|
||||
$set: { lastUpdate: now }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
await DB.bibleVerseCols.updateOne(
|
||||
{ _id: verseKey },
|
||||
{
|
||||
$pull: { highlightedBy: profileid + "" },
|
||||
$set: { updatedAt: now }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (DB.clearProfileCache) DB.clearProfileCache(profileid);
|
||||
return profileUpdate;
|
||||
};
|
||||
|
||||
DB.addBibleNote = async (profileid, verseKey, text) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const now = new Date();
|
||||
const note = {
|
||||
_id: DB.ObjectID().toString(),
|
||||
verseKey,
|
||||
text,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
const _id = DB.ObjectID(profileid);
|
||||
const profileUpdate = await DB.profileCols.updateOne(
|
||||
{ _id },
|
||||
{
|
||||
$push: { bibleNotes: note },
|
||||
$set: { lastUpdate: now }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
await DB.bibleVerseCols.updateOne(
|
||||
{ _id: verseKey },
|
||||
{
|
||||
$setOnInsert: { createdAt: now },
|
||||
$set: { updatedAt: now },
|
||||
$addToSet: { notedBy: profileid + "" },
|
||||
$inc: { notesCount: 1 }
|
||||
},
|
||||
{ upsert: true }
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (DB.clearProfileCache) DB.clearProfileCache(profileid);
|
||||
return profileUpdate ? note : false;
|
||||
};
|
||||
|
||||
DB.updateBibleNote = async (profileid, verseKey, noteId, text) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const now = new Date();
|
||||
const _id = DB.ObjectID(profileid);
|
||||
const result = await DB.profileCols.findOneAndUpdate(
|
||||
{ _id, bibleNotes: { $elemMatch: { _id: noteId, verseKey } } },
|
||||
{
|
||||
$set: {
|
||||
"bibleNotes.$.text": text,
|
||||
"bibleNotes.$.updatedAt": now,
|
||||
lastUpdate: now,
|
||||
}
|
||||
},
|
||||
{
|
||||
returnOriginal: false,
|
||||
projection: { bibleNotes: 1 }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (DB.clearProfileCache) DB.clearProfileCache(profileid);
|
||||
return result?.value?.bibleNotes?.find((note) => note._id === noteId) || null;
|
||||
};
|
||||
|
||||
DB.removeBibleNote = async (profileid, verseKey, noteId) => {
|
||||
if (!DB.ObjectID.isValid(profileid)) return false;
|
||||
const now = new Date();
|
||||
const _id = DB.ObjectID(profileid);
|
||||
const result = await DB.profileCols.updateOne(
|
||||
{ _id, bibleNotes: { $elemMatch: { _id: noteId, verseKey } } },
|
||||
{
|
||||
$pull: { bibleNotes: { _id: noteId, verseKey } },
|
||||
$set: { lastUpdate: now }
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (result?.modifiedCount) {
|
||||
const stillHasNotes = await DB.profileCols.findOne(
|
||||
{ _id, "bibleNotes.verseKey": verseKey },
|
||||
{ projection: { _id: 1 } }
|
||||
);
|
||||
|
||||
const verseUpdate = {
|
||||
$inc: { notesCount: -1 },
|
||||
$set: { updatedAt: now }
|
||||
};
|
||||
if (!stillHasNotes) {
|
||||
verseUpdate.$pull = { notedBy: profileid + "" };
|
||||
}
|
||||
|
||||
await DB.bibleVerseCols.updateOne({ _id: verseKey }, verseUpdate).catch((err) => {
|
||||
console.log(err);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
if (DB.clearProfileCache) DB.clearProfileCache(profileid);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = bibleDB;
|
||||
@@ -5,6 +5,10 @@ let userProfileCache = {};
|
||||
userDB = (DB) => {
|
||||
DB.profileCols = DB.db.db(DBName).collection("profiles");
|
||||
|
||||
DB.clearProfileCache = (profileid) => {
|
||||
if (userProfileCache[profileid]) delete userProfileCache[profileid];
|
||||
};
|
||||
|
||||
DB.newProfile = (profileObj) => {
|
||||
return DB.profileCols.insertOne(profileObj.toObj()).catch((err) => {
|
||||
console.log(err);
|
||||
|
||||
Reference in New Issue
Block a user