If You are validating coupon, why pass coupon_id? Just pass a coupon struct. This way, no need to call db.
And You could pattern match on Coupon to be sure You are working with a valid struct.
validate_coupon(%Coupon{} = coupon)
This would put side effect (loading from db) outside the function, making it pure.
And if You return the updated coupon, You could chain…
coupon_id
|> load_from_db()
|> validate_coupon()
|> increase_counter()


















