UPS9-Notes CRUD

This commit is contained in:
Omar Mihilmy 2019-01-30 09:48:11 +00:00
parent 1006554f73
commit cbeb15936e
3 changed files with 174 additions and 0 deletions

View File

@ -1,5 +1,6 @@
const AuthHandlers = require('../ups/auth/handlers');
const ProfileHandlers = require('../ups/profiles/handlers');
const NoteHandlers = require('../ups/notes/handlers');
/**
* Main router for our application, include all routes here. No logic should be added in this file.
@ -25,6 +26,12 @@ function router(app) {
app.get('/profiles/me/:profileNumber', ProfileHandlers.getUserProfile);
app.put('/profiles/uploadImage/:profileNumber', ProfileHandlers.updateUserProfileImage);
app.get('/profiles/suggest', ProfileHandlers.suggestNProfiles);
// Notes Endpoints
app.get('/notes/me/:tagferId', NoteHandlers.getAllNotes);
app.put('/notes/me/:tagferId', NoteHandlers.createNote);
app.post('/notes/me/:tagferId', NoteHandlers.updateNote);
app.delete('/notes/me/:tagferId', NoteHandlers.deleteNote);
}
module.exports = router;

77
src/ups/notes/dao.js Normal file
View File

@ -0,0 +1,77 @@
const admin = require('firebase-admin');
const errors = require('../../config/errors');
const db = admin.database();
/**
* Creates a new note. NoteIDs are the chronologically ordered keys generated by firebase.
*
* @param {String} from From-TagferID represents the 'from' side of the connection
* @param {String} to To-TagferID represents the 'to' side of the connection
* @param {Object} noteObject Contains the `content` and `updatedAt` timestamp
*/
function createNote(from, to, noteObject) {
const noteRef = db.ref(`notes/${from}/${to}`).push();
return noteRef.set(noteObject)
.then(() => noteRef.key)
.catch(() => { throw errors.APP_FIREBASE_DATABASE_ERROR; });
}
/**
* Updates an existing note. The reason we delete and create a new entry is this allows us to levearge the keys to
* provide ordering without needing to index our data.
*
* @param {String} from From-TagferID represents the 'from' side of the connection
* @param {String} to To-TagferID represents the 'to' side of the connection
* @param {Object} noteObject Contains the `content` and `updatedAt` timestamp
*/
function updateNote(from, to, noteObject){
const { noteId, content, updatedAt } = noteObject;
const notesRef = db.ref(`notes/${from}/${to}`);
const newNoteId = notesRef.push().key;
const updates = {};
updates[noteId] = null;
updates[newNoteId] = { content, updatedAt };
return notesRef.update(updates)
.then(() => newNoteId)
.catch(() => { throw errors.APP_FIREBASE_DATABASE_ERROR; });
}
/**
* Delete an existing note.
*
* @param {String} from From-TagferID represents the 'from' side of the connection
* @param {String} to To-TagferID represents the 'to' side of the connection
* @param {String} noteId UUID generated by firebase
*/
function deleteNote(from, to, noteId) {
return db.ref(`notes/${from}/${to}/${noteId}`).remove().catch(() => { throw errors.APP_FIREBASE_DATABASE_ERROR; });
}
/**
* Gets all notes between to users. Since on creation we used chronologically ordered keys, ordering here needs to be
* in reverse.
*
* @param {String} from From-TagferID represents the 'from' side of the connection
* @param {String} to To-TagferID represents the 'to' side of the connection
*/
function getAllNotes(from, to) {
return db.ref(`notes/${from}/${to}`).once('value').then(data => {
const allNotes = new Array(data.numChildren());
let index = data.numChildren() - 1;
data.forEach(note => {
const { content, updatedAt } = note.val();
allNotes[index--] = { noteId: note.key, content , updatedAt };
});
return allNotes;
}).catch(() => { throw errors.APP_FIREBASE_DATABASE_ERROR; });
}
module.exports = {
createNote,
updateNote,
deleteNote,
getAllNotes
};

90
src/ups/notes/handlers.js Normal file
View File

@ -0,0 +1,90 @@
const authDao = require('../auth/dao');
const notesDao = require('./dao');
const utils = require('../utils/utils');
/**
* Creates a new note
*
* @param req { content: String }
* @param res { noteId: String } | { error: AUTH_INVALID_SESSION | FIREBASE_DATABASE_ERROR }
*/
async function createNote(req,res) {
const noteObject = req.body;
const toTagferId = req.params.tagferId;
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
try {
const fromTagferId = authDao.getSession(sessionId).tagferId;
const noteId = await notesDao.createNote(fromTagferId, toTagferId, noteObject);
res.json({ noteId });
} catch (error) {
res.json({ error });
}
}
/**
* Updates an existing note
*
* @param req { noteId: String, content: String }
* @param res { noteId: String } | { error: AUTH_INVALID_SESSION | FIREBASE_DATABASE_ERROR }
*/
async function updateNote(req,res) {
const noteObject = req.body;
const toTagferId = req.params.tagferId;
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
try {
const fromTagferId = authDao.getSession(sessionId).tagferId;
const noteId = await notesDao.updateNote(fromTagferId, toTagferId, noteObject);
res.json({ noteId });
} catch (error) {
res.json({ error });
}
}
/**
* Deletes an existing note.
*
* @param req { noteId: String }
* @param res {} | { error: AUTH_INVALID_SESSION | FIREBASE_DATABASE_ERROR }
*/
async function deleteNote(req,res) {
const { noteId } = req.body;
const toTagferId = req.params.tagferId;
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
try {
const fromTagferId = authDao.getSession(sessionId).tagferId;
await notesDao.deleteNote(fromTagferId, toTagferId, noteId);
res.json({});
} catch (error) {
res.json({ error });
}
}
/**
* Gets all notes between two users.
*
* @param req {}
* @param res [{ noteId: String, updatedAt: Number, content: String }] | { error: AUTH_INVALID_SESSION | FIREBASE_DATABASE_ERROR }
*/
async function getAllNotes(req,res) {
const toTagferId = req.params.tagferId;
const sessionId = utils.getSessionIdFromAuthHeader(req, res);
try {
const fromTagferId = authDao.getSession(sessionId).tagferId;
const allNotes = await notesDao.getAllNotes(fromTagferId, toTagferId);
res.json({ notes: allNotes });
} catch (error) {
res.json({ error });
}
}
module.exports = {
createNote,
updateNote,
deleteNote,
getAllNotes
};