BacklogBreak-proofing
How sir might try to break the app (and the easy fixes)
Sir said he will be attempting to break it. These are the classic ways demo apps die, and every one of them is cheap to fix. Worth turning into Pest tests as you go.
1. He types letters into a number box
“abc” in the watts field. If the app is lucky it throws a validation error, if not it 500s. Fix: validate every numeric field server side and show a friendly message like “Enter a number”. Never let a raw Laravel error page render.
2. He types zero or a negative number
0 watts, minus 3 hours, 0 panels. Zero hours should give 0 usage, not a crash. Negative anything should be rejected. Fix: validation rules with sensible ranges (watts above 0, hours 0 to 24, quantity at least 1).
3. He types a ridiculous number
999,999,999 watts makes totals explode and layouts overflow. Fix: sensible maximums, and format big numbers with thousand separators so the page stays readable.
4. He types numbers the weird way
“1,5” with a comma, or pastes “150 W” with the unit. Fix: clean the input before validating, accept plain numbers only, say so in the error.
5. He adds a thousand items
A list with 1,000 rows loads forever and the page chokes. Fix: paginate the list (or at least chunk it) and make sure the queries are indexed. Never load an entire table to show one screen.
6. He types fast in a search box
One database query per keystroke is a great way to look slow. Fix: debounce, about 300 milliseconds after the last keystroke before searching.
7. He clicks Save twice, fast
Two identical records, or a double referral. Fix: disable the button while the request is in flight, and add a server side guard so a double submit cannot create two rows.
8. He types strange characters
A name of “<script>alert(1)</script>”, an emoji, or 500 characters long. Fix: Blade escapes output by default, so never use the raw {!! !!} syntax on anything a user typed. Limit field lengths and check that a really long name does not wreck the layout.
9. He submits a form with nothing in it
Empty equipment list into the calculator, blank required fields. Fix: friendly validation on every form, and friendly empty states everywhere. Never divide by zero.
10. He makes the savings come out to zero
No bill entered or identical before and after bills means payback = cost / 0, which is infinity or a crash depending on your luck. Fix: check before dividing. If savings are zero or negative, show “solar would not pay for itself with these numbers” instead of a broken page.
11. He guesses someone else's URL
/equipment/7 while logged in as a different customer. Fix: ownership checks (policies) on every record. He should get a 403, never someone else's data.
12. He lets the login expire mid form
Fills in 20 items, session dies, hits save. Fix: the redirect to login should carry a clear message, and ideally the form data survives so he does not have to retype everything.
13. He hits back after submitting and submits again
Classic duplicate record maker. Fix: use the POST then redirect then GET pattern so a refresh or back never resubmits the form.
14. The money math looks like a computer's
0.1 + 0.2 = 0.30000000000000004, and bills showing $133.333333333 destroy trust. Fix: do money math carefully (integer cents or controlled rounding), and always display money rounded to 2 decimal places.
15. He opens the same record in two tabs and edits both
Last save silently wins and someone's edit vanishes. Fix: at minimum, never crash. The nice version: check updated_at before saving and warn that the record changed.
16. He clones the project fresh and it does not run
Missing seed data means no demo. Fix: migrations and seeders so php artisan migrate --seed always produces a working demo with the sample shop data. This is also what makes all six teams test against the same numbers.