{
  "filename": "src/Controller/CancelOrderController.php",
  "rule": "- name: order-voter-before-mutation\n  where: \"src/Controller/CancelOrderController.php\"\n  ensure: >-\n    CancelOrderController must call denyAccessUnlessGranted with ORDER_CANCEL and the loaded order before changing or flushing its status.",
  "corrected": "<?php\nnamespace App\\Controller;\nuse App\\Entity\\Order;\nuse Doctrine\\ORM\\EntityManagerInterface;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\n\nclass CancelOrderController extends AbstractController {\n    public function __invoke(Order $order, EntityManagerInterface $manager): JsonResponse {\n        $this->denyAccessUnlessGranted('ORDER_CANCEL', $order);\n        if ($order->getStatus() !== 'pending') throw new \\RuntimeException('Not pending');\n        $order->setStatus('cancelled');\n        $manager->flush();\n        return new JsonResponse(['status' => 'cancelled']);\n    }\n}\n",
  "broken": "<?php\nnamespace App\\Controller;\nuse App\\Entity\\Order;\nuse Doctrine\\ORM\\EntityManagerInterface;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse;\n\nclass CancelOrderController extends AbstractController {\n    public function __invoke(Order $order, EntityManagerInterface $manager): JsonResponse {\n        if ($order->getStatus() !== 'pending') throw new \\RuntimeException('Not pending');\n        $order->setStatus('cancelled');\n        $manager->flush();\n        return new JsonResponse(['status' => 'cancelled']);\n    }\n}\n",
  "regression": [
    "        $this->denyAccessUnlessGranted('ORDER_CANCEL', $order);\n",
    ""
  ],
  "test_scenarios": [
    [
      "Owner in tenant",
      "Voter permits before flush"
    ],
    [
      "Signed-in user in another tenant",
      "Access denied, no setter or flush"
    ],
    [
      "Permission denied",
      "No state change"
    ],
    [
      "Shipped order",
      "State guard rejects after authorization"
    ]
  ],
  "test_source": null,
  "test_command": "php bin/phpunit tests/Controller/CancelOrderControllerTest.php"
}