@blackcode_sa/metaestetics-api 1.12.40 → 1.12.41

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/index.d.mts CHANGED
@@ -565,9 +565,10 @@ interface FilledDocumentFileValue {
565
565
  *
566
566
  * @property id - Unique identifier of the product
567
567
  * @property name - Name of the product
568
- * @property description - Detailed description of the product and its purpose
569
568
  * @property brandId - ID of the brand that manufactures this product
570
- * @property technologyId - ID of the technology this product is used with
569
+ * @property brandName - Name of the brand (denormalized for display)
570
+ * @property assignedTechnologyIds - Array of technology IDs this product is assigned to
571
+ * @property description - Detailed description of the product and its purpose
571
572
  * @property technicalDetails - Technical details and specifications
572
573
  * @property warnings - List of warnings related to product use
573
574
  * @property dosage - Dosage information (if applicable)
@@ -583,10 +584,7 @@ interface Product {
583
584
  name: string;
584
585
  brandId: string;
585
586
  brandName: string;
586
- technologyId: string;
587
- technologyName: string;
588
- categoryId: string;
589
- subcategoryId: string;
587
+ assignedTechnologyIds?: string[];
590
588
  createdAt: Date;
591
589
  updatedAt: Date;
592
590
  isActive: boolean;
@@ -597,12 +595,86 @@ interface Product {
597
595
  composition?: string;
598
596
  indications?: string[];
599
597
  contraindications?: ContraindicationDynamic[];
598
+ /** @deprecated Use assignedTechnologyIds instead */
599
+ technologyId?: string;
600
+ /** @deprecated Will be removed in future version */
601
+ technologyName?: string;
602
+ /** @deprecated Not needed in top-level collection */
603
+ categoryId?: string;
604
+ /** @deprecated Not needed in top-level collection */
605
+ subcategoryId?: string;
600
606
  }
601
607
  /**
602
608
  * Interface for the ProductService class
609
+ *
610
+ * NOTE: This interface maintains backward compatibility while adding new top-level collection methods.
611
+ * Old methods using technologyId are kept for existing code, new methods work with top-level collection.
603
612
  */
604
613
  interface IProductService {
605
614
  /**
615
+ * Creates a new product in the top-level collection
616
+ * @param brandId - ID of the brand that manufactures this product
617
+ * @param product - Product data
618
+ * @param technologyIds - Optional array of technology IDs to assign this product to
619
+ */
620
+ createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
621
+ /**
622
+ * Gets all products from the top-level collection
623
+ * @param options - Query options
624
+ */
625
+ getAllTopLevel(options: {
626
+ rowsPerPage: number;
627
+ lastVisible?: any;
628
+ brandId?: string;
629
+ }): Promise<{
630
+ products: Product[];
631
+ lastVisible: any;
632
+ }>;
633
+ /**
634
+ * Gets a product by ID from the top-level collection
635
+ * @param productId - ID of the product
636
+ */
637
+ getByIdTopLevel(productId: string): Promise<Product | null>;
638
+ /**
639
+ * Updates a product in the top-level collection
640
+ * @param productId - ID of the product to update
641
+ * @param product - Updated product data
642
+ */
643
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
644
+ /**
645
+ * Deletes a product from the top-level collection (soft delete)
646
+ * @param productId - ID of the product to delete
647
+ */
648
+ deleteTopLevel(productId: string): Promise<void>;
649
+ /**
650
+ * Assigns a product to a technology
651
+ * @param productId - ID of the product
652
+ * @param technologyId - ID of the technology
653
+ */
654
+ assignToTechnology(productId: string, technologyId: string): Promise<void>;
655
+ /**
656
+ * Unassigns a product from a technology
657
+ * @param productId - ID of the product
658
+ * @param technologyId - ID of the technology
659
+ */
660
+ unassignFromTechnology(productId: string, technologyId: string): Promise<void>;
661
+ /**
662
+ * Gets products assigned to a specific technology
663
+ * @param technologyId - ID of the technology
664
+ */
665
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
666
+ /**
667
+ * Gets products NOT assigned to a specific technology
668
+ * @param technologyId - ID of the technology
669
+ */
670
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
671
+ /**
672
+ * Gets all products for a brand
673
+ * @param brandId - ID of the brand
674
+ */
675
+ getByBrand(brandId: string): Promise<Product[]>;
676
+ /**
677
+ * @deprecated Use createTopLevel instead
606
678
  * Creates a new product
607
679
  * @param technologyId - ID of the technology this product is used with
608
680
  * @param brandId - ID of the brand that manufactures this product
@@ -610,6 +682,7 @@ interface IProductService {
610
682
  */
611
683
  create(technologyId: string, brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'technologyId'>): Promise<Product>;
612
684
  /**
685
+ * @deprecated Use getAllTopLevel instead
613
686
  * Gets a paginated list of all products, with optional filters.
614
687
  */
615
688
  getAll(options: {
@@ -623,6 +696,7 @@ interface IProductService {
623
696
  lastVisible: any;
624
697
  }>;
625
698
  /**
699
+ * @deprecated Use alternative counting methods
626
700
  * Gets the total count of active products, with optional filters.
627
701
  */
628
702
  getProductsCount(options: {
@@ -631,6 +705,7 @@ interface IProductService {
631
705
  technologyId?: string;
632
706
  }): Promise<number>;
633
707
  /**
708
+ * @deprecated Use alternative counting methods
634
709
  * Gets counts of active products grouped by category, subcategory, and technology.
635
710
  */
636
711
  getProductCounts(): Promise<{
@@ -639,16 +714,19 @@ interface IProductService {
639
714
  byTechnology: Record<string, number>;
640
715
  }>;
641
716
  /**
717
+ * @deprecated Use getAssignedProducts instead
642
718
  * Gets all products for a specific technology (non-paginated, for filters/dropdowns)
643
719
  * @param technologyId - ID of the technology
644
720
  */
645
721
  getAllByTechnology(technologyId: string): Promise<Product[]>;
646
722
  /**
723
+ * @deprecated Use getByBrand instead
647
724
  * Gets all products for a brand
648
725
  * @param brandId - ID of the brand
649
726
  */
650
727
  getAllByBrand(brandId: string): Promise<Product[]>;
651
728
  /**
729
+ * @deprecated Use updateTopLevel instead
652
730
  * Updates a product
653
731
  * @param technologyId - ID of the technology
654
732
  * @param productId - ID of the product to update
@@ -656,12 +734,14 @@ interface IProductService {
656
734
  */
657
735
  update(technologyId: string, productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId' | 'technologyId'>>): Promise<Product | null>;
658
736
  /**
737
+ * @deprecated Use deleteTopLevel instead
659
738
  * Deletes a product (soft delete)
660
739
  * @param technologyId - ID of the technology
661
740
  * @param productId - ID of the product to delete
662
741
  */
663
742
  delete(technologyId: string, productId: string): Promise<void>;
664
743
  /**
744
+ * @deprecated Use getByIdTopLevel instead
665
745
  * Gets a product by ID
666
746
  * @param technologyId - ID of the technology
667
747
  * @param productId - ID of the product
@@ -1480,7 +1560,12 @@ declare class FilledDocumentService extends BaseService {
1480
1560
 
1481
1561
  declare class ProductService extends BaseService implements IProductService {
1482
1562
  /**
1483
- * Gets reference to products collection under a technology
1563
+ * Gets reference to top-level products collection (source of truth)
1564
+ * @returns Firestore collection reference
1565
+ */
1566
+ private getTopLevelProductsRef;
1567
+ /**
1568
+ * Gets reference to products collection under a technology (backward compatibility)
1484
1569
  * @param technologyId - ID of the technology
1485
1570
  * @returns Firestore collection reference
1486
1571
  */
@@ -1512,8 +1597,9 @@ declare class ProductService extends BaseService implements IProductService {
1512
1597
  technologyId?: string;
1513
1598
  }): Promise<number>;
1514
1599
  /**
1515
- * Gets counts of active products grouped by category, subcategory, and technology.
1516
- * This uses a single collectionGroup query for efficiency.
1600
+ * Gets counts of active products grouped by technology.
1601
+ * NOTE: Only counts top-level collection to avoid duplication during migration.
1602
+ * Categories/subcategories not available in top-level structure.
1517
1603
  */
1518
1604
  getProductCounts(): Promise<{
1519
1605
  byCategory: Record<string, number>;
@@ -1540,6 +1626,53 @@ declare class ProductService extends BaseService implements IProductService {
1540
1626
  * Gets a product by ID
1541
1627
  */
1542
1628
  getById(technologyId: string, productId: string): Promise<Product | null>;
1629
+ /**
1630
+ * Creates a new product in the top-level collection
1631
+ */
1632
+ createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
1633
+ /**
1634
+ * Gets all products from the top-level collection
1635
+ */
1636
+ getAllTopLevel(options: {
1637
+ rowsPerPage: number;
1638
+ lastVisible?: any;
1639
+ brandId?: string;
1640
+ }): Promise<{
1641
+ products: Product[];
1642
+ lastVisible: any;
1643
+ }>;
1644
+ /**
1645
+ * Gets a product by ID from the top-level collection
1646
+ */
1647
+ getByIdTopLevel(productId: string): Promise<Product | null>;
1648
+ /**
1649
+ * Updates a product in the top-level collection
1650
+ */
1651
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
1652
+ /**
1653
+ * Deletes a product from the top-level collection (soft delete)
1654
+ */
1655
+ deleteTopLevel(productId: string): Promise<void>;
1656
+ /**
1657
+ * Assigns a product to a technology
1658
+ */
1659
+ assignToTechnology(productId: string, technologyId: string): Promise<void>;
1660
+ /**
1661
+ * Unassigns a product from a technology
1662
+ */
1663
+ unassignFromTechnology(productId: string, technologyId: string): Promise<void>;
1664
+ /**
1665
+ * Gets products assigned to a specific technology
1666
+ */
1667
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
1668
+ /**
1669
+ * Gets products NOT assigned to a specific technology
1670
+ */
1671
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
1672
+ /**
1673
+ * Gets all products for a brand (from top-level collection)
1674
+ */
1675
+ getByBrand(brandId: string): Promise<Product[]>;
1543
1676
  }
1544
1677
 
1545
1678
  /**
@@ -1973,10 +2106,10 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
1973
2106
  description: string;
1974
2107
  family: ProcedureFamily;
1975
2108
  isActive: boolean;
1976
- categoryId: string;
1977
- subcategoryId: string;
1978
2109
  technicalDetails?: string | undefined;
1979
2110
  contraindications: ContraindicationDynamic[];
2111
+ categoryId: string;
2112
+ subcategoryId: string;
1980
2113
  requirements: {
1981
2114
  pre: Requirement[];
1982
2115
  post: Requirement[];
@@ -2245,6 +2378,32 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2245
2378
  * Gets all active technologies for filter dropdowns.
2246
2379
  */
2247
2380
  getAllForFilter(): Promise<Technology[]>;
2381
+ /**
2382
+ * Assigns multiple products to a technology
2383
+ * Updates each product's assignedTechnologyIds array
2384
+ */
2385
+ assignProducts(technologyId: string, productIds: string[]): Promise<void>;
2386
+ /**
2387
+ * Unassigns multiple products from a technology
2388
+ * Updates each product's assignedTechnologyIds array
2389
+ */
2390
+ unassignProducts(technologyId: string, productIds: string[]): Promise<void>;
2391
+ /**
2392
+ * Gets products assigned to a specific technology
2393
+ * Reads from top-level collection for immediate consistency (Cloud Functions may lag)
2394
+ */
2395
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
2396
+ /**
2397
+ * Gets products NOT assigned to a specific technology
2398
+ */
2399
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
2400
+ /**
2401
+ * Gets product assignment statistics for a technology
2402
+ */
2403
+ getProductStats(technologyId: string): Promise<{
2404
+ totalAssigned: number;
2405
+ byBrand: Record<string, number>;
2406
+ }>;
2248
2407
  }
2249
2408
 
2250
2409
  /**
package/dist/index.d.ts CHANGED
@@ -565,9 +565,10 @@ interface FilledDocumentFileValue {
565
565
  *
566
566
  * @property id - Unique identifier of the product
567
567
  * @property name - Name of the product
568
- * @property description - Detailed description of the product and its purpose
569
568
  * @property brandId - ID of the brand that manufactures this product
570
- * @property technologyId - ID of the technology this product is used with
569
+ * @property brandName - Name of the brand (denormalized for display)
570
+ * @property assignedTechnologyIds - Array of technology IDs this product is assigned to
571
+ * @property description - Detailed description of the product and its purpose
571
572
  * @property technicalDetails - Technical details and specifications
572
573
  * @property warnings - List of warnings related to product use
573
574
  * @property dosage - Dosage information (if applicable)
@@ -583,10 +584,7 @@ interface Product {
583
584
  name: string;
584
585
  brandId: string;
585
586
  brandName: string;
586
- technologyId: string;
587
- technologyName: string;
588
- categoryId: string;
589
- subcategoryId: string;
587
+ assignedTechnologyIds?: string[];
590
588
  createdAt: Date;
591
589
  updatedAt: Date;
592
590
  isActive: boolean;
@@ -597,12 +595,86 @@ interface Product {
597
595
  composition?: string;
598
596
  indications?: string[];
599
597
  contraindications?: ContraindicationDynamic[];
598
+ /** @deprecated Use assignedTechnologyIds instead */
599
+ technologyId?: string;
600
+ /** @deprecated Will be removed in future version */
601
+ technologyName?: string;
602
+ /** @deprecated Not needed in top-level collection */
603
+ categoryId?: string;
604
+ /** @deprecated Not needed in top-level collection */
605
+ subcategoryId?: string;
600
606
  }
601
607
  /**
602
608
  * Interface for the ProductService class
609
+ *
610
+ * NOTE: This interface maintains backward compatibility while adding new top-level collection methods.
611
+ * Old methods using technologyId are kept for existing code, new methods work with top-level collection.
603
612
  */
604
613
  interface IProductService {
605
614
  /**
615
+ * Creates a new product in the top-level collection
616
+ * @param brandId - ID of the brand that manufactures this product
617
+ * @param product - Product data
618
+ * @param technologyIds - Optional array of technology IDs to assign this product to
619
+ */
620
+ createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
621
+ /**
622
+ * Gets all products from the top-level collection
623
+ * @param options - Query options
624
+ */
625
+ getAllTopLevel(options: {
626
+ rowsPerPage: number;
627
+ lastVisible?: any;
628
+ brandId?: string;
629
+ }): Promise<{
630
+ products: Product[];
631
+ lastVisible: any;
632
+ }>;
633
+ /**
634
+ * Gets a product by ID from the top-level collection
635
+ * @param productId - ID of the product
636
+ */
637
+ getByIdTopLevel(productId: string): Promise<Product | null>;
638
+ /**
639
+ * Updates a product in the top-level collection
640
+ * @param productId - ID of the product to update
641
+ * @param product - Updated product data
642
+ */
643
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
644
+ /**
645
+ * Deletes a product from the top-level collection (soft delete)
646
+ * @param productId - ID of the product to delete
647
+ */
648
+ deleteTopLevel(productId: string): Promise<void>;
649
+ /**
650
+ * Assigns a product to a technology
651
+ * @param productId - ID of the product
652
+ * @param technologyId - ID of the technology
653
+ */
654
+ assignToTechnology(productId: string, technologyId: string): Promise<void>;
655
+ /**
656
+ * Unassigns a product from a technology
657
+ * @param productId - ID of the product
658
+ * @param technologyId - ID of the technology
659
+ */
660
+ unassignFromTechnology(productId: string, technologyId: string): Promise<void>;
661
+ /**
662
+ * Gets products assigned to a specific technology
663
+ * @param technologyId - ID of the technology
664
+ */
665
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
666
+ /**
667
+ * Gets products NOT assigned to a specific technology
668
+ * @param technologyId - ID of the technology
669
+ */
670
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
671
+ /**
672
+ * Gets all products for a brand
673
+ * @param brandId - ID of the brand
674
+ */
675
+ getByBrand(brandId: string): Promise<Product[]>;
676
+ /**
677
+ * @deprecated Use createTopLevel instead
606
678
  * Creates a new product
607
679
  * @param technologyId - ID of the technology this product is used with
608
680
  * @param brandId - ID of the brand that manufactures this product
@@ -610,6 +682,7 @@ interface IProductService {
610
682
  */
611
683
  create(technologyId: string, brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'technologyId'>): Promise<Product>;
612
684
  /**
685
+ * @deprecated Use getAllTopLevel instead
613
686
  * Gets a paginated list of all products, with optional filters.
614
687
  */
615
688
  getAll(options: {
@@ -623,6 +696,7 @@ interface IProductService {
623
696
  lastVisible: any;
624
697
  }>;
625
698
  /**
699
+ * @deprecated Use alternative counting methods
626
700
  * Gets the total count of active products, with optional filters.
627
701
  */
628
702
  getProductsCount(options: {
@@ -631,6 +705,7 @@ interface IProductService {
631
705
  technologyId?: string;
632
706
  }): Promise<number>;
633
707
  /**
708
+ * @deprecated Use alternative counting methods
634
709
  * Gets counts of active products grouped by category, subcategory, and technology.
635
710
  */
636
711
  getProductCounts(): Promise<{
@@ -639,16 +714,19 @@ interface IProductService {
639
714
  byTechnology: Record<string, number>;
640
715
  }>;
641
716
  /**
717
+ * @deprecated Use getAssignedProducts instead
642
718
  * Gets all products for a specific technology (non-paginated, for filters/dropdowns)
643
719
  * @param technologyId - ID of the technology
644
720
  */
645
721
  getAllByTechnology(technologyId: string): Promise<Product[]>;
646
722
  /**
723
+ * @deprecated Use getByBrand instead
647
724
  * Gets all products for a brand
648
725
  * @param brandId - ID of the brand
649
726
  */
650
727
  getAllByBrand(brandId: string): Promise<Product[]>;
651
728
  /**
729
+ * @deprecated Use updateTopLevel instead
652
730
  * Updates a product
653
731
  * @param technologyId - ID of the technology
654
732
  * @param productId - ID of the product to update
@@ -656,12 +734,14 @@ interface IProductService {
656
734
  */
657
735
  update(technologyId: string, productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId' | 'technologyId'>>): Promise<Product | null>;
658
736
  /**
737
+ * @deprecated Use deleteTopLevel instead
659
738
  * Deletes a product (soft delete)
660
739
  * @param technologyId - ID of the technology
661
740
  * @param productId - ID of the product to delete
662
741
  */
663
742
  delete(technologyId: string, productId: string): Promise<void>;
664
743
  /**
744
+ * @deprecated Use getByIdTopLevel instead
665
745
  * Gets a product by ID
666
746
  * @param technologyId - ID of the technology
667
747
  * @param productId - ID of the product
@@ -1480,7 +1560,12 @@ declare class FilledDocumentService extends BaseService {
1480
1560
 
1481
1561
  declare class ProductService extends BaseService implements IProductService {
1482
1562
  /**
1483
- * Gets reference to products collection under a technology
1563
+ * Gets reference to top-level products collection (source of truth)
1564
+ * @returns Firestore collection reference
1565
+ */
1566
+ private getTopLevelProductsRef;
1567
+ /**
1568
+ * Gets reference to products collection under a technology (backward compatibility)
1484
1569
  * @param technologyId - ID of the technology
1485
1570
  * @returns Firestore collection reference
1486
1571
  */
@@ -1512,8 +1597,9 @@ declare class ProductService extends BaseService implements IProductService {
1512
1597
  technologyId?: string;
1513
1598
  }): Promise<number>;
1514
1599
  /**
1515
- * Gets counts of active products grouped by category, subcategory, and technology.
1516
- * This uses a single collectionGroup query for efficiency.
1600
+ * Gets counts of active products grouped by technology.
1601
+ * NOTE: Only counts top-level collection to avoid duplication during migration.
1602
+ * Categories/subcategories not available in top-level structure.
1517
1603
  */
1518
1604
  getProductCounts(): Promise<{
1519
1605
  byCategory: Record<string, number>;
@@ -1540,6 +1626,53 @@ declare class ProductService extends BaseService implements IProductService {
1540
1626
  * Gets a product by ID
1541
1627
  */
1542
1628
  getById(technologyId: string, productId: string): Promise<Product | null>;
1629
+ /**
1630
+ * Creates a new product in the top-level collection
1631
+ */
1632
+ createTopLevel(brandId: string, product: Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'brandId' | 'assignedTechnologyIds'>, technologyIds?: string[]): Promise<Product>;
1633
+ /**
1634
+ * Gets all products from the top-level collection
1635
+ */
1636
+ getAllTopLevel(options: {
1637
+ rowsPerPage: number;
1638
+ lastVisible?: any;
1639
+ brandId?: string;
1640
+ }): Promise<{
1641
+ products: Product[];
1642
+ lastVisible: any;
1643
+ }>;
1644
+ /**
1645
+ * Gets a product by ID from the top-level collection
1646
+ */
1647
+ getByIdTopLevel(productId: string): Promise<Product | null>;
1648
+ /**
1649
+ * Updates a product in the top-level collection
1650
+ */
1651
+ updateTopLevel(productId: string, product: Partial<Omit<Product, 'id' | 'createdAt' | 'brandId'>>): Promise<Product | null>;
1652
+ /**
1653
+ * Deletes a product from the top-level collection (soft delete)
1654
+ */
1655
+ deleteTopLevel(productId: string): Promise<void>;
1656
+ /**
1657
+ * Assigns a product to a technology
1658
+ */
1659
+ assignToTechnology(productId: string, technologyId: string): Promise<void>;
1660
+ /**
1661
+ * Unassigns a product from a technology
1662
+ */
1663
+ unassignFromTechnology(productId: string, technologyId: string): Promise<void>;
1664
+ /**
1665
+ * Gets products assigned to a specific technology
1666
+ */
1667
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
1668
+ /**
1669
+ * Gets products NOT assigned to a specific technology
1670
+ */
1671
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
1672
+ /**
1673
+ * Gets all products for a brand (from top-level collection)
1674
+ */
1675
+ getByBrand(brandId: string): Promise<Product[]>;
1543
1676
  }
1544
1677
 
1545
1678
  /**
@@ -1973,10 +2106,10 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
1973
2106
  description: string;
1974
2107
  family: ProcedureFamily;
1975
2108
  isActive: boolean;
1976
- categoryId: string;
1977
- subcategoryId: string;
1978
2109
  technicalDetails?: string | undefined;
1979
2110
  contraindications: ContraindicationDynamic[];
2111
+ categoryId: string;
2112
+ subcategoryId: string;
1980
2113
  requirements: {
1981
2114
  pre: Requirement[];
1982
2115
  post: Requirement[];
@@ -2245,6 +2378,32 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2245
2378
  * Gets all active technologies for filter dropdowns.
2246
2379
  */
2247
2380
  getAllForFilter(): Promise<Technology[]>;
2381
+ /**
2382
+ * Assigns multiple products to a technology
2383
+ * Updates each product's assignedTechnologyIds array
2384
+ */
2385
+ assignProducts(technologyId: string, productIds: string[]): Promise<void>;
2386
+ /**
2387
+ * Unassigns multiple products from a technology
2388
+ * Updates each product's assignedTechnologyIds array
2389
+ */
2390
+ unassignProducts(technologyId: string, productIds: string[]): Promise<void>;
2391
+ /**
2392
+ * Gets products assigned to a specific technology
2393
+ * Reads from top-level collection for immediate consistency (Cloud Functions may lag)
2394
+ */
2395
+ getAssignedProducts(technologyId: string): Promise<Product[]>;
2396
+ /**
2397
+ * Gets products NOT assigned to a specific technology
2398
+ */
2399
+ getUnassignedProducts(technologyId: string): Promise<Product[]>;
2400
+ /**
2401
+ * Gets product assignment statistics for a technology
2402
+ */
2403
+ getProductStats(technologyId: string): Promise<{
2404
+ totalAssigned: number;
2405
+ byBrand: Record<string, number>;
2406
+ }>;
2248
2407
  }
2249
2408
 
2250
2409
  /**