Skip to content

[PM-33854] feat: Add getPlans endpoint to BillingAPIService#2501

Merged
andrebispo5 merged 8 commits intomainfrom
pm-33854/premium-plans-endpoint
Mar 30, 2026
Merged

[PM-33854] feat: Add getPlans endpoint to BillingAPIService#2501
andrebispo5 merged 8 commits intomainfrom
pm-33854/premium-plans-endpoint

Conversation

@andrebispo5
Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-33854

📔 Objective

Add the getPlans() endpoint to BillingAPIService to retrieve the list of available subscription plans. This endpoint is needed for the premium upgrade flow.

Changes:

  • Add PlanType enum (23 plan types) and ProductTierType enum (5 tiers)
  • Add response models: PlansResponseModel, PlanResponseModel, PasswordManagerPlanFeaturesResponseModel, SecretsManagerPlanFeaturesResponseModel
  • Add GetPlansRequest for GET /plans endpoint
  • Add getPlans() method to BillingAPIService protocol and implementation
  • Add test fixtures and unit tests

📸 Screenshots

N/A - API layer changes only

Copilot AI review requested due to automatic review settings March 27, 2026 17:53
@andrebispo5 andrebispo5 requested review from a team and matt-livefront as code owners March 27, 2026 17:53
@github-actions github-actions bot added app:password-manager Bitwarden Password Manager app context t:feature labels Mar 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Billing API endpoint (getPlans) to retrieve available subscription plans, along with the supporting request/response models and fixtures to power the premium upgrade flow.

Changes:

  • Introduces GetPlansRequest (GET /plans) and wires getPlans() into BillingAPIService.
  • Adds plan/tier enums and response models to decode the /plans payload.
  • Adds a JSON fixture plus unit tests validating request construction and response decoding.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
BitwardenShared/Core/Billing/Services/API/Requests/GetPlansRequest.swift Defines the GET /plans request and response type.
BitwardenShared/Core/Billing/Services/API/Requests/GetPlansRequestTests.swift Unit tests for request method/path/body behavior.
BitwardenShared/Core/Billing/Services/API/BillingAPIService.swift Adds getPlans() to protocol and APIService implementation.
BitwardenShared/Core/Billing/Services/API/BillingAPIServiceTests.swift Adds a unit test validating request URL/method and basic decoding.
BitwardenShared/Core/Billing/Services/API/Fixtures/plansResponse.json Adds fixture payload used to test /plans decoding.
BitwardenShared/Core/Billing/Services/API/Fixtures/APITestData+Billing.swift Exposes the new plans fixture via APITestData.
BitwardenShared/Core/Billing/Models/Response/PlansResponseModel.swift Adds top-level response container for plan list.
BitwardenShared/Core/Billing/Models/Response/PlanResponseModel.swift Adds per-plan response model including feature sub-objects.
BitwardenShared/Core/Billing/Models/Response/PasswordManagerPlanFeaturesResponseModel.swift Adds Password Manager feature fields/pricing for a plan.
BitwardenShared/Core/Billing/Models/Response/SecretsManagerPlanFeaturesResponseModel.swift Adds Secrets Manager feature fields/pricing for a plan.
BitwardenShared/Core/Billing/Models/Enum/PlanType.swift Adds plan-type enum used by plan response decoding.
BitwardenShared/Core/Billing/Models/Enum/ProductTierType.swift Adds product-tier enum and helper property used by consumers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3 to +5
public enum ProductTierType: Int, Codable, Equatable, Sendable {
/// Free tier.
case free = 0
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

ProductTierType also uses synthesized Codable for an Int raw-value enum, which will throw on unknown tier values. Since PlanResponseModel.productTier is non-optional, any new tier introduced server-side would make /plans undecodable for all users. Add an explicit unknown/default behavior (e.g., .unknown + custom init(from:), or conform to the project’s default-value decoding pattern) to make this endpoint forward-compatible.

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +5
public enum PlanType: Int, Codable, Equatable, Sendable {
/// Free plan.
case free = 0
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

PlanType relies on the compiler-synthesized Codable conformance for an Int raw-value enum. That decoding throws when the server sends a raw value the client doesn't know about, which would cause the entire /plans response to fail to parse (and break the premium upgrade flow) as soon as the backend adds a new plan type. Consider adding an explicit fallback (e.g., an .unknown case and a custom init(from:) that defaults to it, optionally logging), similar to how other API enums handle unknown raw values (e.g., SendAuthType, PolicyType).

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.94%. Comparing base (daaf1e8) to head (896f69d).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2501      +/-   ##
==========================================
+ Coverage   86.92%   86.94%   +0.02%     
==========================================
  Files        1852     1857       +5     
  Lines      163591   163782     +191     
==========================================
+ Hits       142203   142403     +200     
+ Misses      21388    21379       -9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +25 to +27
var isNotSelfUpgradable: Bool {
self != .free && self != .teamsStarter && self != .families
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⛏️ Add tests.


/// API response model for Password Manager plan features.
///
struct PasswordManagerPlanFeaturesResponseModel: JSONResponse, Equatable, Sendable {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⛏️ Order properties inside each block


// MARK: CodingKeys

enum CodingKeys: String, CodingKey {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🤔 Do you only need the coding keys because of the PascalCase keys?


/// API response model for a subscription plan.
///
struct PlanResponseModel: JSONResponse, Equatable, Sendable {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⛏️ Order properties


/// API response model for Secrets Manager plan features.
///
struct SecretsManagerPlanFeaturesResponseModel: JSONResponse, Equatable, Sendable {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⛏️ Order properties

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 30, 2026

Logo
Checkmarx One – Scan Summary & Details06af0c50-858e-4e15-94fa-9ddac20a3e76

Great job! No new security vulnerabilities introduced in this pull request

@andrebispo5 andrebispo5 enabled auto-merge (squash) March 30, 2026 21:33
@andrebispo5 andrebispo5 merged commit daa621d into main Mar 30, 2026
16 checks passed
@andrebispo5 andrebispo5 deleted the pm-33854/premium-plans-endpoint branch March 30, 2026 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:password-manager Bitwarden Password Manager app context t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants