Re_Backend/docs/COST_BREAKUP_TABLE_ARCHITECTURE.md

4.4 KiB

Cost Breakup Table Architecture

Overview

This document describes the enhanced architecture for storing cost breakups in the Dealer Claim Management system. Instead of storing cost breakups as JSONB arrays, we now use a dedicated relational table for better querying, reporting, and data integrity.

Architecture Decision

Previous Approach (JSONB)

  • Storage: Cost breakups stored as JSONB array in dealer_proposal_details.cost_breakup
  • Limitations:
    • Difficult to query individual cost items
    • Hard to update specific items
    • Not ideal for reporting and analytics
    • No referential integrity

New Approach (Separate Table)

  • Storage: Dedicated dealer_proposal_cost_items table
  • Benefits:
    • Better querying and filtering capabilities
    • Easier to update individual cost items
    • Better for analytics and reporting
    • Maintains referential integrity
    • Supports proper ordering of items

Database Schema

Table: dealer_proposal_cost_items

CREATE TABLE dealer_proposal_cost_items (
  cost_item_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  proposal_id UUID NOT NULL REFERENCES dealer_proposal_details(proposal_id) ON DELETE CASCADE,
  request_id UUID NOT NULL REFERENCES workflow_requests(request_id) ON DELETE CASCADE,
  item_description VARCHAR(500) NOT NULL,
  amount DECIMAL(15, 2) NOT NULL,
  item_order INTEGER NOT NULL DEFAULT 0,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

Indexes:

  • idx_proposal_cost_items_proposal_id on proposal_id
  • idx_proposal_cost_items_request_id on request_id
  • idx_proposal_cost_items_proposal_order on (proposal_id, item_order)

Backward Compatibility

The system maintains backward compatibility by:

  1. Dual Storage: Still saves cost breakups to JSONB field for backward compatibility
  2. Smart Retrieval: When fetching proposal details:
    • First tries to get cost items from the new table
    • Falls back to JSONB field if table is empty
  3. Migration: Automatically migrates existing JSONB data to the new table during migration

API Response Format

The API always returns cost breakups as an array, regardless of storage method:

{
  "proposalDetails": {
    "proposalId": "uuid",
    "costBreakup": [
      {
        "description": "Item 1",
        "amount": 10000
      },
      {
        "description": "Item 2",
        "amount": 20000
      }
    ],
    "costItems": [
      {
        "costItemId": "uuid",
        "itemDescription": "Item 1",
        "amount": 10000,
        "itemOrder": 0
      }
    ]
  }
}

Implementation Details

Saving Cost Items

When a proposal is submitted:

  1. Save proposal details to dealer_proposal_details (with JSONB for backward compatibility)
  2. Delete existing cost items for the proposal (if updating)
  3. Insert new cost items into dealer_proposal_cost_items table
  4. Items are ordered by itemOrder field

Retrieving Cost Items

When fetching proposal details:

  1. Query dealer_proposal_details with include for costItems
  2. If cost items exist in the table, use them
  3. If not, fall back to parsing JSONB costBreakup field
  4. Always return as a normalized array format

Migration

The migration (20251210-create-proposal-cost-items-table.ts):

  1. Creates the new table
  2. Creates indexes for performance
  3. Migrates existing JSONB data to the new table automatically
  4. Handles errors gracefully (doesn't fail if migration of existing data fails)

Model Associations

DealerProposalDetails.hasMany(DealerProposalCostItem, {
  as: 'costItems',
  foreignKey: 'proposalId',
  sourceKey: 'proposalId'
});

DealerProposalCostItem.belongsTo(DealerProposalDetails, {
  as: 'proposal',
  foreignKey: 'proposalId',
  targetKey: 'proposalId'
});

Benefits for Frontend

  1. Consistent Format: Always receives cost breakups as an array
  2. No Changes Required: Frontend code doesn't need to change
  3. Better Performance: Can query specific cost items if needed
  4. Future Extensibility: Easy to add features like:
    • Cost item categories
    • Approval status per item
    • Historical tracking of cost changes

Future Enhancements

Potential future improvements:

  • Add category field to cost items
  • Add approved_amount vs requested_amount for budget approval workflows
  • Add notes field for item-level comments
  • Add audit trail for cost item changes
  • Add is_approved flag for individual item approval