Merge branch 'task-23-feature/model_router_Project' into 'development'

Task 23 feature/model router project

See merge request !5
parents a04934c2 275cabde
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -26,9 +26,13 @@ ...@@ -26,9 +26,13 @@
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/express": "^4.17.14", "@types/express": "^4.17.14",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
"class-validator": "^0.13.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"mongoose": "^6.7.0", "mongoose": "^6.7.0",
"nanoid": "^3.3.4" "nanoid": "^3.3.4",
"pg": "^8.8.0",
"reflect-metadata": "^0.1.13",
"typeorm": "^0.3.10"
} }
} }
import { DataSource } from "typeorm";
import {User} from './models/User';
import {Task} from './models/Task';
import { Project } from "./models/Project";
export const myDataSource = new DataSource({
type: "postgres",
host: "localhost",
port: 5432,
username: "pluser",
password: "pluser",
database: "planner",
entities: [User,Task,Project],
logging: true,
synchronize: true, // in build switch to false
migrationsRun: false
})
\ No newline at end of file
import {
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
BaseEntity,
ManyToOne,
ManyToMany,
OneToMany
} from 'typeorm';
import {User} from './User';
import {Task} from './Task';
// type IncomingData={
// title: string | null;
// color: string
// admin:User
// workers?: User[]
// tasks?: Task[]
// dateDue?:Date
// department?:boolean
// }
interface IProject{
id: string;
title: string;
color: string;
admin:User;
workers:User[];
tasks:Task[]|null;
createdAt: Date;
dateDue: Date| null;
department:boolean;
}
@Entity({ name: 'Project' })
export class Project extends BaseEntity implements IProject{
// data: IncomingData;
// constructor(data:IncomingData){
// super();
// this.data = data
// }
@PrimaryGeneratedColumn('uuid')
id!: string
// @Column({ name: 'title', type: 'varchar', length:100,nullable: false, default: this.data.title })
// title!: string
@Column({ name: 'title', type: 'varchar', length:100,nullable: false})
title!: string
@CreateDateColumn({ name: 'createdAt', type: Date, default: new Date() })
createdAt!: Date;
@Column({ name: 'color', type: 'varchar', length:100,nullable: true })
color!: string
@Column({ name: 'dateDue', type: Date, default: null })
dateDue!: Date| null;
@Column({ name: 'department', type: Boolean,nullable:true ,default: false})
department!: boolean | false;
@ManyToOne(() => User, (user: { projects: Project[]; }) => user.projects)
admin!: User;
@ManyToMany(() => User, (user: { projects: Project[]; }) => user.projects)
workers!: User[];
@OneToMany(() => Task, (task: { project: Project; })=>task.project)
tasks!:Task[]|null;
}
import {
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
BaseEntity,
ManyToOne,
ManyToMany
} from 'typeorm';
import {User} from './User';
import {Project} from './Project';
type taskFinishType = "open" | "done" |"failed";
interface ITask{
id: string;
title: string;
description: string;
createdAt: Date;
// dateTimeStart:Date| null;
// dateTimeDue:Date| null;
assignedTo: User[];
accomplish: taskFinishType;
author: User;
project:Project|null;
}
@Entity({ name: 'Task' })
export class Task extends BaseEntity implements ITask{
@PrimaryGeneratedColumn('uuid')
id!: string
@Column({ name: 'title', type: 'varchar', length:50,nullable: false })
title!: string
@Column({ name: 'description', type: 'varchar', length:50,nullable: true })
description!: string
@CreateDateColumn({ name: 'created_at', type: Date, default: new Date() })
createdAt!: Date;
// @CreateDateColumn({ name: 'dateTimeStart', type: Date,nullable: true })
// dateTimeStart!: Date | null;
// @CreateDateColumn({ name: 'dateTimeDue', type: Date,nullable: true })
// dateTimeDue!: Date | null;
@Column({
type: "enum",
enum: ["opened", "done" , "failed"],
default: "opened"
})
accomplish!: taskFinishType
@ManyToOne(() => User, (user: { tasks: Task[]; }) => user.tasks)
author!: User;
@ManyToMany(() => User, (user: { tasks: Task[]; }) => user.tasks)
assignedTo!: User[];
@ManyToOne(()=>Project,(project:{tasks: Task[]}) => project.tasks)
project!: Project | null;
}
import { Schema, model } from 'mongoose'; import {
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
BeforeInsert,
BaseEntity,
ManyToMany,
OneToMany
} from 'typeorm';
import {IsEmail
} from "class-validator";
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
import {nanoid} from 'nanoid'; import {nanoid} from 'nanoid';
import {Task} from './Task';
import {Project} from './Project';
const SALT_WORK_FACTOR= 10; const SALT_WORK_FACTOR= 10;
// 1. Create an interface representing a document in MongoDB.
type userRoleType = "worker" | "director";
interface IUser { interface IUser {
id:string;
name: string; name: string;
surname: string; surname: string;
email: string; email: string;
displayName: string; displayName: string;
password:string; password:string;
role: string; token: string;
role: userRoleType;
createdAt: Date;
createdTasks:Task[]| null;
} }
// 2. Create a Schema corresponding to the document interface.
const UserSchema = new Schema<IUser>({
name: { type: String, required: true }, @Entity({ name: 'User' })
surname: { type: String, required: true }, export class User extends BaseEntity implements IUser {
email: { type: String, required: true }, @PrimaryGeneratedColumn('uuid')
displayName: { type: String, required: true }, id!: string
password: { type: String, required: true }, @Column({ name: 'name', type: 'varchar', length:20,nullable: false })
role:{type:String,default: 'user',enum:['user','admin']} name!: string
});
@Column({ name: 'surname', type: 'varchar', length:30,nullable: false })
surname!: string
// How does next's type defined?
UserSchema.pre('save', async function(next:any):Promise<void>{ @Column({ name: 'displayName', type: 'varchar', length:30,nullable: false })
if(!this.isModified('password')) return next(); displayName!: string
console.log('next', next)
const salt = await bcrypt.genSalt(SALT_WORK_FACTOR); @Column({ name: 'email', type: 'varchar',length:20, unique: true, nullable: false })
const hash = await bcrypt.hash(this.password, salt); @IsEmail()
this.password = hash; email!: string
next();
}) @Column({ name: 'phone', type: 'varchar',length:10, unique: true, nullable: true})
phone?: string
UserSchema.set('toJSON',{
transform:(doc:any, ret:any, options:any)=>{ @Column({ name: 'token', type: 'varchar',length:100, unique: true, nullable: false })
delete ret.password; token!: string
return ret;
@CreateDateColumn({ name: 'created_at', type: Date, default: new Date() })
createdAt!: Date;
@Column({
type: "enum",
enum: ["worker", "director"],
default: "worker"
})
role!: userRoleType
@Column({ type: 'varchar', nullable: false, select:false })
password!: string
@OneToMany(() => Task, (task: { user: User }) => task.user)
createdTasks!: Task[];
@ManyToMany(() => Task, (task: { users: User[] }) =>task.users)
tasksToMake!: Task[];
@OneToMany(() => Project, (project: { user: User }) => project.user)
adminInProjects!: Project[];
@ManyToMany(() => Project, (project: { users: User[] }) =>project.users)
workerInProjects!: Project[];
@BeforeInsert()
protected async beforeInserthashPassword():Promise<void> {
const salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
this.password = await bcrypt.hash(this.password, salt);
} }
})
UserSchema.methods.checkPassword =function(password:string):Promise<boolean>{ public generateToken():void{
return bcrypt.compare(password,this.password); this.token = nanoid()
} return
}
public async checkPassword(
candidatePassword: string,
):Promise<boolean> {
console.log("Checking password", candidatePassword,'this.password', this.password)
return await bcrypt.compare(candidatePassword, this.password);
}
UserSchema.methods.generateToken =function(){
this.token=nanoid();
} }
// 3. Create a Model.
const User = model<IUser>('User', UserSchema);
export default User;
import express,{Router, Request, Response} from 'express';
import {Project} from '../models/Project';
import {myDataSource} from '../app-data-source';
import { User } from '../models/User';
const router:Router = express.Router();
const dataSource = myDataSource;
router.get('/',async (req:Request, res:Response): Promise<Response>=> {
const projects:Project[] = await dataSource.manager.find(Project)
return res.send({projects})
})
router.get("/:project_id",async (req:Request, res:Response): Promise<Response> => {
const project : Project|null= await dataSource.manager.findOneBy(Project, {
id: req.params.project_id
})
if (!project) return res.status(404).send({Message:'no info in the base'})
return res.send({project})
})
router.post('/', async (req:Request, res:Response): Promise<Response> => {
if (!req.body) return res.status(400).send({Message:'problem in incoming req.body'})
const {title, dateDue,color,department, userId,workers,tasks}= req.body;
const user = await dataSource
.createQueryBuilder()
.select("user")
.from(User, "user")
.where("user.id = :id", { id: userId })
.getOne()
if(!user) return res.status(404).send({Message:'user not found'})
const project : Project= new Project()
project.title = title;
project.color = color;
project.dateDue = dateDue || null;
project.department = department;
project.workers = workers|| null;
project.tasks = tasks || null;
project.admin = user;
await project.save()
return res.send({project})
})
// router.get('/:userId', async (req : Request, res : Response): Promise<Response>=>{
// const userId:string = req.params.userId
// const user = await dataSource
// .createQueryBuilder()
// .select("user")
// .from(User, "user")
// .where("user.id = :id", { id: userId })
// .getOne()
// console.log('user ', user)
// const userProjects = await dataSource
// .createQueryBuilder()
// .select('project')
// .from(Project, "project")
// .where("Project_adminId = :id", { id: userId })
// return res.send({userProjects})
// })
export default router;
import express,{Router, Request, Response} from 'express';
// import {User} from '../models/User';
// import {Project} from '../models/Project';
import {Task} from '../models/Task';
import {myDataSource} from '../app-data-source';
// import { nanoid } from 'nanoid';
const router:Router = express.Router();
const dataSource = myDataSource;
router.get('/', async(req:Request, res:Response):Promise<Response> => {
const tasks = await dataSource.manager.find(Task)
return res.send({tasks})
})
export default router;
import express,{Router, Request, Response} from 'express'; import express,{Router, Request, Response} from 'express';
import User from '../models/User'; import {User} from '../models/User';
import {myDataSource} from '../app-data-source';
import { nanoid } from 'nanoid';
const router:Router = express.Router(); const router:Router = express.Router();
const dataSource = myDataSource;
router.get('/', async (req : Request, res : Response):Promise<object> => {
const users = await dataSource.manager.find(User)
return res.send({users})
})
router.post('/', async (req : Request, res : Response):Promise<object> => {
router.post('/', async (req : Request, res : Response) => {
try{
const {name,surname,password,email} = req.body; const {name,surname,password,email} = req.body;
const displayName = surname+' '+name[0]+'.' const displayName = surname+' '+name[0]+'.'
const user = new User({ const user = new User();
name:name, user.name = name;
surname:surname, user.surname = surname;
email:email, user.password = password;
password:password, user.displayName= displayName;
displayName:displayName user.email = email;
}) user.generateToken()
await user.save(); await user.save();
return res.send({user}) const userToFront:User|null = await dataSource.manager.findOneBy(User, {
}catch(e ){ email: user.email
if (e instanceof Error){ })
return res.status(404).send({'message':e.message}); return res.send({userToFront})
} })
return res.status(500).send({'message':'Broke server'});
}
router.post('/sessions/', async (req : Request, res : Response):Promise<object> => {
const {email, password} = req.body;
const user = await dataSource
.createQueryBuilder()
.select("user")
.from(User, "user")
.where("user.email = :email", { email: email })
.getOne()
if(!user) return res.status(404).send({Message:'user not found'})
const isMatch:boolean = await user.checkPassword(password);
if (!isMatch) return res.status(400).send({
error: "Wrong Password"
})
const userToFront:User|null = await dataSource.manager.findOneBy(User, {
email: req.body.email
})
return res.send({
message: "message: 'Correct user & password",
user: userToFront
})
}) })
router.get('/', async (req : Request, res : Response):Promise<Response<any, Record<string, any>>> => { router.delete('/sessions', async(req: Request, res: Response):Promise<void | object> => {
const users = await User.find() const token = req.get('Authorization');
return res.send({users}) const successMsg = {message:'success'};
if(!token) return res.send(successMsg)
const user = await dataSource.manager.findOneBy(User, {
token: token
})
if(!user) return res.send({successMsg});
console.log('token: ' + token)
user.token = nanoid();
await user.save();
}) })
export default router; export default router;
import express, { Express } from 'express'; import express, { Express } from 'express';
import cors from 'cors'; import cors from 'cors';
import mongoose from 'mongoose';
import users from './routers/users'; import users from './routers/users';
import tasks from './routers/tasks';
import projects from './routers/projects';
import {myDataSource} from './app-data-source';
console.log('Hello world!');
myDataSource
.initialize()
.then(() => {
console.log("Data Source has been initialized!")
})
.catch((err) => {
console.error("Error during Data Source initialization:", err)
})
const app:Express = express(); const app:Express = express();
app.use(express.static('public')); app.use(express.static('public'));
...@@ -11,18 +21,17 @@ app.use(cors()) ...@@ -11,18 +21,17 @@ app.use(cors())
app.use(express.json()); app.use(express.json());
const PORT = 8000; const PORT = 8000;
app.use('/users',users) app.use('/users',users)
app.use('/tasks',tasks)
app.use('/projects',projects)
const run = async() => { const run = async() => {
mongoose.connect(`mongodb://localhost:27017/task-planner`);
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`Server started at http://localhost:${PORT}/`); console.log(`Server started at http://localhost:${PORT}/`);
}) })
process.on("exit", () => {
mongoose.disconnect();
})
} }
console.log('Hello world!');
run().catch(console.error); run().catch(console.error);
\ No newline at end of file
{ {
"compilerOptions": { "compilerOptions": {
"experimentalDecorators": true,
/* Visit https://aka.ms/tsconfig to read more about this file */ /* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */ /* Projects */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment