149 lines
5.2 KiB
TypeScript
149 lines
5.2 KiB
TypeScript
import { Router } from 'express'
|
|
import { requireCompanyAuth } from '../../middleware/requireCompanyAuth'
|
|
import { requireTenant } from '../../middleware/requireTenant'
|
|
import { requireSubscription } from '../../middleware/requireSubscription'
|
|
import { requireRole } from '../../middleware/requireRole'
|
|
import { parseBody, parseQuery, parseParams } from '../../http/validate'
|
|
import { ok, created } from '../../http/respond'
|
|
import { imageUpload, assertImageFiles } from '../../http/upload'
|
|
import * as service from './vehicle.service'
|
|
import {
|
|
vehicleSchema, listQuerySchema, availabilityQuerySchema, calendarQuerySchema,
|
|
calendarBlockSchema, maintenanceLogSchema, publishSchema, statusSchema,
|
|
idParamSchema, photoIdxSchema, blockIdParamSchema,
|
|
} from './vehicle.schemas'
|
|
|
|
const router = Router()
|
|
|
|
router.use(requireCompanyAuth, requireTenant, requireSubscription)
|
|
|
|
router.get('/', async (req, res, next) => {
|
|
try {
|
|
const query = parseQuery(listQuerySchema, req)
|
|
const result = await service.listVehicles(req.companyId, query)
|
|
res.json(result)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const body = parseBody(vehicleSchema, req)
|
|
const vehicle = await service.createVehicle(body, req.companyId)
|
|
created(res, vehicle)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/:id', async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const vehicle = await service.getVehicle(id, req.companyId)
|
|
ok(res, vehicle)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.patch('/:id', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const body = parseBody(vehicleSchema.partial(), req)
|
|
const vehicle = await service.updateVehicle(id, req.companyId, body)
|
|
ok(res, vehicle)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.delete('/:id', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
await service.deleteVehicle(id, req.companyId)
|
|
ok(res, { success: true })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/:id/photos', requireRole('MANAGER'), imageUpload.array('photos', 10), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const files = req.files as Express.Multer.File[]
|
|
assertImageFiles(files)
|
|
const updated = await service.uploadPhotos(id, req.companyId, files)
|
|
ok(res, updated)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.delete('/:id/photos/:idx', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id, idx } = parseParams(photoIdxSchema, req)
|
|
const updated = await service.deletePhoto(id, req.companyId, parseInt(idx, 10))
|
|
ok(res, updated)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.patch('/:id/status', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const { status } = parseBody(statusSchema, req)
|
|
ok(res, await service.setStatus(id, req.companyId, status))
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.patch('/:id/publish', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const { isPublished } = parseBody(publishSchema, req)
|
|
await service.setPublished(id, req.companyId, isPublished)
|
|
ok(res, { success: true, isPublished })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/:id/availability', async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const { startDate, endDate } = parseQuery(availabilityQuerySchema, req)
|
|
const result = await service.checkAvailability(id, req.companyId, startDate, endDate)
|
|
ok(res, result)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/:id/calendar', async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const { year, month } = parseQuery(calendarQuerySchema, req)
|
|
const events = await service.getCalendar(id, req.companyId, year, month)
|
|
ok(res, events)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/:id/calendar/blocks', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const body = parseBody(calendarBlockSchema, req)
|
|
const block = await service.createCalendarBlock(id, req.companyId, body)
|
|
created(res, block)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.delete('/:id/calendar/blocks/:blockId', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id, blockId } = parseParams(blockIdParamSchema, req)
|
|
await service.deleteCalendarBlock(id, req.companyId, blockId)
|
|
ok(res, { success: true })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/:id/maintenance', async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const logs = await service.getMaintenanceLogs(id, req.companyId)
|
|
ok(res, logs)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/:id/maintenance', requireRole('MANAGER'), async (req, res, next) => {
|
|
try {
|
|
const { id } = parseParams(idParamSchema, req)
|
|
const body = parseBody(maintenanceLogSchema, req)
|
|
const log = await service.createMaintenanceLog(id, req.companyId, body)
|
|
created(res, log)
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
export default router
|