attempted to refactor db seed, still needs more updating
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
import { IUser, IUserAuth } from "../schemas";
|
import { IUser, IUserAuth } from "../schemas";
|
||||||
import { User } from "../models/user";
|
import { User } from "../models/user";
|
||||||
|
import { Collection } from "../models/collection";
|
||||||
import createError from "http-errors";
|
import createError from "http-errors";
|
||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
import now from "../util/now";
|
import now from "../util/now";
|
||||||
|
|
||||||
const UserInstance = new User();
|
const UserInstance = new User();
|
||||||
|
const CollectionInstance = new Collection();
|
||||||
export default class AuthService {
|
export default class AuthService {
|
||||||
// methods for local strategies
|
// methods for local strategies
|
||||||
async register(data: IUser) {
|
async register(data: IUser) {
|
||||||
@@ -20,7 +21,8 @@ export default class AuthService {
|
|||||||
const user = await UserInstance.getOneByEmail(email);
|
const user = await UserInstance.getOneByEmail(email);
|
||||||
if (user) throw createError('409', 'Email already in use');
|
if (user) throw createError('409', 'Email already in use');
|
||||||
|
|
||||||
bcrypt.genSalt(10, (err, salt) => {
|
// hash password and create new user record
|
||||||
|
return bcrypt.genSalt(10, (err, salt) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
bcrypt.hash(password!, salt, async (err, hash) => {
|
bcrypt.hash(password!, salt, async (err, hash) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -29,7 +31,18 @@ export default class AuthService {
|
|||||||
password: hash
|
password: hash
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await UserInstance.post(newData);
|
const result: IUser = await UserInstance.post(newData);
|
||||||
|
|
||||||
|
// basic profile setup
|
||||||
|
await CollectionInstance.post({
|
||||||
|
name: `${data.firstname}'s Collection`,
|
||||||
|
active: true,
|
||||||
|
ismaincollection: true,
|
||||||
|
ownerid: result.id!.toString(),
|
||||||
|
datecreated: now,
|
||||||
|
datemodified: now
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Collection } from "../models/collection";
|
|||||||
const CollectionInstance = new Collection();
|
const CollectionInstance = new Collection();
|
||||||
|
|
||||||
export default class CollectionCtl {
|
export default class CollectionCtl {
|
||||||
async getOne(id: string) {
|
async getOne(id: number | string) {
|
||||||
const result = await CollectionInstance.getOne(id);
|
const result = await CollectionInstance.getOne(id);
|
||||||
if (!result) throw createError('404', 'Collection not found');
|
if (!result) throw createError('404', 'Collection not found');
|
||||||
return result;
|
return result;
|
||||||
@@ -16,25 +16,31 @@ export default class CollectionCtl {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUserDefault(id: number | string) {
|
||||||
|
const result = await CollectionInstance.getUserDefault(id);
|
||||||
|
if (!result) throw createError('404', "No default collection found. Contact an admin, this isn't supposed to happen");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
async post(data: ICollection) {
|
async post(data: ICollection) {
|
||||||
const result = await CollectionInstance.post(data);
|
const result = await CollectionInstance.post(data);
|
||||||
if (!result) throw createError('400', 'Bad request');
|
if (!result) throw createError('400', 'Bad request');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSubscriptions(userid: string) {
|
async getSubscriptions(userid: number | string) {
|
||||||
const result = await CollectionInstance.getSubscriptions(userid);
|
const result = await CollectionInstance.getSubscriptions(userid);
|
||||||
if (!result) throw createError('404', 'No subscriptions found');
|
if (!result) throw createError('404', 'No subscriptions found');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async postSubscription(collectionid: string, userid: string) {
|
async postSubscription(collectionid: number | string, userid: number | string) {
|
||||||
const { ok, code, data } = await CollectionInstance.postSubscription(collectionid, userid);
|
const { ok, code, data } = await CollectionInstance.postSubscription(collectionid, userid);
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
throw createError(code, data);
|
throw createError(code, data as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,24 @@ export default class RecipeCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllAuthored(id: string) {
|
||||||
|
try {
|
||||||
|
const result = await RecipeInstance.getAllAuthored(id);
|
||||||
|
if (!result) throw createError('404', "No recipes found");
|
||||||
|
return result;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllAccessible(id: string) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async updateOne(id: string, data: IRecipe) {
|
async updateOne(id: string, data: IRecipe) {
|
||||||
try {
|
try {
|
||||||
const result = await RecipeInstance.updateOneByID(id, data);
|
const result = await RecipeInstance.updateOneByID(id, data);
|
||||||
@@ -24,9 +42,9 @@ export default class RecipeCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(data: IRecipe) {
|
async post(userid: string, data: IRecipe) {
|
||||||
try {
|
try {
|
||||||
const result = await RecipeInstance.post(data);
|
const result = await RecipeInstance.post(userid, data);
|
||||||
if (!result) throw createError('400', "Bad request");
|
if (!result) throw createError('400', "Bad request");
|
||||||
return result;
|
return result;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOne(id: string) {
|
async getOne(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const user = await UserInstance.getOneByID(id);
|
const user = await UserInstance.getOneByID(id);
|
||||||
if (!user) throw createError(404, "User not found");
|
if (!user) throw createError(404, "User not found");
|
||||||
@@ -34,7 +34,7 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateOne(id: string, data: IUser) {
|
async updateOne(id: number | string, data: IUser) {
|
||||||
try {
|
try {
|
||||||
const result = await UserInstance.updateOneByID(id, data);
|
const result = await UserInstance.updateOneByID(id, data);
|
||||||
if (!result) throw createError(400, "Bad request");
|
if (!result) throw createError(400, "Bad request");
|
||||||
@@ -44,7 +44,7 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFriends(id: string) {
|
async getFriends(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const result = await UserInstance.getFriends(id);
|
const result = await UserInstance.getFriends(id);
|
||||||
if (!result) throw createError(404, "You have no friends");
|
if (!result) throw createError(404, "You have no friends");
|
||||||
@@ -54,7 +54,7 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFriendshipByID(id: string, userid: string) {
|
async getFriendshipByID(id: number | string, userid: number | string) {
|
||||||
try {
|
try {
|
||||||
const { ok, code, result } = await UserInstance.getFriendshipByID(id, userid);
|
const { ok, code, result } = await UserInstance.getFriendshipByID(id, userid);
|
||||||
if (ok) return result;
|
if (ok) return result;
|
||||||
@@ -64,7 +64,7 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFriendship(userid: string, targetid: string) {
|
async addFriendship(userid: number | string, targetid: number | string) {
|
||||||
try {
|
try {
|
||||||
const result = await UserInstance.addFriendship(userid, targetid);
|
const result = await UserInstance.addFriendship(userid, targetid);
|
||||||
if (!result) throw createError(400, "something went wrong");
|
if (!result) throw createError(400, "something went wrong");
|
||||||
@@ -74,11 +74,11 @@ export default class UserCtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFriendship(id: string, data: { active: boolean, pending: boolean, dateterminated?: string }) {
|
async updateFriendship(id: number | string, userid: number | string, data: { active: boolean, pending: boolean, dateterminated?: string }) {
|
||||||
try {
|
try {
|
||||||
const result = await UserInstance.updateFriendship(id, data);
|
const { ok, code, result } = await UserInstance.updateFriendship(id, userid, data);
|
||||||
if (!result) throw createError(400, "something went wrong");
|
if (ok) return result;
|
||||||
return result;
|
throw createError(code, result);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
142
server/db/newPopulate.ts
Normal file
142
server/db/newPopulate.ts
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import pool from ".";
|
||||||
|
import { IIngredient, IRecipe, IUser } from "../schemas";
|
||||||
|
import { User } from "../models/user";
|
||||||
|
import { Recipe } from "../models/recipe";
|
||||||
|
import { Collection } from "../models/collection";
|
||||||
|
import { Ingredient } from "../models/ingredient";
|
||||||
|
import AuthService from "../auth";
|
||||||
|
import now from "../util/now";
|
||||||
|
|
||||||
|
const auth = new AuthService();
|
||||||
|
const user = new User();
|
||||||
|
|
||||||
|
const collection = new Collection();
|
||||||
|
const ingredient = new Ingredient();
|
||||||
|
|
||||||
|
export default async function populate() {
|
||||||
|
// register new users; initialize default collection
|
||||||
|
const usr1: IUser = {
|
||||||
|
firstname: "Mikayla",
|
||||||
|
lastname: "Dobson",
|
||||||
|
handle: "innocuoussymmetry",
|
||||||
|
password: "coolpassword",
|
||||||
|
email: "mikayla@mikayla.com",
|
||||||
|
active: true,
|
||||||
|
isadmin: true
|
||||||
|
}
|
||||||
|
|
||||||
|
const usr2: IUser = {
|
||||||
|
firstname: "Emily",
|
||||||
|
lastname: "Dobson",
|
||||||
|
handle: "emjdobson",
|
||||||
|
password: "coolpassword",
|
||||||
|
email: "emily@emily.com",
|
||||||
|
active: true,
|
||||||
|
isadmin: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const usr3: IUser = {
|
||||||
|
firstname: "Montanna",
|
||||||
|
lastname: "Dobson",
|
||||||
|
handle: "delayedlemon",
|
||||||
|
password: "coolpassword",
|
||||||
|
email: "montanna@montanna.com",
|
||||||
|
active: true,
|
||||||
|
isadmin: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const usr4: IUser = {
|
||||||
|
firstname: 'someother',
|
||||||
|
lastname: 'person',
|
||||||
|
handle: 'someperson',
|
||||||
|
password: 'coolpassword',
|
||||||
|
email: 'someperson@email.com',
|
||||||
|
active: false,
|
||||||
|
isadmin: false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let usr of [usr1, usr2, usr3, usr4]) {
|
||||||
|
await auth.register(usr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
// recipes onto new user profiles; insert into new default collections
|
||||||
|
const rec1: IRecipe = {
|
||||||
|
name: "Pad Thai",
|
||||||
|
preptime: '1 hour',
|
||||||
|
authoruserid: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const rec2: IRecipe = {
|
||||||
|
name: "Bo ssam",
|
||||||
|
preptime: '8 hours',
|
||||||
|
authoruserid: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
const rec3: IRecipe = {
|
||||||
|
name: "Banana bread",
|
||||||
|
preptime: '90 minutes',
|
||||||
|
authoruserid: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
const rec4: IRecipe = {
|
||||||
|
name: "garlic confit",
|
||||||
|
preptime: "2 hours",
|
||||||
|
authoruserid: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let rec of [rec1, rec2, rec3, rec4]) {
|
||||||
|
await recipe.post(rec.authoruserid as string, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// set up a couple of friendships
|
||||||
|
// await user.addFriendship(1, 2);
|
||||||
|
// await user.addFriendship(1, 3);
|
||||||
|
// await user.addFriendship(2, 3);
|
||||||
|
|
||||||
|
// await user.updateFriendship(1, 2, {
|
||||||
|
// active: true,
|
||||||
|
// pending: false
|
||||||
|
// });
|
||||||
|
|
||||||
|
// await user.updateFriendship(2, 3, {
|
||||||
|
// active: true,
|
||||||
|
// pending: false
|
||||||
|
// })
|
||||||
|
|
||||||
|
// // request and validate subscriptions
|
||||||
|
// const usr1default = await collection.getUserDefault(1);
|
||||||
|
// await collection.postSubscription(usr1default.id, 2);
|
||||||
|
|
||||||
|
// const usr3default = await collection.getUserDefault(3);
|
||||||
|
// await collection.postSubscription(usr3default.id, 1);
|
||||||
|
|
||||||
|
// add some ingredients
|
||||||
|
const ing1: IIngredient = {
|
||||||
|
name: "cucumber",
|
||||||
|
description: "vegetal",
|
||||||
|
datecreated: now,
|
||||||
|
createdbyid: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const ing2: IIngredient = {
|
||||||
|
name: "tofu",
|
||||||
|
description: "soy protein",
|
||||||
|
datecreated: now,
|
||||||
|
createdbyid: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const ing3: IIngredient = {
|
||||||
|
name: 'garlic',
|
||||||
|
description: "lifeblood",
|
||||||
|
datecreated: now,
|
||||||
|
createdbyid: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let ing of [ing1, ing2, ing3]) {
|
||||||
|
await ingredient.post(ing);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ export default async function populate() {
|
|||||||
|
|
||||||
const populateFriendships = `
|
const populateFriendships = `
|
||||||
INSERT INTO recipin.cmp_userfriendships
|
INSERT INTO recipin.cmp_userfriendships
|
||||||
(datecreated, active, pending, firstuserid, seconduserid)
|
(datecreated, active, pending, senderid, targetid)
|
||||||
VALUES
|
VALUES
|
||||||
($1, true, false, 1, 2),
|
($1, true, false, 1, 2),
|
||||||
($1, true, false, 1, 4),
|
($1, true, false, 1, 4),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
|
import newPopulate from './newPopulate';
|
||||||
import populate from "./populate";
|
import populate from "./populate";
|
||||||
import pool from ".";
|
import pool from ".";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
@@ -41,6 +42,7 @@ dotenv.config();
|
|||||||
|
|
||||||
console.log("Database seed successful. Attempting to populate...");
|
console.log("Database seed successful. Attempting to populate...");
|
||||||
await populate();
|
await populate();
|
||||||
|
// await newPopulate();
|
||||||
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
})();
|
})();
|
||||||
@@ -4,6 +4,6 @@ CREATE TABLE IF NOT EXISTS recipin.cmp_userfriendships (
|
|||||||
active boolean NOT NULL,
|
active boolean NOT NULL,
|
||||||
pending boolean NOT NULL,
|
pending boolean NOT NULL,
|
||||||
dateterminated varchar,
|
dateterminated varchar,
|
||||||
firstuserid int REFERENCES recipin.appusers (id),
|
senderid int REFERENCES recipin.appusers (id),
|
||||||
seconduserid int REFERENCES recipin.appusers (id)
|
targetid int REFERENCES recipin.appusers (id)
|
||||||
);
|
);
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
CREATE TABLE IF NOT EXISTS recipin.cmp_usersubscriptions (
|
CREATE TABLE IF NOT EXISTS recipin.cmp_usersubscriptions (
|
||||||
id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
collectionid int REFERENCES recipin.collection (id),
|
collectionid int REFERENCES recipin.collection (id),
|
||||||
usermemberid int REFERENCES recipin.appusers (id)
|
usermemberid int REFERENCES recipin.appusers (id),
|
||||||
|
active boolean NOT NULL
|
||||||
);
|
);
|
||||||
@@ -5,5 +5,5 @@ CREATE TABLE IF NOT EXISTS recipin.recipe (
|
|||||||
datecreated varchar NOT NULL,
|
datecreated varchar NOT NULL,
|
||||||
datemodified varchar NOT NULL,
|
datemodified varchar NOT NULL,
|
||||||
description varchar,
|
description varchar,
|
||||||
authoruserid int REFERENCES recipin.appusers (id) NOT NULL
|
authoruserid int REFERENCES recipin.appusers (id)
|
||||||
);
|
);
|
||||||
@@ -8,6 +8,6 @@ SELECT
|
|||||||
recipin.appusers.email
|
recipin.appusers.email
|
||||||
FROM recipin.cmp_userfriendships
|
FROM recipin.cmp_userfriendships
|
||||||
INNER JOIN recipin.appusers
|
INNER JOIN recipin.appusers
|
||||||
ON recipin.appusers.id = recipin.cmp_userfriendships.seconduserid
|
ON recipin.appusers.id = recipin.cmp_userfriendships.targetid
|
||||||
WHERE firstuserid = $1 OR seconduserid = $1
|
WHERE senderid = $1 OR targetid = $1
|
||||||
AND cmp_userfriendships.active = true;
|
AND cmp_userfriendships.active = true;
|
||||||
0
server/db/sql/get/allaccessiblerecipes.sql
Normal file
0
server/db/sql/get/allaccessiblerecipes.sql
Normal file
2
server/db/sql/get/alloriginalrecipes.sql
Normal file
2
server/db/sql/get/alloriginalrecipes.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
SELECT * FROM recipin.recipe
|
||||||
|
WHERE authorid = $1;
|
||||||
@@ -8,7 +8,7 @@ SELECT
|
|||||||
recipin.appusers.email
|
recipin.appusers.email
|
||||||
FROM recipin.cmp_userfriendships
|
FROM recipin.cmp_userfriendships
|
||||||
INNER JOIN recipin.appusers
|
INNER JOIN recipin.appusers
|
||||||
ON recipin.appusers.id = recipin.cmp_userfriendships.firstuserid
|
ON recipin.appusers.id = recipin.cmp_userfriendships.senderid
|
||||||
WHERE recipin.cmp_userfriendships.id = $1
|
WHERE recipin.cmp_userfriendships.id = $1
|
||||||
UNION
|
UNION
|
||||||
SELECT
|
SELECT
|
||||||
@@ -21,5 +21,5 @@ SELECT
|
|||||||
recipin.appusers.email
|
recipin.appusers.email
|
||||||
FROM recipin.cmp_userfriendships
|
FROM recipin.cmp_userfriendships
|
||||||
INNER JOIN recipin.appusers
|
INNER JOIN recipin.appusers
|
||||||
ON recipin.appusers.id = recipin.cmp_userfriendships.seconduserid
|
ON recipin.appusers.id = recipin.cmp_userfriendships.targetid
|
||||||
WHERE recipin.cmp_userfriendships.id = $1;
|
WHERE recipin.cmp_userfriendships.id = $1;
|
||||||
@@ -6,7 +6,7 @@ import pool from "../db";
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
const UserInstance = new User();
|
const UserInstance = new User();
|
||||||
export class Collection {
|
export class Collection {
|
||||||
async getOne(id: string) {
|
async getOne(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const statement = `SELECT * FROM recipin.collection WHERE id = $1`;
|
const statement = `SELECT * FROM recipin.collection WHERE id = $1`;
|
||||||
const values = [id];
|
const values = [id];
|
||||||
@@ -18,6 +18,21 @@ export class Collection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUserDefault(id: number | string) {
|
||||||
|
try {
|
||||||
|
const statement = `
|
||||||
|
SELECT * FROM recipin.collection
|
||||||
|
WHERE ownerid = $1
|
||||||
|
AND ismaincollection = true;
|
||||||
|
`
|
||||||
|
const result = await pool.query(statement, [id]);
|
||||||
|
if (result.rows.length) return result.rows[0];
|
||||||
|
return null;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getAll() {
|
async getAll() {
|
||||||
// requires clearance
|
// requires clearance
|
||||||
try {
|
try {
|
||||||
@@ -31,6 +46,8 @@ export class Collection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async post(data: ICollection) {
|
async post(data: ICollection) {
|
||||||
|
console.log('new default collection');
|
||||||
|
console.log(data);
|
||||||
const { name, active, ismaincollection, ownerid } = data;
|
const { name, active, ismaincollection, ownerid } = data;
|
||||||
try {
|
try {
|
||||||
const statement = `
|
const statement = `
|
||||||
@@ -48,7 +65,7 @@ export class Collection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSubscriptions(userid: string) {
|
async getSubscriptions(userid: number | string) {
|
||||||
try {
|
try {
|
||||||
const sql = fs.readFileSync(appRoot + '/db/sql/get/getsubscriptions.sql').toString();
|
const sql = fs.readFileSync(appRoot + '/db/sql/get/getsubscriptions.sql').toString();
|
||||||
console.log(sql);
|
console.log(sql);
|
||||||
@@ -60,7 +77,7 @@ export class Collection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async postSubscription(collectionid: string, userid: string): Promise<{ ok: boolean, code: number, data: string | any[] }> {
|
async postSubscription(collectionid: number | string, userid: number | string): Promise<{ ok: boolean, code: number, data: number | string | any[] }> {
|
||||||
try {
|
try {
|
||||||
// ensure user exists
|
// ensure user exists
|
||||||
const user: IUser | null = await UserInstance.getOneByID(userid);
|
const user: IUser | null = await UserInstance.getOneByID(userid);
|
||||||
@@ -83,7 +100,8 @@ export class Collection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure a user cannot subscribe to their own collection
|
// ensure a user cannot subscribe to their own collection
|
||||||
if (target.ownerid == parseInt(userid)) {
|
let typedUserID: number = (userid == typeof 'string') ? parseInt(userid) : userid as number;
|
||||||
|
if (target.ownerid == typedUserID) {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
code: 403,
|
code: 403,
|
||||||
@@ -99,7 +117,7 @@ export class Collection {
|
|||||||
const subscriptionResult = await pool.query(allSubscriptions, [collectionid]);
|
const subscriptionResult = await pool.query(allSubscriptions, [collectionid]);
|
||||||
if (subscriptionResult.rows?.length) {
|
if (subscriptionResult.rows?.length) {
|
||||||
for (let row of subscriptionResult.rows) {
|
for (let row of subscriptionResult.rows) {
|
||||||
if (row.usermemberid == parseInt(userid)) {
|
if (row.usermemberid == typedUserID) {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
code: 403,
|
code: 403,
|
||||||
@@ -112,8 +130,8 @@ export class Collection {
|
|||||||
// finally, execute insertion
|
// finally, execute insertion
|
||||||
const statement = `
|
const statement = `
|
||||||
INSERT INTO recipin.cmp_usersubscriptions
|
INSERT INTO recipin.cmp_usersubscriptions
|
||||||
(collectionid, usermemberid)
|
(collectionid, usermemberid, active)
|
||||||
VALUES ($1, $2)
|
VALUES ($1, $2, true)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { IIngredient } from "../schemas";
|
import { IIngredient } from "../schemas";
|
||||||
import pool from "../db";
|
import pool from "../db";
|
||||||
|
import now from "../util/now";
|
||||||
|
|
||||||
export class Ingredient {
|
export class Ingredient {
|
||||||
async getAll() {
|
async getAll() {
|
||||||
@@ -28,9 +29,9 @@ export class Ingredient {
|
|||||||
try {
|
try {
|
||||||
const statement = `
|
const statement = `
|
||||||
INSERT INTO recipin.ingredient
|
INSERT INTO recipin.ingredient
|
||||||
(name, description)
|
(name, description, datecreated)
|
||||||
VALUES ($1, $2) RETURNING *`;
|
VALUES ($1, $2, $3) RETURNING *`;
|
||||||
const values = [data.name, data.description];
|
const values = [data.name, data.description, data.datecreated || now];
|
||||||
const result = await pool.query(statement, values);
|
const result = await pool.query(statement, values);
|
||||||
if (result.rows.length) return result.rows[0];
|
if (result.rows.length) return result.rows[0];
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { IRecipe } from "../schemas";
|
import { IRecipe } from "../schemas";
|
||||||
import pgPromise from "pg-promise";
|
|
||||||
import pool from "../db";
|
import pool from "../db";
|
||||||
|
import { CollectionCtl } from "../controllers";
|
||||||
const pgp = pgPromise({ capSQL: true });
|
import now from "../util/now";
|
||||||
|
const CollectionInstance = new CollectionCtl();
|
||||||
|
|
||||||
export class Recipe {
|
export class Recipe {
|
||||||
async getOneByID(id: string) {
|
async getOneByID(id: string) {
|
||||||
@@ -17,9 +17,24 @@ export class Recipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllByUserID(id: string) {
|
async getAllAuthored(id: string) {
|
||||||
try {
|
try {
|
||||||
// to do: use setupbrowser.sql to setup the recipe browser
|
const statement = `SELECT * FROM recipin.recipe WHERE authoruserid = $1`;
|
||||||
|
const result = await pool.query(statement, [id]);
|
||||||
|
if (result.rows.length) return result.rows;
|
||||||
|
return null;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllAccessible(id: string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchRecipesByCollection(collectionid: string) {
|
||||||
|
try {
|
||||||
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
@@ -45,15 +60,32 @@ export class Recipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(data: IRecipe) {
|
async post(userid: string, data: IRecipe) {
|
||||||
const { name, description, preptime } = data;
|
const { name, description, preptime } = data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const statement = `INSERT INTO recipin.recipe (name, description, preptime, authoruserid) VALUES ($1, $2, $3, (SELECT id FROM recipin.appusers WHERE id = 1)) RETURNING *;`
|
// create recipe itself
|
||||||
const values = [name, description, preptime];
|
const statement = `
|
||||||
|
INSERT INTO recipin.recipe
|
||||||
|
(name, description, preptime, authoruserid, datecreated, datemodified)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
|
RETURNING *;
|
||||||
|
`
|
||||||
|
const values = [name, description, preptime, userid, now, now];
|
||||||
const result = await pool.query(statement, values);
|
const result = await pool.query(statement, values);
|
||||||
if (result.rows) return result.rows[0];
|
if (!result.rows.length) return null;
|
||||||
return null;
|
|
||||||
|
// associate recipe with default collection once created
|
||||||
|
const collection = await CollectionInstance.getUserDefault(userid);
|
||||||
|
const associateToCollection = `
|
||||||
|
INSERT INTO recipin.cmp_recipecollection
|
||||||
|
(recipeid, collectionid)
|
||||||
|
VALUES ($1, $2) RETURNING *
|
||||||
|
`
|
||||||
|
const associateResult = await pool.query(associateToCollection, [result.rows[0].id, collection.id]);
|
||||||
|
if (!associateResult.rows.length) return null;
|
||||||
|
|
||||||
|
return { recipe: result.rows[0], collection: associateResult.rows[0] }
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOneByID(id: string) {
|
async getOneByID(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const statement = `SELECT * FROM recipin.appusers WHERE id = $1`;
|
const statement = `SELECT * FROM recipin.appusers WHERE id = $1`;
|
||||||
const values = [id];
|
const values = [id];
|
||||||
@@ -29,7 +29,7 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOneByEmail(email: string) {
|
async getOneByEmail(email: number | string) {
|
||||||
try {
|
try {
|
||||||
const statement = `SELECT * FROM recipin.appusers WHERE email = $1`;
|
const statement = `SELECT * FROM recipin.appusers WHERE email = $1`;
|
||||||
const result = await pool.query(statement, [email]);
|
const result = await pool.query(statement, [email]);
|
||||||
@@ -41,7 +41,7 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateOneByID(id: string, data: IUser) {
|
async updateOneByID(id: number | string, data: IUser) {
|
||||||
try {
|
try {
|
||||||
const statement = `
|
const statement = `
|
||||||
UPDATE recipin.appusers
|
UPDATE recipin.appusers
|
||||||
@@ -85,14 +85,14 @@ export class User {
|
|||||||
`;
|
`;
|
||||||
const params = [firstname, lastname, handle, email, password, active, isadmin, datecreated, datemodified];
|
const params = [firstname, lastname, handle, email, password, active, isadmin, datecreated, datemodified];
|
||||||
const result = await pool.query(statement, params);
|
const result = await pool.query(statement, params);
|
||||||
if (result.rows.length) return result.rows;
|
if (result.rows.length) return result.rows[0];
|
||||||
return null;
|
return null;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFriends(id: string) {
|
async getFriends(id: number | string) {
|
||||||
try {
|
try {
|
||||||
const sql = fs.readFileSync(appRoot + '/db/sql/derived/friendships.sql').toString();
|
const sql = fs.readFileSync(appRoot + '/db/sql/derived/friendships.sql').toString();
|
||||||
const result = await pool.query(sql, [id]);
|
const result = await pool.query(sql, [id]);
|
||||||
@@ -103,14 +103,14 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFriendshipByID(id: string, userid: string) {
|
async getFriendshipByID(id: number | string, userid: number | string) {
|
||||||
try {
|
try {
|
||||||
const statement = `SELECT * FROM recipin.cmp_userfriendships WHERE id = $1`;
|
const statement = `SELECT * FROM recipin.cmp_userfriendships WHERE id = $1`;
|
||||||
const result = await pool.query(statement, [id]);
|
const result = await pool.query(statement, [id]);
|
||||||
|
|
||||||
if (result.rows.length) {
|
if (result.rows.length) {
|
||||||
const row = result.rows[0];
|
const row = result.rows[0];
|
||||||
if (row.firstuserid == userid || row.seconduserid == userid) {
|
if (row.senderid == userid || row.targetid == userid) {
|
||||||
const sql = fs.readFileSync(appRoot + '/db/sql/get/friendshipbyid.sql').toString();
|
const sql = fs.readFileSync(appRoot + '/db/sql/get/friendshipbyid.sql').toString();
|
||||||
const formattedResult = await pool.query(sql, [id]);
|
const formattedResult = await pool.query(sql, [id]);
|
||||||
if (formattedResult.rows.length) return { ok: true, code: 200, result: formattedResult.rows }
|
if (formattedResult.rows.length) return { ok: true, code: 200, result: formattedResult.rows }
|
||||||
@@ -125,11 +125,11 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFriendship(userid: string, targetid: string) {
|
async addFriendship(userid: number | string, targetid: number | string) {
|
||||||
try {
|
try {
|
||||||
const statement = `
|
const statement = `
|
||||||
INSERT INTO recipin.cmp_userfriendships
|
INSERT INTO recipin.cmp_userfriendships
|
||||||
(datecreated, active, pending, firstuserid, seconduserid)
|
(datecreated, active, pending, senderid, targetid)
|
||||||
VALUES ($1, false, true, $2, $3)
|
VALUES ($1, false, true, $2, $3)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
`
|
`
|
||||||
@@ -144,8 +144,15 @@ export class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFriendship(id: string, data: { active: boolean, pending: boolean, dateterminated?: string }) {
|
async updateFriendship(id: number | string, userid: number | string, data: { active: boolean, pending: boolean, dateterminated?: string }) {
|
||||||
try {
|
try {
|
||||||
|
const query = `SELECT * FROM recipin.cmp_userfriendships WHERE id = $1`;
|
||||||
|
const friendship = await pool.query(query, [id]);
|
||||||
|
if (!friendship.rows.length) return { ok: false, code: 404, result: "Friendship with this code not found" };
|
||||||
|
if (!(friendship.rows[0].active) && friendship.rows[0].senderid == userid) {
|
||||||
|
return { ok: false, code: 403, result: "Please wait for friend request to be accepted" }
|
||||||
|
}
|
||||||
|
|
||||||
const statement = `
|
const statement = `
|
||||||
UPDATE recipin.cmp_userfriendships
|
UPDATE recipin.cmp_userfriendships
|
||||||
SET active = $1,
|
SET active = $1,
|
||||||
@@ -154,10 +161,10 @@ export class User {
|
|||||||
WHERE id = $4
|
WHERE id = $4
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
`
|
`
|
||||||
const values = [data.active, data.pending, data.dateterminated || null, id];
|
const values = [data.active, data.pending, (data.dateterminated || null), id];
|
||||||
const result = await pool.query(statement, values);
|
const result = await pool.query(statement, values);
|
||||||
if (result.rows.length) return result.rows[0];
|
if (result.rows.length) return { ok: true, code: 200, result: result.rows[0] }
|
||||||
return null;
|
return { ok: false, code: 400, result: "Bad request" }
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
6
server/routes/comment.ts
Normal file
6
server/routes/comment.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { Express, Router } from "express"
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
export const commentRoute = (app: Express) => {
|
||||||
|
app.use('/comment', router);
|
||||||
|
}
|
||||||
@@ -49,9 +49,10 @@ export const friendRouter = (app: Express) => {
|
|||||||
router.put('/:id', async (req, res, next) => {
|
router.put('/:id', async (req, res, next) => {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
const { user }: any = req.user;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await UserInstance.updateFriendship(id, data);
|
const result = await UserInstance.updateFriendship(id, user.id, data);
|
||||||
res.status(200).send(result);
|
res.status(200).send(result);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
next(e);
|
next(e);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Express, Router } from "express"
|
import { Express, Router } from "express"
|
||||||
|
import { restrictAccess } from "../auth/middlewares";
|
||||||
import RecipeCtl from "../controllers/RecipeCtl";
|
import RecipeCtl from "../controllers/RecipeCtl";
|
||||||
const recipectl = new RecipeCtl();
|
const recipectl = new RecipeCtl();
|
||||||
|
|
||||||
@@ -18,6 +19,27 @@ export const recipeRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.get('/', async (req, res, next) => {
|
||||||
|
const { user }: any = req.user;
|
||||||
|
const { filterby } = req.query;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let result;
|
||||||
|
switch (filterby) {
|
||||||
|
case "allaccessible":
|
||||||
|
result = await recipectl.getAllAccessible(user.id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = await recipectl.getAllAuthored(user.id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send(result);
|
||||||
|
} catch(e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.put('/:id', async (req, res, next) => {
|
router.put('/:id', async (req, res, next) => {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
@@ -30,12 +52,12 @@ export const recipeRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.post('/', async (req, res, next) => {
|
router.post('/', restrictAccess, async (req, res, next) => {
|
||||||
|
const { user }: any = req.user;
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await recipectl.post(data);
|
const result = await recipectl.post(user.id, data);
|
||||||
res.status(201).send(result);
|
res.status(201).send(result);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
next(e);
|
next(e);
|
||||||
|
|||||||
@@ -31,21 +31,22 @@ export interface IRecipe extends HasHistory, CanDeactivate {
|
|||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
preptime: string
|
preptime: string
|
||||||
authoruserid: IUser["id"]
|
authoruserid: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IIngredient extends HasHistory {
|
export interface IIngredient extends HasHistory {
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
|
createdbyid: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICollection extends HasHistory, CanDeactivate {
|
export interface ICollection extends HasHistory, CanDeactivate {
|
||||||
name: string
|
name: string
|
||||||
ismaincollection: boolean
|
ismaincollection: boolean
|
||||||
ownerid: IUser["id"]
|
ownerid: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGroceryList extends HasHistory, CanDeactivate {
|
export interface IGroceryList extends HasHistory, CanDeactivate {
|
||||||
name: string
|
name: string
|
||||||
ownerid: IUser["id"]
|
ownerid: string | number
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user