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:
Jeppe Bundgaard
2026-02-18 14:13:05 +01:00
parent 008e2af09a
commit 51014bf774
8 changed files with 800 additions and 0 deletions
@@ -17,6 +17,10 @@ trait selfserve_lane_cache_t
const CACHE_SELFSERVE_LANE_KEY_CUSTOMER_NUMBER = self::CACHE_SELFSERVE_PREFIX . 'customer_number';
const CACHE_SELFSERVE_LANE_KEY_LICENSE_PLATE = self::CACHE_SELFSERVE_PREFIX . 'license_plate';
// Allowed services for this lane, derived from currently shown tasks after Q&A.
// Stored as an array of service names (e.g., ['MACHINE']).
const CACHE_SELFSERVE_LANE_KEY_ALLOWED_SERVICES = self::CACHE_SELFSERVE_PREFIX . 'allowed_services';
/**
* Get the cache key for the lane
@@ -9,6 +9,7 @@ use modules\selfserve\helpers\selfserve_lane_log_action;
use modules\selfserve\helpers\selfserve_lane_relay;
use modules\selfserve\helpers\selfserve_lane_state;
use modules\selfserve\helpers\selfserve_lane_status;
use modules\selfserve\helpers\selfserve_lane_services;
use modules\shelly\helpers\shelly_device_switch;
use modules\shelly\helpers\shelly_request_body_get_states;
@@ -29,6 +30,14 @@ trait selfserve_lane_relay_controller_t
if ($this->status->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn on relay on CLOSED lane");
if ($this->status->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn on relay on MAINTENANCE lane");
if ($this->status->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn on relay on FAULT lane");
// Enforce that MACHINE relay can only be enabled when allowed by current self-serve tasks (self-serve, manual trigger required)
if ($relay === selfserve_lane_relay::MACHINE) {
// Allowed services are stored as an array of names in lane cache
$allowed = $this->getLaneCache($this->id, self::CACHE_SELFSERVE_LANE_KEY_ALLOWED_SERVICES);
if (!is_array($allowed) || !in_array(selfserve_lane_services::MACHINE->name, $allowed, true)) {
throw new \Exception("MACHINE relay is not allowed to be enabled at this time");
}
}
// Get the relay ID based on the relay type
$relay_id = match ($relay) {
selfserve_lane_relay::MACHINE => $this->department_lane->relay_machine_id->value(),