Skip to content

[PM-32809] feat: wire Bank Account through BitwardenSdk#2576

Draft
SaintPatrck wants to merge 4 commits intovault/pm-32809-ios-bank-account-foundationfrom
vault/pm-32809-ios-bank-account-sdk-bridge
Draft

[PM-32809] feat: wire Bank Account through BitwardenSdk#2576
SaintPatrck wants to merge 4 commits intovault/pm-32809-ios-bank-account-foundationfrom
vault/pm-32809-ios-bank-account-sdk-bridge

Conversation

@SaintPatrck
Copy link
Copy Markdown
Contributor

@SaintPatrck SaintPatrck commented Apr 24, 2026

🎟️ Tracking

📔 Objective

Stage the CipherType.bankAccount case and the SDK bridge arms on top of the foundation PR so the eventual sdk-swift bump is a drop-in. Will not compile against the currently pinned SDK — held with hold label until the SDK release lands. Once available, one commit bumps project-common.yml + Package.resolved and this PR goes green.

…M-32809 Part 1/3)

First of three vertical slices for PM-32809. Establishes the type-
level foundation for the Bank Account cipher type without touching
the vault-list plumbing (Part 2/3) or the add/edit/view UI surfaces
(Part 3/3).

Included:

- `FeatureFlag.newItemTypes` (`pm-32009-new-item-types`) added to the
  flag registry. Gates the epic's three new cipher types at the flag
  layer; default OFF.
- `CipherType.bankAccount = 6` added alongside `allCases`,
  `localizedName`, `allowedFieldTypes` (text / hidden / boolean —
  `.linked` is excluded per US-1.1), and the new `iconPlaceholder`
  helper that centralizes icon routing for PM-34128's eventual asset
  swap.
- `CipherType.init(type:)` and `CipherType.init(_:)` become failable
  (`init?`) with `@unknown default: return nil`, so future SDK bumps
  no longer force a closed-switch compile break on unrelated PRs.
  Cascade `?? .secureNote` fallbacks land at the five existing call
  sites (`CipherItemState` clone / existing / apply, `CipherView+
  Update.updatedView`, `CipherRequestModel`, `BitwardenSdk+Vault`
  response-model inits, `ExportVaultService` restricted-type filter).
- `canCreateCasesBase` / `canCreateCasesWithNewItemTypes` constants
  plus the flag-aware `canCreateCases(isNewItemTypesEnabled:)` helper.
  The legacy static `canCreateCases` is gone; Part 2/3 wires the
  helper through `VaultRepository.getItemTypesUserCanCreate()`.
- `BankAccountType` raw-value enum (Checking / Savings / CD /
  LineOfCredit / InvestmentBrokerage / MoneyMarket / Other). Ships
  without `Menuable` conformance in Part 1 — that conformance (and
  the seven display-name localization keys it depends on) lands in
  Part 3/3 when the menu field consumes it.
- `CipherBankAccountModel` API model (Codable, Equatable, Sendable)
  with an explicit memberwise init defaulting every parameter to
  `nil`. Carries the serialization-tripwire docstring so future-you
  knows the model must never reach the wire directly — only through
  SDK encryption once the SDK exposes `BankAccount` / `BankAccountView`.
- `CipherDetailsResponseModel` / `CipherMiniResponseModel` each gain
  `var bankAccount: CipherBankAccountModel? = nil` with the
  swiftformat/swiftlint pins that keep the `= nil` alive, so the
  synthesized memberwise init remains source-compatible with all
  pre-PM-32009 test call sites.
- `NewItemTypesSdkBridge` (stateless enum shim) centralizes SDK-
  availability gating. `isBankAccountAvailable` is the single switch
  to flip when the SDK dependency is bumped; `sdkCipherTypeForBank
  Account()` and `appCipherTypeForBankAccount(_:)` route the conversions.
  PRs 2 and 3 (Driver's License, Passport) will extend this shim.
- `BitwardenSdk.CipherType(_:)` becomes failable with a Debug-build
  `assertionFailure` tripwire on the `.bankAccount → nil` path so
  accidentally enabling the flag before SDK readiness is caught in
  development.
- `ViewItemState.navigationTitle` gets a `.bankAccount` arm using
  `Localizations.viewBankAccount`; `CipherItemState.navigationTitle`
  uses `Localizations.newItem` / `Localizations.edit` as Part 1
  placeholders — Part 3/3 replaces those with `newBankAccount` /
  `editBankAccount`.
- `LinkedIdType.getLinkedIdType(for:)` gains an empty-array arm for
  `.bankAccount` so the exhaustive switch keeps compiling.

Tests: `BankAccountTypeTests` (raw values, ordering, JSON round-trip),
`CipherBankAccountModelTests` (memberwise init, Codable round-trip),
expanded `CipherTypeTests` (`canCreateCasesBase`,
`canCreateCasesWithNewItemTypes`, `canCreateCases(isNewItemTypesEnabled:)`,
`.bankAccount` on `allowedFieldTypes` / `localizedName` / `allCases`).

Localization: ONLY `TypeBankAccount` and `ViewBankAccount` added.
Field labels, account-type display names, and processor alert strings
are deferred to the Part 2/3 and Part 3/3 slices that introduce the
UI consuming them.

SDK dependency: `BitwardenSdk` currently stops at `CipherType.sshKey = 5`
with no `BankAccount` / `BankAccountView`. All SDK-facing paths are
gated through `NewItemTypesSdkBridge` and TODO-marked with `PM-32009
Blocked on SDK`. The flag must remain OFF until the SDK is bumped —
coordinate with PM-34060 (Nick Krantz's cross-platform SDK work).

Ticket: PM-32809 (Part 1/3)
Folds in the two non-blocking nits from review Round 2:

- `CipherItemState.swift`: Add the parallel `// TODO: PM-32809 Part 3/3`
  comment to the `.add → .bankAccount` branch so both the new/edit
  placeholder strings get picked up atomically when Part 3/3 swaps in
  `Localizations.newBankAccount` / `Localizations.editBankAccount`.
- `BankAccountType.swift`: Drop the unused `import BitwardenResources`.
  The `Menuable` conformance (which needs the localization keys) is
  deferred to Part 3/3; the raw enum in Part 1 doesn't need the import.

Also tightens three cascade breaks that appeared after the previous
build pass — all stem from `CipherType.bankAccount` becoming a case on
an exhaustive switch / a renamed static:

- `View.swift`, `VaultListState.swift`, `VaultGroupState.swift`: the
  three default-parameter sites that previously pointed at the legacy
  `CipherType.canCreateCases` static (now removed in favor of the
  flag-aware helper) now seed from `CipherType.canCreateCasesBase`. The
  processors continue to override these defaults via
  `VaultRepository.getItemTypesUserCanCreate()` — that wiring lands in
  Part 2/3.
- `AddEditItemView.swift` (`itemTypeSection`) and
  `ViewItemDetailsView.swift` (`itemInformationSection`): add an
  `EmptyView()` placeholder for `.bankAccount` so the exhaustive switch
  compiles. Creation is flag-gated upstream, so these branches are
  unreachable until Part 3/3 wires the real `AddEditBankAccountItemView`
  / `ViewBankAccountItemView` — TODOs pinned at both sites.

Ticket: PM-32809 (Part 1/3)
Relies solely on the `newItemTypes` feature flag to gate bank account
creation end-to-end. Adds the final PM-34128 bank account icon asset.
Stages the CipherType.bankAccount case and SDK bridge arms so the
upcoming sdk-swift release (2.0.0-6370-96753eef) is a drop-in bump.
@SaintPatrck SaintPatrck added t:feature-app Change Type - Product feature or enhancement app:password-manager Bitwarden Password Manager app context hold This shouldn't be merged yet labels Apr 24, 2026
@github-actions github-actions Bot added t:feature and removed t:feature-app Change Type - Product feature or enhancement labels Apr 24, 2026
@SaintPatrck SaintPatrck added the ai-review-vnext Request a Claude code review using the vNext workflow label Apr 24, 2026
@SaintPatrck SaintPatrck force-pushed the vault/pm-32809-ios-bank-account-foundation branch from 6cfe443 to 1d619c0 Compare April 30, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review-vnext Request a Claude code review using the vNext workflow app:password-manager Bitwarden Password Manager app context hold This shouldn't be merged yet t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant