All files / src/services/db conversion.db.ts

39.49% Statements 47/119
100% Branches 6/6
50% Functions 3/6
37.11% Lines 36/97

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 982x 2x 2x 2x 2x 2x 27x   2x 2x 2x 2x 2x 2x 3x 3x 3x 3x 2x 3x 2x 1x     3x   3x 2x   1x                                     2x 2x 2x       1x   1x                                       4x 4x 2x     3x 2x     3x                        
// src/services/db/conversion.db.ts
import type { Logger } from 'pino';
import { getPool } from './connection.db';
import { handleDbError, NotFoundError } from './errors.db';
import type { UnitConversion } from '../../types';
 
export const conversionRepo = {
  /**
   * Fetches unit conversions, optionally filtered by master_item_id.
   */
  async getConversions(
    filters: { masterItemId?: number },
    logger: Logger,
  ): Promise<UnitConversion[]> {
    const { masterItemId } = filters;
    try {
      let query = 'SELECT * FROM public.unit_conversions';
      const params: (string | number)[] = [];
 
      if (masterItemId) {
        query += ' WHERE master_item_id = $1';
        params.push(masterItemId);
      }

      query += ' ORDER BY master_item_id, from_unit, to_unit';

      const result = await getPool().query<UnitConversion>(query, params);
      return result.rows;
    } catch (error) {
      handleDbError(
        error,
        logger,
        'Database error in getConversions',
        { filters },
        {
          defaultMessage: 'Failed to retrieve unit conversions.',
        },
      );
    }
  },

  /**
   * Creates a new unit conversion rule.
   */
  async createConversion(
    conversionData: Omit<UnitConversion, 'unit_conversion_id' | 'created_at' | 'updated_at'>,
    logger: Logger,
  ): Promise<UnitConversion> {
    const { master_item_id, from_unit, to_unit, factor } = conversionData;
    try {
      const res = await getPool().query<UnitConversion>(
        'INSERT INTO public.unit_conversions (master_item_id, from_unit, to_unit, factor) VALUES ($1, $2, $3, $4) RETURNING *',
        [master_item_id, from_unit, to_unit, factor],
      );
      return res.rows[0];
    } catch (error) {
      handleDbError(
        error,
        logger,
        'Database error in createConversion',
        { conversionData },
        {
          fkMessage: 'The specified master item does not exist.',
          uniqueMessage: 'This conversion rule already exists for this item.',
          checkMessage:
            'Invalid unit conversion data provided (e.g., factor must be > 0, units cannot be the same).',
          defaultMessage: 'Failed to create unit conversion.',
        },
      );
    }
  },

  /**
   * Deletes a unit conversion rule.
   */
  async deleteConversion(conversionId: number, logger: Logger): Promise<void> {
    try {
      const res = await getPool().query(
        'DELETE FROM public.unit_conversions WHERE unit_conversion_id = $1',
        [conversionId],
      );
      if (res.rowCount === 0) {
        throw new NotFoundError(`Unit conversion with ID ${conversionId} not found.`);
      }
    } catch (error) {
      handleDbError(
        error,
        logger,
        'Database error in deleteConversion',
        { conversionId },
        {
          defaultMessage: 'Failed to delete unit conversion.',
        },
      );
    }
  },
};