* feat(mcp): ask the bank first: connect link deep-starts the named bank's consent The connect card used to open the generic picker page; the user then chose the bank there. The agent now asks 'vilken bank har företaget?' among the opening questions and passes it to gnubok_connect_bank, whose connect_url becomes /import?mode=psd2&bank=<name>. BankSelector resolves the name (exact, then unique prefix, then unique substring: ambiguous names fall back to the prefilled picker rather than guessing an institution) and auto-starts that bank's consent through the same onConnect handler, so the duplicate-pending and renew-instead guards stay fully interactive. The param is stripped via history.replaceState after the one-shot so an aborted bank flow plus back-navigation does not silently relaunch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mcp): first-year suggestion keeps the AB vs enskild firma distinction Compliance-review finding on #1949: the suggestion text collapsed both forms onto a 31 December end. Only an enskild firma's first year MUST end 31 December; an AB may pick any end within BFL 3 kap 3 §'s 18-month cap, with 31 December as the common default. The lookup tool's still_to_ask line and the skill now say so explicitly, and first-year-defaults documents that fiscalYear-null is a strong-not-perfect filed-report signal that must only ever feed confirm-question suggestions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
/**
|
|
* Resolve a user-stated bank name ("swedbank", "SEB", "handelsbanken") to
|
|
* one ASPSP from the Enable Banking list, so a deep link can start that
|
|
* bank's consent directly instead of showing the picker.
|
|
*
|
|
* Matching is deliberately conservative: exact (case-insensitive) first,
|
|
* then a UNIQUE prefix match, then a UNIQUE substring match. An ambiguous
|
|
* or unknown name returns null and the caller falls back to the picker
|
|
* with the query prefilled: guessing between "Länsförsäkringar Bank" and a
|
|
* regional "Länsförsäkringar Skåne" would start a consent at the wrong
|
|
* institution.
|
|
*/
|
|
export function matchBankByName<T extends { name: string }>(
|
|
banks: T[],
|
|
query: string
|
|
): T | null {
|
|
const q = query.trim().toLowerCase()
|
|
if (!q) return null
|
|
|
|
const exact = banks.filter((b) => b.name.toLowerCase() === q)
|
|
if (exact.length === 1) return exact[0]
|
|
if (exact.length > 1) return null
|
|
|
|
const prefix = banks.filter((b) => b.name.toLowerCase().startsWith(q))
|
|
if (prefix.length === 1) return prefix[0]
|
|
if (prefix.length > 1) return null
|
|
|
|
const substring = banks.filter((b) => b.name.toLowerCase().includes(q))
|
|
if (substring.length === 1) return substring[0]
|
|
|
|
return null
|
|
}
|