@blackcode_sa/metaestetics-api 1.12.41 → 1.12.42
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.
- package/dist/admin/index.d.mts +4 -4
- package/dist/admin/index.d.ts +4 -4
- package/dist/backoffice/index.d.mts +12 -7
- package/dist/backoffice/index.d.ts +12 -7
- package/dist/backoffice/index.js +52 -8
- package/dist/backoffice/index.mjs +52 -8
- package/dist/index.d.mts +12 -7
- package/dist/index.d.ts +12 -7
- package/dist/index.js +52 -8
- package/dist/index.mjs +52 -8
- package/package.json +1 -1
- package/src/backoffice/services/product.service.ts +13 -10
- package/src/backoffice/services/technology.service.ts +58 -0
- package/src/backoffice/types/product.types.ts +7 -6
package/dist/admin/index.d.mts
CHANGED
|
@@ -482,13 +482,13 @@ interface Product {
|
|
|
482
482
|
composition?: string;
|
|
483
483
|
indications?: string[];
|
|
484
484
|
contraindications?: ContraindicationDynamic[];
|
|
485
|
-
/**
|
|
485
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
486
486
|
technologyId?: string;
|
|
487
|
-
/**
|
|
487
|
+
/** Present only in subcollections - synced from technology name */
|
|
488
488
|
technologyName?: string;
|
|
489
|
-
/**
|
|
489
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
490
490
|
categoryId?: string;
|
|
491
|
-
/**
|
|
491
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
492
492
|
subcategoryId?: string;
|
|
493
493
|
}
|
|
494
494
|
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -482,13 +482,13 @@ interface Product {
|
|
|
482
482
|
composition?: string;
|
|
483
483
|
indications?: string[];
|
|
484
484
|
contraindications?: ContraindicationDynamic[];
|
|
485
|
-
/**
|
|
485
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
486
486
|
technologyId?: string;
|
|
487
|
-
/**
|
|
487
|
+
/** Present only in subcollections - synced from technology name */
|
|
488
488
|
technologyName?: string;
|
|
489
|
-
/**
|
|
489
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
490
490
|
categoryId?: string;
|
|
491
|
-
/**
|
|
491
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
492
492
|
subcategoryId?: string;
|
|
493
493
|
}
|
|
494
494
|
|
|
@@ -611,13 +611,13 @@ interface Product {
|
|
|
611
611
|
composition?: string;
|
|
612
612
|
indications?: string[];
|
|
613
613
|
contraindications?: ContraindicationDynamic[];
|
|
614
|
-
/**
|
|
614
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
615
615
|
technologyId?: string;
|
|
616
|
-
/**
|
|
616
|
+
/** Present only in subcollections - synced from technology name */
|
|
617
617
|
technologyName?: string;
|
|
618
|
-
/**
|
|
618
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
619
619
|
categoryId?: string;
|
|
620
|
-
/**
|
|
620
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
621
621
|
subcategoryId?: string;
|
|
622
622
|
}
|
|
623
623
|
/**
|
|
@@ -1585,9 +1585,8 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1585
1585
|
technologyId?: string;
|
|
1586
1586
|
}): Promise<number>;
|
|
1587
1587
|
/**
|
|
1588
|
-
* Gets counts of active products grouped by technology.
|
|
1589
|
-
*
|
|
1590
|
-
* Categories/subcategories not available in top-level structure.
|
|
1588
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1589
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1591
1590
|
*/
|
|
1592
1591
|
getProductCounts(): Promise<{
|
|
1593
1592
|
byCategory: Record<string, number>;
|
|
@@ -2171,6 +2170,12 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2171
2170
|
totalAssigned: number;
|
|
2172
2171
|
byBrand: Record<string, number>;
|
|
2173
2172
|
}>;
|
|
2173
|
+
/**
|
|
2174
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2175
|
+
* @param technologyId - ID of the technology
|
|
2176
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2177
|
+
*/
|
|
2178
|
+
private updateProductsInSubcollection;
|
|
2174
2179
|
}
|
|
2175
2180
|
|
|
2176
2181
|
/**
|
|
@@ -611,13 +611,13 @@ interface Product {
|
|
|
611
611
|
composition?: string;
|
|
612
612
|
indications?: string[];
|
|
613
613
|
contraindications?: ContraindicationDynamic[];
|
|
614
|
-
/**
|
|
614
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
615
615
|
technologyId?: string;
|
|
616
|
-
/**
|
|
616
|
+
/** Present only in subcollections - synced from technology name */
|
|
617
617
|
technologyName?: string;
|
|
618
|
-
/**
|
|
618
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
619
619
|
categoryId?: string;
|
|
620
|
-
/**
|
|
620
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
621
621
|
subcategoryId?: string;
|
|
622
622
|
}
|
|
623
623
|
/**
|
|
@@ -1585,9 +1585,8 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1585
1585
|
technologyId?: string;
|
|
1586
1586
|
}): Promise<number>;
|
|
1587
1587
|
/**
|
|
1588
|
-
* Gets counts of active products grouped by technology.
|
|
1589
|
-
*
|
|
1590
|
-
* Categories/subcategories not available in top-level structure.
|
|
1588
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1589
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1591
1590
|
*/
|
|
1592
1591
|
getProductCounts(): Promise<{
|
|
1593
1592
|
byCategory: Record<string, number>;
|
|
@@ -2171,6 +2170,12 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2171
2170
|
totalAssigned: number;
|
|
2172
2171
|
byBrand: Record<string, number>;
|
|
2173
2172
|
}>;
|
|
2173
|
+
/**
|
|
2174
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2175
|
+
* @param technologyId - ID of the technology
|
|
2176
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2177
|
+
*/
|
|
2178
|
+
private updateProductsInSubcollection;
|
|
2174
2179
|
}
|
|
2175
2180
|
|
|
2176
2181
|
/**
|
package/dist/backoffice/index.js
CHANGED
|
@@ -1275,9 +1275,8 @@ var ProductService = class extends BaseService {
|
|
|
1275
1275
|
return snapshot.data().count;
|
|
1276
1276
|
}
|
|
1277
1277
|
/**
|
|
1278
|
-
* Gets counts of active products grouped by technology.
|
|
1279
|
-
*
|
|
1280
|
-
* Categories/subcategories not available in top-level structure.
|
|
1278
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1279
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1281
1280
|
*/
|
|
1282
1281
|
async getProductCounts() {
|
|
1283
1282
|
const counts = {
|
|
@@ -1285,14 +1284,18 @@ var ProductService = class extends BaseService {
|
|
|
1285
1284
|
bySubcategory: {},
|
|
1286
1285
|
byTechnology: {}
|
|
1287
1286
|
};
|
|
1288
|
-
const q = (0, import_firestore8.query)(this.
|
|
1287
|
+
const q = (0, import_firestore8.query)((0, import_firestore8.collectionGroup)(this.db, PRODUCTS_COLLECTION), (0, import_firestore8.where)("isActive", "==", true));
|
|
1289
1288
|
const snapshot = await (0, import_firestore8.getDocs)(q);
|
|
1290
1289
|
snapshot.docs.forEach((doc11) => {
|
|
1291
1290
|
const product = doc11.data();
|
|
1292
|
-
if (product.
|
|
1293
|
-
product.
|
|
1294
|
-
|
|
1295
|
-
|
|
1291
|
+
if (product.categoryId) {
|
|
1292
|
+
counts.byCategory[product.categoryId] = (counts.byCategory[product.categoryId] || 0) + 1;
|
|
1293
|
+
}
|
|
1294
|
+
if (product.subcategoryId) {
|
|
1295
|
+
counts.bySubcategory[product.subcategoryId] = (counts.bySubcategory[product.subcategoryId] || 0) + 1;
|
|
1296
|
+
}
|
|
1297
|
+
if (product.technologyId) {
|
|
1298
|
+
counts.byTechnology[product.technologyId] = (counts.byTechnology[product.technologyId] || 0) + 1;
|
|
1296
1299
|
}
|
|
1297
1300
|
});
|
|
1298
1301
|
return counts;
|
|
@@ -2066,7 +2069,18 @@ var TechnologyService = class extends BaseService {
|
|
|
2066
2069
|
});
|
|
2067
2070
|
updateData.updatedAt = /* @__PURE__ */ new Date();
|
|
2068
2071
|
const docRef = (0, import_firestore11.doc)(this.technologiesRef, id);
|
|
2072
|
+
const beforeTech = await this.getById(id);
|
|
2069
2073
|
await (0, import_firestore11.updateDoc)(docRef, updateData);
|
|
2074
|
+
const categoryChanged = beforeTech && updateData.categoryId && beforeTech.categoryId !== updateData.categoryId;
|
|
2075
|
+
const subcategoryChanged = beforeTech && updateData.subcategoryId && beforeTech.subcategoryId !== updateData.subcategoryId;
|
|
2076
|
+
const nameChanged = beforeTech && updateData.name && beforeTech.name !== updateData.name;
|
|
2077
|
+
if (categoryChanged || subcategoryChanged || nameChanged) {
|
|
2078
|
+
await this.updateProductsInSubcollection(id, {
|
|
2079
|
+
categoryId: updateData.categoryId,
|
|
2080
|
+
subcategoryId: updateData.subcategoryId,
|
|
2081
|
+
technologyName: updateData.name
|
|
2082
|
+
});
|
|
2083
|
+
}
|
|
2070
2084
|
return this.getById(id);
|
|
2071
2085
|
}
|
|
2072
2086
|
/**
|
|
@@ -2591,6 +2605,36 @@ var TechnologyService = class extends BaseService {
|
|
|
2591
2605
|
byBrand
|
|
2592
2606
|
};
|
|
2593
2607
|
}
|
|
2608
|
+
/**
|
|
2609
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2610
|
+
* @param technologyId - ID of the technology
|
|
2611
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2612
|
+
*/
|
|
2613
|
+
async updateProductsInSubcollection(technologyId, updates) {
|
|
2614
|
+
const productsRef = (0, import_firestore11.collection)(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
2615
|
+
const productsSnapshot = await (0, import_firestore11.getDocs)(productsRef);
|
|
2616
|
+
if (productsSnapshot.empty) {
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
const batch = (0, import_firestore11.writeBatch)(this.db);
|
|
2620
|
+
for (const productDoc of productsSnapshot.docs) {
|
|
2621
|
+
const productRef = productDoc.ref;
|
|
2622
|
+
const updateFields = {};
|
|
2623
|
+
if (updates.categoryId !== void 0) {
|
|
2624
|
+
updateFields.categoryId = updates.categoryId;
|
|
2625
|
+
}
|
|
2626
|
+
if (updates.subcategoryId !== void 0) {
|
|
2627
|
+
updateFields.subcategoryId = updates.subcategoryId;
|
|
2628
|
+
}
|
|
2629
|
+
if (updates.technologyName !== void 0) {
|
|
2630
|
+
updateFields.technologyName = updates.technologyName;
|
|
2631
|
+
}
|
|
2632
|
+
if (Object.keys(updateFields).length > 0) {
|
|
2633
|
+
batch.update(productRef, updateFields);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
await batch.commit();
|
|
2637
|
+
}
|
|
2594
2638
|
};
|
|
2595
2639
|
|
|
2596
2640
|
// src/backoffice/services/constants.service.ts
|
|
@@ -1254,9 +1254,8 @@ var ProductService = class extends BaseService {
|
|
|
1254
1254
|
return snapshot.data().count;
|
|
1255
1255
|
}
|
|
1256
1256
|
/**
|
|
1257
|
-
* Gets counts of active products grouped by technology.
|
|
1258
|
-
*
|
|
1259
|
-
* Categories/subcategories not available in top-level structure.
|
|
1257
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1258
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1260
1259
|
*/
|
|
1261
1260
|
async getProductCounts() {
|
|
1262
1261
|
const counts = {
|
|
@@ -1264,14 +1263,18 @@ var ProductService = class extends BaseService {
|
|
|
1264
1263
|
bySubcategory: {},
|
|
1265
1264
|
byTechnology: {}
|
|
1266
1265
|
};
|
|
1267
|
-
const q = query6(this.
|
|
1266
|
+
const q = query6(collectionGroup(this.db, PRODUCTS_COLLECTION), where6("isActive", "==", true));
|
|
1268
1267
|
const snapshot = await getDocs6(q);
|
|
1269
1268
|
snapshot.docs.forEach((doc11) => {
|
|
1270
1269
|
const product = doc11.data();
|
|
1271
|
-
if (product.
|
|
1272
|
-
product.
|
|
1273
|
-
|
|
1274
|
-
|
|
1270
|
+
if (product.categoryId) {
|
|
1271
|
+
counts.byCategory[product.categoryId] = (counts.byCategory[product.categoryId] || 0) + 1;
|
|
1272
|
+
}
|
|
1273
|
+
if (product.subcategoryId) {
|
|
1274
|
+
counts.bySubcategory[product.subcategoryId] = (counts.bySubcategory[product.subcategoryId] || 0) + 1;
|
|
1275
|
+
}
|
|
1276
|
+
if (product.technologyId) {
|
|
1277
|
+
counts.byTechnology[product.technologyId] = (counts.byTechnology[product.technologyId] || 0) + 1;
|
|
1275
1278
|
}
|
|
1276
1279
|
});
|
|
1277
1280
|
return counts;
|
|
@@ -2085,7 +2088,18 @@ var TechnologyService = class extends BaseService {
|
|
|
2085
2088
|
});
|
|
2086
2089
|
updateData.updatedAt = /* @__PURE__ */ new Date();
|
|
2087
2090
|
const docRef = doc9(this.technologiesRef, id);
|
|
2091
|
+
const beforeTech = await this.getById(id);
|
|
2088
2092
|
await updateDoc9(docRef, updateData);
|
|
2093
|
+
const categoryChanged = beforeTech && updateData.categoryId && beforeTech.categoryId !== updateData.categoryId;
|
|
2094
|
+
const subcategoryChanged = beforeTech && updateData.subcategoryId && beforeTech.subcategoryId !== updateData.subcategoryId;
|
|
2095
|
+
const nameChanged = beforeTech && updateData.name && beforeTech.name !== updateData.name;
|
|
2096
|
+
if (categoryChanged || subcategoryChanged || nameChanged) {
|
|
2097
|
+
await this.updateProductsInSubcollection(id, {
|
|
2098
|
+
categoryId: updateData.categoryId,
|
|
2099
|
+
subcategoryId: updateData.subcategoryId,
|
|
2100
|
+
technologyName: updateData.name
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2089
2103
|
return this.getById(id);
|
|
2090
2104
|
}
|
|
2091
2105
|
/**
|
|
@@ -2610,6 +2624,36 @@ var TechnologyService = class extends BaseService {
|
|
|
2610
2624
|
byBrand
|
|
2611
2625
|
};
|
|
2612
2626
|
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2629
|
+
* @param technologyId - ID of the technology
|
|
2630
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2631
|
+
*/
|
|
2632
|
+
async updateProductsInSubcollection(technologyId, updates) {
|
|
2633
|
+
const productsRef = collection9(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
2634
|
+
const productsSnapshot = await getDocs9(productsRef);
|
|
2635
|
+
if (productsSnapshot.empty) {
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
const batch = writeBatch(this.db);
|
|
2639
|
+
for (const productDoc of productsSnapshot.docs) {
|
|
2640
|
+
const productRef = productDoc.ref;
|
|
2641
|
+
const updateFields = {};
|
|
2642
|
+
if (updates.categoryId !== void 0) {
|
|
2643
|
+
updateFields.categoryId = updates.categoryId;
|
|
2644
|
+
}
|
|
2645
|
+
if (updates.subcategoryId !== void 0) {
|
|
2646
|
+
updateFields.subcategoryId = updates.subcategoryId;
|
|
2647
|
+
}
|
|
2648
|
+
if (updates.technologyName !== void 0) {
|
|
2649
|
+
updateFields.technologyName = updates.technologyName;
|
|
2650
|
+
}
|
|
2651
|
+
if (Object.keys(updateFields).length > 0) {
|
|
2652
|
+
batch.update(productRef, updateFields);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
await batch.commit();
|
|
2656
|
+
}
|
|
2613
2657
|
};
|
|
2614
2658
|
|
|
2615
2659
|
// src/backoffice/services/constants.service.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -595,13 +595,13 @@ interface Product {
|
|
|
595
595
|
composition?: string;
|
|
596
596
|
indications?: string[];
|
|
597
597
|
contraindications?: ContraindicationDynamic[];
|
|
598
|
-
/**
|
|
598
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
599
599
|
technologyId?: string;
|
|
600
|
-
/**
|
|
600
|
+
/** Present only in subcollections - synced from technology name */
|
|
601
601
|
technologyName?: string;
|
|
602
|
-
/**
|
|
602
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
603
603
|
categoryId?: string;
|
|
604
|
-
/**
|
|
604
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
605
605
|
subcategoryId?: string;
|
|
606
606
|
}
|
|
607
607
|
/**
|
|
@@ -1597,9 +1597,8 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1597
1597
|
technologyId?: string;
|
|
1598
1598
|
}): Promise<number>;
|
|
1599
1599
|
/**
|
|
1600
|
-
* Gets counts of active products grouped by technology.
|
|
1601
|
-
*
|
|
1602
|
-
* Categories/subcategories not available in top-level structure.
|
|
1600
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1601
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1603
1602
|
*/
|
|
1604
1603
|
getProductCounts(): Promise<{
|
|
1605
1604
|
byCategory: Record<string, number>;
|
|
@@ -2404,6 +2403,12 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2404
2403
|
totalAssigned: number;
|
|
2405
2404
|
byBrand: Record<string, number>;
|
|
2406
2405
|
}>;
|
|
2406
|
+
/**
|
|
2407
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2408
|
+
* @param technologyId - ID of the technology
|
|
2409
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2410
|
+
*/
|
|
2411
|
+
private updateProductsInSubcollection;
|
|
2407
2412
|
}
|
|
2408
2413
|
|
|
2409
2414
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -595,13 +595,13 @@ interface Product {
|
|
|
595
595
|
composition?: string;
|
|
596
596
|
indications?: string[];
|
|
597
597
|
contraindications?: ContraindicationDynamic[];
|
|
598
|
-
/**
|
|
598
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
599
599
|
technologyId?: string;
|
|
600
|
-
/**
|
|
600
|
+
/** Present only in subcollections - synced from technology name */
|
|
601
601
|
technologyName?: string;
|
|
602
|
-
/**
|
|
602
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
603
603
|
categoryId?: string;
|
|
604
|
-
/**
|
|
604
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
605
605
|
subcategoryId?: string;
|
|
606
606
|
}
|
|
607
607
|
/**
|
|
@@ -1597,9 +1597,8 @@ declare class ProductService extends BaseService implements IProductService {
|
|
|
1597
1597
|
technologyId?: string;
|
|
1598
1598
|
}): Promise<number>;
|
|
1599
1599
|
/**
|
|
1600
|
-
* Gets counts of active products grouped by technology.
|
|
1601
|
-
*
|
|
1602
|
-
* Categories/subcategories not available in top-level structure.
|
|
1600
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
1601
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
1603
1602
|
*/
|
|
1604
1603
|
getProductCounts(): Promise<{
|
|
1605
1604
|
byCategory: Record<string, number>;
|
|
@@ -2404,6 +2403,12 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
|
|
|
2404
2403
|
totalAssigned: number;
|
|
2405
2404
|
byBrand: Record<string, number>;
|
|
2406
2405
|
}>;
|
|
2406
|
+
/**
|
|
2407
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
2408
|
+
* @param technologyId - ID of the technology
|
|
2409
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
2410
|
+
*/
|
|
2411
|
+
private updateProductsInSubcollection;
|
|
2407
2412
|
}
|
|
2408
2413
|
|
|
2409
2414
|
/**
|
package/dist/index.js
CHANGED
|
@@ -18813,7 +18813,18 @@ var TechnologyService = class extends BaseService {
|
|
|
18813
18813
|
});
|
|
18814
18814
|
updateData.updatedAt = /* @__PURE__ */ new Date();
|
|
18815
18815
|
const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
|
|
18816
|
+
const beforeTech = await this.getById(id);
|
|
18816
18817
|
await (0, import_firestore61.updateDoc)(docRef, updateData);
|
|
18818
|
+
const categoryChanged = beforeTech && updateData.categoryId && beforeTech.categoryId !== updateData.categoryId;
|
|
18819
|
+
const subcategoryChanged = beforeTech && updateData.subcategoryId && beforeTech.subcategoryId !== updateData.subcategoryId;
|
|
18820
|
+
const nameChanged = beforeTech && updateData.name && beforeTech.name !== updateData.name;
|
|
18821
|
+
if (categoryChanged || subcategoryChanged || nameChanged) {
|
|
18822
|
+
await this.updateProductsInSubcollection(id, {
|
|
18823
|
+
categoryId: updateData.categoryId,
|
|
18824
|
+
subcategoryId: updateData.subcategoryId,
|
|
18825
|
+
technologyName: updateData.name
|
|
18826
|
+
});
|
|
18827
|
+
}
|
|
18817
18828
|
return this.getById(id);
|
|
18818
18829
|
}
|
|
18819
18830
|
/**
|
|
@@ -19338,6 +19349,36 @@ var TechnologyService = class extends BaseService {
|
|
|
19338
19349
|
byBrand
|
|
19339
19350
|
};
|
|
19340
19351
|
}
|
|
19352
|
+
/**
|
|
19353
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
19354
|
+
* @param technologyId - ID of the technology
|
|
19355
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
19356
|
+
*/
|
|
19357
|
+
async updateProductsInSubcollection(technologyId, updates) {
|
|
19358
|
+
const productsRef = (0, import_firestore61.collection)(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
19359
|
+
const productsSnapshot = await (0, import_firestore61.getDocs)(productsRef);
|
|
19360
|
+
if (productsSnapshot.empty) {
|
|
19361
|
+
return;
|
|
19362
|
+
}
|
|
19363
|
+
const batch = (0, import_firestore61.writeBatch)(this.db);
|
|
19364
|
+
for (const productDoc of productsSnapshot.docs) {
|
|
19365
|
+
const productRef = productDoc.ref;
|
|
19366
|
+
const updateFields = {};
|
|
19367
|
+
if (updates.categoryId !== void 0) {
|
|
19368
|
+
updateFields.categoryId = updates.categoryId;
|
|
19369
|
+
}
|
|
19370
|
+
if (updates.subcategoryId !== void 0) {
|
|
19371
|
+
updateFields.subcategoryId = updates.subcategoryId;
|
|
19372
|
+
}
|
|
19373
|
+
if (updates.technologyName !== void 0) {
|
|
19374
|
+
updateFields.technologyName = updates.technologyName;
|
|
19375
|
+
}
|
|
19376
|
+
if (Object.keys(updateFields).length > 0) {
|
|
19377
|
+
batch.update(productRef, updateFields);
|
|
19378
|
+
}
|
|
19379
|
+
}
|
|
19380
|
+
await batch.commit();
|
|
19381
|
+
}
|
|
19341
19382
|
};
|
|
19342
19383
|
|
|
19343
19384
|
// src/backoffice/services/product.service.ts
|
|
@@ -19426,9 +19467,8 @@ var ProductService = class extends BaseService {
|
|
|
19426
19467
|
return snapshot.data().count;
|
|
19427
19468
|
}
|
|
19428
19469
|
/**
|
|
19429
|
-
* Gets counts of active products grouped by technology.
|
|
19430
|
-
*
|
|
19431
|
-
* Categories/subcategories not available in top-level structure.
|
|
19470
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
19471
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
19432
19472
|
*/
|
|
19433
19473
|
async getProductCounts() {
|
|
19434
19474
|
const counts = {
|
|
@@ -19436,14 +19476,18 @@ var ProductService = class extends BaseService {
|
|
|
19436
19476
|
bySubcategory: {},
|
|
19437
19477
|
byTechnology: {}
|
|
19438
19478
|
};
|
|
19439
|
-
const q = (0, import_firestore62.query)(this.
|
|
19479
|
+
const q = (0, import_firestore62.query)((0, import_firestore62.collectionGroup)(this.db, PRODUCTS_COLLECTION), (0, import_firestore62.where)("isActive", "==", true));
|
|
19440
19480
|
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19441
19481
|
snapshot.docs.forEach((doc44) => {
|
|
19442
19482
|
const product = doc44.data();
|
|
19443
|
-
if (product.
|
|
19444
|
-
product.
|
|
19445
|
-
|
|
19446
|
-
|
|
19483
|
+
if (product.categoryId) {
|
|
19484
|
+
counts.byCategory[product.categoryId] = (counts.byCategory[product.categoryId] || 0) + 1;
|
|
19485
|
+
}
|
|
19486
|
+
if (product.subcategoryId) {
|
|
19487
|
+
counts.bySubcategory[product.subcategoryId] = (counts.bySubcategory[product.subcategoryId] || 0) + 1;
|
|
19488
|
+
}
|
|
19489
|
+
if (product.technologyId) {
|
|
19490
|
+
counts.byTechnology[product.technologyId] = (counts.byTechnology[product.technologyId] || 0) + 1;
|
|
19447
19491
|
}
|
|
19448
19492
|
});
|
|
19449
19493
|
return counts;
|
package/dist/index.mjs
CHANGED
|
@@ -19128,7 +19128,18 @@ var TechnologyService = class extends BaseService {
|
|
|
19128
19128
|
});
|
|
19129
19129
|
updateData.updatedAt = /* @__PURE__ */ new Date();
|
|
19130
19130
|
const docRef = doc41(this.technologiesRef, id);
|
|
19131
|
+
const beforeTech = await this.getById(id);
|
|
19131
19132
|
await updateDoc38(docRef, updateData);
|
|
19133
|
+
const categoryChanged = beforeTech && updateData.categoryId && beforeTech.categoryId !== updateData.categoryId;
|
|
19134
|
+
const subcategoryChanged = beforeTech && updateData.subcategoryId && beforeTech.subcategoryId !== updateData.subcategoryId;
|
|
19135
|
+
const nameChanged = beforeTech && updateData.name && beforeTech.name !== updateData.name;
|
|
19136
|
+
if (categoryChanged || subcategoryChanged || nameChanged) {
|
|
19137
|
+
await this.updateProductsInSubcollection(id, {
|
|
19138
|
+
categoryId: updateData.categoryId,
|
|
19139
|
+
subcategoryId: updateData.subcategoryId,
|
|
19140
|
+
technologyName: updateData.name
|
|
19141
|
+
});
|
|
19142
|
+
}
|
|
19132
19143
|
return this.getById(id);
|
|
19133
19144
|
}
|
|
19134
19145
|
/**
|
|
@@ -19653,6 +19664,36 @@ var TechnologyService = class extends BaseService {
|
|
|
19653
19664
|
byBrand
|
|
19654
19665
|
};
|
|
19655
19666
|
}
|
|
19667
|
+
/**
|
|
19668
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
19669
|
+
* @param technologyId - ID of the technology
|
|
19670
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
19671
|
+
*/
|
|
19672
|
+
async updateProductsInSubcollection(technologyId, updates) {
|
|
19673
|
+
const productsRef = collection36(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
19674
|
+
const productsSnapshot = await getDocs36(productsRef);
|
|
19675
|
+
if (productsSnapshot.empty) {
|
|
19676
|
+
return;
|
|
19677
|
+
}
|
|
19678
|
+
const batch = writeBatch7(this.db);
|
|
19679
|
+
for (const productDoc of productsSnapshot.docs) {
|
|
19680
|
+
const productRef = productDoc.ref;
|
|
19681
|
+
const updateFields = {};
|
|
19682
|
+
if (updates.categoryId !== void 0) {
|
|
19683
|
+
updateFields.categoryId = updates.categoryId;
|
|
19684
|
+
}
|
|
19685
|
+
if (updates.subcategoryId !== void 0) {
|
|
19686
|
+
updateFields.subcategoryId = updates.subcategoryId;
|
|
19687
|
+
}
|
|
19688
|
+
if (updates.technologyName !== void 0) {
|
|
19689
|
+
updateFields.technologyName = updates.technologyName;
|
|
19690
|
+
}
|
|
19691
|
+
if (Object.keys(updateFields).length > 0) {
|
|
19692
|
+
batch.update(productRef, updateFields);
|
|
19693
|
+
}
|
|
19694
|
+
}
|
|
19695
|
+
await batch.commit();
|
|
19696
|
+
}
|
|
19656
19697
|
};
|
|
19657
19698
|
|
|
19658
19699
|
// src/backoffice/services/product.service.ts
|
|
@@ -19757,9 +19798,8 @@ var ProductService = class extends BaseService {
|
|
|
19757
19798
|
return snapshot.data().count;
|
|
19758
19799
|
}
|
|
19759
19800
|
/**
|
|
19760
|
-
* Gets counts of active products grouped by technology.
|
|
19761
|
-
*
|
|
19762
|
-
* Categories/subcategories not available in top-level structure.
|
|
19801
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
19802
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
19763
19803
|
*/
|
|
19764
19804
|
async getProductCounts() {
|
|
19765
19805
|
const counts = {
|
|
@@ -19767,14 +19807,18 @@ var ProductService = class extends BaseService {
|
|
|
19767
19807
|
bySubcategory: {},
|
|
19768
19808
|
byTechnology: {}
|
|
19769
19809
|
};
|
|
19770
|
-
const q = query37(this.
|
|
19810
|
+
const q = query37(collectionGroup3(this.db, PRODUCTS_COLLECTION), where37("isActive", "==", true));
|
|
19771
19811
|
const snapshot = await getDocs37(q);
|
|
19772
19812
|
snapshot.docs.forEach((doc44) => {
|
|
19773
19813
|
const product = doc44.data();
|
|
19774
|
-
if (product.
|
|
19775
|
-
product.
|
|
19776
|
-
|
|
19777
|
-
|
|
19814
|
+
if (product.categoryId) {
|
|
19815
|
+
counts.byCategory[product.categoryId] = (counts.byCategory[product.categoryId] || 0) + 1;
|
|
19816
|
+
}
|
|
19817
|
+
if (product.subcategoryId) {
|
|
19818
|
+
counts.bySubcategory[product.subcategoryId] = (counts.bySubcategory[product.subcategoryId] || 0) + 1;
|
|
19819
|
+
}
|
|
19820
|
+
if (product.technologyId) {
|
|
19821
|
+
counts.byTechnology[product.technologyId] = (counts.byTechnology[product.technologyId] || 0) + 1;
|
|
19778
19822
|
}
|
|
19779
19823
|
});
|
|
19780
19824
|
return counts;
|
package/package.json
CHANGED
|
@@ -134,9 +134,8 @@ export class ProductService extends BaseService implements IProductService {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
|
-
* Gets counts of active products grouped by technology.
|
|
138
|
-
*
|
|
139
|
-
* Categories/subcategories not available in top-level structure.
|
|
137
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
138
|
+
* Queries technology subcollections which have the legacy fields synced by Cloud Functions.
|
|
140
139
|
*/
|
|
141
140
|
async getProductCounts(): Promise<{
|
|
142
141
|
byCategory: Record<string, number>;
|
|
@@ -149,18 +148,22 @@ export class ProductService extends BaseService implements IProductService {
|
|
|
149
148
|
byTechnology: {} as Record<string, number>,
|
|
150
149
|
};
|
|
151
150
|
|
|
152
|
-
// Query
|
|
153
|
-
const q = query(this.
|
|
151
|
+
// Query technology subcollections (which have synced legacy fields)
|
|
152
|
+
const q = query(collectionGroup(this.db, PRODUCTS_COLLECTION), where('isActive', '==', true));
|
|
154
153
|
const snapshot = await getDocs(q);
|
|
155
154
|
|
|
156
155
|
snapshot.docs.forEach(doc => {
|
|
157
156
|
const product = doc.data() as Product;
|
|
158
157
|
|
|
159
|
-
//
|
|
160
|
-
if (product.
|
|
161
|
-
product.
|
|
162
|
-
|
|
163
|
-
|
|
158
|
+
// Use legacy fields from subcollections
|
|
159
|
+
if (product.categoryId) {
|
|
160
|
+
counts.byCategory[product.categoryId] = (counts.byCategory[product.categoryId] || 0) + 1;
|
|
161
|
+
}
|
|
162
|
+
if (product.subcategoryId) {
|
|
163
|
+
counts.bySubcategory[product.subcategoryId] = (counts.bySubcategory[product.subcategoryId] || 0) + 1;
|
|
164
|
+
}
|
|
165
|
+
if (product.technologyId) {
|
|
166
|
+
counts.byTechnology[product.technologyId] = (counts.byTechnology[product.technologyId] || 0) + 1;
|
|
164
167
|
}
|
|
165
168
|
});
|
|
166
169
|
|
|
@@ -242,7 +242,25 @@ export class TechnologyService extends BaseService implements ITechnologyService
|
|
|
242
242
|
updateData.updatedAt = new Date();
|
|
243
243
|
|
|
244
244
|
const docRef = doc(this.technologiesRef, id);
|
|
245
|
+
|
|
246
|
+
// Get the technology before update to check what changed
|
|
247
|
+
const beforeTech = await this.getById(id);
|
|
248
|
+
|
|
245
249
|
await updateDoc(docRef, updateData);
|
|
250
|
+
|
|
251
|
+
// If categoryId, subcategoryId, or name changed, update all products in subcollection
|
|
252
|
+
const categoryChanged = beforeTech && updateData.categoryId && beforeTech.categoryId !== updateData.categoryId;
|
|
253
|
+
const subcategoryChanged = beforeTech && updateData.subcategoryId && beforeTech.subcategoryId !== updateData.subcategoryId;
|
|
254
|
+
const nameChanged = beforeTech && updateData.name && beforeTech.name !== updateData.name;
|
|
255
|
+
|
|
256
|
+
if (categoryChanged || subcategoryChanged || nameChanged) {
|
|
257
|
+
await this.updateProductsInSubcollection(id, {
|
|
258
|
+
categoryId: updateData.categoryId,
|
|
259
|
+
subcategoryId: updateData.subcategoryId,
|
|
260
|
+
technologyName: updateData.name,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
246
264
|
return this.getById(id);
|
|
247
265
|
}
|
|
248
266
|
|
|
@@ -889,4 +907,44 @@ export class TechnologyService extends BaseService implements ITechnologyService
|
|
|
889
907
|
byBrand,
|
|
890
908
|
};
|
|
891
909
|
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Updates products in technology subcollection when technology metadata changes
|
|
913
|
+
* @param technologyId - ID of the technology
|
|
914
|
+
* @param updates - Fields to update (categoryId, subcategoryId, technologyName)
|
|
915
|
+
*/
|
|
916
|
+
private async updateProductsInSubcollection(
|
|
917
|
+
technologyId: string,
|
|
918
|
+
updates: { categoryId?: string; subcategoryId?: string; technologyName?: string }
|
|
919
|
+
): Promise<void> {
|
|
920
|
+
const productsRef = collection(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
|
|
921
|
+
const productsSnapshot = await getDocs(productsRef);
|
|
922
|
+
|
|
923
|
+
if (productsSnapshot.empty) {
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const batch = writeBatch(this.db);
|
|
928
|
+
|
|
929
|
+
for (const productDoc of productsSnapshot.docs) {
|
|
930
|
+
const productRef = productDoc.ref;
|
|
931
|
+
const updateFields: any = {};
|
|
932
|
+
|
|
933
|
+
if (updates.categoryId !== undefined) {
|
|
934
|
+
updateFields.categoryId = updates.categoryId;
|
|
935
|
+
}
|
|
936
|
+
if (updates.subcategoryId !== undefined) {
|
|
937
|
+
updateFields.subcategoryId = updates.subcategoryId;
|
|
938
|
+
}
|
|
939
|
+
if (updates.technologyName !== undefined) {
|
|
940
|
+
updateFields.technologyName = updates.technologyName;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
if (Object.keys(updateFields).length > 0) {
|
|
944
|
+
batch.update(productRef, updateFields);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
await batch.commit();
|
|
949
|
+
}
|
|
892
950
|
}
|
|
@@ -41,15 +41,16 @@ export interface Product {
|
|
|
41
41
|
indications?: string[];
|
|
42
42
|
contraindications?: ContraindicationDynamic[];
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
// These fields
|
|
46
|
-
|
|
44
|
+
// LEGACY FIELDS: Only present in technology subcollections (/technologies/{id}/products/)
|
|
45
|
+
// These fields are synced by Cloud Functions for backward compatibility
|
|
46
|
+
// NOT stored in top-level /products collection
|
|
47
|
+
/** Present only in subcollections - synced from technology metadata */
|
|
47
48
|
technologyId?: string;
|
|
48
|
-
/**
|
|
49
|
+
/** Present only in subcollections - synced from technology name */
|
|
49
50
|
technologyName?: string;
|
|
50
|
-
/**
|
|
51
|
+
/** Present only in subcollections - synced from technology categoryId */
|
|
51
52
|
categoryId?: string;
|
|
52
|
-
/**
|
|
53
|
+
/** Present only in subcollections - synced from technology subcategoryId */
|
|
53
54
|
subcategoryId?: string;
|
|
54
55
|
}
|
|
55
56
|
|