added ratings, count and a range validator

This commit is contained in:
Pau 2025-04-14 01:17:12 +02:00
parent 29036d14a8
commit d4ec892288
6 changed files with 33 additions and 28 deletions

View File

@ -6,12 +6,12 @@ const _coordinatesSelectQuery = (_pagination = '') => ({ count }) => ({ uuid, la
const longitudeCondition = longitude ? 'AND c.longitude = :longitude ' : ''; const longitudeCondition = longitude ? 'AND c.longitude = :longitude ' : '';
return ` return `
SELECT SELECT ${count ||
c.uuid, `c.uuid,
c.created, c.created,
c.createdby, c.createdby,
c.latitude, c.latitude,
c.longitude c.longitude`}
FROM acloc.coordinates AS c FROM acloc.coordinates AS c
WHERE c.created <= :now WHERE c.created <= :now
AND (c.deleted > :now OR c.deleted IS NULL) AND (c.deleted > :now OR c.deleted IS NULL)

View File

@ -7,15 +7,14 @@ const _placeSelectQuery = (_pagination = '') => ({ count }) => ({ uuid, name, de
const addressCondition = address ? `AND p.address LIKE CONCAT('%',:address,'%')` : ''; const addressCondition = address ? `AND p.address LIKE CONCAT('%',:address,'%')` : '';
const fk_coordinateCondition = latitude && longitude ? 'AND fk_coordinate = (SELECT id FROM acloc.coordinates WHERE latitude = :latitude AND longitude = :longitude)' : ''; const fk_coordinateCondition = latitude && longitude ? 'AND fk_coordinate = (SELECT id FROM acloc.coordinates WHERE latitude = :latitude AND longitude = :longitude)' : '';
return ` return `
SELECT SELECT ${count ||
p.uuid, `p.uuid,
p.name, p.name,
p.description, p.description,
p.address, p.address,
c.latitude, c.latitude,
c.longitude, c.longitude,
p.created, p.created`}
p.createdby
FROM acloc.places AS p FROM acloc.places AS p
JOIN acloc.coordinates AS c ON p.fk_coordinate = c.id JOIN acloc.coordinates AS c ON p.fk_coordinate = c.id
WHERE p.deleted IS NULL WHERE p.deleted IS NULL

View File

@ -4,11 +4,8 @@ const _coordinatesSelectQuery = (_pagination = '') => ({ count }) => ({ uuid, na
const uuidCondition = uuid ? 'AND rt.uuid = :uuid ' : ''; const uuidCondition = uuid ? 'AND rt.uuid = :uuid ' : '';
const nameCondition = name ? `AND rt.name LIKE CONCAT('%',:name,'%')` : ''; const nameCondition = name ? `AND rt.name LIKE CONCAT('%',:name,'%')` : '';
return ` return `
SELECT SELECT ${count ||
rt.uuid, `*`}
rt.name,
rt.created,
rt.createdby
FROM acloc.report_types AS rt FROM acloc.report_types AS rt
WHERE rt.created <= :now WHERE rt.created <= :now
AND (rt.deleted > :now OR rt.deleted IS NULL) AND (rt.deleted > :now OR rt.deleted IS NULL)

View File

@ -1,24 +1,20 @@
import { pagination } from "../../utils/pagination.js"; import { pagination } from "../../utils/pagination.js";
//reports repository //reports repository
const _userHasPlacesSelectQuery = (_pagination = '') => ({ count }) => ({ uuid, uuidUser, uuidPlace, uuidReportType }) => { const _userHasPlacesSelectQuery = (_pagination = '') => ({ count }) => ({ uuid, uuidUser, uuidPlace, uuidReportType, rating }) => {
const uuidCondition = uuid ? 'AND up.uuid = :uuid ' : ''; const uuidCondition = uuid ? 'AND up.uuid = :uuid ' : '';
const uuidUserCondition = uuidUser ? 'AND up.fk_user = (SELECT id FROM acloc.users WHERE uuid = :uuidUser)' : ''; const uuidUserCondition = uuidUser ? 'AND up.fk_user = (SELECT id FROM acloc.users WHERE uuid = :uuidUser)' : '';
const uuidPlaceCondition = uuidPlace ? 'AND up.fk_place = (SELECT id FROM acloc.places WHERE uuid = :uuidPlace)' : ''; const uuidPlaceCondition = uuidPlace ? 'AND up.fk_place = (SELECT id FROM acloc.places WHERE uuid = :uuidPlace)' : '';
const uuidReportTypeCondition = uuidReportType ? 'AND up.fk_report_type = (SELECT id FROM acloc.report_types WHERE uuid = :uuidReportType)' : ''; const uuidReportTypeCondition = uuidReportType ? 'AND up.fk_report_type = (SELECT id FROM acloc.report_types WHERE uuid = :uuidReportType)' : '';
const ratingCondition = rating ? 'AND up.rating = :rating' : '';
return ` return `
SELECT SELECT ${count ||
up.uuid, `up.*,
up.fk_user,
up.fk_place,
up.created,
up.createdby,
u.username AS user_username, u.username AS user_username,
u.uuid AS user_uuid, u.uuid AS user_uuid,
p.name AS place_name, p.name AS place_name,
p.uuid AS place_uuid, p.uuid AS place_uuid,
rt.name AS report_type_name, rt.name AS report_type_name,
rt.uuid AS report_type_uuid rt.uuid AS report_type_uuid`}
FROM acloc.users_has_places AS up FROM acloc.users_has_places AS up
JOIN acloc.users AS u ON up.fk_user = u.id JOIN acloc.users AS u ON up.fk_user = u.id
JOIN acloc.places AS p ON up.fk_place = p.id JOIN acloc.places AS p ON up.fk_place = p.id
@ -33,6 +29,7 @@ const _userHasPlacesSelectQuery = (_pagination = '') => ({ count }) => ({ uuid,
${uuidUserCondition} ${uuidUserCondition}
${uuidPlaceCondition} ${uuidPlaceCondition}
${uuidReportTypeCondition} ${uuidReportTypeCondition}
${ratingCondition}
${_pagination} ${_pagination}
`; `;
} }
@ -48,12 +45,14 @@ const insertUserHasPlacesQuery = ({ uuidUser, uuidPlace, createdBy, uuidReportTy
const uuidPlaceCondition = uuidPlace ? '(SELECT id FROM acloc.places WHERE uuid = :uuidPlace),' : null; const uuidPlaceCondition = uuidPlace ? '(SELECT id FROM acloc.places WHERE uuid = :uuidPlace),' : null;
const createdByCondition = createdBy ? 'createdBy = :createdBy' : null; const createdByCondition = createdBy ? 'createdBy = :createdBy' : null;
const reportTypeCondition = uuidReportType ? '(SELECT id FROM acloc.report_types WHERE uuid = :reportType),' : null; const reportTypeCondition = uuidReportType ? '(SELECT id FROM acloc.report_types WHERE uuid = :reportType),' : null;
return ` return `
INSERT INTO acloc.users_has_places ( INSERT INTO acloc.users_has_places (
uuid, uuid,
fk_user, fk_user,
fk_place, fk_place,
fk_report_type, fk_report_type,
rating,
created, created,
createdBy createdBy
) )
@ -62,6 +61,7 @@ const insertUserHasPlacesQuery = ({ uuidUser, uuidPlace, createdBy, uuidReportTy
${uuidUserCondition} ${uuidUserCondition}
${uuidPlaceCondition} ${uuidPlaceCondition}
${reportTypeCondition} ${reportTypeCondition}
:rating,
:now, :now,
${createdByCondition} ${createdByCondition}
); );
@ -69,16 +69,18 @@ const insertUserHasPlacesQuery = ({ uuidUser, uuidPlace, createdBy, uuidReportTy
` `
} }
const modifyUserHasPlacesQuery = (uuidUser, uuidPlace, uuidReportType) => { const modifyUserHasPlacesQuery = (uuidUser, uuidPlace, uuidReportType, rating) => {
const uuidUserCondition = uuidUser ? 'fk_user = (SELECT id FROM acloc.users WHERE uuid = :uuidUser)' : ``; const uuidUserCondition = uuidUser ? 'fk_user = (SELECT id FROM acloc.users WHERE uuid = :uuidUser)' : ``;
const uuidPlaceCondition = uuidPlace ? 'fk_place = (SELECT id FROM acloc.places WHERE uuid = :uuidPlace)' : ``; const uuidPlaceCondition = uuidPlace ? 'fk_place = (SELECT id FROM acloc.places WHERE uuid = :uuidPlace)' : ``;
const uuidReportTypeCondition = uuidReportType ? 'fk_report_type = (SELECT id FROM acloc.report_types WHERE uuid = :uuidReportType)' : ``; const uuidReportTypeCondition = uuidReportType ? 'fk_report_type = (SELECT id FROM acloc.report_types WHERE uuid = :uuidReportType)' : ``;
const ratingCondition = rating ? 'rating = :rating' : ``;
return ` return `
UPDATE acloc.users_has_places UPDATE acloc.users_has_places
SET SET
${uuidUserCondition} ${uuidUserCondition}
${uuidPlaceCondition} ${uuidPlaceCondition}
${uuidReportTypeCondition} ${uuidReportTypeCondition}
${ratingCondition}
uuid = :uuid uuid = :uuid
WHERE WHERE
users_has_places.uuid = :uuid users_has_places.uuid = :uuid

View File

@ -15,7 +15,8 @@ import {
sendOkResponse, sendOkResponse,
sendResponseNoContent, sendResponseNoContent,
} from '../utils/responses.js' } from '../utils/responses.js'
import { uuid, varChar} from '../validators/expressValidator/customValidators.js' import { integer, uuid, varChar } from '../validators/expressValidator/customValidators.js'
import { integerRange } from '../validators/expressValidator/integerRangeValidator.js' // Adjust the path as needed
import {payloadExpressValidator} from '../validators/expressValidator/payloadExpressValidator.js' import {payloadExpressValidator} from '../validators/expressValidator/payloadExpressValidator.js'
import { authorizePermission, setToken, authenticateToken, refreshAuthenticate} from '../middlewares/auth.js' import { authorizePermission, setToken, authenticateToken, refreshAuthenticate} from '../middlewares/auth.js'
import { postRegisterController } from '../controllers/authorization/registerController.js' import { postRegisterController } from '../controllers/authorization/registerController.js'
@ -1181,7 +1182,8 @@ export default(config) => {
uuid('uuid'), uuid('uuid'),
uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }), uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }),
uuid('uuidUser').optional({ nullable: false, values: 'falsy' }), uuid('uuidUser').optional({ nullable: false, values: 'falsy' }),
uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }) uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }),
integerRange('rating', {min: 1, max: 3}).optional({ nullable: false, values: 'falsy' })
], ],
(req, res, next) => payloadExpressValidator(req, res, next, config), (req, res, next) => payloadExpressValidator(req, res, next, config),
(req, res, next) => getUserHasPlacesListController(req, res, next, config), (req, res, next) => getUserHasPlacesListController(req, res, next, config),
@ -1214,7 +1216,8 @@ export default(config) => {
uuid('uuid'), uuid('uuid'),
uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }), uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }),
uuid('uuidUser').optional({ nullable: false, values: 'falsy' }), uuid('uuidUser').optional({ nullable: false, values: 'falsy' }),
uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }) uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }),
integerRange('rating', {min: 1, max: 3}).optional({ nullable: false, values: 'falsy' })
], ],
(req, res, next) => payloadExpressValidator(req, res, next, config), (req, res, next) => payloadExpressValidator(req, res, next, config),
(req, res, next) => getUserHasPlacesByUuidController(req, res, next, config), (req, res, next) => getUserHasPlacesByUuidController(req, res, next, config),
@ -1245,9 +1248,10 @@ export default(config) => {
(req, res, next) => authenticateToken(req, res, next, config), (req, res, next) => authenticateToken(req, res, next, config),
(req, res, next) => authorizePermission('/reports')(req, res, next, config), (req, res, next) => authorizePermission('/reports')(req, res, next, config),
[ [
uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }), uuid('uuidPlace'),
uuid('uuidUser').optional({ nullable: false, values: 'falsy' }), uuid('uuidUser'),
uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }), uuid('uuidReportType'),
integerRange('rating', {min: 1, max: 3}),
varChar('description').optional({ nullable: true, values: 'falsy' }), varChar('description').optional({ nullable: true, values: 'falsy' }),
], ],
(req, res, next) => payloadExpressValidator(req, res, next, config), (req, res, next) => payloadExpressValidator(req, res, next, config),
@ -1284,6 +1288,7 @@ export default(config) => {
uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }), uuid('uuidPlace').optional({ nullable: false, values: 'falsy' }),
uuid('uuidUser').optional({ nullable: false, values: 'falsy' }), uuid('uuidUser').optional({ nullable: false, values: 'falsy' }),
uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }), uuid('uuidReportType').optional({ nullable: false, values: 'falsy' }),
integerRange('rating', {min: 1, max: 3}).optional({ nullable: false, values: 'falsy' }),
varChar('description').optional({ nullable: true, values: 'falsy' }), varChar('description').optional({ nullable: true, values: 'falsy' }),
], ],
(req, res, next) => payloadExpressValidator(req, res, next, config), (req, res, next) => payloadExpressValidator(req, res, next, config),

