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

    CFX's side of an application: handing an APPROVED one over to provisioning.

    Hierarchy (View Summary)

    Index
    db: B2bDatabase
    logger: Pick<Console, "warn" | "error">
    instance: (...args: []) => CustomerApplicationAdminService = ...

    The process service: the applicant's side plus AiPrise, Attio and onboarding.

    • Whether userId may start an application: not while one of theirs (screened out included) is where they belong, nor once they are an ACTIVE member of a customer. Membership of another ACTIVE customer outranks their own application: an applicant invited into one belongs in its dashboard.

      Parameters

      • __namedParameters: { userId: string }

      Returns Promise<
          | { eligible: true }
          | {
              application: CustomerApplication;
              eligible: false;
              reason: "HAS_APPLICATION";
          }
          | { eligible: false; reason: "CUSTOMER_MEMBER" },
      >

    • Provisions the customer of an application whose business profile AiPrise APPROVED, on the operator path: the applicant's workspace, the people AiPrise holds, one workflow run per application. Safe to repeat, and to run concurrently: one profile's handovers take turns.

      Parameters

      • __namedParameters: { verificationProfileId: string }

      Returns Promise<
          | { ok: true; value: { customerId: string } }
          | {
              error:
                  | ServiceError<
                      "ADDRESS_REQUIRED"
                      | "EMAIL_REQUIRED"
                      | "PHONE_REQUIRED",
                  >
                  | ServiceError<
                      | "APPLICATION_NOT_FOUND"
                      | "NOT_APPROVED"
                      | "NO_CONTROL_PERSON"
                      | "INVALID_ADOPTED_PERSON",
                  >
                  | ServiceError<"ONBOARDING_START_FAILED" | "NOT_A_ROUTE_FUSION_PROGRAM">
                  | RoutedError;
              ok: false;
          },
      >

    • The customer provisioning made from an application went ACTIVE: tell the workspace its account is ready. Call only from the write that activated it, so it is sent once. notified is false for an operator-path customer.

      Parameters

      • __namedParameters: { customerId: string }

      Returns Promise<{ ok: true; value: { notified: boolean } }>

    • The framed form's URL for an ACTIVE member of the application's workspace. Rebuilds the stored session's URL, renewing it when under a day is left; only a DRAFT asks AiPrise for a session, getting its profile too.

      Parameters

      • __namedParameters: Applicant & ReturnOrigin & { id: string }

      Returns Promise<
          | { ok: true; value: { url: string } }
          | { error: ServiceError; ok: false },
      >

    • A refresh of the application's AiPrise profile has been written: when it moved the application into review, an information request or a decline, tell the workspace. previous is the shadow the refresh's own write replaced, so a duplicate delivery, which replaces an identical row, finds no change. notified is false when nothing was published.

      Parameters

      • __namedParameters: {
            previous:
                | {
                    lifecycleStatus: | "PROFILE_NOT_SUBMITTED"
                    | "ONBOARDING_SESSIONS_PENDING"
                    | "READY_FOR_REVIEW"
                    | "ADDITIONAL_INFO_REQUESTED"
                    | "MONITORING_UPDATES"
                    | "SESSIONS_EXPIRED"
                    | null;
                    result: | "DECLINED"
                    | "APPROVED"
                    | "REVIEW"
                    | "UNKNOWN"
                    | "DEACTIVATED"
                    | null;
                }
                | null;
            verificationProfileId: string;
        }

      Returns Promise<{ ok: true; value: { notified: boolean } }>

    • Extends the AiPrise session of an applicant who still has the form to finish to a day under AiPrise's 90: the RENEW_LINK of availableActions. Returns only the expiries, never the session.

      Parameters

      • __namedParameters: { id: string }

      Returns Promise<
          | {
              ok: true;
              value: { expiresAt: string; previousExpiresAt: string
              | null };
          }
          | { error: ServiceError; ok: false },
      >

    • Hands a SUBMITTED application whose profile reads APPROVED over again by its id: the RETRY_HANDOVER of availableActions.

      Parameters

      • __namedParameters: { id: string }

      Returns Promise<
          | { ok: true; value: { customerId: string } }
          | {
              error:
                  | ServiceError<
                      "ADDRESS_REQUIRED"
                      | "EMAIL_REQUIRED"
                      | "PHONE_REQUIRED",
                  >
                  | ServiceError<
                      | "APPLICATION_NOT_FOUND"
                      | "NOT_APPROVED"
                      | "NO_CONTROL_PERSON"
                      | "INVALID_ADOPTED_PERSON",
                  >
                  | ServiceError<"ONBOARDING_START_FAILED" | "NOT_A_ROUTE_FUSION_PROGRAM">
                  | RoutedError
                  | ServiceError<
                      "APPLICATION_NOT_FOUND"
                      | "NOT_APPROVED"
                      | "NOT_SUBMITTED",
                  >;
              ok: false;
          },
      >

    • Basics and screener in one submit: screened out, or a workspace the applicant owns, an AiPrise profile and a session. An AiPrise failure throws and leaves the row DRAFT, which openSession resumes.

      Parameters

      Returns Promise<
          | { ok: true; value: CustomerApplication }
          | {
              error:
                  | ServiceError<"INVALID_BASICS", { field: keyof ApplicationBasics }>
                  | ServiceError<
                      "SHORT_NAME_TAKEN"
                      | "ALREADY_APPLYING"
                      | "ALREADY_CUSTOMER_MEMBER",
                  >;
              ok: false;
          },
      >

    • The one write to an existing application. only and unless make it a compare-and-set: the row changes only while its status is only's, and while that column is still null, its status is not yet the one named, or no customer holds its workspace. True when a row changed.

      Parameters

      • __namedParameters: {
            id: number;
            only?: { statuses: CustomerApplicationStatus[] };
            set: Partial<
                Pick<
                    SelectCustomerApplication,
                    | "status"
                    | "verificationProfileId"
                    | "verificationSessionId"
                    | "verificationSessionExpiresAt"
                    | "attioId",
                >,
            >;
            unless?: | { set: "verificationProfileId"
            | "verificationSessionId" }
            | { status: CustomerApplicationStatus }
            | { customer: "exists" };
        }
      • db: Executor = ...

      Returns Promise<boolean>