Linkando van com usuário

This commit is contained in:
Matheus Albino Brunhara
2022-06-20 05:40:56 -05:00
parent 04de75faf6
commit 2f55141bdf
13 changed files with 287 additions and 1159 deletions

108
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/jsonwebtoken": "^8.5.1", "@types/jsonwebtoken": "^8.5.1",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"axios": "^0.27.2",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.17.1", "express": "^4.17.1",
@@ -211,6 +212,20 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"dependencies": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -449,6 +464,17 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -511,6 +537,14 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": { "node_modules/depd": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -671,6 +705,38 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/forwarded": { "node_modules/forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -2150,6 +2216,20 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
}, },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
"requires": {
"follow-redirects": "^1.14.9",
"form-data": "^4.0.0"
}
},
"balanced-match": { "balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2314,6 +2394,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2364,6 +2452,11 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"depd": { "depd": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -2495,6 +2588,21 @@
"unpipe": "~1.0.0" "unpipe": "~1.0.0"
} }
}, },
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"forwarded": { "forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",

View File

@@ -0,0 +1,20 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';
export class AddUserIdFieldToVansTable1655720865095
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.addColumn(
'vans',
new TableColumn({
name: 'user_id',
type: 'uuid',
isNullable: true,
}),
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn('vans', 'user_id');
}
}

View File

@@ -0,0 +1,24 @@
import { MigrationInterface, QueryRunner, TableForeignKey } from 'typeorm';
export class AddFKUserIdToVansTable1655720873936 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createForeignKey(
'vans',
new TableForeignKey({
name: 'UserIdVan', // nome da FK, serve para referenciar numa exclusão pelo QueryRunner se necessário
columnNames: ['user_id'], // coluna que vai virar FK
referencedColumnNames: ['id_user'], // coluna PK da primeira tabela
referencedTableName: 'users', // nome da tabela que possui a PK
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
}),
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropForeignKey(
'vans',
'UserIdVan',
);
}
}

View File

