fix: review findings from full-diff audit (7 fixed)
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
- popularSearches sent translated display text as the actual search query instead of the canonical term - useSuggestion() now prefers target.query.q when present. - CartService.addItem() dedup guard resolved immediately instead of awaiting the real in-flight add; now tracks the pending Promise per itemID so concurrent callers await the actual result. - addItem()'s Promise never rejected on failure (resolve() in both next/error branches) - now rejects on error; buyNow() catches and shows an error toast instead of navigating on a failed add. - Quick View had no stale-response guard - a slower earlier request could overwrite a faster later one. Added a request-generation counter. - cart autoSubmitPurchase() set paymentStatus to null synchronously right after firing the async submit call, blanking the success screen while the request was still in flight. Removed the redundant/harmful line. - Order terminal-status guard (cancelled/refunded can't be reopened) lived only in the page component. Moved enforcement into the gateway (single write path) via a shared TERMINAL_ORDER_STATUSES const, so no future caller can bypass it. - TranslatePipe's per-instance memoization cache had no eviction, so bindings with volatile params (pagination counts) grew it unbounded for the component's lifetime. Capped at 50 entries. Not changed: the dark-mode color override was flagged as clobbering admin branding, but it's the exact palette explicitly requested this session for the global dark default - not a bug. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ export class CartService {
|
||||
private readonly STORAGE_KEY = 'marketplace_cart';
|
||||
private cartItems = signal<CartItem[]>([]);
|
||||
private isTelegram = typeof window !== 'undefined' && !!window.Telegram?.WebApp;
|
||||
private addingItems = new Set<number>();
|
||||
private addingItems = new Map<number, Promise<void>>();
|
||||
private initialized = false;
|
||||
|
||||
items = this.cartItems.asReadonly();
|
||||
@@ -211,8 +211,11 @@ export class CartService {
|
||||
* synchronously.
|
||||
*/
|
||||
addItem(itemID: number, quantity: number = 1, variant?: CartVariant): Promise<void> {
|
||||
// Prevent duplicate API calls for same item
|
||||
if (this.addingItems.has(itemID)) return Promise.resolve();
|
||||
// A concurrent call for the same not-yet-in-cart item awaits the same
|
||||
// in-flight promise instead of resolving immediately - otherwise a
|
||||
// rapid double-click could see the item "added" before it actually is.
|
||||
const pending = this.addingItems.get(itemID);
|
||||
if (pending) return pending;
|
||||
|
||||
const currentItems = this.cartItems();
|
||||
const existingItem = currentItems.find(i => this.isSameCartLine(i, itemID, variant));
|
||||
@@ -224,9 +227,8 @@ export class CartService {
|
||||
}
|
||||
|
||||
// Get item details from API and add to cart
|
||||
this.addingItems.add(itemID);
|
||||
return import('./api.service').then(({ ApiService }) =>
|
||||
new Promise<void>((resolve) => {
|
||||
const promise = import('./api.service').then(({ ApiService }) =>
|
||||
new Promise<void>((resolve, reject) => {
|
||||
this.injector.get(ApiService).getItem(itemID).subscribe({
|
||||
next: (item) => {
|
||||
const cartItem = this.normalizeCartItem({
|
||||
@@ -244,14 +246,18 @@ export class CartService {
|
||||
error: (err) => {
|
||||
console.error('Error adding to cart:', err);
|
||||
this.addingItems.delete(itemID);
|
||||
resolve();
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
})
|
||||
).catch((err) => {
|
||||
console.error('Error loading API service:', err);
|
||||
this.addingItems.delete(itemID);
|
||||
throw err;
|
||||
});
|
||||
|
||||
this.addingItems.set(itemID, promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
updateQuantity(itemID: number, quantity: number, variant?: CartVariant): void {
|
||||
|
||||
Reference in New Issue
Block a user