@cfxlabsinc/b2b-services
    Preparing search index...

    Module @cfxlabsinc/bank-services

    bank-services

    Services For managing transactions exposed to us by different banks.

    BankAdminService reads and writes a bank together with its dashboard workspace row (bank.bank_dashboard_workspace, one per bank through b2b.bank.workspace_id). The workspace holds the dashboard-only configuration, which Bank exposes as dashboardDomain, dashboardEnabled, theme and workspaceId (the bws_… id). Design: DASHBOARD_WORKSPACE_TABLES.md.

    • create inserts the workspace with the bank. update naming only dashboardDomain, dashboardEnabled or theme writes nothing on bank.
    • A dashboard domain is one label under cfx.to or dev.cfx.to (BANK_DASHBOARD_DOMAIN_PATTERN, exported only from the @cfxlabsinc/bank-services/dashboardDomain subpath, the same pattern as the table's CHECK). One that fails it is BANK_DASHBOARD_DOMAIN_INVALID; one another bank holds is BANK_DASHBOARD_DOMAIN_TAKEN.
    • dashboardEnabled is independent of the domain. Giving a bank its first domain enables its dashboard and clearing the domain disables it, unless the call passes dashboardEnabled.
    • BankDashboardHostService.getDashboardHost({ host }) is the read bank-dashboard makes before anyone has signed in: the name, theme and enabled flag of the workspace whose domain is host, enabled or not, else null. The dashboard brands only an enabled host and refuses everyone on a disabled one. It names no bank or workspace id. It is cached per host under the dashboardHost key prefix of the bank-search namespace (a miss is kept 60s). BankAdminService takes the reader as dashboardHostService and every bank write calls its invalidate, deleting the entry for each host the bank held before or holds now. Construct both with the same valkeyClient; under a null client (tests) each instance holds its own entries, so pass the reader the host reads go through.

    BankDocumentService keeps a bank's documents: the bytes in S3 under bank-documents/<bankId>/, and one row per file or folder in bank.bank_document. Every create and delete writes both, S3 first on a create and the row first on a delete, so a failure never leaves a row pointing at nothing. Every listing and lookup reads the table, behind the bank-document-search cache that each write busts by bank; S3 is read only when a file is opened, previewed or downloaded. The engine is the shared DocumentIndex of document-services, which customer documents use too; BankDocumentCache holds the bank's configuration of it.

    reconcile indexes what S3 already holds for a bank and never changes an existing row. scripts/backfillBankDocuments.ts runs it for one bank or all of them; when and how is in bank-document-not-indexed.md.

    reconcileObject({ key }) is the one-key version s3-event-handler calls for each S3 object event: a live object with no row gets its row and the folder rows above it, a row whose object is gone is soft-deleted, and a signed dashboard upload (an object carrying uploaded-by metadata) is skipped. S3 is never written. Every file written or deleted is published as bank.document.created / bank.document.deleted on the internal event bus, with data { bankId, key }; dashboard writes, the workflows and s3-event-handler publish the same two, and reconcile publishes none.

    BankAccountAdminService
    BankAccountQueryService
    BankAdminService
    BankBrandingService
    BankDashboardHostService
    BankDocumentCache
    BankDocumentQueryService
    BankDocumentService
    ProgramAdminService
    ProgramQueryService
    Bank
    BankAccount
    BankAccountOrderField
    BankAccountRegistration
    BankDashboardHost
    BankDocument
    BankDocumentCreatedEvent
    BankDocumentDeletedEvent
    BankDocumentStream
    BankId
    Program
    ProgramGrant
    ProviderBankPlan
    RecordedRouteFusionBeneficiary