fix(market): re-link stallName when stall arrives after product
Subscription delivers stall (kind 30017) and product (kind 30018) events without ordering guarantees. handleProductEvent and loadProducts looked up stall name once at product-ingest time and froze "Unknown Stall" on the product object when the stall hadn't arrived yet — even when the stall landed milliseconds later. Two-sided fix in the Pinia store: - addStall: after upserting a stall, sweep products and re-stamp stallName for any matching stall_id (handles product-arrives-first race + downstream stall name updates). - addProduct: do the lookup itself instead of trusting the caller's stallName field (handles stall-arrives-first race + paranoia). Both paths converge on the live stalls collection, so eventual consistency is guaranteed regardless of event order. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b55792ee90
commit
eb3393f1b8
1 changed files with 21 additions and 4 deletions
|
|
@ -239,14 +239,23 @@ export const useMarketStore = defineStore('market', () => {
|
|||
}
|
||||
|
||||
const addProduct = (product: Product) => {
|
||||
const existingIndex = products.value.findIndex(p => p.id === product.id)
|
||||
// Lookup stallName from the current stall set — the value passed in by
|
||||
// the caller can be stale ("Unknown Stall") if the stall event hadn't
|
||||
// arrived yet. The reverse race (stall arrives first) is handled in
|
||||
// addStall below.
|
||||
const matchedStall = stalls.value.find(s => s.id === product.stall_id)
|
||||
const enriched: Product = matchedStall
|
||||
? { ...product, stallName: matchedStall.name }
|
||||
: product
|
||||
|
||||
const existingIndex = products.value.findIndex(p => p.id === enriched.id)
|
||||
if (existingIndex >= 0) {
|
||||
products.value[existingIndex] = product
|
||||
products.value[existingIndex] = enriched
|
||||
} else {
|
||||
products.value.push(product)
|
||||
products.value.push(enriched)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const addStall = (stall: Stall) => {
|
||||
const existingIndex = stalls.value.findIndex(s => s.id === stall.id)
|
||||
if (existingIndex >= 0) {
|
||||
|
|
@ -254,6 +263,14 @@ export const useMarketStore = defineStore('market', () => {
|
|||
} else {
|
||||
stalls.value.push(stall)
|
||||
}
|
||||
// Re-stamp stallName on any products that arrived before this stall did
|
||||
// (or whose stall name has changed). Direct property mutation on items
|
||||
// in a reactive array triggers Vue's deep reactivity.
|
||||
products.value.forEach(p => {
|
||||
if (p.stall_id === stall.id && p.stallName !== stall.name) {
|
||||
p.stallName = stall.name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const addMarket = (market: Market) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue