diff --git a/README.md b/README.md index 9f0cc17..0f44406 100644 --- a/README.md +++ b/README.md @@ -2124,9 +2124,11 @@ weiter, du musst dich um nichts mehr kümmern."* New **Bumped `@einfach-produktiv/invoicing` to 0.2.8** — fixes a font-path bug that broke every invoice/correction-invoice PDF render *inside the -Payload backend* specifically (this frontend's own renders were -unaffected). See that package's own README for the Turbopack -asset-hashing root cause. +Payload backend* specifically. See that package's own README for the +Turbopack asset-hashing root cause. (This turned out to be an +incomplete picture — see "Cart bugs" below: 0.2.8 itself broke this +frontend's own client bundle, just not in a way anyone noticed yet at +the time this was written.) ## Order list mobile grid (2026-07-30) @@ -2168,6 +2170,44 @@ Went through several rounds of visual feedback: still applies); `self-start` keeps the badge background only as wide as its label. +## Cart bugs (2026-07-30) + +Two independent bugs, both reported together as "cart count keeps going up +after every logout/login, and `/cart` won't open": + +**1. Quantities doubled on every logout/login cycle.** `LogoutButton.tsx` +never cleared the local cart (`ep_cart` in `localStorage`), and +`mergeServerCartIntoLocal()` (`lib/cart.ts`, called after every login) adds +the server-side cart's quantities into the existing local ones +(`existing.qty += qty`) rather than replacing them — correct behavior for +folding in genuine guest-cart additions, wrong once `CartSync.tsx` has +already mirrored the local cart to the server. Since both sides held the +same quantities at logout time, every login added them together, doubling +the total each cycle. Fixed by clearing the local cart on logout — the next +login's merge then starts from empty (or only genuinely new guest-session +items) instead of re-adding already-synced quantities. `readCart()`/ +`getCart()` also gained an `Array.isArray()` check after `JSON.parse` +(previously only guarded against parse *syntax* errors, not the parsed +value being some other shape) as a general defensive hardening, though this +turned out not to be the `/cart` crash's actual cause — see below. + +**2. `/cart` couldn't open: `@einfach-produktiv/invoicing`'s `fonts.ts` +crashed the client bundle.** Unrelated to bug 1 — this frontend's own +`CartContent.tsx` imports `computeTaxBreakdown` from +`@einfach-produktiv/invoicing`'s barrel `index.ts`, which also re-exports +`invoicePdf.tsx`, which imports `fonts.ts`. The same-day v0.2.8 fix in that +package (see the entry above) made `fonts.ts` call `fileURLToPath` at +module scope unconditionally — fine in Node.js, but `node:url`'s +`fileURLToPath` isn't a real function in a browser bundle's polyfilled +shim, so **every** client bundle that transitively reached this module +crashed on module evaluation (`Uncaught TypeError: fileURLToPath is not a +function`), including `/cart`'s entire client-rendered page. Fixed +upstream in `@einfach-produktiv/invoicing` 0.2.9 (see that package's own +README) by branching on `typeof window === "undefined"` — browser keeps +the original `new URL(..., import.meta.url)` idiom, Node.js keeps the +`fileURLToPath` resolution. Re-ran `npm install @einfach-produktiv/invoicing` +here to pick it up. + ## Deployment - **Dockerfile**: 3-stage build (`deps` → `builder` → `runner`) with diff --git a/package-lock.json b/package-lock.json index b3def8b..197311d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -455,8 +455,8 @@ } }, "node_modules/@einfach-produktiv/invoicing": { - "version": "0.2.8", - "resolved": "git+https://git.mk360.de/Marco/einfach-produktiv-invoicing.git#ed96d36b54ba529a9ce4bf4a8ee94fd4c2a50d90", + "version": "0.2.9", + "resolved": "git+https://git.mk360.de/Marco/einfach-produktiv-invoicing.git#87cf1db330e6a415fbcd31b83c6c4470a73b07a9", "dependencies": { "@e-invoice-eu/core": "^3.1.1" },