Back to Feed
article 3m read

Every edit on my schedule page calls save, and the chores still never reach the file

The agent wired a save call into every handler on my staff-schedule page, but save only sends the list of people, so the separate chore list never gets stored, and the save path under it is thinner than it looks.

Article DepthPractice

Flow

Weak spots in the save path and what I'd do

  1. 1Chores never stored

    Give chores a place in the saved file, with their weekday rule, and test each kind of edit with a reload.

  2. 2Save never reports back

    Wait for each save and show a failure instead of a success message.

  3. 3Empty start after a failed load

    Block saving until the first load has worked.

  4. 4Token in the web address

    Move it out of the address so it stays out of logs and history.

Every edit on my staff-schedule page calls save, and the chore list above the table still never gets stored.

Where the schedule lived before

Before that day, the schedule was sample data inside the script. Edits lived in the browser, and a reload wiped them. The agent added a small endpoint that keeps the schedule in one file. The page loads the file when it starts and sends the whole schedule back after each edit.

Two passes over the handlers

The first pass added a save call to most edits. A second pass a few minutes later caught the rest: moving rows, adding a task to one person, and deleting a chore. After that, every edit did the same steps: change the data, redraw, save. I read both and would have said yes.

What save actually sends

Save sends one thing, the list of people. Chores sit in a separate list next to it. So when you add a chore, save runs and sends the same people as before. The chore never leaves the browser.

chores.push(text); redraw(); persist(); // persist sends people only

Every check that looks for save calls passes. You only see the gap by asking what save really sends. I haven't watched a chore vanish on reload, but that's what the code says will happen.

Auditing from the state side

Check it the other way around. Make a list of everything a user can change. Next to each item, write where it lives in the stored file. Chores are the only item with nothing next to them. One default chore only shows on some days, so storing chores has to keep that rule too. Then add a test that makes each kind of edit, reloads from the file, and checks that the change came back.

The rest of the write path

Save doesn't wait for an answer or report failures, so two fast edits can arrive in the wrong order. The server writes over the file with whatever it gets. If the first load fails, the page starts empty, and I think the next edit could save that near-empty schedule over the real one. The access token also rides in the web address, so it lands in logs.

Paper as a second reader

A print page added that day reads the stored file. It only prints people, and a bad read prints an empty table. That's annoying, but it makes the printout a fair test of what was saved.

When that day's work stopped, chores still had nowhere to go, and the page still showed a success message every time you added one.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward
Related idea

Device limit counts first and saves later, and the test never sends two at once

The licensing code I shipped checks how many devices a key already has, then inserts the new one in a separate step, so two activations racing for the last slot can both get in. The test activates devices one at a time and can't see it, a device racing itself gets a server error, and a key-only check passes for keys never bound anywhere. I found this by reading, not by running anything concurrent.

via #state-management