@cfxlabsinc/b2b-services
    Preparing search index...
    interface CreateCustomerWorkflowArgs {
        customer: Omit<
            Parameters<typeof createCustomer>[1],
            "id" | "propelauthWorkspaceId",
        >;
        customerId: string;
        monthlyFeeAmount?: string;
        organization: Omit<
            CreateMainOrganizationInput,
            "customerId"
            | "relatedPeople",
        > & { verificationProfileId: string };
        propelAuth: { domain: string; name: string };
        relatedPeople: Omit<
            RelatedPersonInput & {
                countryOfResidence: string;
                customerId: string;
                organizationId: string;
                type: "BENEFICIAL_OWNER"
                | "CONTROL";
            },
            "organizationId"
            | "customerId",
        >[];
        slack: { channelId: string; slackBotInstallationId: string };
    }
    Index
    customer: Omit<
        Parameters<typeof createCustomer>[1],
        "id" | "propelauthWorkspaceId",
    >

    Customer-record inputs (mirrors the synchronous form fields).

    customerId: string

    Pre-generated external customer id (cust_…); also the workflow id.

    monthlyFeeAmount?: string

    Optional AUTO monthly FIXED platform fee (MOVEUSD), configured once the Operating account exists.

    No actor travels with it: the audit entry for an onboarding-set fee is recorded by the dashboard action that starts this workflow, which is the only place that knows who asked. See lib/adminActivities.ts.

    organization: Omit<CreateMainOrganizationInput, "customerId" | "relatedPeople"> & {
        verificationProfileId: string;
    }

    Primary-organization inputs, derived from the AiPrise profile in the action. customerId / isMainOrg / relatedPeople are supplied by the workflow itself.

    verificationProfileId is REQUIRED here even though OrganizationService.create takes it as optional: the org-api path can create an org that AiPrise has not seen yet and let the async verify() catch up, but onboarding cannot. It gates on the profile being APPROVED so the primary org is ACTIVE at insert time — there is no profile to check without an id.

    propelAuth: { domain: string; name: string }

    PropelAuth workspace inputs.

    relatedPeople: Omit<
        RelatedPersonInput & {
            countryOfResidence: string;
            customerId: string;
            organizationId: string;
            type: "BENEFICIAL_OWNER"
            | "CONTROL";
        },
        "organizationId"
        | "customerId",
    >[]

    Control persons / beneficial owners for the primary org. Required — at least one CONTROL person (validateCustomerOnboardingInput rejects otherwise, before any write).

    slack: { channelId: string; slackBotInstallationId: string }

    Slack bot + events-channel ids.