A shared shopping list, optimistic end to end - #10
Merged
Conversation
Chores and groceries are the two things every shared household actually coordinates. Flatastic wins flatshares by bundling them, and keeping them in one app is what stops the list drifting back into a group chat where nothing can be ticked off. Every interaction is optimistic. This screen gets used one-handed while pushing a trolley, on whatever signal a supermarket has, and a tick that waits for a round trip before it moves feels broken - people tap again, and then they stop trusting it. React reconciles against the server when the answer lands. Ticking moves an item to the trolley rather than deleting it: mid-shop, 'what have I already picked up' is the question the list is really being asked. Unticking clears the buyer as well as the timestamp, or the row would claim someone bought something that is back on the list. Who added an item and who bought it are tracked separately, because they are usually different people. Bought items older than a week prune themselves on read. Without that the list grows forever, and nobody is ever going to press 'clear' as a task in its own right. Also fixes a CSS regression from the design pass: a bulk token rename had turned accent-[var(--accent)] into [var(--brand)], which is not a class at all, silently stripping the accent colour from the effort slider and every checkbox. 11 integration tests against a real database, including that one household can neither read, tick, remove nor clear another household's list. 142 tests total, lint and typecheck clean, all routes verified 200 against the running server.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chores and groceries are the two things every shared household actually coordinates. The research was clear that this is how Flatastic wins flatshares, and keeping both in one app is what stops the list drifting back into a group chat where nothing can be ticked off.
Optimistic everywhere
This screen gets used one-handed, pushing a trolley, on whatever signal a supermarket has. A tick that waits for a round trip before it moves feels broken — people tap again, and then they stop trusting the list. So adding, ticking, unticking, removing and clearing all apply instantly via
useOptimistic, and React reconciles against the server's answer when it lands.Decisions worth reviewing
Ticking moves an item to the trolley rather than deleting it. Mid-shop, "what have I already picked up" is the question the list is really being asked. It only disappears when someone clears it, or after a week.
Unticking clears the buyer as well as the timestamp. Otherwise the row quietly claims Ben bought something that is sitting back on the list. There's a test for exactly this.
Who added an item and who bought it are tracked separately, because they're usually different people — the same reasoning as
completed_byvsassigneeon chores.Bought items older than a week prune themselves on read. Without it the list grows forever, and nobody is ever going to press "clear" as a chore in its own right.
An empty submit is silently ignored rather than raising an error. That's someone hitting enter on a blank field, not a mistake worth interrupting them for.
A regression this caught
The bulk token rename in the design PR had rewritten
accent-[var(--accent)]into[var(--brand)]— which isn't a class at all. That silently stripped the accent colour from the effort slider and every checkbox in the app. Fixed here.Testing
11 new integration tests against a real database, including a full isolation suite proving one household can neither read, tick, remove, nor clear another household's list — the same standard the chores service is held to.
142 tests total. Lint, typecheck and build clean, and every route verified 200 against the running server.