View File

@ -2,11 +2,13 @@ import { check } from 'express-validator'
const varChar = (field, { max = 255 } = {}) => check(field).isString().trim().isLength({ min: 1, max }).withMessage(`|${field}| must be a string with a length between 1 and ${max}`) const varChar = (field, { max = 255 } = {}) => check(field).isString().trim().isLength({ min: 1, max }).withMessage(`|${field}| must be a string with a length between 1 and ${max}`)
const integer = field => check(field).isInt({min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER}).withMessage(`|${field}| must be an integer`) const integer = field => check(field).isInt({min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER}).withMessage(`|${field}| must be an integer`)
const integerRange = (field, { min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER } = {}) => check(field).isInt({min, max}).withMessage(`|${field}| must be an integer between ${min} and ${max}`)
const uuid = field => check(field).isUUID('all').withMessage(`|${field}| must be a valid UUID`) const uuid = field => check(field).isUUID('all').withMessage(`|${field}| must be a valid UUID`)
const bigInt = field => check(field).isBigInt().withMessage(`|${field}| must be a valid BigInt`) const bigInt = field => check(field).isBigInt().withMessage(`|${field}| must be a valid BigInt`)
export { export {
integer, integer,
integerRange,
uuid, uuid,
varChar, varChar,
bigInt bigInt