* Protected API route to update selection timing (start and end times)
*
* @route PATCH /api/files/selections/:selectionId/timing
* @authentication Required
* @param {string} selectionId - Selection ID from URL parameter
* @param {Object} body - Request body containing startTime and endTime
* @returns {Object} Response containing updated selection
* @error 400 - If selectionId is invalid or timing data is missing
* @error 403 - If user doesn't have EDIT permission for the dataset
* @error 404 - If selection not found
* @error 500 - If database operation fails
* @description Updates the start and end times for a specific selection
*/
files.patch("/selections/:selectionId/timing", authenticate, async (c) => {
try {
const jwtPayload = (c as unknown as { jwtPayload: JWTPayload }).jwtPayload;
const userId = jwtPayload.sub;
const selectionId = c.req.param("selectionId");
// Validate selection ID format
if (!isValidFileId(selectionId)) {
return c.json({
error: "Invalid selection ID format"
}, 400);
}
// Parse request body
const body = await c.req.json();
const { startTime, endTime } = body;
if (typeof startTime !== 'number' || typeof endTime !== 'number') {
return c.json({
error: "Missing or invalid startTime or endTime"
}, 400);
}
if (startTime < 0 || endTime < 0 || startTime >= endTime) {
return c.json({
error: "Invalid timing: startTime must be >= 0, endTime must be > startTime"
}, 400);
}
// Connect to database
const db = createDatabase(c.env);
// Get selection and dataset info for permission check
const selectionResult = await db
.select({
id: selection.id,
datasetId: selection.datasetId,
active: selection.active
})
.from(selection)
.where(eq(selection.id, selectionId))
.limit(1);
if (selectionResult.length === 0) {
return c.json({
error: "Selection not found"
}, 404);
}
const selectionRecord = selectionResult[0];
if (!selectionRecord.active) {
return c.json({
error: "Selection is not active"
}, 404);
}
// Check if user has EDIT permission for this dataset
const hasPermission = await checkUserPermission(db, userId, selectionRecord.datasetId, 'EDIT');
if (!hasPermission) {
return c.json({
error: "Access denied: No EDIT permission for this dataset"
}, 403);
}
// Update the selection timing
await db
.update(selection)
.set({
startTime: startTime.toString(),
endTime: endTime.toString(),
lastModified: new Date(),
modifiedBy: userId
})
.where(eq(selection.id, selectionId));
return c.json({
data: {
selectionId,
startTime,
endTime
}
});
} catch (error) {
return c.json(standardErrorResponse(error, "updating selection timing"), 500);
}
});
/**