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

    Unless need to directly act on an identity specifically, you should be using EntityService instead.

    Extends IdentityCache for the bust seam its writer subclass needs, not for a read surface — this search is not cached today. Rooting it here is what lets IdentityAdminService bust the instance it reads through once it is, rather than a detached buster, whose delete cannot reach this instance's entries under a null client.

    Hierarchy (View Summary)

    Index
    cache: ServiceCache<
        CachedSearchPage<
            {
                achName: string;
                amlVerification?: { id: string; status: VerificationStatus } & {
                    statusDescription: string;
                };
                capabilities: (
                    | "TRANSACT"
                    | "MANAGE_PAYMENT_INSTRUMENT"
                    | "MANAGE_LEDGER_ACCOUNT"
                    | "MANAGE_DEPOSIT_MEMO"
                )[];
                countryCode: string;
                countryOfResidence: string;
                createdAt: Date;
                customerVerification?: { id: string };
                dateOfBirth?: string;
                deletedAt?: Date;
                email: string;
                fullName: string;
                id: string;
                identityDocumentVerification?: { id: string; status: VerificationStatus } & {
                    statusDescription: string;
                };
                metadata: Record<string, string>;
                name: { firstName: string; lastName: string; middleName?: string };
                phone: string;
                referenceId?: string;
                requiredInfo: RequiredInfoField[];
                status:
                    | "PENDING_VERIFICATION"
                    | "ACTION_REQUIRED"
                    | "APPROVED"
                    | "DISABLED"
                    | "DELETED"
                    | "REVIEW"
                    | "BLOCKED";
                statusDescription: string;
                taxId?: string;
                type: "IDENTITY";
                updatedAt: Date;
                uuid: string;
                verificationProfileId?: string;
                verificationReasonCode?: | "OTHER"
                | "INVALID_TAX_ID"
                | "ADDRESS_MISMATCH"
                | "REGISTRY_NOT_FOUND"
                | "DOCUMENT_ISSUE"
                | "IDENTITY_MISMATCH";
                verificationReasonCodeDescription?: string;
                wireName: string;
            },
        >,
    >
    db: B2bDatabase
    instance: (...args: []) => IdentityAdminService = ...

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

    • Push an operator's decision to AiPrise; the RESULT_UPDATE webhook is the only status writer. A caller that already read the live row passes verificationProfileId to skip the re-read.

      Parameters

      • __namedParameters: {
            decision: "APPROVED" | "DECLINED";
            id: string;
            note?: string;
            reasonCode?: string;
            verificationProfileId?: string;
        }
        • decision: "APPROVED" | "DECLINED"
        • id: string
        • Optionalnote?: string

          Kept beside the code as the MANUAL reason's detail; AiPrise never sees it.

        • OptionalreasonCode?: string
        • OptionalverificationProfileId?: string

      Returns Promise<
          | { ok: true; value: { verificationProfileId: string } }
          | { error: ServiceError; 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>

    • 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[]

    • Updates do NOT trigger AiPrise verification, and publish a status event only when the status they write differs from the stored one.

      data.workspaceId links the IDENTITY workspace this person signs in through. Set once: the same workspace again writes nothing, another is refused. Only a link may run in a caller's tx, in a savepoint of it, so a refused link leaves the tx usable.

      Parameters

      • args: {
            customerId?: string;
            data: Partial<
                Pick<
                    {
                        achName: string;
                        amlVerification?: { id: string; status: VerificationStatus } & {
                            statusDescription: string;
                        };
                        capabilities: (
                            | "TRANSACT"
                            | "MANAGE_PAYMENT_INSTRUMENT"
                            | "MANAGE_LEDGER_ACCOUNT"
                            | "MANAGE_DEPOSIT_MEMO"
                        )[];
                        countryCode: string;
                        countryOfResidence: string;
                        createdAt: Date;
                        customerVerification?: { id: string };
                        dateOfBirth?: string;
                        deletedAt?: Date;
                        email: string;
                        fullName: string;
                        id: string;
                        identityDocumentVerification?: {
                            id: string;
                            status: VerificationStatus;
                        } & { statusDescription: string };
                        metadata: Record<string, string>;
                        name: { firstName: string; lastName: string; middleName?: string };
                        phone: string;
                        referenceId?: string;
                        requiredInfo: RequiredInfoField[];
                        status:
                            | "PENDING_VERIFICATION"
                            | "ACTION_REQUIRED"
                            | "APPROVED"
                            | "DISABLED"
                            | "DELETED"
                            | "REVIEW"
                            | "BLOCKED";
                        statusDescription: string;
                        taxId?: string;
                        type: "IDENTITY";
                        updatedAt: Date;
                        uuid: string;
                        verificationProfileId?: string;
                        verificationReasonCode?: | "OTHER"
                        | "INVALID_TAX_ID"
                        | "ADDRESS_MISMATCH"
                        | "REGISTRY_NOT_FOUND"
                        | "DOCUMENT_ISSUE"
                        | "IDENTITY_MISMATCH";
                        verificationReasonCodeDescription?: string;
                        wireName: string;
                    },
                    "name"
                    | "achName"
                    | "wireName",
                >,
            > & {
                amlVerification?: { id: string; status: VerificationStatus };
                customerVerification?: { id: string };
                identityDocumentVerification?: { id: string; status: VerificationStatus };
                verificationProfileId?: string;
            } & {
                dateOfBirth?: string
                | null;
                status?:
                    | "PENDING_VERIFICATION"
                    | "ACTION_REQUIRED"
                    | "APPROVED"
                    | "DISABLED"
                    | "REVIEW"
                    | "BLOCKED";
                taxId?: string
                | null;
                verificationReasons?: VerificationReasons | null;
            } & { workspaceId?: undefined };
            id: string;
            tx?: undefined;
        }

      Returns Promise<
          | {
              ok: true;
              value: {
                  achName: string;
                  amlVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  capabilities: (
                      | "TRANSACT"
                      | "MANAGE_PAYMENT_INSTRUMENT"
                      | "MANAGE_LEDGER_ACCOUNT"
                      | "MANAGE_DEPOSIT_MEMO"
                  )[];
                  countryCode: string;
                  countryOfResidence: string;
                  createdAt: Date;
                  customerVerification?: { id: string };
                  dateOfBirth?: string;
                  deletedAt?: Date;
                  email: string;
                  fullName: string;
                  id: string;
                  identityDocumentVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  metadata: Record<string, string>;
                  name: { firstName: string; lastName: string; middleName?: string };
                  phone: string;
                  referenceId?: string;
                  requiredInfo: RequiredInfoField[];
                  status:
                      | "PENDING_VERIFICATION"
                      | "ACTION_REQUIRED"
                      | "APPROVED"
                      | "DISABLED"
                      | "DELETED"
                      | "REVIEW"
                      | "BLOCKED";
                  statusDescription: string;
                  taxId?: string;
                  type: "IDENTITY";
                  updatedAt: Date;
                  uuid: string;
                  verificationProfileId?: string;
                  verificationReasonCode?: | "OTHER"
                  | "INVALID_TAX_ID"
                  | "ADDRESS_MISMATCH"
                  | "REGISTRY_NOT_FOUND"
                  | "DOCUMENT_ISSUE"
                  | "IDENTITY_MISMATCH";
                  verificationReasonCodeDescription?: string;
                  wireName: string;
              } & { customerId: string };
          }
          | { error: ServiceError; ok: false },
      >

    • Updates do NOT trigger AiPrise verification, and publish a status event only when the status they write differs from the stored one.

      data.workspaceId links the IDENTITY workspace this person signs in through. Set once: the same workspace again writes nothing, another is refused. Only a link may run in a caller's tx, in a savepoint of it, so a refused link leaves the tx usable.

      Parameters

      • args: IdentityAdminUpdateArgs

      Returns Promise<
          | {
              ok: true;
              value: {
                  achName: string;
                  amlVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  capabilities: (
                      | "TRANSACT"
                      | "MANAGE_PAYMENT_INSTRUMENT"
                      | "MANAGE_LEDGER_ACCOUNT"
                      | "MANAGE_DEPOSIT_MEMO"
                  )[];
                  countryCode: string;
                  countryOfResidence: string;
                  createdAt: Date;
                  customerVerification?: { id: string };
                  dateOfBirth?: string;
                  deletedAt?: Date;
                  email: string;
                  fullName: string;
                  id: string;
                  identityDocumentVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  metadata: Record<string, string>;
                  name: { firstName: string; lastName: string; middleName?: string };
                  phone: string;
                  referenceId?: string;
                  requiredInfo: RequiredInfoField[];
                  status:
                      | "PENDING_VERIFICATION"
                      | "ACTION_REQUIRED"
                      | "APPROVED"
                      | "DISABLED"
                      | "DELETED"
                      | "REVIEW"
                      | "BLOCKED";
                  statusDescription: string;
                  taxId?: string;
                  type: "IDENTITY";
                  updatedAt: Date;
                  uuid: string;
                  verificationProfileId?: string;
                  verificationReasonCode?: | "OTHER"
                  | "INVALID_TAX_ID"
                  | "ADDRESS_MISMATCH"
                  | "REGISTRY_NOT_FOUND"
                  | "DOCUMENT_ISSUE"
                  | "IDENTITY_MISMATCH";
                  verificationReasonCodeDescription?: string;
                  wireName: string;
              } & { customerId: string };
          }
          | {
              error: ServiceError<"NOT_FOUND">
              | IdentityWorkspaceLinkError;
              ok: false;
          },
      >

    • Uplift an identity that was created with Plaid verification before AiPrise was introduced.

      It creates the AiPrise profile and configures continuous AML monitoring.

      Parameters

      • __namedParameters: { customerId?: string; id: string }

      Returns Promise<
          | { error: ServiceError; ok: false }
          | {
              ok: true;
              value: {
                  achName: string;
                  amlVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  capabilities: (
                      | "TRANSACT"
                      | "MANAGE_PAYMENT_INSTRUMENT"
                      | "MANAGE_LEDGER_ACCOUNT"
                      | "MANAGE_DEPOSIT_MEMO"
                  )[];
                  countryCode: string;
                  countryOfResidence: string;
                  createdAt: Date;
                  customerVerification?: { id: string };
                  dateOfBirth?: string;
                  deletedAt?: Date;
                  email: string;
                  fullName: string;
                  id: string;
                  identityDocumentVerification?: { id: string; status: VerificationStatus } & {
                      statusDescription: string;
                  };
                  metadata: Record<string, string>;
                  name: { firstName: string; lastName: string; middleName?: string };
                  phone: string;
                  referenceId?: string;
                  requiredInfo: RequiredInfoField[];
                  status:
                      | "PENDING_VERIFICATION"
                      | "ACTION_REQUIRED"
                      | "APPROVED"
                      | "DISABLED"
                      | "DELETED"
                      | "REVIEW"
                      | "BLOCKED";
                  statusDescription: string;
                  taxId?: string;
                  type: "IDENTITY";
                  updatedAt: Date;
                  uuid: string;
                  verificationProfileId?: string;
                  verificationReasonCode?: | "OTHER"
                  | "INVALID_TAX_ID"
                  | "ADDRESS_MISMATCH"
                  | "REGISTRY_NOT_FOUND"
                  | "DOCUMENT_ISSUE"
                  | "IDENTITY_MISMATCH";
                  verificationReasonCodeDescription?: string;
                  wireName: string;
              } & { customerId: string };
          },
      >

    • The exact cache key IdentityQueryService.get reads through.

      get folds onto search, so its entry is an ordinary single-row search page — these args must stay identical to the ones get passes ({ customerId, ids: [id], pageSize: 1 }, with search's page default of 1). Every other search filter is undefined there, and serviceCacheKey canonicalizes with JCS, which drops undefined properties — so naming only the four that are set produces the same digest. identityCache.test.ts pins that equivalence.

      Writers pass this to SearchCache.invalidateCache's keys so read-after-write holds in memory mode, where tag invalidation no-ops. The cache hashes and surface-prefixes it; this returns the arguments only.

      Parameters

      • __namedParameters: { customerId: string; id: string }

      Returns Record<string, unknown>

    • Identity → the dashboard wire form. Not the cached shape; needs no cache instance.

      Parameters

      • identity: {
            achName: string;
            amlVerification?: { id: string; status: VerificationStatus } & {
                statusDescription: string;
            };
            capabilities: (
                | "TRANSACT"
                | "MANAGE_PAYMENT_INSTRUMENT"
                | "MANAGE_LEDGER_ACCOUNT"
                | "MANAGE_DEPOSIT_MEMO"
            )[];
            countryCode: string;
            countryOfResidence: string;
            createdAt: Date;
            customerVerification?: { id: string };
            dateOfBirth?: string;
            deletedAt?: Date;
            email: string;
            fullName: string;
            id: string;
            identityDocumentVerification?: { id: string; status: VerificationStatus } & {
                statusDescription: string;
            };
            metadata: Record<string, string>;
            name: { firstName: string; lastName: string; middleName?: string };
            phone: string;
            referenceId?: string;
            requiredInfo: RequiredInfoField[];
            status:
                | "PENDING_VERIFICATION"
                | "ACTION_REQUIRED"
                | "APPROVED"
                | "DISABLED"
                | "DELETED"
                | "REVIEW"
                | "BLOCKED";
            statusDescription: string;
            taxId?: string;
            type: "IDENTITY";
            updatedAt: Date;
            uuid: string;
            verificationProfileId?: string;
            verificationReasonCode?: | "OTHER"
            | "INVALID_TAX_ID"
            | "ADDRESS_MISMATCH"
            | "REGISTRY_NOT_FOUND"
            | "DOCUMENT_ISSUE"
            | "IDENTITY_MISMATCH";
            verificationReasonCodeDescription?: string;
            wireName: string;
        }
        • achName: string
        • OptionalamlVerification?: { id: string; status: VerificationStatus } & { statusDescription: string }
        • capabilities: (
              | "TRANSACT"
              | "MANAGE_PAYMENT_INSTRUMENT"
              | "MANAGE_LEDGER_ACCOUNT"
              | "MANAGE_DEPOSIT_MEMO"
          )[]

          What this identity is capable of executing currently

        • countryCode: string

          Country of jurisdiction; alias of countryOfResidence

        • countryOfResidence: string
        • createdAt: Date
        • OptionalcustomerVerification?: { id: string }

          Details of customer's own verification of the identity

          • id: string

            Verification unique identifier in the customer's system

        • OptionaldateOfBirth?: string

          In ISO format: yyyy-MM-dd

        • OptionaldeletedAt?: Date
        • email: string
        • fullName: string
        • id: string
        • OptionalidentityDocumentVerification?: { id: string; status: VerificationStatus } & { statusDescription: string }
        • metadata: Record<string, string>
        • name: { firstName: string; lastName: string; middleName?: string }
        • phone: string
        • OptionalreferenceId?: string
        • requiredInfo: RequiredInfoField[]

          Field paths verification needs and the identity lacks; derived, never stored.

        • status:
              | "PENDING_VERIFICATION"
              | "ACTION_REQUIRED"
              | "APPROVED"
              | "DISABLED"
              | "DELETED"
              | "REVIEW"
              | "BLOCKED"
        • statusDescription: string

          The one label status is shown under, computed in SQL beside it.

        • OptionaltaxId?: string

          The person's own tax identification number — an SSN or ITIN for a US person, the local equivalent elsewhere. Stored as entered.

          Mirrors related_person.data.taxId: the two are the same fact about the same kind of party, and both forward to AiPrise the same way (additional_info: TAX_IDENTIFICATION_NUMBER on the identity-document verification run — AiPrise's user profile has no field for it).

        • type: "IDENTITY"

          Discriminator shared with Organization for mixed entity lists

        • updatedAt: Date
        • uuid: string
        • OptionalverificationProfileId?: string

          AiPrise user profile ID

          Only set if we verify the identity.

        • OptionalverificationReasonCode?:
              | "OTHER"
              | "INVALID_TAX_ID"
              | "ADDRESS_MISMATCH"
              | "REGISTRY_NOT_FOUND"
              | "DOCUMENT_ISSUE"
              | "IDENTITY_MISMATCH"

          Customer-safe; set while the verification is declined, in review or needs info.

        • OptionalverificationReasonCodeDescription?: string
        • wireName: string

      Returns CachedIdentity