In the PromotionService class, inside the claim() method, you are throwing a RuntimeException, not sure why... While the RuntimeException works, a custom exception provides much clearer and more specific context about why the claim failed, which is beneficial for code maintainability, debugging, and handling the error in the calling code. Use a custom exception like
throw new PromotionAlreadyClaimedException('This promotion has already been claimed');
Lastly, I noticed that you aren't using a 201 status code for the createPromotion() method for the BoPromotionContrller, for some reason when you do in other Controllers