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

    Write bank documents: the bytes to S3 and their index to bank.bank_document. Every write busts the bank's cached reads once its rows are committed, and every file written or deleted is published on the internal bus.

    Hierarchy (View Summary)

    Index
    cache: ServiceCache<CachedSearchPage<OwnedDocument<"bankId">>>
    db: B2bDatabase
    index: DocumentIndexConfig<"bankId", "BANK">
    s3Bucket: () => string

    Read at each use: a config namespace's resolver.

    s3Client: S3Client
    instance: (...args: []) => BankDocumentService = ...

    The process default: built from each dependency's own instance().

    • Indexes a file a bank user's browser has put in S3 through createUpload, sized from S3 and typed from its name. replaced says whether a live file was at the path.

      Parameters

      Returns Promise<
          | {
              ok: true;
              value: { document: OwnedDocumentFile<"bankId">; replaced: boolean };
          }
          | { error: DocumentError; ok: false },
      >

    • Checks a bank user's upload and signs the PUT their browser sends straight to S3. Writes no row: completeUpload indexes the file once the bytes are there. headers is exactly what the PUT must carry.

      Parameters

      • args: DocumentOwnerArg<"bankId"> & {
            folder: string;
            name: string;
            type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS";
            updatedByUserId?: string;
        } & { replace: boolean } & { size: number }
        • folder: string
        • name: string
        • type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS"
        • OptionalupdatedByUserId?: string

          The dashboard user writing it; omit for CFX staff, who leave it null.

        • replace: boolean

          Whether a live file already at the path may be overwritten.

        • size: number

          In bytes; the signature holds the upload to exactly this length.

      Returns Promise<
          | {
              ok: true;
              value: { expiresAt: Date; headers: Record<string, string>; url: string };
          }
          | { error: DocumentError; ok: false },
      >

    • Soft-deletes a document of type and, for a file, removes its object. An unknown or already deleted id is fine; a retry finishes a delete whose S3 call failed. A folder that still holds a live document is refused with FOLDER_NOT_EMPTY.

      Parameters

      Returns Promise<{ ok: true; value: void } | { error: DocumentError; ok: false }>

    • A 15-minute link that downloads the file under its name; null as getStream.

      Parameters

      • args: DocumentOwnerArg<"bankId"> & {
            id: string;
            type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS";
        }
        • id: string
        • type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS"

          A document of any other type is not found.

      Returns Promise<{ ok: true; value: string | null }>

    • Indexes a file a dashboard user's browser has put in S3 through signUpload. Its size is read from S3 and its content type from its name; neither is taken from the caller or from what the browser sent. The object must be that upload: newer than the row it replaces, or recent where there is no row. replaced says whether a live file was at the path.

      Parameters

      Returns Promise<
          | {
              ok: true;
              value: { document: OwnedDocumentFile<"bankId">; replaced: boolean };
          }
          | { error: DocumentError; ok: false },
      >

    • Clear each customer's membership tag and each record tag wherever cached, and always this namespace's collection tag. keys are exact deletes in this instance's key space: the only bust a null client honours.

      Parameters

      • __namedParameters: {
            customerIds: readonly string[];
            keys?: readonly CacheKey[];
            records?: readonly string[];
        }

      Returns Promise<void>

    • Where type's objects go under the owner's root, below folder if given.

      Parameters

      • __namedParameters: Pick<Owner, "root">
      • type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS"
      • Optionalfolder: string

      Returns string

    • Indexes what is already in S3 for one bank: inserts the file and folder rows that are missing and never modifies an existing one. dryRun reads S3 and the index and reports what a run would insert.

      Parameters

      • args: { bankId: string; dryRun: boolean }

      Returns Promise<
          {
              ok: true;
              value: {
                  files: { found: number; inserted: number; skipped: number };
                  folders: { found: number; inserted: number };
              };
          },
      >

    • Indexes what is already in S3 for one owner: inserts the file and folder rows that are missing and never modifies an existing one. dryRun reads S3 and the index and reports what a run would insert. files.found counts every live object, files.skipped those whose path the index cannot hold.

      Parameters

      Returns Promise<
          {
              ok: true;
              value: {
                  files: { found: number; inserted: number; skipped: number };
                  folders: { found: number; inserted: number };
              };
          },
      >

    • Soft-deletes a document of type and, for a file, removes its object. An id that names nothing of that type and those kinds is fine. So is one already deleted, whose object is removed again: that is how a retry finishes a delete whose S3 call failed. A folder that still holds a live document is refused and left as it is.

      Parameters

      Returns Promise<{ ok: true; value: void } | { error: DocumentError; ok: false }>

    • One owner's documents, folders before files and then by orderBy, which defaults to name ascending. folders matches the parent path exactly, so [""] lists the root. A filter given an empty list matches nothing.

      Parameters

      Returns Promise<
          {
              ok: true;
              value: {
                  hasNext: boolean;
                  items: OwnedDocument<"bankId">[];
                  total: number;
              };
          },
      >

    • Tags for a page: the scope its query searched (each customer's membership tag, else the collection tag), so an empty page is bustable too, plus the records it projects and the fields that chose or ordered its rows.

      Parameters

      • __namedParameters: {
            customerIds: readonly string[] | undefined;
            fields?: readonly string[];
            records?: readonly string[];
        }

      Returns string[]

    • Checks a dashboard user's upload and signs the PUT their browser sends straight to S3. Writes no row: indexUpload indexes the file once the bytes are there. headers is exactly what the PUT must carry: the uploader, signed into the object's metadata, and a condition on what the key holds now, so the URL writes once and cannot replay over a later write.

      Parameters

      • args: DocumentOwnerArg<"bankId"> & {
            folder: string;
            name: string;
            type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS";
            updatedByUserId?: string;
        } & { replace: boolean } & { size: number }
        • folder: string
        • name: string
        • type: "CUSTOM" | "LOGO" | "PRICING_SCHEDULE" | "TERMS"
        • OptionalupdatedByUserId?: string

          The dashboard user writing it; omit for CFX staff, who leave it null.

        • replace: boolean

          Whether a live file already at the path may be overwritten.

        • size: number

          In bytes; the signature holds the upload to exactly this length.

      Returns Promise<
          | {
              ok: true;
              value: { expiresAt: Date; headers: Record<string, string>; url: string };
          }
          | { error: DocumentError; ok: false },
      >