Release: shopping list overview with item previews (spec 002), race-free optimistic locking #31

Merged
araemer merged 20 commits from stage into main 2026-10-04 06:25:41 +00:00
Owner

Merges the current state of stage into main.

Included

  • Shopping list overview with item previews (spec 002) (#25): the overview returns each list's first open items and its open item count, and is ordered by the last item change. Adds a shopping_list_item_change table that records the last item change of each transaction. Includes concurrency and overview integration tests on a new database-backed integration test setup, ADRs and the implementation plan.
  • Race-free optimistic locking (#23, issue #20): optimistic-lock updates no longer race.
  • Docs: testing and locking how-tos, the DataSource naming suffix, and the architecture doc for the item change time and the overview read.

Contract

Both repos pin recipe-platform a022bd3 in contract.ref (spec 002's contract, on platform main). scripts/release.sh needs the pins to be equal, so release both repos together.

Deployment

The stage build for 5b8bd32 is green. This release adds a migration (1780012800013-CreateShoppingListItemChangeTable). Merging does not deploy: production deploys start from a v* tag on main. Deploy the backend before the app, because the app expects the new overview fields.

🤖 Generated with Claude Code

Merges the current state of `stage` into `main`. ## Included - **Shopping list overview with item previews (spec 002)** (#25): the overview returns each list's first open items and its open item count, and is ordered by the last item change. Adds a `shopping_list_item_change` table that records the last item change of each transaction. Includes concurrency and overview integration tests on a new database-backed integration test setup, ADRs and the implementation plan. - **Race-free optimistic locking** (#23, issue #20): optimistic-lock updates no longer race. - **Docs:** testing and locking how-tos, the `DataSource` naming suffix, and the architecture doc for the item change time and the overview read. ## Contract Both repos pin recipe-platform `a022bd3` in `contract.ref` (spec 002's contract, on platform `main`). `scripts/release.sh` needs the pins to be equal, so release both repos together. ## Deployment The `stage` build for 5b8bd32 is green. This release adds a migration (`1780012800013-CreateShoppingListItemChangeTable`). Merging does not deploy: production deploys start from a `v*` tag on `main`. Deploy the backend before the app, because the app expects the new overview fields. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(repositories) Make optimistic-lock updates race-free
All checks were successful
/ test (pull_request) Successful in 1m8s
bdfa3e8590
Two overlapping saves of the same entity could both pass the version check
and the later one silently overwrote the earlier one (issue #20).

- AbstractRepository.updateWithVersionCheck() locks the row with
  SELECT ... FOR UPDATE, compares the version, saves, and increments the
  root version if the save did not, so child-only edits of a recipe or
  meal plan day also move the version
- update(), updateRecipe(), updateDay() and updateShare() share that one
  implementation
- A missing version yields 400, a vanished row 404
- AbstractRepository and its subclasses take an EntityManager
- Correct the AbstractEntity JSDoc: save() never rejects a stale version

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(adr) Add shopping list overview ADRs for spec 002
Some checks failed
/ test (pull_request) Failing after 40s
5f5f9e6d1a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(plan) Add shopping list overview previews plan (spec 002)
Some checks failed
/ test (pull_request) Failing after 40s
5f5c325589
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore(contract) Pin the contract for spec 002
Some checks failed
/ test (pull_request) Failing after 41s
/ contract_pin (pull_request) Successful in 2s
8f03157eaa
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(integration) Add database-backed integration test setup
Some checks failed
/ contract_pin (pull_request) Has been cancelled
/ test (pull_request) Has been cancelled
c35966b494
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(shoppingList) Add shopping_list_item_change table
Some checks failed
/ test (pull_request) Failing after 40s
/ contract_pin (pull_request) Successful in 8s
64b559de2f
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(shoppingList) Record item changes as the last write of each transaction
Some checks failed
/ test (pull_request) Failing after 41s
/ contract_pin (pull_request) Successful in 3s
19998d4d2b
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(shoppingList) Return item previews and order the overview by last item change
All checks were successful
/ test (pull_request) Successful in 1m9s
/ contract_pin (pull_request) Successful in 2s
efca1d8354
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(shoppingList) Add concurrency and overview integration tests
Some checks failed
/ contract_pin (pull_request) Has been cancelled
/ test (pull_request) Has been cancelled
f4d33751f2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(architecture) Document the item change time and the overview read
All checks were successful
/ test (pull_request) Successful in 1m8s
/ contract_pin (pull_request) Successful in 2s
783d735114
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refactor(shoppingList) Remove the unused list repository from ShoppingListItemHandler
All checks were successful
/ test (pull_request) Successful in 1m9s
/ contract_pin (pull_request) Successful in 2s
173e8401fa
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(howto) Add testing and locking how-tos and the DataSource naming suffix
Some checks failed
/ test (pull_request) Has been cancelled
/ contract_pin (pull_request) Has been cancelled
afd6c04f18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore(coverage) Remove the coverage report committed by mistake
All checks were successful
/ test (pull_request) Successful in 1m11s
/ contract_pin (pull_request) Successful in 3s
6630bba099
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(shoppingList) Fix review findings in the tests and ignore the coverage report
All checks were successful
/ test (pull_request) Successful in 1m9s
/ contract_pin (pull_request) Successful in 2s
78cad6bf85
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(architecture) Split the table of contents, shorten the testing section and link the tracking issues
All checks were successful
/ test (pull_request) Successful in 1m9s
/ contract_pin (pull_request) Successful in 2s
367f4f944d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(shoppingList) Address PR feedback: state why the change time is not on the list row, rename previewsOfList
All checks were successful
/ test (pull_request) Successful in 1m15s
/ contract_pin (pull_request) Successful in 2s
720329e895
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewed-on: #23
Merge remote-tracking branch 'origin/stage' into 002-shopping-list-overview-previews
All checks were successful
/ test (pull_request) Successful in 1m10s
/ contract_pin (pull_request) Successful in 2s
5e6354d58a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge pull request 'feat(shoppingList) Shopping list overview with item previews (spec 002)' (#25) from 002-shopping-list-overview-previews into stage
All checks were successful
/ build (push) Successful in 1m47s
/ test (pull_request) Successful in 1m9s
/ contract_pin (pull_request) Successful in 2s
5b8bd32ef1
Reviewed-on: #25
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
araemer/recipe-backend!31
No description provided.