feat: Add BankCapabilities to expose bank feature flags#36
feat: Add BankCapabilities to expose bank feature flags#36
Conversation
Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
- Add BankCapabilities interface to types.ts with 9 capability flags derived from FinTS parameter segments (HIKAZS, HISALS, HIWPDS, HICCSS, HIDSES, HICDBS) - Add supportsCreditTransfer, supportsDirectDebit, hikazsMinSignatures and hisalsMinSignatures fields to Dialog, populated during sync() - Add Dialog.capabilities getter assembling BankCapabilities from state - Add Client.capabilities() async method (sync + return capabilities) - Add tests in test-client.ts and test-dialog.ts Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8cb423fe8b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const hikazs = response.findSegment(HIKAZS); | ||
| this.hikazsMinSignatures = hikazs?.minSignatures ?? 0; | ||
| const hisals = response.findSegment(HISALS); | ||
| this.hisalsMinSignatures = hisals?.minSignatures ?? 0; |
There was a problem hiding this comment.
Derive TAN requirements from negotiated segment version
sync() determines supported HIKAZS/HISALS versions via segmentMaxVersion(...), but requiresTanForTransactions/requiresTanForBalance are populated from response.findSegment(...), which returns the first segment instance, not necessarily the version that will actually be used by requests. When a bank advertises multiple versions of these parameter segments and minSignatures differs between versions, dialog.capabilities can report incorrect TAN requirements; read minSignatures from the selected max version (or aggregate safely across all advertised versions).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds a first-class way to discover which FinTS business transactions a bank advertises during the initial sync dialog, so callers can avoid probing endpoints individually.
Changes:
- Introduce a new
BankCapabilitiesinterface to represent bank feature flags derived from sync parameter segments. - Extend
Dialog.sync()to record additional capability-related fields and add adialog.capabilitiesgetter. - Add
Client.capabilities()plus unit tests covering bothDialogandClientcapability derivation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/fints/src/types.ts | Adds BankCapabilities interface and documentation. |
| packages/fints/src/dialog.ts | Captures additional sync-derived fields and exposes them via a capabilities getter. |
| packages/fints/src/client.ts | Adds capabilities(): Promise<BankCapabilities> convenience API. |
| packages/fints/src/tests/test-dialog.ts | Tests Dialog.capabilities mapping from dialog state. |
| packages/fints/src/tests/test-client.ts | Tests Client.capabilities() behavior using mocked sync/end responses. |
| IMPLEMENTATION_SUMMARY.md | Removed from repository in this PR. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/fints/src/dialog.ts
Outdated
| @@ -153,12 +174,18 @@ export class Dialog extends DialogConfig { | |||
| this.hicdbVersion = response.segmentMaxVersion(HICDBS); | |||
There was a problem hiding this comment.
sync() sets hisalsVersion/hikazsVersion/hicdbVersion directly to segmentMaxVersion(...), which can be 0 when the parameter segment is absent. These version fields are later used to construct request segments (e.g. HKSAL/HKKAZ) that throw on unsupported versions, so this can cause a local "Unsupported ... version 0" error instead of a clear "feature not supported" result. Consider keeping the request version at a valid default (e.g. latest supported) and tracking support separately, or add explicit capability checks before constructing versioned request segments.
There was a problem hiding this comment.
Fixed in 3c89d4c. The approach:
- Added dedicated
supportsBalance,supportsTransactions, andsupportsStandingOrdersboolean fields (defaulting tofalse) alongside the existingsupportsCreditTransfer/supportsDirectDebitpattern. sync()now sets each boolean flag fromsegmentMaxVersion > 0and only updates the request-version field when the bank actually advertises support — sohisalsVersion,hikazsVersion, andhicdbVersionkeep their safe defaults (6,6,1) when the segment is absent, preventing any "Unsupported version 0" error inHKSAL/HKKAZ.- The
capabilitiesgetter now reads from the boolean fields rather than> 0version checks, which also fixes incorrect pre-sync()values (the old defaults of 6/6/1 would have producedtruebefore sync ran). - Also merged the two separate
./typesimport statements into one.
packages/fints/src/dialog.ts
Outdated
| HICCSS, | ||
| Segment, | ||
| } from "./segments"; | ||
| import { BankCapabilities } from "./types"; |
There was a problem hiding this comment.
There are now two separate imports from ./types (Connection above and BankCapabilities here). Consider merging them into a single import to avoid duplication and keep import blocks consistent.
packages/fints/src/dialog.ts
Outdated
| public get capabilities(): BankCapabilities { | ||
| return { | ||
| supportsAccounts: true, | ||
| supportsBalance: this.hisalsVersion > 0, | ||
| supportsTransactions: this.hikazsVersion > 0, |
There was a problem hiding this comment.
capabilities can return incorrect supports* values if accessed before sync() runs, because several *Version fields have non-zero defaults (e.g. hisalsVersion = 6, hikazsVersion = 6, hicdbVersion = 1). Consider adding a guard (e.g. track hasSynced and throw) or deriving support from fields that are only set during sync so consumers can’t accidentally get a misleading capabilities object.
| public async capabilities(): Promise<BankCapabilities> { | ||
| const dialog = this.createDialog(); | ||
| await dialog.sync(); | ||
| return dialog.capabilities; | ||
| } |
There was a problem hiding this comment.
The PR description focuses on adding BankCapabilities, but the diff also removes IMPLEMENTATION_SUMMARY.md entirely. If that removal is intentional cleanup, please mention it in the PR description or move it to a separate PR to keep this change focused.
|
@copilot apply changes based on the comments in this thread |
- Add supportsBalance, supportsTransactions, supportsStandingOrders boolean fields (default false) to Dialog, populated during sync() - Keep hisalsVersion, hikazsVersion, hicdbVersion at their safe defaults when the bank does not advertise the feature, preventing 'Unsupported version 0' errors in HKSAL/HKKAZ constructors - Update capabilities getter to use the new boolean fields instead of version > 0 checks, fixing misleading results before sync() runs - Merge the two separate import blocks from ./types into one - Add pre-sync capabilities test to test-dialog.ts Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
This file pre-existed and was unintentionally removed in the feature commit. Restoring it to keep this PR focused on the BankCapabilities feature only. Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
All four review comments are now addressed:
|
Banks vary in which FinTS business transactions they support. There was no way to discover this without probing each endpoint individually.
Changes
New
BankCapabilitiesinterface (types.ts)Nine flags derived from parameter segments in the sync response:
supportsAccountstrue(universally supported)supportsBalancesupportsTransactionssupportsHoldingssupportsStandingOrderssupportsCreditTransfersupportsDirectDebitrequiresTanForTransactionsminSignatures > 0requiresTanForBalanceminSignatures > 0Dialog(dialog.ts)supportsCreditTransfer,supportsDirectDebit,hikazsMinSignatures,hisalsMinSignaturesfields, populated duringsync()capabilitiesgetter that assemblesBankCapabilitiesfrom current dialog stateClient(client.ts)capabilities(): Promise<BankCapabilities>— runs a sync dialog and returnsdialog.capabilitiesBankCapabilitiesis exported from the package's public index.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.