-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create rental routes, infra, domain
- Loading branch information
1 parent
6e65988
commit 08c989c
Showing
13 changed files
with
381 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Router, Request, Response } from 'express'; | ||
import rentalCarController from '../../infraestructure/factories/RentalCarFactory'; | ||
|
||
const router = Router(); | ||
|
||
router.post('/', (req: Request, res: Response) => rentalCarController.create(req, res)); | ||
router.put('/:driverId', (req: Request, res: Response) => rentalCarController.update(req, res)); | ||
router.get('/:driverId', (req: Request, res: Response) => rentalCarController.getById(req, res)); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class RentalCar { | ||
constructor( | ||
public licensePlateId: string, | ||
public driverId: number, | ||
public startDate: Date, | ||
public endDate: Date | null, | ||
public description: string, | ||
) { } | ||
} | ||
|
||
export default RentalCar; |
10 changes: 10 additions & 0 deletions
10
src/domain/repositories/RentalCar/IRentalCarPersistence.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import RentalCar from '../../entities/RentalCar'; | ||
|
||
interface IRentalCarPersistence { | ||
save(rentalCar: Omit<RentalCar, 'startDate' | 'endDate'>): Promise<RentalCar>; | ||
update(driverId: string): Promise<RentalCar | null>; | ||
getById(driverId: string): Promise<RentalCar | null>; | ||
getCarAndDriberAbleToRent(driverId: number, licensePlateId: string): Promise<RentalCar | null>; | ||
} | ||
|
||
export default IRentalCarPersistence; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import RentalCar from '../../entities/RentalCar'; | ||
import IRentalCarPersistence from './IRentalCarPersistence'; | ||
|
||
class DriverRepository { | ||
constructor(private iRentalCarPersistence: IRentalCarPersistence) { } | ||
|
||
async create(rentalCar: Omit<RentalCar, 'startDate' | 'endDate'>): Promise<RentalCar> { | ||
console.log('testresesse', rentalCar); | ||
return this.iRentalCarPersistence.save(rentalCar); | ||
} | ||
|
||
async update(driverId: string): Promise<RentalCar | null> { | ||
return this.iRentalCarPersistence.update(driverId); | ||
} | ||
|
||
async getById(driverId: string): Promise<RentalCar | null> { | ||
return this.iRentalCarPersistence.getById(driverId); | ||
} | ||
|
||
async getCarAndDriberAbleToRent( | ||
driverId: number, | ||
licensePlateId: string, | ||
): Promise<RentalCar | null> { | ||
return this.iRentalCarPersistence.getCarAndDriberAbleToRent(driverId, licensePlateId); | ||
} | ||
} | ||
|
||
export default DriverRepository; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import RentalCar from '../entities/RentalCar'; | ||
import RentalCarRepository from '../repositories/RentalCar/RentalCarRepository'; | ||
|
||
class CarUseCase { | ||
constructor(private carRepository: RentalCarRepository) {} | ||
|
||
public async create( | ||
rentalCar: Omit<RentalCar, 'startDate' | 'endDate'>, | ||
): Promise<RentalCar | null> { | ||
const findCar = await this.carRepository.getCarAndDriberAbleToRent( | ||
rentalCar.driverId, | ||
rentalCar.licensePlateId, | ||
); | ||
|
||
if (findCar) return null; | ||
|
||
return this.carRepository.create(rentalCar); | ||
} | ||
|
||
public async getById(driverId: string): Promise<RentalCar | null> { | ||
const findCar = await this.carRepository.getById(driverId); | ||
return findCar; | ||
} | ||
|
||
public async update(driverId: string): Promise<RentalCar | null> { | ||
const findCar = await this.carRepository.getById(driverId); | ||
|
||
if (!findCar) return null; | ||
|
||
return this.carRepository.update(driverId); | ||
} | ||
} | ||
|
||
export default CarUseCase; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Request, Response } from 'express'; | ||
import RentalCarUseCase from '../../domain/usecase/RentalCarUseCase'; | ||
import StatusCode from '../enum/statusCode'; | ||
|
||
class DriverController { | ||
private messageDriverNotFound = 'Driver not found'; | ||
|
||
constructor(private rentalCarUseCase: RentalCarUseCase) { } | ||
|
||
async create(req: Request, res: Response): Promise<Response> { | ||
const { licensePlateId, driverId, description } = req.body; | ||
console.log('test coruja'); | ||
|
||
const createNewRentalDriver = await this.rentalCarUseCase.create({ | ||
licensePlateId, driverId, description, | ||
}); | ||
|
||
if (!createNewRentalDriver) { | ||
return res.status(StatusCode.BAD_REQUEST).json({ message: 'Driver already rented' }); | ||
} | ||
|
||
return res.status(StatusCode.CREATED).json(createNewRentalDriver); | ||
} | ||
|
||
async update(req: Request, res: Response): Promise<Response> { | ||
const { driverId } = req.params; | ||
|
||
const driverReturningCar = await this.rentalCarUseCase.update(driverId); | ||
if (!driverReturningCar) { | ||
return res.status(StatusCode.NOT_FOUND).json({ message: this.messageDriverNotFound }); | ||
} | ||
|
||
return res.status(StatusCode.OK).json(driverReturningCar); | ||
} | ||
|
||
async getById(req: Request, res: Response): Promise<Response> { | ||
const { driverId } = req.params; | ||
|
||
const driverData = await this.rentalCarUseCase.getById(driverId); | ||
if (!driverData) { | ||
return res.status(StatusCode.NOT_FOUND).json({ message: this.messageDriverNotFound }); | ||
} | ||
|
||
return res.status(StatusCode.OK).json(driverData); | ||
} | ||
} | ||
|
||
export default DriverController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import RentalCarController from '../controllers/RentalCarController'; | ||
import RentalCarRepository from '../../domain/repositories/RentalCar/RentalCarRepository'; | ||
import RentalCarUseCase from '../../domain/usecase/RentalCarUseCase'; | ||
import RentalCarPersistence from '../persistence/RentalCarPersistence'; | ||
import RentalCarModel from '../persistence/database/models/RentalCarModel'; | ||
import DriverModel from '../persistence/database/models/DriverModel'; | ||
import CarModel from '../persistence/database/models/CarModel'; | ||
|
||
const rentalCarPersistence = new RentalCarPersistence(RentalCarModel, DriverModel, CarModel); | ||
const rentalCarRepository = new RentalCarRepository(rentalCarPersistence); | ||
const rentalCarUseCases = new RentalCarUseCase(rentalCarRepository); | ||
const controller = new RentalCarController(rentalCarUseCases); | ||
|
||
export default controller; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { ModelStatic, Op } from 'sequelize'; | ||
import RentalCar from '../../domain/entities/RentalCar'; | ||
import IRentalCarPersistence from '../../domain/repositories/RentalCar/IRentalCarPersistence'; | ||
import RentalCarModel from './database/models/RentalCarModel'; | ||
import DriverModel from './database/models/DriverModel'; | ||
import CarModel from './database/models/CarModel'; | ||
|
||
class RentalCarPersistence implements IRentalCarPersistence { | ||
constructor( | ||
private rentalCarModel: ModelStatic<RentalCarModel>, | ||
private driverModel: ModelStatic<DriverModel>, | ||
private carModel: ModelStatic<CarModel>, | ||
) { } | ||
|
||
async save(rentalCar: Omit<RentalCar, 'startDate' | 'endDate'>): Promise<RentalCar> { | ||
const newDriver = await this.rentalCarModel.create({ | ||
licensePlateId: rentalCar.licensePlateId, | ||
driverId: rentalCar.driverId, | ||
description: rentalCar.description, | ||
}); | ||
return newDriver.dataValues; | ||
} | ||
|
||
async update(id: string): Promise<RentalCar | null> { | ||
const findDriver = await this.rentalCarModel.findOne({ | ||
where: { driverId: id, endDate: null as any }, | ||
attributes: ['licensePlateId', 'driverId', 'startDate', 'endDate', 'description'], | ||
}); | ||
|
||
console.log('findDriver', findDriver); | ||
if (!findDriver) return null; | ||
|
||
return (await findDriver.update({ endDate: new Date() })).dataValues; | ||
} | ||
|
||
async getById(driverId: string): Promise<RentalCar | null> { | ||
const findDriver = await this.driverModel.findOne({ | ||
where: { id: driverId }, | ||
include: [{ | ||
model: this.carModel, | ||
as: 'rentalCars', | ||
attributes: ['licensePlateId', 'name', 'brand', 'color'], | ||
through: { | ||
attributes: ['startDate', 'endDate', 'description'], | ||
}, | ||
}], | ||
}); | ||
if (!findDriver) return null; | ||
|
||
return findDriver.dataValues as unknown as RentalCar; | ||
} | ||
|
||
async getCarAndDriberAbleToRent( | ||
driverId: number, | ||
licensePlateId: string, | ||
): Promise<RentalCar | null> { | ||
const findDriverOrCar = await this.rentalCarModel.findOne({ | ||
where: { | ||
[Op.and]: [ | ||
{ endDate: null as any }, | ||
{ | ||
[Op.or]: [ | ||
{ driverId }, | ||
{ licensePlateId }, | ||
], | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
if (!findDriverOrCar) return null; | ||
|
||
return findDriverOrCar.dataValues; | ||
} | ||
} | ||
|
||
export default RentalCarPersistence; |
46 changes: 46 additions & 0 deletions
46
src/infraestructure/persistence/database/migrations/20240109222410-create-rental-car.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { DataTypes, Model, QueryInterface } from 'sequelize'; | ||
import RentalCar from '../../../../domain/entities/RentalCar'; | ||
|
||
export default { | ||
up(queryInterface: QueryInterface) { | ||
return queryInterface.createTable<Model<RentalCar>>('rental_cars', { | ||
licensePlateId: { | ||
type: DataTypes.CHAR(8), | ||
allowNull: false, | ||
field: 'license_plate_id', | ||
references: { | ||
model: 'cars', | ||
key: 'license_plate_id', | ||
}, | ||
}, | ||
driverId: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false, | ||
field: 'driver_id', | ||
references: { | ||
model: 'drivers', | ||
key: 'id', | ||
}, | ||
}, | ||
startDate: { | ||
type: DataTypes.DATE, | ||
allowNull: false, | ||
defaultValue: new Date(), | ||
field: 'start_date', | ||
}, | ||
endDate: { | ||
type: DataTypes.DATE, | ||
allowNull: true, | ||
field: 'end_date', | ||
}, | ||
description: { | ||
type: DataTypes.STRING, | ||
allowNull: false, | ||
}, | ||
}); | ||
}, | ||
|
||
down(queryInterface: QueryInterface) { | ||
return queryInterface.dropTable('rental_cars'); | ||
}, | ||
}; |
63 changes: 63 additions & 0 deletions
63
src/infraestructure/persistence/database/models/RentalCarModel.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { | ||
DataTypes, | ||
Model, | ||
InferAttributes, | ||
InferCreationAttributes, | ||
CreationOptional, | ||
} from 'sequelize'; | ||
import db from '.'; | ||
import DriverModel from './DriverModel'; | ||
import CarModel from './CarModel'; | ||
|
||
class RentalCarModel extends Model<InferAttributes<RentalCarModel>, | ||
InferCreationAttributes<RentalCarModel>> { | ||
declare licensePlateId: string; | ||
declare driverId: number; | ||
declare startDate: CreationOptional<Date>; | ||
declare endDate: CreationOptional<Date> | null; | ||
declare description: string; | ||
} | ||
|
||
RentalCarModel.init({ | ||
licensePlateId: { | ||
type: DataTypes.CHAR(8), | ||
primaryKey: true, | ||
}, | ||
driverId: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false, | ||
field: 'driver_id', | ||
}, | ||
startDate: { | ||
type: DataTypes.DATE, | ||
allowNull: false, | ||
defaultValue: new Date(), | ||
}, | ||
endDate: { | ||
type: DataTypes.DATE, | ||
allowNull: true, | ||
}, | ||
description: { | ||
type: DataTypes.STRING, | ||
allowNull: false, | ||
}, | ||
}, { | ||
tableName: 'rental_cars', | ||
timestamps: false, | ||
underscored: true, | ||
sequelize: db, | ||
}); | ||
|
||
CarModel.belongsToMany(DriverModel, { | ||
through: RentalCarModel, | ||
foreignKey: 'license_plate_id', | ||
as: 'drivers', | ||
}); | ||
|
||
DriverModel.belongsToMany(CarModel, { | ||
through: RentalCarModel, | ||
foreignKey: 'driver_id', | ||
as: 'rentalCars', | ||
}); | ||
|
||
export default RentalCarModel; |
40 changes: 40 additions & 0 deletions
40
src/infraestructure/persistence/database/seeders/20240109223209-add-rental-car.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { QueryInterface } from 'sequelize'; | ||
|
||
export default { | ||
up(queryInterface: QueryInterface) { | ||
return queryInterface.bulkInsert('rental_cars', [ | ||
{ | ||
license_plate_id: 'ABC-1234', | ||
driver_id: 1, | ||
start_date: new Date(), | ||
end_date: new Date(), | ||
description: 'Rental car 1', | ||
}, | ||
{ | ||
license_plate_id: 'DEF-5678', | ||
driver_id: 2, | ||
start_date: new Date(), | ||
end_date: null, | ||
description: 'Rental car 1', | ||
}, | ||
{ | ||
license_plate_id: 'GHI-9012', | ||
driver_id: 3, | ||
start_date: new Date(), | ||
end_date: new Date(), | ||
description: 'Rental car 1', | ||
}, | ||
{ | ||
license_plate_id: 'JKL-3456', | ||
driver_id: 1, | ||
start_date: new Date(), | ||
end_date: null, | ||
description: 'Rental car 1', | ||
}, | ||
], {}); | ||
}, | ||
|
||
down(queryInterface: QueryInterface) { | ||
return queryInterface.bulkDelete('rental_cars', {}); | ||
} | ||
}; |
Empty file.
Empty file.