'closed'"), 'Default Jobcards filter must exclude closed records.'); jobcard_feature_assert(str_contains($front, "j.status = 'closed'"), 'Closed filter must explicitly select closed records.'); jobcard_feature_assert(str_contains($front, 'All clients') && str_contains($front, '$reportClient'), 'Reports must use a client-name dropdown.'); jobcard_feature_assert(str_contains($front, 'format=xls&detail=1'), 'Reports must expose detailed XLS export.'); jobcard_feature_assert(str_contains($front, "if (\$user['role_name'] === 'Technician') {") && str_contains($front, '$reportClientsStmt->execute'), 'Report client dropdown must bind parameters only on the technician prepared-query branch.'); jobcard_feature_assert(str_contains($front, '$reportClientsStmt->execute([(int)$user[\'id\']])'), 'Technician report client lookup must use a positional bound parameter.'); foreach (['Work requested', 'Technician notes / Work performed', 'Hours notes'] as $heading) jobcard_feature_assert(str_contains($front, $heading), "Detailed report must include {$heading}."); printf("Jobcard search/close/report tests: 10 passed\n");