@mohasinac/appkit 4.40.0 → 4.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -381,7 +381,7 @@ export class CategoriesRepository extends BaseRepository {
|
|
|
381
381
|
.update({ isLeaf: true, updatedAt: new Date() });
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
|
-
await this.rewriteProductChains(rebuilt);
|
|
384
|
+
await this.rewriteProductChains(rebuilt, categoryId);
|
|
385
385
|
return writes.map((w) => w.id);
|
|
386
386
|
}
|
|
387
387
|
/**
|
|
@@ -405,11 +405,33 @@ export class CategoriesRepository extends BaseRepository {
|
|
|
405
405
|
* no repository in this codebase imports another feature's, because that is
|
|
406
406
|
* the import chain that drags firebase-admin into a client bundle.
|
|
407
407
|
*/
|
|
408
|
-
async rewriteProductChains(rebuilt) {
|
|
408
|
+
async rewriteProductChains(rebuilt, movedId) {
|
|
409
|
+
/*
|
|
410
|
+
* ONE query for the whole subtree, matched on `categorySlugs` — NOT N queries
|
|
411
|
+
* on the scalar `category`.
|
|
412
|
+
*
|
|
413
|
+
* 🛑 MEASURED 2026-09-14: `category` is unset on all 95 production products.
|
|
414
|
+
* It is written by deriveTaxonomy, but every product here came from the seed,
|
|
415
|
+
* which hand-writes `categorySlugs` only — so a `where("category","==",id)`
|
|
416
|
+
* query matched nothing and this rewrite silently did nothing at all. The
|
|
417
|
+
* array field is the one that actually exists, and matching the MOVED node
|
|
418
|
+
* gets the entire subtree in a single read because `categorySlugs` holds the
|
|
419
|
+
* full ancestor chain.
|
|
420
|
+
*/
|
|
421
|
+
const snap = await this.db
|
|
422
|
+
.collection("products")
|
|
423
|
+
.where(PRODUCT_FIELDS.CATEGORY_SLUGS, "array-contains", movedId)
|
|
424
|
+
.get();
|
|
409
425
|
const writes = [];
|
|
410
|
-
for (const
|
|
426
|
+
for (const doc of snap.docs) {
|
|
427
|
+
const current = doc.data().categorySlugs ?? [];
|
|
428
|
+
const leaf = current[0];
|
|
429
|
+
const cat = leaf ? rebuilt.get(leaf) : undefined;
|
|
430
|
+
// A product whose leaf is outside the moved subtree has nothing to re-derive.
|
|
431
|
+
if (!leaf || !cat)
|
|
432
|
+
continue;
|
|
411
433
|
// Self first, root last — byte-identical to what deriveTaxonomy produces.
|
|
412
|
-
const chain = [
|
|
434
|
+
const chain = [leaf, ...(cat.parentIds ?? []).slice().reverse()];
|
|
413
435
|
/*
|
|
414
436
|
* Byte-identical to what deriveTaxonomy produces, INCLUDING the falsy
|
|
415
437
|
* filter — these two must agree, or a product's names chain would differ
|
|
@@ -420,16 +442,12 @@ export class CategoriesRepository extends BaseRepository {
|
|
|
420
442
|
cat.name,
|
|
421
443
|
...(cat.ancestors ?? []).map((a) => a?.name).reverse(),
|
|
422
444
|
].filter((n) => !!n);
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
id: doc.id,
|
|
430
|
-
data: { categorySlugs: chain, categoryNames: names, updatedAt: new Date() },
|
|
431
|
-
});
|
|
432
|
-
}
|
|
445
|
+
if (chain.join(">") === current.join(">"))
|
|
446
|
+
continue; // nothing moved for this row
|
|
447
|
+
writes.push({
|
|
448
|
+
id: doc.id,
|
|
449
|
+
data: { categorySlugs: chain, categoryNames: names, updatedAt: new Date() },
|
|
450
|
+
});
|
|
433
451
|
}
|
|
434
452
|
if (!writes.length)
|
|
435
453
|
return;
|