@@ -4,7 +4,9 @@ import {
PrimaryGeneratedColumn, PrimaryGeneratedColumn,
CreateDateColumn, CreateDateColumn,
UpdateDateColumn, UpdateDateColumn,
OneToMany,
} from 'typeorm'; } from 'typeorm';
import Van from './Van';
@Entity('users') @Entity('users')
class User { class User {
@@ -44,6 +46,9 @@ class User {
@Column() @Column()
document: string; document: string;
@OneToMany(() => Van, van => van.user)
van: Van[];
@CreateDateColumn() @CreateDateColumn()
created_at: Date; created_at: Date;

View File

@@ -7,7 +7,10 @@ import {
JoinColumn, JoinColumn,
OneToOne, OneToOne,
PrimaryColumn, PrimaryColumn,
OneToMany,
ManyToOne,
} from 'typeorm'; } from 'typeorm';
import User from './User';
@Entity('vans') @Entity('vans')
class Van { class Van {
@@ -41,6 +44,10 @@ class Van {
@Column() @Column()
locator_state: string; locator_state: string;
@ManyToOne(() => User, user => user.van)
@JoinColumn({ name: 'user_id' })
user: User;
@CreateDateColumn() @CreateDateColumn()
created_at: Date; created_at: Date;

View File

@@ -117,7 +117,7 @@ usersRouter.patch('/edit', ensureAuthenticated, async (request, response) => {
document document
}); });
return response.json({ message: 'User info sucessfully updated.' }); return response.json({ message: 'Perfil atualizado com sucesso.' });
}); });
usersRouter.patch('/edit/avatar', ensureAuthenticated, async (request, response) => { usersRouter.patch('/edit/avatar', ensureAuthenticated, async (request, response) => {

View File

@@ -8,6 +8,7 @@ import FindVanService from '../services/FindVanService';
import CreateVanService from '../services/CreateVanService'; import CreateVanService from '../services/CreateVanService';
import UpdateVanService from '../services/UpdateVanService'; import UpdateVanService from '../services/UpdateVanService';
import UpdateVanPlateService from '../services/UpdateVanPlateService'; import UpdateVanPlateService from '../services/UpdateVanPlateService';
import FindVanByUserIdService from '../services/FindVansByUserIdService';
const vansRouter = Router(); const vansRouter = Router();
@@ -19,7 +20,7 @@ vansRouter.get('/list', async (request, response) => {
return response.json({ data: vans }); return response.json({ data: vans });
}); });
vansRouter.get('/:plate', ensureAuthenticated, async (request, response) => { vansRouter.get('/plate/:plate', ensureAuthenticated, async (request, response) => {
const { plate } = request.params; const { plate } = request.params;
const findVanService = new FindVanService(); const findVanService = new FindVanService();
@@ -29,8 +30,19 @@ vansRouter.get('/:plate', ensureAuthenticated, async (request, response) => {
return response.json({ data: van }); return response.json({ data: van });
}); });
vansRouter.get('/user/:id_user', ensureAuthenticated, async (request, response) => {
const { id_user } = request.params;
const findVanByUserIdService = new FindVanByUserIdService();
const vans = await findVanByUserIdService.execute(id_user);
return response.json({ data: vans });
});
vansRouter.post('/', async (request, response) => { vansRouter.post('/', async (request, response) => {
const { const {
id_user,
plate, plate,
brand, brand,
model, model,
@@ -45,6 +57,7 @@ vansRouter.post('/', async (request, response) => {
const createVanService = new CreateVanService(); const createVanService = new CreateVanService();
const van = await createVanService.execute({ const van = await createVanService.execute({
id_user,
plate, plate,
brand, brand,
model, model,

View File

@@ -20,8 +20,9 @@ createConnection();
app.use((err: Error, request: Request, response: Response, _: NextFunction) => { app.use((err: Error, request: Request, response: Response, _: NextFunction) => {
if (err instanceof AppError) { if (err instanceof AppError) {
return response.status(err.statusCode).json({ return response.status(202).json({
status: 'error', status: 'error',
httpCode: err.statusCode,
message: err.message, message: err.message,
}); });
} }

View File

@@ -1,10 +1,12 @@
import { getRepository } from 'typeorm'; import { getRepository } from 'typeorm';
import AppError from '../errors/AppError'; import AppError from '../errors/AppError';
import User from '../models/User';
import Van from '../models/Van'; import Van from '../models/Van';
interface Request { interface Request {
id_user: string;
plate: string; plate: string;
brand: string; brand: string;
model: string; model: string;
@@ -18,6 +20,7 @@ interface Request {
class CreateVanService { class CreateVanService {
public async execute({ public async execute({
id_user,
plate, plate,
brand, brand,
model, model,
@@ -29,6 +32,18 @@ class CreateVanService {
locator_state, locator_state,
}: Request): Promise<Van> { }: Request): Promise<Van> {
const vansRepository = getRepository(Van); const vansRepository = getRepository(Van);
const usersRepository = getRepository(User);
const user = await usersRepository.findOne({
where: { id_user },
});
if (!user) {
throw new AppError(
'O usuário informado não foi encontrado.',
404,
);
}
const vanExists = await vansRepository.findOne({ const vanExists = await vansRepository.findOne({
where: { plate }, where: { plate },
@@ -42,6 +57,7 @@ class CreateVanService {
} }
const van = vansRepository.create({ const van = vansRepository.create({
user,
plate, plate,
brand, brand,
model, model,

View File

@@ -5,15 +5,15 @@ import AppError from '../errors/AppError';
import Van from '../models/Van'; import Van from '../models/Van';
class FindVanService { class FindVanService {
public async execute(id_van: string): Promise<Van> { public async execute(plate: string): Promise<Van> {
const vansRepository = getRepository(Van); const vansRepository = getRepository(Van);
const van = await vansRepository.findOne({ const van = await vansRepository.findOne({
where: { id_van } where: { plate }
}); });
if (!van) { if (!van) {
throw new AppError('Van does not exist.'); throw new AppError('A van informada não existe.');
}; };
return van; return van;

View File

@@ -0,0 +1,33 @@
import { getRepository } from 'typeorm';
import AppError from '../errors/AppError';
import User from '../models/User';
import Van from '../models/Van';
class FindVanByUserIdService {
public async execute(id_user: string): Promise<Van[]> {
const usersRepository = getRepository(User);
const vansRepository = getRepository(Van);
const user = await usersRepository.findOne({
where: { id_user }
});
if (!user) {
throw new AppError('O usuário informado não existe.', 404);
};
const van = await vansRepository.find({
where: { user }
});
if (!van) {
throw new AppError('Não há nenhuma van cadastrada para esse usuário.');
};
return van;
}
}
export default FindVanByUserIdService;

View File

@@ -23,18 +23,29 @@ class UpdateUserService {
const socialRepository = getRepository(Social); const socialRepository = getRepository(Social);
const user = await usersRepository.findOne({ const user = await usersRepository.findOne({
where: { id_user: id_user } where: { id_user }
}); });
if (!user) { if (!user) {
throw new AppError('O usuário informado não existe.'); throw new AppError('O usuário informado não existe.', 404);
}; };
if (name) user.name = name if (name) user.name = name
if (lastname) user.lastname = lastname if (lastname) user.lastname = lastname
if (bio) user.bio = bio if (bio) user.bio = bio
if (email) user.email = email if (email) user.email = email
if (phone_number) user.phone_number = phone_number
if (phone_number) {
const phoneAlreadyExists = await usersRepository.findOne({
where: { phone_number }
});
if (phoneAlreadyExists) {
throw new AppError('O telefone informado já está em uso por outra conta!', 409);
}
}
user.phone_number = phone_number
if (document_type) user.document_type = document_type if (document_type) user.document_type = document_type
if (document) user.document = document if (document) user.document = document

1190
yarn.lock

File diff suppressed because it is too large Load Diff