@blackcode_sa/metaestetics-api 1.14.32 → 1.14.36

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.
@@ -14,7 +14,6 @@ import { z } from 'zod';
14
14
  * @property manufacturer - Naziv proizvođača
15
15
  * @property description - Detaljan opis brenda i njegovih proizvoda
16
16
  * @property website - Web stranica brenda
17
- * @property category - Kategorija brenda (npr. "laser", "peeling", "injectables") - za filtriranje
18
17
  * @property isActive - Da li je brend aktivan u sistemu
19
18
  * @property createdAt - Datum kreiranja
20
19
  * @property updatedAt - Datum poslednjeg ažuriranja
@@ -29,7 +28,6 @@ interface Brand {
29
28
  isActive: boolean;
30
29
  website?: string;
31
30
  description?: string;
32
- category?: string;
33
31
  }
34
32
  /**
35
33
  * Kolekcija u Firestore bazi gde se čuvaju brendovi
@@ -67,26 +65,23 @@ declare class BrandService extends BaseService {
67
65
  isActive: boolean;
68
66
  website?: string | undefined;
69
67
  description?: string | undefined;
70
- category?: string | undefined;
71
68
  id: string;
72
69
  }>;
73
70
  /**
74
- * Gets a paginated list of active brands, optionally filtered by name and category.
71
+ * Gets a paginated list of active brands, optionally filtered by name.
75
72
  * @param rowsPerPage - The number of brands to fetch.
76
73
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
77
74
  * @param lastVisible - An optional document snapshot to use as a cursor for pagination.
78
- * @param category - An optional category to filter brands by.
79
75
  */
80
- getAll(rowsPerPage: number, searchTerm?: string, lastVisible?: any, category?: string): Promise<{
76
+ getAll(rowsPerPage: number, searchTerm?: string, lastVisible?: any): Promise<{
81
77
  brands: Brand[];
82
78
  lastVisible: _firebase_firestore.QueryDocumentSnapshot<DocumentData, DocumentData>;
83
79
  }>;
84
80
  /**
85
- * Gets the total count of active brands, optionally filtered by name and category.
81
+ * Gets the total count of active brands, optionally filtered by name.
86
82
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
87
- * @param category - An optional category to filter brands by.
88
83
  */
89
- getBrandsCount(searchTerm?: string, category?: string): Promise<number>;
84
+ getBrandsCount(searchTerm?: string): Promise<number>;
90
85
  /**
91
86
  * Gets all active brands for filter dropdowns (not paginated).
92
87
  */
@@ -632,20 +627,15 @@ interface UpdateDocumentTemplateData {
632
627
 
633
628
  /**
634
629
  * Product used in procedures
635
- * Can be consumables, equipment, or any other product needed for performing procedures
630
+ * Simplified structure with only essential fields and flexible metadata
636
631
  *
637
632
  * @property id - Unique identifier of the product
638
633
  * @property name - Name of the product
639
- * @property brandId - ID of the brand that manufactures this product
640
- * @property brandName - Name of the brand (denormalized for display)
634
+ * @property brandId - Reference to the Brand document ID
635
+ * @property brandName - Display name of the brand (denormalized for performance)
636
+ * @property description - Detailed description of the product
641
637
  * @property assignedTechnologyIds - Array of technology IDs this product is assigned to
642
- * @property description - Detailed description of the product and its purpose
643
- * @property technicalDetails - Technical details and specifications
644
- * @property warnings - List of warnings related to product use
645
- * @property dosage - Dosage information (if applicable)
646
- * @property composition - Product composition
647
- * @property indications - List of indications for use
648
- * @property contraindications - List of contraindications
638
+ * @property metadata - Flexible key-value pairs for additional product information
649
639
  * @property isActive - Whether the product is active in the system
650
640
  * @property createdAt - Creation date
651
641
  * @property updatedAt - Last update date
@@ -655,17 +645,13 @@ interface Product {
655
645
  name: string;
656
646
  brandId: string;
657
647
  brandName: string;
648
+ description: string;
649
+ category?: string;
658
650
  assignedTechnologyIds?: string[];
651
+ metadata?: Record<string, string | number | boolean>;
652
+ isActive: boolean;
659
653
  createdAt: Date;
660
654
  updatedAt: Date;
661
- isActive: boolean;
662
- description?: string;
663
- technicalDetails?: string;
664
- warnings?: string[];
665
- dosage?: string;
666
- composition?: string;
667
- indications?: string[];
668
- contraindications?: ContraindicationDynamic[];
669
655
  /** Present only in subcollections - synced from technology metadata */
670
656
  technologyId?: string;
671
657
  /** Present only in subcollections - synced from technology name */
@@ -688,11 +674,10 @@ declare const PRODUCTS_COLLECTION = "products";
688
674
  interface IProductService {
689
675
  /**
690
676
  * Creates a new product in the top-level collection
691
- * @param brandId - ID of the brand that manufactures this product
692
677
  * @param product - Product data
693
678
  * @param technologyIds - Optional array of technology IDs to assign this product to
694
679
  */
695
- createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
680
+ createTopLevel(product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
696
681
  /**
697
682
  * Gets all products from the top-level collection
698
683
  * @param options - Query options
@@ -701,6 +686,7 @@ interface IProductService {
701
686
  rowsPerPage: number;
702
687
  lastVisible?: any;
703
688
  brandId?: string;
689
+ category?: string;
704
690
  }): Promise<{
705
691
  products: Product[];
706
692
  lastVisible: any;
@@ -715,7 +701,7 @@ interface IProductService {
715
701
  * @param productId - ID of the product to update
716
702
  * @param product - Updated product data
717
703
  */
718
- updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
704
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'>>): Promise<Product | null>;
719
705
  /**
720
706
  * Deletes a product from the top-level collection (soft delete)
721
707
  * @param productId - ID of the product to delete
@@ -1754,7 +1740,7 @@ declare class ProductService extends BaseService implements IProductService {
1754
1740
  /**
1755
1741
  * Creates a new product in the top-level collection
1756
1742
  */
1757
- createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
1743
+ createTopLevel(product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
1758
1744
  /**
1759
1745
  * Gets all products from the top-level collection
1760
1746
  */
@@ -1762,6 +1748,7 @@ declare class ProductService extends BaseService implements IProductService {
1762
1748
  rowsPerPage: number;
1763
1749
  lastVisible?: any;
1764
1750
  brandId?: string;
1751
+ category?: string;
1765
1752
  }): Promise<{
1766
1753
  products: Product[];
1767
1754
  lastVisible: any;
@@ -1773,7 +1760,7 @@ declare class ProductService extends BaseService implements IProductService {
1773
1760
  /**
1774
1761
  * Updates a product in the top-level collection
1775
1762
  */
1776
- updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
1763
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt'>>): Promise<Product | null>;
1777
1764
  /**
1778
1765
  * Deletes a product from the top-level collection (soft delete)
1779
1766
  */
@@ -2074,15 +2061,15 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2074
2061
  isActive: boolean;
2075
2062
  description: string;
2076
2063
  family: ProcedureFamily;
2077
- technicalDetails?: string | undefined;
2078
- contraindications: ContraindicationDynamic[];
2079
2064
  categoryId: string;
2080
2065
  subcategoryId: string;
2066
+ technicalDetails?: string | undefined;
2081
2067
  requirements: {
2082
2068
  pre: Requirement[];
2083
2069
  post: Requirement[];
2084
2070
  };
2085
2071
  blockingConditions: BlockingCondition[];
2072
+ contraindications: ContraindicationDynamic[];
2086
2073
  benefits: TreatmentBenefitDynamic[];
2087
2074
  certificationRequirement: CertificationRequirement;
2088
2075
  documentationTemplates?: TechnologyDocumentationTemplate[] | undefined;
@@ -5240,11 +5227,6 @@ declare const technologySchema: z.ZodObject<{
5240
5227
  name: string;
5241
5228
  isActive: boolean;
5242
5229
  family: ProcedureFamily;
5243
- contraindications: {
5244
- id: string;
5245
- name: string;
5246
- description?: string | undefined;
5247
- }[];
5248
5230
  categoryId: string;
5249
5231
  subcategoryId: string;
5250
5232
  requirements: {
@@ -5274,6 +5256,11 @@ declare const technologySchema: z.ZodObject<{
5274
5256
  }[];
5275
5257
  };
5276
5258
  blockingConditions: BlockingCondition[];
5259
+ contraindications: {
5260
+ id: string;
5261
+ name: string;
5262
+ description?: string | undefined;
5263
+ }[];
5277
5264
  benefits: {
5278
5265
  id: string;
5279
5266
  name: string;
@@ -5386,14 +5373,14 @@ declare const technologySchema: z.ZodObject<{
5386
5373
  }, {
5387
5374
  name: string;
5388
5375
  family: ProcedureFamily;
5376
+ categoryId: string;
5377
+ subcategoryId: string;
5378
+ blockingConditions: BlockingCondition[];
5389
5379
  contraindications: {
5390
5380
  id: string;
5391
5381
  name: string;
5392
5382
  description?: string | undefined;
5393
5383
  }[];
5394
- categoryId: string;
5395
- subcategoryId: string;
5396
- blockingConditions: BlockingCondition[];
5397
5384
  benefits: {
5398
5385
  id: string;
5399
5386
  name: string;
@@ -6257,14 +6244,9 @@ declare const technologyUpdateSchema: z.ZodObject<{
6257
6244
  isActive?: boolean | undefined;
6258
6245
  description?: string | undefined;
6259
6246
  family?: ProcedureFamily | undefined;
6260
- technicalDetails?: string | undefined;
6261
- contraindications?: {
6262
- id: string;
6263
- name: string;
6264
- description?: string | undefined;
6265
- }[] | undefined;
6266
6247
  categoryId?: string | undefined;
6267
6248
  subcategoryId?: string | undefined;
6249
+ technicalDetails?: string | undefined;
6268
6250
  requirements?: {
6269
6251
  pre: {
6270
6252
  name: string;
@@ -6292,6 +6274,11 @@ declare const technologyUpdateSchema: z.ZodObject<{
6292
6274
  }[];
6293
6275
  } | undefined;
6294
6276
  blockingConditions?: BlockingCondition[] | undefined;
6277
+ contraindications?: {
6278
+ id: string;
6279
+ name: string;
6280
+ description?: string | undefined;
6281
+ }[] | undefined;
6295
6282
  benefits?: {
6296
6283
  id: string;
6297
6284
  name: string;
@@ -6404,14 +6391,9 @@ declare const technologyUpdateSchema: z.ZodObject<{
6404
6391
  isActive?: boolean | undefined;
6405
6392
  description?: string | undefined;
6406
6393
  family?: ProcedureFamily | undefined;
6407
- technicalDetails?: string | undefined;
6408
- contraindications?: {
6409
- id: string;
6410
- name: string;
6411
- description?: string | undefined;
6412
- }[] | undefined;
6413
6394
  categoryId?: string | undefined;
6414
6395
  subcategoryId?: string | undefined;
6396
+ technicalDetails?: string | undefined;
6415
6397
  requirements?: {
6416
6398
  pre: {
6417
6399
  name: string;
@@ -6439,6 +6421,11 @@ declare const technologyUpdateSchema: z.ZodObject<{
6439
6421
  }[];
6440
6422
  } | undefined;
6441
6423
  blockingConditions?: BlockingCondition[] | undefined;
6424
+ contraindications?: {
6425
+ id: string;
6426
+ name: string;
6427
+ description?: string | undefined;
6428
+ }[] | undefined;
6442
6429
  benefits?: {
6443
6430
  id: string;
6444
6431
  name: string;
@@ -162,13 +162,12 @@ var BrandService = class extends BaseService {
162
162
  return { id: docRef.id, ...newBrand };
163
163
  }
164
164
  /**
165
- * Gets a paginated list of active brands, optionally filtered by name and category.
165
+ * Gets a paginated list of active brands, optionally filtered by name.
166
166
  * @param rowsPerPage - The number of brands to fetch.
167
167
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
168
168
  * @param lastVisible - An optional document snapshot to use as a cursor for pagination.
169
- * @param category - An optional category to filter brands by.
170
169
  */
171
- async getAll(rowsPerPage, searchTerm, lastVisible, category) {
170
+ async getAll(rowsPerPage, searchTerm, lastVisible) {
172
171
  const constraints = [
173
172
  (0, import_firestore.where)("isActive", "==", true),
174
173
  (0, import_firestore.orderBy)("name_lowercase")
@@ -180,9 +179,6 @@ var BrandService = class extends BaseService {
180
179
  (0, import_firestore.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
181
180
  );
182
181
  }
183
- if (category) {
184
- constraints.push((0, import_firestore.where)("category", "==", category));
185
- }
186
182
  if (lastVisible) {
187
183
  constraints.push((0, import_firestore.startAfter)(lastVisible));
188
184
  }
@@ -199,11 +195,10 @@ var BrandService = class extends BaseService {
199
195
  return { brands, lastVisible: newLastVisible };
200
196
  }
201
197
  /**
202
- * Gets the total count of active brands, optionally filtered by name and category.
198
+ * Gets the total count of active brands, optionally filtered by name.
203
199
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
204
- * @param category - An optional category to filter brands by.
205
200
  */
206
- async getBrandsCount(searchTerm, category) {
201
+ async getBrandsCount(searchTerm) {
207
202
  const constraints = [(0, import_firestore.where)("isActive", "==", true)];
208
203
  if (searchTerm) {
209
204
  const lowercasedSearchTerm = searchTerm.toLowerCase();
@@ -212,9 +207,6 @@ var BrandService = class extends BaseService {
212
207
  (0, import_firestore.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
213
208
  );
214
209
  }
215
- if (category) {
216
- constraints.push((0, import_firestore.where)("category", "==", category));
217
- }
218
210
  const q = (0, import_firestore.query)(this.getBrandsRef(), ...constraints);
219
211
  const snapshot = await (0, import_firestore.getCountFromServer)(q);
220
212
  return snapshot.data().count;
@@ -284,7 +276,6 @@ var BrandService = class extends BaseService {
284
276
  "id",
285
277
  "name",
286
278
  "manufacturer",
287
- "category",
288
279
  "website",
289
280
  "description",
290
281
  "isActive"
@@ -315,15 +306,14 @@ var BrandService = class extends BaseService {
315
306
  return includeBom ? "\uFEFF" + csvBody : csvBody;
316
307
  }
317
308
  brandToCsvRow(brand) {
318
- var _a, _b, _c, _d, _e, _f, _g;
309
+ var _a, _b, _c, _d, _e, _f;
319
310
  const values = [
320
311
  (_a = brand.id) != null ? _a : "",
321
312
  (_b = brand.name) != null ? _b : "",
322
313
  (_c = brand.manufacturer) != null ? _c : "",
323
- (_d = brand.category) != null ? _d : "",
324
- (_e = brand.website) != null ? _e : "",
325
- (_f = brand.description) != null ? _f : "",
326
- String((_g = brand.isActive) != null ? _g : "")
314
+ (_d = brand.website) != null ? _d : "",
315
+ (_e = brand.description) != null ? _e : "",
316
+ String((_f = brand.isActive) != null ? _f : "")
327
317
  ];
328
318
  return values.map((v) => this.formatCsvValue(v)).join(",");
329
319
  }
@@ -1871,11 +1861,10 @@ var ProductService = class extends BaseService {
1871
1861
  /**
1872
1862
  * Creates a new product in the top-level collection
1873
1863
  */
1874
- async createTopLevel(brandId, product, technologyIds = []) {
1864
+ async createTopLevel(product, technologyIds = []) {
1875
1865
  const now = /* @__PURE__ */ new Date();
1876
1866
  const newProduct = {
1877
1867
  ...product,
1878
- brandId,
1879
1868
  assignedTechnologyIds: technologyIds,
1880
1869
  createdAt: now,
1881
1870
  updatedAt: now,
@@ -1888,11 +1877,14 @@ var ProductService = class extends BaseService {
1888
1877
  * Gets all products from the top-level collection
1889
1878
  */
1890
1879
  async getAllTopLevel(options) {
1891
- const { rowsPerPage, lastVisible, brandId } = options;
1880
+ const { rowsPerPage, lastVisible, brandId, category } = options;
1892
1881
  const constraints = [(0, import_firestore8.where)("isActive", "==", true), (0, import_firestore8.orderBy)("name")];
1893
1882
  if (brandId) {
1894
1883
  constraints.push((0, import_firestore8.where)("brandId", "==", brandId));
1895
1884
  }
1885
+ if (category) {
1886
+ constraints.push((0, import_firestore8.where)("category", "==", category));
1887
+ }
1896
1888
  if (lastVisible) {
1897
1889
  constraints.push((0, import_firestore8.startAfter)(lastVisible));
1898
1890
  }
@@ -2033,14 +2025,10 @@ var ProductService = class extends BaseService {
2033
2025
  "name",
2034
2026
  "brandId",
2035
2027
  "brandName",
2028
+ "category",
2036
2029
  "assignedTechnologyIds",
2037
2030
  "description",
2038
- "technicalDetails",
2039
- "dosage",
2040
- "composition",
2041
- "indications",
2042
- "contraindications",
2043
- "warnings",
2031
+ "metadata",
2044
2032
  "isActive"
2045
2033
  ];
2046
2034
  const rows = [];
@@ -2069,21 +2057,17 @@ var ProductService = class extends BaseService {
2069
2057
  return includeBom ? "\uFEFF" + csvBody : csvBody;
2070
2058
  }
2071
2059
  productToCsvRow(product) {
2072
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2060
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2073
2061
  const values = [
2074
2062
  (_a = product.id) != null ? _a : "",
2075
2063
  (_b = product.name) != null ? _b : "",
2076
2064
  (_c = product.brandId) != null ? _c : "",
2077
2065
  (_d = product.brandName) != null ? _d : "",
2078
- (_f = (_e = product.assignedTechnologyIds) == null ? void 0 : _e.join(";")) != null ? _f : "",
2079
- (_g = product.description) != null ? _g : "",
2080
- (_h = product.technicalDetails) != null ? _h : "",
2081
- (_i = product.dosage) != null ? _i : "",
2082
- (_j = product.composition) != null ? _j : "",
2083
- (_l = (_k = product.indications) == null ? void 0 : _k.join(";")) != null ? _l : "",
2084
- (_n = (_m = product.contraindications) == null ? void 0 : _m.map((c) => c.name).join(";")) != null ? _n : "",
2085
- (_p = (_o = product.warnings) == null ? void 0 : _o.join(";")) != null ? _p : "",
2086
- String((_q = product.isActive) != null ? _q : "")
2066
+ (_e = product.category) != null ? _e : "",
2067
+ (_g = (_f = product.assignedTechnologyIds) == null ? void 0 : _f.join(";")) != null ? _g : "",
2068
+ (_h = product.description) != null ? _h : "",
2069
+ product.metadata ? JSON.stringify(product.metadata) : "",
2070
+ String((_i = product.isActive) != null ? _i : "")
2087
2071
  ];
2088
2072
  return values.map((v) => this.formatCsvValue(v)).join(",");
2089
2073
  }
@@ -3415,7 +3399,8 @@ var TechnologyService = class extends BaseService {
3415
3399
  const products = await this.getAssignedProducts(technologyId);
3416
3400
  const byBrand = {};
3417
3401
  products.forEach((product) => {
3418
- byBrand[product.brandName] = (byBrand[product.brandName] || 0) + 1;
3402
+ const brandName = product.brandName || "Unknown";
3403
+ byBrand[brandName] = (byBrand[brandName] || 0) + 1;
3419
3404
  });
3420
3405
  return {
3421
3406
  totalAssigned: products.length,
@@ -68,13 +68,12 @@ var BrandService = class extends BaseService {
68
68
  return { id: docRef.id, ...newBrand };
69
69
  }
70
70
  /**
71
- * Gets a paginated list of active brands, optionally filtered by name and category.
71
+ * Gets a paginated list of active brands, optionally filtered by name.
72
72
  * @param rowsPerPage - The number of brands to fetch.
73
73
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
74
74
  * @param lastVisible - An optional document snapshot to use as a cursor for pagination.
75
- * @param category - An optional category to filter brands by.
76
75
  */
77
- async getAll(rowsPerPage, searchTerm, lastVisible, category) {
76
+ async getAll(rowsPerPage, searchTerm, lastVisible) {
78
77
  const constraints = [
79
78
  where("isActive", "==", true),
80
79
  orderBy("name_lowercase")
@@ -86,9 +85,6 @@ var BrandService = class extends BaseService {
86
85
  where("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
87
86
  );
88
87
  }
89
- if (category) {
90
- constraints.push(where("category", "==", category));
91
- }
92
88
  if (lastVisible) {
93
89
  constraints.push(startAfter(lastVisible));
94
90
  }
@@ -105,11 +101,10 @@ var BrandService = class extends BaseService {
105
101
  return { brands, lastVisible: newLastVisible };
106
102
  }
107
103
  /**
108
- * Gets the total count of active brands, optionally filtered by name and category.
104
+ * Gets the total count of active brands, optionally filtered by name.
109
105
  * @param searchTerm - An optional string to filter brand names by (starts-with search).
110
- * @param category - An optional category to filter brands by.
111
106
  */
112
- async getBrandsCount(searchTerm, category) {
107
+ async getBrandsCount(searchTerm) {
113
108
  const constraints = [where("isActive", "==", true)];
114
109
  if (searchTerm) {
115
110
  const lowercasedSearchTerm = searchTerm.toLowerCase();
@@ -118,9 +113,6 @@ var BrandService = class extends BaseService {
118
113
  where("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
119
114
  );
120
115
  }
121
- if (category) {
122
- constraints.push(where("category", "==", category));
123
- }
124
116
  const q = query(this.getBrandsRef(), ...constraints);
125
117
  const snapshot = await getCountFromServer(q);
126
118
  return snapshot.data().count;
@@ -190,7 +182,6 @@ var BrandService = class extends BaseService {
190
182
  "id",
191
183
  "name",
192
184
  "manufacturer",
193
- "category",
194
185
  "website",
195
186
  "description",
196
187
  "isActive"
@@ -221,15 +212,14 @@ var BrandService = class extends BaseService {
221
212
  return includeBom ? "\uFEFF" + csvBody : csvBody;
222
213
  }
223
214
  brandToCsvRow(brand) {
224
- var _a, _b, _c, _d, _e, _f, _g;
215
+ var _a, _b, _c, _d, _e, _f;
225
216
  const values = [
226
217
  (_a = brand.id) != null ? _a : "",
227
218
  (_b = brand.name) != null ? _b : "",
228
219
  (_c = brand.manufacturer) != null ? _c : "",
229
- (_d = brand.category) != null ? _d : "",
230
- (_e = brand.website) != null ? _e : "",
231
- (_f = brand.description) != null ? _f : "",
232
- String((_g = brand.isActive) != null ? _g : "")
220
+ (_d = brand.website) != null ? _d : "",
221
+ (_e = brand.description) != null ? _e : "",
222
+ String((_f = brand.isActive) != null ? _f : "")
233
223
  ];
234
224
  return values.map((v) => this.formatCsvValue(v)).join(",");
235
225
  }
@@ -1847,11 +1837,10 @@ var ProductService = class extends BaseService {
1847
1837
  /**
1848
1838
  * Creates a new product in the top-level collection
1849
1839
  */
1850
- async createTopLevel(brandId, product, technologyIds = []) {
1840
+ async createTopLevel(product, technologyIds = []) {
1851
1841
  const now = /* @__PURE__ */ new Date();
1852
1842
  const newProduct = {
1853
1843
  ...product,
1854
- brandId,
1855
1844
  assignedTechnologyIds: technologyIds,
1856
1845
  createdAt: now,
1857
1846
  updatedAt: now,
@@ -1864,11 +1853,14 @@ var ProductService = class extends BaseService {
1864
1853
  * Gets all products from the top-level collection
1865
1854
  */
1866
1855
  async getAllTopLevel(options) {
1867
- const { rowsPerPage, lastVisible, brandId } = options;
1856
+ const { rowsPerPage, lastVisible, brandId, category } = options;
1868
1857
  const constraints = [where6("isActive", "==", true), orderBy6("name")];
1869
1858
  if (brandId) {
1870
1859
  constraints.push(where6("brandId", "==", brandId));
1871
1860
  }
1861
+ if (category) {
1862
+ constraints.push(where6("category", "==", category));
1863
+ }
1872
1864
  if (lastVisible) {
1873
1865
  constraints.push(startAfter5(lastVisible));
1874
1866
  }
@@ -2009,14 +2001,10 @@ var ProductService = class extends BaseService {
2009
2001
  "name",
2010
2002
  "brandId",
2011
2003
  "brandName",
2004
+ "category",
2012
2005
  "assignedTechnologyIds",
2013
2006
  "description",
2014
- "technicalDetails",
2015
- "dosage",
2016
- "composition",
2017
- "indications",
2018
- "contraindications",
2019
- "warnings",
2007
+ "metadata",
2020
2008
  "isActive"
2021
2009
  ];
2022
2010
  const rows = [];
@@ -2045,21 +2033,17 @@ var ProductService = class extends BaseService {
2045
2033
  return includeBom ? "\uFEFF" + csvBody : csvBody;
2046
2034
  }
2047
2035
  productToCsvRow(product) {
2048
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2036
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2049
2037
  const values = [
2050
2038
  (_a = product.id) != null ? _a : "",
2051
2039
  (_b = product.name) != null ? _b : "",
2052
2040
  (_c = product.brandId) != null ? _c : "",
2053
2041
  (_d = product.brandName) != null ? _d : "",
2054
- (_f = (_e = product.assignedTechnologyIds) == null ? void 0 : _e.join(";")) != null ? _f : "",
2055
- (_g = product.description) != null ? _g : "",
2056
- (_h = product.technicalDetails) != null ? _h : "",
2057
- (_i = product.dosage) != null ? _i : "",
2058
- (_j = product.composition) != null ? _j : "",
2059
- (_l = (_k = product.indications) == null ? void 0 : _k.join(";")) != null ? _l : "",
2060
- (_n = (_m = product.contraindications) == null ? void 0 : _m.map((c) => c.name).join(";")) != null ? _n : "",
2061
- (_p = (_o = product.warnings) == null ? void 0 : _o.join(";")) != null ? _p : "",
2062
- String((_q = product.isActive) != null ? _q : "")
2042
+ (_e = product.category) != null ? _e : "",
2043
+ (_g = (_f = product.assignedTechnologyIds) == null ? void 0 : _f.join(";")) != null ? _g : "",
2044
+ (_h = product.description) != null ? _h : "",
2045
+ product.metadata ? JSON.stringify(product.metadata) : "",
2046
+ String((_i = product.isActive) != null ? _i : "")
2063
2047
  ];
2064
2048
  return values.map((v) => this.formatCsvValue(v)).join(",");
2065
2049
  }
@@ -3431,7 +3415,8 @@ var TechnologyService = class extends BaseService {
3431
3415
  const products = await this.getAssignedProducts(technologyId);
3432
3416
  const byBrand = {};
3433
3417
  products.forEach((product) => {
3434
- byBrand[product.brandName] = (byBrand[product.brandName] || 0) + 1;
3418
+ const brandName = product.brandName || "Unknown";
3419
+ byBrand[brandName] = (byBrand[brandName] || 0) + 1;
3435
3420
  });
3436
3421
  return {
3437
3422
  totalAssigned: products.length,