Add development guidelines, testing rules, and secure routes documentation
- Add `.junie/guidelines.md` with comprehensive development instructions. - Include `.aiassistant/rules/Creating and maintaining tests.md` and `.aiassistant/rules/Creating and securing routes.md`. - Introduce `CACHE_SELFSERVE_LANE_KEY_ALLOWED_SERVICES` for lane service validation. - Update `selfserve_lane_relay_controller_t` to enforce service-specific permissions for machine relay.
This commit is contained in:
@@ -9,6 +9,7 @@ use classes\router;
|
||||
use classes\selfserve;
|
||||
use classes\stripe;
|
||||
use modules\selfserve\helpers\selfserve_lane_command;
|
||||
use modules\selfserve\helpers\selfserve_lane_relay;
|
||||
use objects\departments_o;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
@@ -125,5 +126,86 @@ class moduleSelfServeRoute
|
||||
'modules_selfserve_lane_command_bypass_customer_number_validation' => 'Bypass customer number validation when executing commands',
|
||||
]
|
||||
);
|
||||
|
||||
/** Modules > Self Serve > Lane > Allowed services (derived from shown tasks) */
|
||||
$this->post('/modules/self-serve/lane/services/allowed', function () {
|
||||
global $response;
|
||||
self::requirePermission('modules_selfserve_lane_services_set_allowed');
|
||||
$selfserve = new selfserve();
|
||||
// Validate parameters
|
||||
self::requireParameters(['lane_id']);
|
||||
$lane_id = (int)$this->getParameter('lane_id');
|
||||
self::requireType($lane_id, self::type_int());
|
||||
self::requireMinValue($lane_id, 1);
|
||||
// Parse task_ids from request (optional, may be empty to clear)
|
||||
$task_ids_param = $this->isParametersSet(['task_ids']) ? $this->getParameter('task_ids') : [];
|
||||
if (is_string($task_ids_param)) {
|
||||
$decoded = json_decode($task_ids_param, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
|
||||
$task_ids_param = $decoded;
|
||||
} else {
|
||||
$task_ids_param = array_filter(array_map(fn($s) => (int)trim($s), explode(',', $task_ids_param)), fn($v) => $v > 0);
|
||||
}
|
||||
}
|
||||
if (!is_array($task_ids_param)) {
|
||||
$response->error('Invalid format for task_ids. Expected array, JSON array, or comma-separated string of IDs.', 400);
|
||||
}
|
||||
$task_ids = array_values(array_unique(array_map(fn($v) => (int)$v, $task_ids_param)));
|
||||
// Build allowed services from provided tasks
|
||||
$lane = $selfserve->lane($lane_id);
|
||||
$allowed_services = [];
|
||||
foreach ($task_ids as $tid) {
|
||||
if ($tid <= 0) continue;
|
||||
$t = new \objects\department_selfserve_tasks_o();
|
||||
$t->select($tid);
|
||||
if (!$t->exists()) continue; // ignore unknown ids
|
||||
// Validate the task belongs to the same lane
|
||||
if ((int)$t->lane->value() !== $lane_id) continue;
|
||||
// Merge services (if any)
|
||||
$services = (array)$t->services->value();
|
||||
foreach ($services as $srv) {
|
||||
$name = strtoupper((string)$srv);
|
||||
if (!in_array($name, $allowed_services, true)) {
|
||||
$allowed_services[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Persist on lane cache (overwrites previous allowed services)
|
||||
$lane->setLaneCache($lane_id, $lane::CACHE_SELFSERVE_LANE_KEY_ALLOWED_SERVICES, $allowed_services);
|
||||
$response->success(['lane_id' => $lane_id, 'allowed_services' => $allowed_services]);
|
||||
}, [
|
||||
'modules_selfserve_lane_services_set_allowed' => 'Set allowed services for a lane based on currently shown tasks (post-Q&A)'
|
||||
]);
|
||||
|
||||
/** Modules > Self Serve > Lane > Relay > Enable MACHINE (manual, gated by allowed services) */
|
||||
$this->post('/modules/self-serve/lane/relay/machine/enable', function () {
|
||||
global $response;
|
||||
self::requirePermission('modules_selfserve_lane_relay_enable_machine');
|
||||
$selfserve = new selfserve();
|
||||
// Validate parameters
|
||||
self::requireParameters(['lane_id']);
|
||||
$lane_id = (int)$this->getParameter('lane_id');
|
||||
self::requireType($lane_id, self::type_int());
|
||||
self::requireMinValue($lane_id, 1);
|
||||
$duration = null;
|
||||
if ($this->isParametersSet(['duration'])) {
|
||||
$duration = (int)$this->getParameter('duration');
|
||||
self::requireMinValue($duration, 1);
|
||||
}
|
||||
$lane = $selfserve->lane($lane_id);
|
||||
try {
|
||||
$lane->turnOnRelay(selfserve_lane_relay::MACHINE, $duration);
|
||||
$response->success(['lane_id' => $lane_id, 'relay' => 'MACHINE', 'enabled' => true, 'duration' => $duration]);
|
||||
} catch (\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
// If gating prevented activation, respond with 403
|
||||
if (str_contains(strtoupper($msg), 'NOT ALLOWED')) {
|
||||
$response->error($msg, 403);
|
||||
}
|
||||
$response->error('Failed to enable MACHINE relay: ' . $msg, 400);
|
||||
}
|
||||
}, [
|
||||
'modules_selfserve_lane_relay_enable_machine' => 'Manually enable MACHINE relay for a lane (requires allowed task to be present)'
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user