Preserve fractional Secrets Manager trial credit balances

What does this MR do and why?

CustomersDot reports the Secrets Manager trial credit balance as a decimal string (for example "0.1"), but parse_credit_amount in the subscription portal REST client truncated it with .to_i. Any balance between 0 and 1 was therefore reported as exactly 0.

Because the frontend uses a strict creditsRemaining === 0 check, customers with a small remaining balance saw the "All trial credits used" alert, which incorrectly claims they are incurring on-demand charges. QA reproduced this on staging with a $0.10 balance.

This MR parses credit amounts with .to_f to keep full precision, and changes the creditsRemaining and creditsTotal fields on the SecretsManagerEntitlement GraphQL type from Int to Float. Both fields are experimental (introduced in 19.2), so the type change needs no deprecation. Both are changed because they share the same parse path, and leaving creditsTotal as Int would let GraphQL silently re-truncate it. No frontend logic change is needed: the display already rounds percentages (sub-1% clamps to 1%), and the exhausted check now only matches a genuinely zero balance. Everything is behind the secrets_manager_paid_experience feature flag (default off).

Changes:

  • ee/lib/gitlab/subscription_portal/clients/rest.rb: parse_credit_amount uses .to_f instead of .to_i
  • ee/app/graphql/types/secrets_management/entitlement_type.rb: creditsRemaining and creditsTotal become Float
  • Spec updates: the REST client spec asserts a 0.1 balance is preserved; the GraphQL type spec asserts Float signatures; the request spec passes 749.5 through the API; a new Jest test asserts 0.1 remaining credits renders the "1% of credits left" low-credits alert rather than the exhausted alert (guards against a future creditsRemaining <= 0 "fix", which would not help since truncation happened server-side)
  • Regenerated doc/api/graphql/reference/_index.md

References

Screenshots or screen recordings

No UI changes in this MR. The alert copy and display logic are unchanged; this fixes the data feeding them, so screenshots are not applicable.

How to set up and validate locally

Validating end to end requires a CDot-connected environment with an active Secrets Manager trial, which is impractical locally. The behavior is covered by specs:

bundle exec rspec ee/spec/lib/gitlab/subscription_portal/clients/rest_spec.rb \
  ee/spec/graphql/types/secrets_management/entitlement_type_spec.rb \
  ee/spec/requests/api/graphql/group/secrets_manager_entitlement_spec.rb
yarn jest ee/spec/frontend/ci/secrets/components/secrets_app_spec.js

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Merge request reports

Loading
Loading