Skip to content

feat: javascript-server #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 122 commits into
base: master
Choose a base branch
from
Open

feat: javascript-server #28

wants to merge 122 commits into from

Conversation

AryanSinghal
Copy link
Owner

Day 1 - Basic GIT Intro, features of VS CODE

  • create git account and install vs code

Day 2 - MERN Stack,12 factor app

  • write about MERN stack and 12 Factor APP stack in detail.

Day 3 - Intro to Node.js & NPM

  • Create functions for the patterns

Day 4 - Objects and Array

  • Create file permissions.js and validation.js

Day 5 - Packages in Node.js

  • install various packages of node

Day 6 - Advantages of TypeScript

  • use TypeScript

Day 7 - Setup of Express (OOps based)

  • setup express server

Day 8 -HTTP Status code and handlers

  • create error hander and not found route

Day 9 - Setting of Routes Skeletons (REST API)

  • create route for different request

Day 10 -Generic Routes Validations

  • create middleware

Day 11 - Authentication and Authorization

  • create authmiddleware

Day 12 - Intro to Mongoose and promises

  • Setup MongoDB using mongoose

Day 13 - Models setup with initial seed

  • create initial seeding and model setup for MongoDB

Day 14 - Profile Setup

  • count check on the seeding of users and create a jwt token by using data from DB

Day 15 - Setup all the Entities

  • create generic methods like create, update, generateObjectId in versionableRepository

Day 16 - Magic of Await

  • use bcrypt for encryption of password and use async-await

Day 17 - APIs Completion

  • Count total no. of trainees, implement Sorting and implement Server Side Pagination.

Day 18 - APIs Completion

  • implement search on email and name
  • Implement Swagger on all APIs.

{
str=str+" ";
}
for(let j=0;j<=i;j++)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No proper indentation is done over here in this file

let str="";
for(let k=0;k<n-i-1;k++)
{
str=str+" ";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation in file

@@ -0,0 +1,3 @@
import diamond from "./diamond.js";
import equilateral from "./equilateral.js";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation in file

if(email.match(regex))
{
return true;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation in file

{
return true;
}
else
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need else statement over here?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, we do not need else statement

return false;
let data=permissions[moduleName];
let tmp=false;
if(data[permissionType]===undefined)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation is done

let invalidEmails=[];
user.forEach(function(value,index)
{
const {traineeEmail,reviewerEmail}=user[index];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are getting value as first argument then why do we need to extract value using index?

import { hasPermission, validateUser } from './utils/index';
import { Iuser } from './interface';
diamond(10);
equilateral(8);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please a proper space between import statements and calling of functions.

}
export { Iuser };
interface Iauthority {
all: string[];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export at the end of file with single export statement.

return false;
const data = permissions[moduleName];
let tmp: boolean = false;
if (data[permissionType] === undefined)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if value of data[permissionType] is null?

import { userRepository } from '../../repositories/user';
import SystemResponse from '../../libs/SystemResponse';
import * as bcrypt from 'bcrypt';
class Controller {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One line space is needed.

import { userRepository } from '../../repositories/user';
import SystemResponse from '../../libs/SystemResponse';
import * as bcrypt from 'bcrypt';
class Controller {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to name it TraineeController

try {
const hash = await bcrypt.hash(password, 10);
email = email.toLowerCase();
name = name.toLowerCase();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are converting name to lowercase?

let { name, email } = req.body;
try {
const hash = await bcrypt.hash(password, 10);
email = email.toLowerCase();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do not we do it using the validation handler by using custom function?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I have to make a custom function that will return a promise and i have to handle promise which will make my validation handler non-generic.

const hash = await bcrypt.hash(password, 10);
email = email.toLowerCase();
name = name.toLowerCase();
const validity = await userRepository.findByEmail(email);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we creating methods such as findByEmail(email)?

We should be creating function for findOne({email}) which will accept an object as it can be reused again by passing different arguments, Suppose I need to find a user by Id then I will need a another function which do not make sense to me.

const validity = await userRepository.findByEmail(email);
if (!validity) {
const userData = await userRepository.create(req.user._id, { name, address, email, dob, mob, hobbies, role, password: hash });
const message = 'Trainee added successfully';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indentation in code

const userData = await userRepository.create(req.user._id, { name, address, email, dob, mob, hobbies, role, password: hash });
const message = 'Trainee added successfully';
userData.password = '*****';
console.log(userData);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write the above code as below:

if(!validation) {
throw error;
}

Then continue coding

The above code looks good and also reduces the number of bolcks as we do not need else block now

sortBy = { name: req.query.order};
else
sortBy = {updatedAt: req.query.order};
if (req.query.search !== undefined) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating query for sort and search, There is too much of if and else, I do not think it was necessary, We may use switch.

And better to have helpers methods for these types of tasks that can handle it in more good manner

else
sortBy = {updatedAt: req.query.order};
if (req.query.search !== undefined) {
dataList = await userRepository.list('trainee', req.query.skip, req.query.limit, sortBy, {name: { $regex: req.query.search.toLowerCase()}});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to call list method of userRepository two times?

And why are we creating sortBy and even then passing limit and skip?

Why are we not taking a query object from controller to repository rather than passing arguments.

dataList = await userRepository.list('trainee', req.query.skip, req.query.limit, sortBy, {name: { $regex: req.query.search.toLowerCase()}});
const List = await userRepository.list('trainee', req.query.skip, req.query.limit, sortBy, {email: { $regex: req.query.search.toLowerCase()}});
dataList = {...dataList, ...List };
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are unnecessary calling of functions which can be reduced.

update = async (req, res: Response) => {
console.log('----------Update Trainee----------');
try {
const value = await userRepository.update(req, req.body.id, req.body.dataToUpdate);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we sending req object to update method????

const value = await userRepository.update(req, req.body.id, req.body.dataToUpdate);
if (value) {
const message = 'Trainee Data successfully Updated';
const data = req.body.dataToUpdate;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not have to send the data that is being updated rather send the whole user after updation.

SystemResponse.success(res, data, message);
}
else
return SystemResponse.failure(res, 'User data is not Updated', 'Email id already exist');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we sure that the error will be of Email duplication?

console.log('----------Delete Trainee----------');
try {
const value = await userRepository.delete(req, req.params.id);
if (value) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as for above update method.

}
me = (req, res: Response) => {
console.log('--------------me-------------');
delete req.user.password;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not using try catch in controller?

version: '1.0.0',
},
securityDefinitions: {
Bearer: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not taking these options from config??

console.log(err);
}
else {
console.log(`Express app Successfully started on port : ${Port} `);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary else

});
}
catch (err) {
console.log(err);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throe this error please

@@ -0,0 +1,7 @@
export interface IConfig {
Port: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are using Pascal Case over here for keys??

Port : process.env.PORT,
NODE_ENV : process.env.NODE_ENV,
Key : process.env.SECRET_KEY,
MongoURL: process.env.MONGO_URL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pascal case for keys why??

Please use camel case

@@ -0,0 +1,6 @@
import { Server } from './Server';
import config from './config/configuration';
const server: Server = new Server(config);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One line space before this line

import UserRepository from '../../repositories/user/UserRepository';
import IUserModel from '../../repositories/user/IUserModel';
interface IRequest extends Request {
user: IUserModel;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this interface to respective file or folder

console.log(userData);
req.user = userData;
const role: string = userData.role;
if (decodedUser._id === req.body.id && req.method === 'PUT')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this condition??

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that the user can update his own data

if (count === 0) {
const { Password } = config;
const hash = await bcrypt.hash(Password, 10);
UserRepository.create(undefined, { ...user, password: hash });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use try catch in this please

}
update = (req, id, updatedData) => {
return super.update(req, id, updatedData);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No proper indentation.

Why eslint is not throwing errors?

}
async delete(req, id) {
const oldData: any = await this.versionModel.findOne({originalId: id , deletedAt: undefined}).exec();
return this.versionModel.findByIdAndUpdate( oldData._id ,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we passing req to this function rather we should be creating data and then sending the data to this function

const oldData: any = await this.versionModel.findOne({originalId: id , deletedAt: undefined}).exec();
const { name, address, email, dob, mob, hobbies, role, password} = oldData;
if ( updatedData.name !== undefined)
updatedData.name = updatedData.name.toLowerCase();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why lowercasing the name?

And why is the logic over here??
It should only contain the logic to updating document and making versions of the same.
THis function should not bother about the the data coming for updation

return false;
}
}
public list(userRole, skipRecord, limitRecord, sortBy, searchBy) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we making query over here??

It should be passed by controller.

import { Router } from 'express';
import { traineeRouter, userRouter } from './Controllers';
const mainRouter: Router = Router();
mainRouter.use('/trainee', traineeRouter);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A line break

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants