Explorar el Código

Update category and all shelf APIs completed

master
kj1352 hace 4 años
padre
commit
bdeb739bc9
Se han modificado 8 ficheros con 292 adiciones y 134 borrados
  1. +4
    -0
      src/index.ts
  2. +1
    -2
      src/models/category.ts
  3. +23
    -30
      src/models/shelf.ts
  4. +3
    -2
      src/models/user.ts
  5. +1
    -6
      src/models/word.ts
  6. +119
    -0
      src/user-profile/category-routes.ts
  7. +1
    -94
      src/user-profile/routes.ts
  8. +140
    -0
      src/user-profile/shelf-routes.ts

+ 4
- 0
src/index.ts Ver fichero

@@ -6,6 +6,8 @@ import { connectToDatabaseServer } from './db-utils';
import sendGridMail from '@sendgrid/mail';
import { userProfileRoutes } from './user-profile/routes';
import { revisionRoutes } from './revision/routes';
import { categoryRoutes } from './user-profile/category-routes';
import { shelfRoutes } from './user-profile/shelf-routes';

const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY || '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';

@@ -19,6 +21,8 @@ app.set('port', process.env.PORT || 8001);
app.use('/', authRoutes);
app.use('/', userProfileRoutes);
app.use('/', revisionRoutes);
app.use('/', categoryRoutes);
app.use('/', shelfRoutes);

