Skip to content

feat(db): make PurchaseHistoryRecord.MonthlyCost nullable to preserve nil-vs-zero distinction #255

@cristim

Description

@cristim

Background

PR #254 changed RecommendationRecord.MonthlyCost from float64 to *float64
to distinguish nil (provider API didn't expose a monthly breakdown) from 0.0
(explicit zero recurring charge, e.g. all-upfront commitments).

When a purchase is executed, execution.go copies the field into
PurchaseHistoryRecord.MonthlyCost via derefFloat64, which collapses nil → 0.

Problem

For Azure/GCP recommendations where RecurringMonthlyCost is nil, the history
record will show MonthlyCost = 0.0 after purchase. This is accurate at the
billing level (no recurring monthly charge on those providers at the
commitment layer), but it loses the semantic distinction between "data not
provided" and "explicitly $0".

For AWS all-upfront commitments, RecurringMonthlyCost = 0.0 is correct and
the conversion is lossless.

Resolution

Make PurchaseHistoryRecord.MonthlyCost *float64 and update:

  • internal/config/store_postgres.go SQL write/scan to handle NULL
  • internal/config/types.go struct field tag
  • execution.go to pass the pointer directly
  • Any history analytics or report paths that read MonthlyCost
  • DB migration: ALTER TABLE purchase_history ALTER COLUMN monthly_cost DROP NOT NULL

Why deferred

This requires a non-trivial DB migration and touches the purchase history
analytics path. It was out of scope for the #252 bug fix but should be done
before analytics dashboards start relying on the $0 values for
Azure/GCP purchase history.

Priority

Low — only affects Azure/GCP history display (which currently shows $0
instead of ). AWS data is correct.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions