From a click to saved data
Follow an action through the browser, server, and database.
Why this matters
Follow one action from the screen to what lasts. That's the fastest way to see which parts of your product are real and which are only pixels. Take the foreman assigning tomorrow's shift — if you can't say where the save is checked and what survives, you don't know what you built.
What to understand
The browser can explain permissions and skip bad requests. It can never enforce access — that check lives on the server. Every protected read and save needs a server boundary; a crew name from a form field doesn't prove membership. Ask your agent: "where exactly does the server check this, and what happens if I call it directly?"
Watch for
- Permission checks that exist only in the UI — hidden actions with no server check.
- Treating "request succeeded" as "everything downstream finished" — saved is not delivered.
- Showing "Failed — try again" after a timeout that landed after a successful save.
- Retries that duplicate side effects because no safe-retry contract exists.
- Stale views after a write, with no freshness story.
Strong default
Agree on the API contract up front: what you send, what comes back, errors, access rules, and side effects. Write down paging and ordering for lists, what happens when two edits clash, and how saves may retry. Use an operation ID, a safe-retry key, or a result lookup where the stakes warrant it.
When this doesn't apply
Not every action needs conflict recovery, operation IDs, and queue progress. A simple saved message suits a low-stakes single-editor setting; "reject the stale edit or take the last save" only needs a designed answer when two foremen can actually rename tomorrow's assignment at the same time.
In practice
For an illustrative "Assign crew" flow:
- The browser collects a crew member and site, and flags bad input right away.
- The server proves who you are and checks what you're allowed to do for this crew.
- The server checks the submitted input again, whatever the browser said.
- The database saves the record while enforcing its rules.
- The server returns the final result, including its ID.
- The screen updates the right list, moves on if it should, and explains what happened.
If a notification or email follows, tell "saved" apart from "delivered." A successful request doesn't prove everything downstream finished.
| Concept | Plain-language meaning | Interface consequence |
|---|---|---|
| Database constraint | A rule the stored data cannot violate. | Duplicate prevention must survive concurrent requests. |
| Transaction | Related changes commit together or do not commit. | A partial operation should not look fully successful. |
| Authentication | Establishing who is making the request. | An expired session needs a safe return path. |
| Authorization | Deciding whether that actor may perform this operation on this resource. | A hidden action still needs a server check. |
| Cache | A reusable copy of data with a freshness policy. | Users may see stale results after a write. |
| Idempotency | Repeating the same logical operation does not repeat its effect. | A retry can be safe when the server enforces the contract. |
| Queue | Work that continues outside the current request. | Show progress and eventual outcome separately. |
If this project uses Drizzle with Postgres, the same flow has concrete homes: the schema declares the rules (a unique assignment per crew per day, foreign keys to crew and site), queries join assignments to crew names in one round trip, and your identity provider's session is what the server checks before any write. Ask your agent: "which table and constraint stops a double-booking, and where does the server check crew membership?"
Treat uncertainty as a state. Decide which drafts survive, for how long, and whether shared phones or sensitive fields change where you keep them.
Verify
Replay the happy path and a direct unauthorized request with safe test data. Check the saved result survives reload, errors keep the right input, and failures leave a trace your team can find.
Related skills
Use $flow to map the whole action before or after implementation. Continue with data fetching for freshness, forms for input, and observability for support after launch.
Last updated on