app.get('/', (request, response) => {
response.send('Server running @ port' + app.get('port'));


+ 1
- 2
src/models/category.ts Ver fichero

@@ -1,7 +1,6 @@
import { Shelf } from "./shelf";

export interface Category {
_id: string,
export interface Category { //_id is not needed as it is created by default
name: string,
icon: string,
shelves?: Array<Shelf>,


+ 23
- 30
src/models/shelf.ts Ver fichero

@@ -1,40 +1,33 @@
import { viewPermissionType } from "./variables";
import { Word } from "./word";

export interface Shelf {
_id: string,
name: string,
description: string,
viewType: viewPermissionType,
interface RevisionHistoryRecord {
day: Date,
wasRecallSuccessful: boolean
}

interface AddedWord {
word: Word,
notes: Array<string>,
isFavourite: boolean,
nextRevisionDateTime: Date,
spaceBetweenRecall: number, // in Days
revisionHistory : Array<RevisionHistoryRecord>,
isArchived: boolean,
addedWords: Array<{
word: Word,
notes: Array<string>,
isFavourite: boolean,
nextRevisionDateTime: Date,
spaceBetweenRecall: number, // in Days
revisionHistory : Array<{
day: Date,
wasRecallSuccessful: boolean,
}>
}>
}

export interface MongoShelf {
_id: string,
export interface Shelf {
name: string,
description: string,
description?: string,
viewType: viewPermissionType,
isArchived: boolean,
addedWords: Array<{
word: Word,
notes: Array<string>,
isFavourite: boolean,
nextRevisionDateTime: Date,
spaceBetweenRecall: number, // in Days
revisionHistory : Array<{
day: Date,
wasRecallSuccessful: boolean,
}>
}>
addedWords?: Array<AddedWord>
}

interface MongoAddedWord extends Omit<AddedWord, "word"> {
word: string,
}

export interface MongoShelf extends Omit<Shelf, "addedWords"> {
addedWords?: Array<MongoAddedWord>
}

+ 3
- 2
src/models/user.ts Ver fichero

@@ -12,6 +12,7 @@ export interface User {
uncategorised?: Shelf,
}

export interface MongoUser extends Omit<User, "categories"> {
categories?: Array<string> // Category IDs
export interface MongoUser extends Omit<Omit<User, "categories">, "uncategorised"> {
categories?: Array<string> // Category IDs,
uncategorised: string
}

+ 1
- 6
src/models/word.ts Ver fichero

@@ -7,7 +7,7 @@ interface gramaticalDetail {
}

export interface Word {
_id: string,
//_id is present by default in the DB
name: string,
pronounciation: {
text: string,
@@ -15,11 +15,6 @@ export interface Word {
},
similarWords?: Array<Word>,
grammaticalDetails: Array<gramaticalDetail>,
wordStats: {
favouriteCount: number, // Total users who liked this word
addCount: number, // Total users have added this word to their shelf
},
isArchived: boolean,
}

export interface MongoWord extends Omit<Word, "similarWords"> {


+ 119
- 0
src/user-profile/category-routes.ts Ver fichero

@@ -0,0 +1,119 @@
import express from 'express';
import passport from 'passport';
import { MongoUser } from '../models/user';
import { DB_NAME } from '../db-utils';
import { getDatabaseClient } from '../db-utils';
import { ObjectId } from 'bson';
import { MongoCategory } from '..//models/category';

export const categoryRoutes = express.Router();

export const jwtAuthentication = passport.authenticate('jwt', { session: false });

// Get Category Details
categoryRoutes.get('/category/', jwtAuthentication, async (request, response) => {
const categoryCollection = getDatabaseClient().db(DB_NAME).collection<MongoCategory>('categories');

const currentCategory = await categoryCollection.findOne({
_id: new ObjectId(request.body._id),
});

if (currentCategory) {
response.status(200);
response.json(currentCategory);
} else {
response.status(400);
response.send("Category ID did not match");
}

return;
});


// Add category
categoryRoutes.post('/category/', jwtAuthentication, async (request, response) => {
const user: MongoUser = (request.user as any);

const categoryCollection = getDatabaseClient().db(DB_NAME).collection<MongoCategory>('categories');
const userCollection = getDatabaseClient().db(DB_NAME).collection<MongoUser>('users');

if (!request.body.name) {
response.status(400);
response.send("Category Name missing");
return;
}
try {
const newCategory = await categoryCollection.insertOne({
name: request.body.name,
icon: request.body.icon ? request.body.icon : "",
isArchived: false,
});

if (!user.categories) {
user.categories = [];
}

user.categories.push(newCategory.insertedId.toHexString());

await userCollection.updateOne({
_id: user._id
}, {
$set: {
categories: user.categories
}
});
response.sendStatus(200);
} catch(e) {
response.sendStatus(500);
return;
}

return;
});


// Update category
categoryRoutes.put('/category/', jwtAuthentication, async (request, response) => {
const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories');

const currentCategory = await categoryCollection.findOne({
_id: new ObjectId(request.body._id)
});

if (!currentCategory) {
response.status(400);
response.send("Category ID did not match");
return;
}

if (request.body.isArchived) {
if (typeof request.body.isArchived !== "boolean") {
response.status(400);
response.send("Archived should be a boolean flag");
return;
}
}

try {
await categoryCollection.updateOne({
_id: new ObjectId(request.body._id),
}, {
$set: {
name: request.body.name ? request.body.name : currentCategory.name,
icon: request.body.icon ? request.body.icon : currentCategory.icon,
isArchived: request.body.isArchived !== undefined ? request.body.isArchived : currentCategory.isArchived
}
});

response.sendStatus(200);

} catch (e) {
console.log(e);
response.status(400);
response.send(e.toString());
}

return;
});

+ 1
- 94
src/user-profile/routes.ts Ver fichero

@@ -1,10 +1,6 @@
import express from 'express';
import passport, { use } from 'passport';
import passport from 'passport';
import { MongoUser } from '../models/user';
import { Category, MongoCategory } from '../models/category';
import { DB_NAME } from '../db-utils';
import { getDatabaseClient } from '../db-utils';
import { ObjectId } from 'bson';

export const userProfileRoutes = express.Router();

@@ -22,92 +18,3 @@ userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response)
});
return;
});

userProfileRoutes.post('/category/', jwtAuthentication, async (request, response) => {
const user: MongoUser = (request.user as any);

const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories');
const userCollection = getDatabaseClient().db(DB_NAME).collection('users');

if (!request.body.name || !request.body.icon) {
response.status(400);
response.send("Category Name or icon(base64) missing");
return;
}
try {
const newCategory = await categoryCollection.insertOne({
name: request.body.name,
icon: request.body.icon,
isArchived: false,
});

if (!user.categories) {
user.categories = [];
}

user.categories.push(newCategory.insertedId.toHexString());

await userCollection.updateOne({
_id: user._id
}, {
$set: {
categories: user.categories
}
});
response.sendStatus(200);
} catch(e) {
response.sendStatus(500);
return;
}

return;
});


userProfileRoutes.put('/category/', jwtAuthentication, async (request, response) => {
const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories');

let currentCategory;

try {
currentCategory = await categoryCollection.findOne({
_id: new ObjectId(request.body._id)
});
} catch {
if (!currentCategory) {
response.status(400);
response.send("Category ID did not match");
return;
}
}

if (request.body.isArchived) {
if (typeof request.body.isArchived !== "boolean") {
response.status(400);
response.send("Archived should be a boolean flag");
return;
}
}

try {
await categoryCollection.updateOne({
_id: new ObjectId(request.body._id),
}, {
$set: {
name: request.body.name ? request.body.name : currentCategory.name,
icon: request.body.icon ? request.body.icon : currentCategory.icon,
isArchived: request.body.isArchived !== undefined ? request.body.isArchived : currentCategory.isArchived
}
});

response.sendStatus(200);

} catch (e) {
response.status(400);
response.json(e);
}

return;
});

+ 140
- 0
src/user-profile/shelf-routes.ts Ver fichero

@@ -0,0 +1,140 @@
import { ObjectId } from 'bson';
import express from 'express';
import passport from 'passport';
import { MongoCategory } from '../models/category';
import { DB_NAME } from '../db-utils';
import { getDatabaseClient } from '../db-utils';
import { MongoShelf } from '../models/shelf';

export const shelfRoutes = express.Router();

export const jwtAuthentication = passport.authenticate('jwt', { session: false });


// GET shelf details
shelfRoutes.get('/shelf/', jwtAuthentication, async (request, response) => {
const shelfCollection = getDatabaseClient().db(DB_NAME).collection<MongoShelf>('shelves');

const currentShelf = await shelfCollection.findOne({
_id: new ObjectId(request.body._id)
});

if (!currentShelf) {
response.status(400);
response.send("No shelf with the ID");
} else {
response.status(200);
response.json(currentShelf);
}

return;
});


// Add shelf
shelfRoutes.post('/shelf/', jwtAuthentication, async (request, response) => {
const categoryCollection = getDatabaseClient().db(DB_NAME).collection<MongoCategory>('categories');
const shelfCollection = getDatabaseClient().db(DB_NAME).collection<MongoShelf>('shelves');

const currentCategory = await categoryCollection.findOne({
_id: new ObjectId(request.body.categoryId)
});

let newShelf;

if (!currentCategory) {
response.status(400);
response.send("Category ID did not match");
return;
}

if (!request.body.name) {
response.sendStatus(400);
response.send("Missing shelf name");
return;
}

try {
newShelf = await shelfCollection.insertOne({
name: request.body.name,
description: request.body.description ? request.body.description : "",
viewType: request.body.viewType ? request.body.viewType : "PRIVATE",
isArchived: false,
});
} catch (e) {
response.sendStatus(500);
return;
}

if (!newShelf) {
response.sendStatus(500);
return;
}

if (!currentCategory.shelves) {
currentCategory.shelves = [];
}

currentCategory.shelves.push(newShelf.insertedId.toHexString());

const updatedCategory = await categoryCollection.updateOne({
_id: new ObjectId(request.body.categoryId)
}, {
$set : {
shelves: currentCategory.shelves
}
});

if (updatedCategory) {
response.sendStatus(200);
} else {
response.sendStatus(500);
}

return;
});



// Update shelf
shelfRoutes.put('/shelf/', jwtAuthentication, async (request, response) => {
const shelfCollection = getDatabaseClient().db(DB_NAME).collection<MongoShelf>('shelves');

const currentShelf = await shelfCollection.findOne({
_id: new ObjectId(request.body._id)
});

if (!currentShelf) {
response.status(400);
response.send("No shelf with the ID");
}

if (request.body.isArchived) {
if (typeof request.body.isArchived !== "boolean") {
response.status(400);
response.send("Archived should be a boolean flag");
return;
}
}

try {
await shelfCollection.updateOne({
_id: new ObjectId(request.body._id),
}, {
$set: {
name: request.body.name ? request.body.name : currentShelf.name,
description: request.body.description ? request.body.description : currentShelf.description,
isArchived: request.body.isArchived !== undefined ? request.body.isArchived : currentShelf.isArchived
}
});

response.sendStatus(200);

} catch (e) {
console.log(e);
response.status(400);
response.send(e.toString());
}

return;
});

Cargando…
Cancelar
Guardar