Flow
My chore delete, before and after
1One id per delete
The browser sends one request with the id in the web address.
2Text arrives
Anything in the address reaches the server as text.
3Strict compare
A number never equals text, so every chore was kept.
4Same reply
The server said all went fine either way.
5Convert on arrival
Now the id becomes a number, or the request is refused.
6Still loose
Decimals and a zero id slip through, and the reply has no count yet.
Deleting a chore in my scheduling app didn't stick. The row went away, a success message showed up, and when the list loaded again, the chore was back.
The app is small. It has a schedule, a chore list and a print view. The chores live in one JSON file on the server, and a short PHP script reads and rewrites it.
One request per delete, and the id became text
That day I'd changed the delete. The browser used to send back the whole list. Now it sends one request with the chore's id in the web address. That's better. I'd guess it's also what showed the bug, because anything in a web address arrives as text.
I'd bet the file stores the id as a number. The server compared that number to the text with a strict check, which also checks type:
42 !== "42" // true, so the row is kept
So every chore was kept. The server wrote the same list back and said everything went fine.
Why every layer reported success
The server's answer never changed, whatever it removed. The browser didn't read the answer anyway. It dropped the row and showed its message. Only the file knew, and it only told me on the next load.
Converting at the door
Now the server turns the id into a number as soon as it arrives. If it can't, it refuses the request before touching the file. It turns the stored ids into numbers too, so both sides match.
The numeric check is more generous than I'd like
The check lets odd values through, like decimals, and turns them into some real chore's number. A chore saved with no id counts as zero, so a request for zero would delete all of those. I'd rather accept plain digits only.
The other hard-coded id
The browser had been spotting one special chore by its id. Now it checks a type field. The print view uses the same rule.
Still missing: a test and a count
There's no test yet, and the server still doesn't say how many chores it removed. The next change I want is small: the browser reads the answer before it shows the message.