Skip to content

[PM-37599] refactor: Remove PM37597 always-enable-Stripe-automatic-tax feature flag#7989

Open
amorask-bitwarden wants to merge 2 commits into
mainfrom
billing/PM-37599/remove-ff-always-enable-stripe-automatic-tax
Open

[PM-37599] refactor: Remove PM37597 always-enable-Stripe-automatic-tax feature flag#7989
amorask-bitwarden wants to merge 2 commits into
mainfrom
billing/PM-37599/remove-ff-always-enable-stripe-automatic-tax

Conversation

@amorask-bitwarden

@amorask-bitwarden amorask-bitwarden commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

Jira: PM-37599 — final story of epic PM-36315 "Simplify tax logic". Predecessors shipped in 2026.6.0: PM-37597 (#7662), PM-37598 (#7677), PM-37820 defect (#7719).

📔 Objective

Removes the PM37597_AlwaysEnableStripeAutomaticTax feature flag (LaunchDarkly key pm-37597-always-enable-stripe-automatic-tax) and deletes the now-dead flag-OFF tax logic, making the flag-ON behavior unconditional. The flag has been at 100% in production since 2026.6.0, so this is a pure code-debt removal with no end-user behavior change.

What this locks in

  • Stripe is the source of truth for taxability; new customers default to tax_exempt = "none" (taxable) and automatic_tax stays enabled.
  • Engineering no longer programmatically writes tax_exempt, so a CS-set exemption in Stripe is never overwritten.
  • The tax-ID banner is gated on Stripe's view of taxability; US customers never see it (preserves PM-37820).

Changes

  • Delete the 11 flag-OFF tax_exempt write branches across the org/provider/premium/payment commands, UpcomingInvoiceHandler, and ProviderBillingService (keeping the already-unconditional automatic_tax writes).
  • Collapse the tax-ID banner gating in GetOrganizationWarningsQuery and GetProviderWarningsQuery to the flag-ON conditions.
  • Delete TaxHelpers; relocate the {US, CH} postal-code check onto OrganizationCreateRequestModel as RequiresBillingPostalCode (runtime behavior unchanged).
  • Inline and remove GetCustomerWhileEnsuringCorrectTaxExemptionAsync (its reconciliation is dead once the flag is always-true).
  • Remove the now-unused IFeatureService dependency from 7 classes and delete the flag constant.

No contract or data-model change — the warnings response shape and banner conditions are exactly what production already serves. Server-only, V±2 safe.

Post-merge ops (outside this repo): archive the LaunchDarkly flag pm-37597-always-enable-stripe-automatic-tax.

…x feature flag

The pm-37597-always-enable-stripe-automatic-tax flag has been at 100% in
production since 2026.6.0, so its flag-OFF path is dead code. Remove the flag
and delete the legacy branches that programmatically wrote Stripe tax_exempt,
making the flag-ON behavior unconditional: Stripe is the source of truth for
taxability (customers default to tax_exempt = "none") and the tax-ID banner is
gated on Stripe's view rather than a hardcoded country list.

No end-user behavior change. Relocates the postal-code country check off the
now-deleted TaxHelpers onto OrganizationCreateRequestModel.

Final story of epic PM-36315.
@amorask-bitwarden amorask-bitwarden added the ai-review Request a Claude code review label Jul 15, 2026
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This is a pure code-debt removal of the PM37597_AlwaysEnableStripeAutomaticTax feature flag, which has been at 100% in production since 2026.6.0. The change deletes the dead flag-OFF tax_exempt write branches across the org/provider/premium/payment commands, UpcomingInvoiceHandler, and ProviderBillingService, collapses the tax-ID banner gating in both warnings queries to the flag-ON conditions, and relocates the {US, CH} postal-code check from the deleted TaxHelpers onto OrganizationCreateRequestModel.RequiresBillingPostalCode. Tests were updated in lockstep with the removed branches, and no runtime behavior changes for end users.

Code Review Details

No blocking findings. Verification performed:

  • Both GetOrganizationWarningsQuery and GetProviderWarningsQuery preserve the exact flag-ON conditions (TaxExempt != None → null, US country → null).
  • The GetCustomerWhileEnsuringCorrectTaxExemptionAsync inlining matches the prior flag-ON path (plain GetCustomerOrThrow with the same ["tax", "tax_ids"] expansions).
  • RequiresBillingPostalCode is a faithful relocation of TaxHelpers.IsDirectTaxCountry — same {US, CH} set and same null/empty guard, so runtime behavior is unchanged.
  • No dangling references remain to TaxHelpers, IsDirectTaxCountry, DetermineTaxExemptStatus, the removed flag key, or any inlined/removed helper method (verified repo-wide).
  • Removed IFeatureService dependencies and the flag constant are consistently dropped across the 7 affected classes and their tests.

@amorask-bitwarden amorask-bitwarden added the t:tech-debt Change Type - Tech debt label Jul 15, 2026
@amorask-bitwarden amorask-bitwarden marked this pull request as ready for review July 15, 2026 18:59
@amorask-bitwarden amorask-bitwarden requested review from a team as code owners July 15, 2026 18:59
[InlineData("", false)]
public void Validate_PaidPlanWithoutPostalCode_RequiresPostalCodeForExpectedCountries(
string? billingAddressCountry,
bool postalCodeRequired)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postalCodeRequired is the expected outcome so I'd prefer if this was split into two tests, one expecting true other for false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request a Claude code review t:tech-debt Change Type - Tech debt

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants