Duplication audit (owner-requested) found LeanerCloud/cloud-commitments-cli#1207 added 5 near-identical term-parsing helpers across the service clients, and DRIFT HAS ALREADY BEGUN: requiredMonthsForTerm (opensearch + redshift, identical bar the service name in the error), getDurationString (elasticache + rds, identical), getDurationStringForAPI (memorydb, a variant that ALSO accepts "12"/"36"). All validate the same 1yr/1/3yr/3 domain on a MONEY path (RI term -> offering purchase), so divergence risks mispriced/mistermed purchases.
Consolidate into a shared ParseTermMonths(term, service string) (int, error) + duration-string formatter in providers/aws/internal/purchasecfg (alongside LeanerCloud/cloud-commitments-cli#1390's ResolveTag) or a sibling terms pkg. Keep each caller's fail-loud behavior (LeanerCloud/cloud-commitments-cli#1207); reconcile the memorydb "12"/"36" variant deliberately (decide if numeric forms are valid everywhere). All existing term tests must pass unchanged.
Duplication audit (owner-requested) found LeanerCloud/cloud-commitments-cli#1207 added 5 near-identical term-parsing helpers across the service clients, and DRIFT HAS ALREADY BEGUN: requiredMonthsForTerm (opensearch + redshift, identical bar the service name in the error), getDurationString (elasticache + rds, identical), getDurationStringForAPI (memorydb, a variant that ALSO accepts "12"/"36"). All validate the same 1yr/1/3yr/3 domain on a MONEY path (RI term -> offering purchase), so divergence risks mispriced/mistermed purchases.
Consolidate into a shared ParseTermMonths(term, service string) (int, error) + duration-string formatter in providers/aws/internal/purchasecfg (alongside LeanerCloud/cloud-commitments-cli#1390's ResolveTag) or a sibling terms pkg. Keep each caller's fail-loud behavior (LeanerCloud/cloud-commitments-cli#1207); reconcile the memorydb "12"/"36" variant deliberately (decide if numeric forms are valid everywhere). All existing term tests must pass unchanged.