import { authGuard } from '../authGuard.js' import { uuidv7obj, UUID } from "uuidv7" export const mappings = [ { method: 'get', url:'/keyframes/:kfid', handler: 'getKeyframe', middlewares: [authGuard]}, { method: 'post', url:'/keyframes', handler: 'listKeyframes', middlewares: [authGuard]}, { method: 'put', url:'/keyframes', handler: 'createKeyframe', middlewares: [authGuard]}, { method: 'put', url:'/keyframes/:kfid', handler: 'renameKeyframe', middlewares: [authGuard]}, { method: 'put', url:'/keyframes/:kfid/agents', handler: 'saveKeyframeAgents', middlewares: [authGuard]}, ] export const methods = { async getKeyframe(req, res){ const kfid = req.params.kfid if(!this.utils.isValidUUIDV7(kfid)) { this.err(req, res,`Cannot create Keyframe ! `, `Invalid Keyframe ID !`, 400) return } let results = await this.db.execute(` SELECT BIN_TO_UUID(ekf_uuid) AS ekf_uuid, ekf_name, BIN_TO_UUID(ekf_prev_uuid) AS ekf_prev_uuid FROM p42SIM.edited_keyframes WHERE ekf_uuid = UUID_TO_BIN(?)`, [kfid]) if(results.length!=1){ this.err(req,res,`Cannot find this keyframe !`, `Keyframe ${kfid} not found !`, 404) return } const data = { info: results[0] } results = await this.db.execute(` SELECT BIN_TO_UUID(ekfs_agent_id) AS aid, BIN_TO_UUID(ekfs_ekf_uuid) AS kfId, ekfs_atp_id , ekfs_gps_values AS gps_values, ekfs_store_values AS store_values, atp_props FROM p42SIM.edited_kf_store LEFT JOIN p42SIM.agent_types ON ekfs_atp_id = atp_id WHERE ekfs_ekf_uuid = UUID_TO_BIN(?)`, [kfid]) data.agents = results this.ok(req, res, data) }, async listKeyframes(req, res) { const[isOk, payload, errors] = this.utils.validateMapObject(req.body, { 'kfId': ((val, obj) => ( (typeof(val)=='undefined') || (this.utils.isValidUUIDV7(val)) ) ), 'prevKfId': ((val, obj) => ( (val===null) || (typeof(val)=='undefined') || (this.utils.isValidUUIDV7(val)) ) ), }, { 'kfId': 'kfId', 'prevKfId': 'prevKfId', }) if(!isOk){ this.err(req, res,`Cannot filter on these criteria ! `, `Validations errors for listing KF : ${errors.join(', ')}`, 400) return } const conditions = [] const params = [] if (payload.kfId !== undefined) { conditions.push('ekf_uuid = UUID_TO_BIN(?)') params.push(kfId) } if(payload.prevKfId !== undefined) { if(payload.prevKfId === null) { conditions.push('ekf_prev_uuid IS NULL') } else { conditions.push('ekf_prev_uuid = UUID_TO_BIN(?)') params.push(payload.prevKfId) } } const whereClause = conditions.length ? 'WHERE ' + conditions.join(' AND ') : '' const results = await this.db.execute(` SELECT BIN_TO_UUID(ekf_uuid) AS ekf_uuid, ekf_name, BIN_TO_UUID(ekf_prev_uuid) AS ekf_prev_uuid FROM p42SIM.edited_keyframes ${whereClause}`, params) this.ok(req, res, results) }, async createKeyframe(req, res) { const[isOk, payload, errors] = this.utils.validateMapObject(req.body, { 'kfName': ((val, obj) => ( (typeof(val)=='string') && (new RegExp(/^[\w\s]{5,50}$/).test(val))) ), 'prevKfId': ((val, obj) => ( (typeof(val)=='undefined') || (this.utils.isValidUUIDV7(val)) ) ), }, { 'kfName': 'kfName', 'prevKfId': 'prevKfId', }) if(!isOk){ this.err(req, res,`Cannot create this keyframe ! `, `Validations errors for creating KF : ${errors.join(', ')}`, 400) return } const newKfId = uuidv7obj() await this.db.execute(` INSERT INTO p42SIM.edited_keyframes (ekf_uuid, ekf_name, ekf_prev_uuid) VALUES (?, ?, ?)`, [ Buffer.from(newKfId.bytes), payload.kfName, payload.prevKfId ? UUID.parse(payload.prevKfId).bytes : null ]) this.ok(req, res, { kfId: newKfId.toString() }) }, async renameKeyframe(req, res) { const kfid = req.params.kfid if(!this.utils.isValidUUIDV7(kfid)) { this.err(req, res,`Cannot create Keyframe ! `, `Invalid Keyframe ID !`, 400) return } const[isOk, payload, errors] = this.utils.validateMapObject(req.body, { 'kfName': ((val, obj) => ( (typeof(val)=='string') && (new RegExp(/^\w{5,50}$/).test(val))) ), }, { 'kfName': 'kfName', }) if(!isOk){ this.err(req, res,`Cannot rename this keyframe ! `, `Validations errors for renaming KF : ${errors.join(', ')}`, 400) return } const [result] = await this.db.execute(` UPDATE p42SIM.edited_keyframes SET ekf_name = ? WHERE (ekf_uuid = ?)`, [payload.kfName, UUID.parse(kfid).bytes]) if (result.affectedRows === 0) { this.err(req, res,`Cannot rename this keyframe ! `, `Non-existin kfId: (${UUID.parse(kfid).toString()})`, 400) } else { this.ok(req, res, { kfId: kfid }) } }, async saveKeyframeAgents(req, res) { const kfid = req.params.kfid if(!this.utils.isValidUUIDV7(kfid)) { this.err(req, res,`Cannot create Keyframe ! `, `Invalid Keyframe ID !`, 400) return } const[isOk, payload, errors] = this.utils.validateMapArray(req.body, { 'aid': ((val, obj) => (this.utils.isValidUUIDV7(val)) ), 'type': ((val, obj) => (/^[0-9]\d*$/.test(val)) ), 'storeValues': ((val, obj) => (typeof(val)==='object') ), 'gpsValues': ((val, obj) => (typeof(val)==='object') ), }, { 'aid': 'aid', 'type': 'type', 'storeValues': 'storeValues', 'gpsValues': 'gpsValues', } ) if(!isOk){ this.err(req, res,`Cannot save this keyframe ! `, `Validations errors for saving KF : ${errors.join(', ')}`, 400) return } await this.db.execute(`DELETE FROM p42SIM.edited_kf_store WHERE ekfs_ekf_uuid = ?`, [UUID.parse(kfid).bytes]) for(const entry of payload){ await this.db.execute(` INSERT INTO p42SIM.edited_kf_store (ekfs_ekf_uuid, ekfs_agent_id, ekfs_atp_id, ekfs_store_values, ekfs_gps_values) VALUES (?, ?, ?, ?, ?)`, [ UUID.parse(kfid).bytes, UUID.parse(entry.aid).bytes, entry.type, entry.storeValues, entry.gpsValues ]) } this.ok(req, res, { kfId: kfid }) }, /* REMEMBER READ BACK UUIDS from BINARY : const uuid = uuidStringify(rows[0].ekf_uuid) */ }