Skip to content

Api reference

components.growth.public.business_logic

conversation_management

assign_conversation module-attribute

assign_conversation = assign_conversation

get_intercom_admin_id_from_email module-attribute

get_intercom_admin_id_from_email = (
    get_intercom_admin_id_from_email
)

is_assigned_to_inbound_sales module-attribute

is_assigned_to_inbound_sales = is_assigned_to_inbound_sales

notify_intercom_on_contract_signature module-attribute

notify_intercom_on_contract_signature = (
    notify_intercom_on_contract_signature
)

hubspot

get_hubspot_country module-attribute

get_hubspot_country = get_hubspot_country

get_hubspot_language module-attribute

get_hubspot_language = get_hubspot_language

submit_form_to_hubspot module-attribute

submit_form_to_hubspot = submit_form_to_hubspot

lead_generation_resources

get_livestorm_replay_url module-attribute

get_livestorm_replay_url = get_livestorm_replay_url

prospect_request_contact

prospect_request_contact module-attribute

prospect_request_contact = (
    prospect_request_contact_protected
)

referral

ReferralActions

Actions for the referral lifecycle.

add_contract_to_referral
add_contract_to_referral(referral_id, contract_ref)

Add a contract reference to be rewarded for the referral.

Source code in components/growth/subcomponents/referral/protected/actions/referral_actions.py
def add_contract_to_referral(self, referral_id: UUID, contract_ref: str) -> None:
    """Add a contract reference to be rewarded for the referral."""
    with transaction() as session:
        referral = session.get(Referral, referral_id)

        current_logger.info(
            f"Setting Referral contract ref: Referral {referral_id} to {contract_ref}",
            referral_id=referral_id,
            contract_ref=contract_ref,
        )

        if not referral:
            raise ReferralContractRefException(
                f"Setting Referral contract ref {contract_ref}: Referral {referral_id} not found"
            )

        if referral.referred_contract_rewarded_on:
            raise ReferralContractRefException(
                f"Setting Referral contract ref {contract_ref}: Referral {referral_id} has been rewarded"
            )

        if (
            referral.referred_contract_ref
            and referral.referred_contract_ref != contract_ref
        ):
            raise ReferralContractRefException(
                f"Setting Referral contract ref {contract_ref}: Referral {referral_id} is set with a different contract ref {referral.referred_contract_ref}"
            )

        referral.referred_contract_ref = contract_ref
        session.add(referral)

        register_event(
            ReferralSignedContractEvent(
                referred_profile_id=referral.referred_profile.profile_id,
                referring_profile_id=referral.referring_profile.profile_id
                if referral.referring_profile
                else None,
            )
        )
consume_referral
consume_referral(referral_id, month=None)

Consume a referral for the rewarded contract.

Creates a discount from the referral for a given month if the conditions are met.

Source code in components/growth/subcomponents/referral/protected/actions/referral_actions.py
def consume_referral(self, referral_id: UUID, month: Month | None = None) -> None:
    """
    Consume a referral for the rewarded contract.

    Creates a discount from the referral for a given month if the conditions are met.
    """
    with transaction() as session:
        referral = session.get(Referral, referral_id)

        if not referral:
            raise ReferralConsumptionException(
                f"Consuming Referral {referral_id}: Referral not found"
            )

        if not referral.referred_contract_ref:
            current_logger.info(
                f"Consuming Referral {referral_id}: Referral has no contract ref",
                referral_id=referral_id,
            )
            return None

        if referral.referred_contract_rewarded_on:
            current_logger.info(
                f"Consuming Referral {referral_id}: Referral has already been rewarded",
                referral_id=referral_id,
                rewarded_on=referral.referred_contract_rewarded_on,
            )
            return None

        # Get contract info once - eligibility can be checked for different months
        dependency = get_referral_dependency(referral.referred_country_code)
        contract_info = dependency.get_referred_contract(
            contract_ref=referral.referred_contract_ref
        )
        if not contract_info:
            current_logger.info(
                f"Consuming Referral {referral_id}: Contract not found",
                referral_id=referral_id,
                contract_ref=referral.referred_contract_ref,
            )
            return None

        # Determine reward month
        if month is not None:
            reward_month = month
            if contract_info.eligible_for_free_month(reward_month):
                self._create_discount_for_referral(referral, reward_month, session)
        else:
            # Try current month or next month
            start_month = max(Month.current(), contract_info.start_date)
            if contract_info.eligible_for_free_month(start_month):
                self._create_discount_for_referral(referral, start_month, session)
            else:
                # Try next month
                next_month = start_month.one_month_later
                if contract_info.eligible_for_free_month(next_month):
                    self._create_discount_for_referral(
                        referral, next_month, session
                    )
create_referral
create_referral(
    profile_service,
    referred_profile_id,
    country_code,
    referral_token=None,
    referring_partner=None,
)

Create a referral.

Source code in components/growth/subcomponents/referral/protected/actions/referral_actions.py
@inject_profile_service
def create_referral(
    self,
    profile_service: ProfileService,
    referred_profile_id: UUID,
    country_code: CountryCode,
    referral_token: str | None = None,
    referring_partner: str | None = None,
) -> None | UUID:
    """Create a referral."""
    with transaction() as session:
        profile = profile_service.get_profile(referred_profile_id)

        if not profile:
            current_logger.info(
                "Unable to create Referral: profile not found",
                profile_id=referred_profile_id,
            )
            return None

        referred_profile = self._get_or_create_referral_profile(referred_profile_id)

        if referred_profile.received_referral:
            current_logger.info(
                "Unable to create Referral: referred profile has already been referred",
                referral_id=referred_profile.received_referral.id,
            )
            return (
                None
                if referred_profile.received_referral.referred_contract_ref
                else referred_profile.received_referral.id
            )

        if referral_token:
            referring_profile = (
                session.execute(
                    select(ReferralProfile).filter_by(referral_token=referral_token)
                )
                .scalars()
                .unique()
                .one_or_none()
            )

            if not referring_profile:
                current_logger.info(
                    f"Unable to create Referral: referral profile not found (token: {referral_token})"
                )
                return None

            if referring_profile.profile_id == referred_profile_id:
                current_logger.info(
                    f"Unable to create Referral: referring profile is the same as the referred profile (token: {referral_token})"
                )
                return None

            referral = Referral(
                referred_profile=referred_profile,
                referring_profile=referring_profile,
                referred_country_code=country_code,
            )
            session.add(referral)
            session.flush()

            current_logger.info(
                f"Creating Referral {referral} from profile '{referring_profile.profile_id}",
                referral_id=referral.id,
            )

            register_event(
                ReferralCreatedEvent(
                    referred_profile_id=referred_profile.profile_id,
                    referring_profile_id=referring_profile.profile_id,
                )
            )

            return referral.id

        elif referring_partner:
            referral = Referral(
                referring_partner=referring_partner,
                referred_profile=referred_profile,
                referred_country_code=country_code,
            )
            session.add(referral)
            session.flush()

            current_logger.info(
                f"Creating Referral {referral} from partner '{referring_partner}",
                referral_id=referral.id,
            )

            register_event(
                ReferralCreatedEvent(
                    referred_profile_id=referred_profile.profile_id
                )
            )

            return referral.id

    return None
reward_referring_user
reward_referring_user(referral_id, rewarded_at)

Reward the user who made the referral.

Source code in components/growth/subcomponents/referral/protected/actions/referral_actions.py
def reward_referring_user(self, referral_id: UUID, rewarded_at: datetime) -> None:
    """Reward the user who made the referral."""
    with transaction() as session:
        referral = session.get(Referral, referral_id)

        if not referral:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Referral not found"
            )

        if referral.referring_profile is None:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Referral has no referring profile"
            )

        if referral.referring_user_rewarded_at is not None:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Referral has already been rewarded"
            )

        if referral.referred_contract_ref is None:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Referral has no contract ref"
            )

        dependency = get_referral_dependency(referral.referred_country_code)
        contract_info = dependency.get_referred_contract(
            contract_ref=referral.referred_contract_ref
        )

        if not contract_info:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Contract not found for contract ref {referral.referred_contract_ref}"
            )

        if not contract_info.contractee_type:
            raise ReferralRewardException(
                f"Rewarding Referral {referral_id}: Contract has no contractee type for contract ref {referral.referred_contract_ref}"
            )

        rewarded_referrals = get_rewarded_referrals_for_profile(
            profile_id=referral.referring_profile.profile_id
        )

        amount = get_referral_reward_amount_for_referral(
            referral_id=referral_id,
        )

        referral.referring_user_has_received_amount = amount
        referral.referring_user_rewarded_at = rewarded_at
        session.add(referral)
        session.flush()

        register_event(
            ReferralRewardedEvent(
                referring_profile_id=referral.referring_profile.profile_id,
                country_code=referral.referred_country_code,
                reward_amount=amount,
                already_rewarded_referral_count=len(rewarded_referrals),
                rewarded_at=rewarded_at,
            )
        )

ReferralContractInfo dataclass

ReferralContractInfo(
    contract_ref,
    contract_id,
    start_date,
    signed_at,
    contractee_type,
    is_cancelled,
    _eligibility_checker=None,
)

Bases: DataClassJsonMixin

Entity for a referral contract info.

contract_id instance-attribute
contract_id
contract_ref instance-attribute
contract_ref
contractee_type instance-attribute
contractee_type
eligible_for_free_month
eligible_for_free_month(month)

Check if contract is eligible for free month in the given month.

Source code in components/growth/subcomponents/referral/protected/entities.py
def eligible_for_free_month(self, month: Month) -> bool:
    """
    Check if contract is eligible for free month in the given month.
    """
    if self._eligibility_checker:
        return self._eligibility_checker(month)
    raise NotImplementedError(
        "eligible_for_free_month requires an eligibility_checker to be set"
    )
is_cancelled instance-attribute
is_cancelled
signed_at instance-attribute
signed_at
start_date instance-attribute
start_date

ReferralCreatedEvent dataclass

ReferralCreatedEvent(
    referred_profile_id, referring_profile_id=None
)

Bases: Message

Event triggered when a referral is created.

referred_profile_id instance-attribute
referred_profile_id
referring_profile_id class-attribute instance-attribute
referring_profile_id = None

ReferralDependency

Bases: ABC

Dependency interface for Referral component to access country-specific functionality.

get_user_id_from_global_profile_id abstractmethod
get_user_id_from_global_profile_id(global_profile_id)

Get the user ID from the global profile ID.

Source code in components/growth/subcomponents/referral/dependencies.py
@abstractmethod
def get_user_id_from_global_profile_id(self, global_profile_id: UUID) -> str | None:
    """Get the user ID from the global profile ID."""
    raise NotImplementedError()

ReferralDiscount dataclass

ReferralDiscount(
    country_code,
    start_month,
    end_month,
    amount_for_primary,
    amount_for_partner,
    amount_for_children,
    free_month,
    contract_ref,
    referral_id,
)

Bases: DataClassJsonMixin

Entity for a referral discount.

amount_for_children instance-attribute
amount_for_children
amount_for_partner instance-attribute
amount_for_partner
amount_for_primary instance-attribute
amount_for_primary
contract_ref instance-attribute
contract_ref
country_code instance-attribute
country_code
end_month instance-attribute
end_month
free_month instance-attribute
free_month
referral_id instance-attribute
referral_id
start_month instance-attribute
start_month

ReferralQueries

Queries for the referral.

get_received_referral_for_profile
get_received_referral_for_profile(profile_id)

Get the received referral for a profile.

Source code in components/growth/subcomponents/referral/protected/queries/referral_queries.py
def get_received_referral_for_profile(
    self, profile_id: UUID
) -> ReferralEntity | None:
    """Get the received referral for a profile."""
    referral_profile = (
        current_session.execute(
            select(ReferralProfile).filter_by(profile_id=profile_id)
        )
        .scalars()
        .unique()
        .one_or_none()
    )

    if referral_profile and referral_profile.received_referral:
        return ReferralEntity(referral=referral_profile.received_referral)

    return None

handle_referral_created

handle_referral_created(event)

Handle the referral created event.

Source code in components/growth/subcomponents/referral/protected/events/handlers.py
@enqueueable
def handle_referral_created(event: "ReferralCreatedEvent") -> None:
    """Handle the referral created event."""
    track_referral(event.referred_profile_id, event.referring_profile_id)

set_app_dependency

set_app_dependency(dependency)

Function used to actually inject the dependency class in the component.

Source code in components/growth/subcomponents/referral/dependencies.py
def set_app_dependency(dependency: ReferralDependency) -> None:
    """Function used to actually inject the dependency class in the component."""
    from flask import current_app

    cast("CustomFlask", current_app).add_component_dependency(
        COMPONENT_NAME, dependency
    )

self_serve_feedback

create_self_serve_feedback

create_self_serve_feedback(
    email,
    country_code,
    flow_type,
    survey_response,
    commit=True,
)

Create a new self serve feedback form entry

Source code in components/growth/public/business_logic/self_serve_feedback.py
def create_self_serve_feedback(
    email: str | None,
    country_code: str,
    flow_type: SelfServeFeedbackTypeEnum,
    survey_response: dict[str, Any],
    commit: bool = True,
) -> None:
    """Create a new self serve feedback form entry"""
    from components.growth.internal.models.self_serve_feedback import (
        SelfServeFeedback,
    )
    from shared.helpers.db import current_session

    if email is None:
        raise BaseErrorCode.invalid_arguments(
            description="Email is required for feedback submission."
        )

    if survey_response == {}:
        raise BaseErrorCode.invalid_arguments(
            description="Survey response cannot be empty."
        )

    valid_country_code = check_country_code(
        country_code_string=country_code,
        available_countries=["BE", "FR", "ES", "CA"],
    )

    self_serve_feedback = SelfServeFeedback(
        email=email,
        survey_response=survey_response,
        country_code=valid_country_code,
        flow_type=flow_type,
    )
    current_session.add(self_serve_feedback)
    if commit:
        current_session.commit()

    return

self_serve_flow

create_self_serve_flow_progress

create_self_serve_flow_progress(
    country_code,
    flow_type,
    language,
    alan_partner_code,
    referring_user_token,
    referring_partner,
    user_ref,
    commit=True,
)

Create the self-serve flow progress

Source code in components/growth/public/business_logic/self_serve_flow.py
def create_self_serve_flow_progress(
    country_code: CountryCode,
    flow_type: SelfServeFlowTypeEnum,
    language: Lang,
    alan_partner_code: str | None,
    referring_user_token: str | None,
    referring_partner: str | None,
    user_ref: str | None,
    commit: bool = True,
) -> SelfServeFlowProgressEntity:
    """Create the self-serve flow progress"""
    from components.growth.internal.helpers.country_code import check_country_code

    check_country_code(country_code_string=country_code, available_countries=["FR"])

    if flow_type == SelfServeFlowTypeEnum.company:
        self_serve_flow_progress = SelfServeFlowProgress(
            country_code=country_code,
            flow_type=SelfServeFlowTypeEnum.company,
            state={"language": language},
            user_ref=user_ref,
        )

        if alan_partner_code:
            self_serve_flow_progress.state["alan_partner_code"] = alan_partner_code

        if referring_user_token:
            self_serve_flow_progress.state["referring_user_token"] = (
                referring_user_token
            )
        elif referring_partner:
            self_serve_flow_progress.state["referring_partner"] = referring_partner

        current_session.add(self_serve_flow_progress)

        if commit:
            current_session.commit()

        return SelfServeFlowProgressEntity(
            id=self_serve_flow_progress.id,
            flow_type=self_serve_flow_progress.flow_type,
            country_code=self_serve_flow_progress.country_code,
            state=self_serve_flow_progress.state,
            proposal_ref=self_serve_flow_progress.proposal_ref,
            user_ref=self_serve_flow_progress.user_ref,
        )

    raise ValueError(f"Invalid flow type {flow_type}. Only 'company' is supported.")

get_multiple_self_serve_flow_progress

get_multiple_self_serve_flow_progress(
    self_serve_flow_progress_ids, user_ref
)

Get multiple self-serve flow progress records by ID.

Source code in components/growth/public/business_logic/self_serve_flow.py
def get_multiple_self_serve_flow_progress(
    self_serve_flow_progress_ids: list[UUID] | None,
    user_ref: str | None,
) -> list[SelfServeFlowProgressEntity]:
    """Get multiple self-serve flow progress records by ID."""
    query = current_session.query(SelfServeFlowProgress)  # noqa: ALN085

    if self_serve_flow_progress_ids:
        query = query.filter(SelfServeFlowProgress.id.in_(self_serve_flow_progress_ids))

    if user_ref:
        query = query.filter(SelfServeFlowProgress.user_ref == user_ref)

    flow_progress_objs = query.order_by(SelfServeFlowProgress.updated_at.desc()).all()

    return [
        SelfServeFlowProgressEntity(
            id=progress.id,
            flow_type=progress.flow_type,
            country_code=progress.country_code,
            state=progress.state,
            proposal_ref=progress.proposal_ref,
            user_ref=progress.user_ref,
        )
        for progress in flow_progress_objs
    ]

get_self_serve_flow_progress

get_self_serve_flow_progress(self_serve_flow_progress_id)

Get the self-serve flow progress

Source code in components/growth/public/business_logic/self_serve_flow.py
def get_self_serve_flow_progress(
    self_serve_flow_progress_id: UUID,
) -> SelfServeFlowProgressEntity:
    """Get the self-serve flow progress"""
    self_serve_flow_progress = get_or_raise_missing_resource(
        SelfServeFlowProgress, self_serve_flow_progress_id
    )

    return SelfServeFlowProgressEntity(
        id=self_serve_flow_progress.id,
        flow_type=self_serve_flow_progress.flow_type,
        country_code=self_serve_flow_progress.country_code,
        state=self_serve_flow_progress.state,
        proposal_ref=self_serve_flow_progress.proposal_ref,
        user_ref=self_serve_flow_progress.user_ref,
    )

update_self_serve_flow_progress

update_self_serve_flow_progress(
    self_serve_flow_progress_id,
    params=None,
    proposal_ref=None,
    user_ref=None,
    commit=True,
)

Update the self-serve flow progress

Source code in components/growth/public/business_logic/self_serve_flow.py
def update_self_serve_flow_progress(
    self_serve_flow_progress_id: UUID,
    params: dict[str, Any] | None = None,
    proposal_ref: UUID | None = None,
    user_ref: str | None = None,
    commit: bool = True,
) -> SelfServeFlowProgressEntity:
    """Update the self-serve flow progress"""
    self_serve_flow_progress = get_or_raise_missing_resource(
        SelfServeFlowProgress,
        self_serve_flow_progress_id,
        with_for_update=True,
    )

    # If a parameter is passed with value None, it will overwrite (and reset) the existing value.
    if params:
        for key, value in params.items():
            self_serve_flow_progress.state[key] = value

    if proposal_ref:
        self_serve_flow_progress.proposal_ref = proposal_ref

    if user_ref:
        self_serve_flow_progress.user_ref = user_ref

    if commit:
        current_session.commit()

    return SelfServeFlowProgressEntity(
        id=self_serve_flow_progress.id,
        flow_type=self_serve_flow_progress.flow_type,
        country_code=self_serve_flow_progress.country_code,
        state=self_serve_flow_progress.state,
        proposal_ref=self_serve_flow_progress.proposal_ref,
        user_ref=self_serve_flow_progress.user_ref,
    )

settings

get_integer_setting_value module-attribute

get_integer_setting_value = get_integer_setting_value

slack_reporting

notify_sales_inbound_of_assigned_leads module-attribute

notify_sales_inbound_of_assigned_leads = (
    notify_sales_inbound_of_assigned_leads
)

notify_sales_inbound_of_contract_signature module-attribute

notify_sales_inbound_of_contract_signature = (
    notify_sales_inbound_of_contract_signature
)

user_and_roles

get_available_inbound_sales_intercom_ids module-attribute

get_available_inbound_sales_intercom_ids = (
    get_available_inbound_sales_intercom_ids
)

is_alaner_inbound_sales module-attribute

is_alaner_inbound_sales = is_alaner_inbound_sales

retrieve_alaner_details_from_intercom_admin_id module-attribute

retrieve_alaner_details_from_intercom_admin_id = (
    retrieve_alaner_details_from_intercom_admin_id
)

components.growth.public.commands

growth

growth_commands module-attribute

growth_commands = AppGroup(
    name="growth",
    help="Main command group for the Growth component",
)

components.growth.public.dependencies

COMPONENT_NAME module-attribute

COMPONENT_NAME = 'growth'

GrowthDependency

Bases: ABC

create_conversation_context abstractmethod

create_conversation_context(
    user_id, conversation_type, context_data
)

Implement create_conversation_context

Source code in components/growth/public/dependencies.py
@abstractmethod
def create_conversation_context(
    self,
    user_id: str | None,
    conversation_type: IntercomConversationType,
    context_data: dict[str, Any],
) -> str | None:
    """Implement create_conversation_context"""

get_company_quote_request_data abstractmethod

get_company_quote_request_data(
    language,
    phone_number,
    firstname,
    lastname,
    company_name,
    number_of_employees,
    qualification,
)

Implement get_company_quote_request_event

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_company_quote_request_data(
    self,
    language: str,
    phone_number: str | None,
    firstname: str | None,
    lastname: str | None,
    company_name: str | None,
    number_of_employees: int | None,
    qualification: dict[str, Any],
) -> QuoteRequestData:
    """Implement get_company_quote_request_event"""

get_extra_tags_for_country abstractmethod

get_extra_tags_for_country(prospect_id, request_type)

Implement get_extra_tags_for_country

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_extra_tags_for_country(
    self,
    prospect_id: int | None,
    request_type: ProspectRequestType,
) -> list[str]:
    """Implement get_extra_tags_for_country"""

get_inbound_sales_team abstractmethod

get_inbound_sales_team()

Implement get_inbound_sales_team

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_inbound_sales_team(
    self,
) -> InboundSalesTeam:
    """Implement get_inbound_sales_team"""

get_intercom_admin_id_from_user_id abstractmethod

get_intercom_admin_id_from_user_id(user_id)

Implement get_intercom_admin_id_from_user_id

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_intercom_admin_id_from_user_id(
    self,
    user_id: str,
) -> str | None:
    """Implement get_intercom_admin_id_from_user_id"""

get_prospects_emails_from_phone_number abstractmethod

get_prospects_emails_from_phone_number(phone_number)

Implement get_prospects_emails_from_phone_number

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_prospects_emails_from_phone_number(
    self,
    phone_number: str,
) -> list[str]:
    """Implement get_prospects_emails_from_phone_number"""

get_self_serve_flow_id_from_qualification abstractmethod

get_self_serve_flow_id_from_qualification(qualification)

Implement get_self_serve_flow_id_from_qualification

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_self_serve_flow_id_from_qualification(
    self, qualification: dict[str, Any] | None
) -> str | None:
    """Implement get_self_serve_flow_id_from_qualification"""

get_user abstractmethod

get_user(user_id)

Implement get_user

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_user(
    self,
    user_id: str,
) -> GrowthUser | None:
    """Implement get_user"""

get_user_from_email abstractmethod

get_user_from_email(email)

Implement get_user_id_from_email

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_user_from_email(
    self,
    email: str,
) -> GrowthUser | None:
    """Implement get_user_id_from_email"""

get_user_from_intercom_admin_id abstractmethod

get_user_from_intercom_admin_id(intercom_admin_id)

Implement get_user_from_intercom_admin_id

Source code in components/growth/public/dependencies.py
@abstractmethod
def get_user_from_intercom_admin_id(
    self,
    intercom_admin_id: str,
) -> GrowthUser | None:
    """Implement get_user_from_intercom_admin_id"""

is_admin_sales abstractmethod

is_admin_sales(admin_id)

Implement is_admin_sales

Source code in components/growth/public/dependencies.py
@abstractmethod
def is_admin_sales(
    self,
    admin_id: str,
) -> bool:
    """Implement is_admin_sales"""

is_request_likely_for_care abstractmethod

is_request_likely_for_care(
    prospect_request_type, prospect_email, prospect_id
)

Implement is_request_likely_for_care it should return a tuple with: - a bool if the request is likely for care - a str with the reason if the request is likely for care

Source code in components/growth/public/dependencies.py
@abstractmethod
def is_request_likely_for_care(
    self,
    prospect_request_type: ProspectRequestType,
    prospect_email: str,
    prospect_id: int | None,
) -> tuple[bool, str | None]:
    """Implement is_request_likely_for_care
    it should return a tuple with:
    - a bool if the request is likely for care
    - a str with the reason if the request is likely for care
    """

register_prospect abstractmethod

register_prospect(
    email,
    phone=None,
    attribution_survey_source=None,
    qualification_raw_company=None,
    qualification_raw_individual=None,
    qualification_raw_website=None,
)

Implement register_prospect

Source code in components/growth/public/dependencies.py
@abstractmethod
def register_prospect(
    self,
    email: str,
    phone: str | None = None,
    attribution_survey_source: str | None = None,
    qualification_raw_company: dict[str, Any] | None = None,
    qualification_raw_individual: dict[str, Any] | None = None,
    qualification_raw_website: dict[str, Any] | None = None,
) -> int | None:
    """Implement register_prospect"""

send_unauthenticated_user_async_message_to_intercom abstractmethod

send_unauthenticated_user_async_message_to_intercom(
    email, subject, message
)

Implement send_unauthenticated_user_async_message_to_intercom

Source code in components/growth/public/dependencies.py
@abstractmethod
def send_unauthenticated_user_async_message_to_intercom(
    self,
    email: str,
    subject: str,
    message: str,
) -> None:
    """Implement send_unauthenticated_user_async_message_to_intercom"""

get_app_dependency

get_app_dependency()

Get the growth dependency in the current app context

Source code in components/growth/public/dependencies.py
def get_app_dependency() -> GrowthDependency:
    """
    Get the growth dependency in the current app context
    """
    from flask import current_app

    return cast("CustomFlask", current_app).get_component_dependency(COMPONENT_NAME)  # type: ignore[no-any-return]

set_app_dependency

set_app_dependency(dependency)

Set the growth dependency in the current app context

Source code in components/growth/public/dependencies.py
def set_app_dependency(dependency: GrowthDependency) -> None:
    """
    Set the growth dependency in the current app context
    """
    from flask import current_app

    cast("CustomFlask", current_app).add_component_dependency(
        COMPONENT_NAME, dependency
    )

components.growth.public.entities

alaner_details

AlanerDetails dataclass

AlanerDetails(*, slack_id, slack_handle, is_inbound_sales)

Represents Alaner's during from in the growth component's scope, those are filled from Turing.

is_inbound_sales instance-attribute
is_inbound_sales
slack_handle instance-attribute
slack_handle
slack_id instance-attribute
slack_id

growth_setting

GrowthSetting dataclass

GrowthSetting(*, name, value)

Bases: DataClassJsonMixin

Represents a growth setting.

name instance-attribute
name
value instance-attribute
value

inbound_sales_team

InboundSalesTeam dataclass

InboundSalesTeam(
    *,
    crew_name,
    crew_slack_channel,
    won_contracts_slack_channel,
    crew_lead_user
)

Bases: DataClassJsonMixin

Represents an inbound sales team / crew for a specific country

crew_lead_user instance-attribute
crew_lead_user
crew_name instance-attribute
crew_name
crew_slack_channel instance-attribute
crew_slack_channel
won_contracts_slack_channel instance-attribute
won_contracts_slack_channel

prospect_conversation

ProspectConversation dataclass

ProspectConversation(
    *,
    conversation_id,
    prospect_type,
    prospect_request_type,
    assigned_to,
    segment
)

Bases: DataClassJsonMixin

Represents a conversation with a prospect in the growth component's assignment scope

assigned_to instance-attribute
assigned_to
conversation_id instance-attribute
conversation_id
prospect_request_type instance-attribute
prospect_request_type
prospect_type instance-attribute
prospect_type
segment instance-attribute
segment

quote_request_event

QuoteRequestData dataclass

QuoteRequestData(
    *,
    customer_io_event_name,
    customer_io_event_attributes,
    should_be_sent_to_crm,
    quote_details,
    self_serve_flow_id
)

Bases: DataClassJsonMixin

customer_io_event_attributes instance-attribute
customer_io_event_attributes
customer_io_event_name instance-attribute
customer_io_event_name
quote_details instance-attribute
quote_details
self_serve_flow_id instance-attribute
self_serve_flow_id
should_be_sent_to_crm instance-attribute
should_be_sent_to_crm

self_serve_flow

SelfServeFlowProgressEntity dataclass

SelfServeFlowProgressEntity(
    *,
    id,
    flow_type,
    country_code,
    state,
    proposal_ref,
    user_ref
)

Represents the self-serve flow progress entity as stored in db

country_code instance-attribute
country_code
flow_type instance-attribute
flow_type
id instance-attribute
id
proposal_ref instance-attribute
proposal_ref
state instance-attribute
state
user_ref instance-attribute
user_ref

user

User dataclass

User(*, id, email, pro_email, alan_email, full_name)

Bases: DataClassJsonMixin

Represents a user from in the growth component's scope

alan_email instance-attribute
alan_email
email instance-attribute
email
full_name instance-attribute
full_name
id instance-attribute
id
pro_email instance-attribute
pro_email

components.growth.public.types

codes_and_tags

CODE_ACCOUNT_CREATION_STUCK module-attribute

CODE_ACCOUNT_CREATION_STUCK = '[code:32160]'

CODE_CALLBACK module-attribute

CODE_CALLBACK = '[code:32162]'

CODE_CHAT module-attribute

CODE_CHAT = '[code:32163]'

CODE_MAIL module-attribute

CODE_MAIL = '[code:32167]'

CODE_QUOTE module-attribute

CODE_QUOTE = '[code:32161]'

PROSPECT_SOURCE module-attribute

PROSPECT_SOURCE = 'prospect'

ROLE_CALLBACK_TAG module-attribute

ROLE_CALLBACK_TAG = 'ROLE[CALLBACK]'

SELF_SERVE_TAG_ACCOUNT_CREATION_STUCK module-attribute

SELF_SERVE_TAG_ACCOUNT_CREATION_STUCK = (
    "SELFSERVE[STUCK-ACCOUNT-CREATION]"
)

SELF_SERVE_TAG_AI_QUALIFICATION module-attribute

SELF_SERVE_TAG_AI_QUALIFICATION = (
    "SELFSERVE[AI-QUALIFICATION]"
)

SELF_SERVE_TAG_CALLBACK module-attribute

SELF_SERVE_TAG_CALLBACK = 'SELFSERVE[CALLBACK]'

SELF_SERVE_TAG_CHAT module-attribute

SELF_SERVE_TAG_CHAT = 'SELFSERVE[CHAT]'

SELF_SERVE_TAG_EMAIL_CAPTURE module-attribute

SELF_SERVE_TAG_EMAIL_CAPTURE = 'SELFSERVE[EMAIL-CAPTURE]'

SELF_SERVE_TAG_FPT_RETIREE_TEST module-attribute

SELF_SERVE_TAG_FPT_RETIREE_TEST = (
    "SELFSERVE[FPT_RETIREE_TEST]"
)

SELF_SERVE_TAG_FUNNEL module-attribute

SELF_SERVE_TAG_FUNNEL = 'SELFSERVE[FUNNEL]'

SELF_SERVE_TAG_QUOTE module-attribute

SELF_SERVE_TAG_QUOTE = 'SELFSERVE[QUOTE]'

growth_settings

GrowthSettingEnum

Bases: AlanBaseEnum

Represents the names of all settings in the GrowthSetting table If you need to add a new setting, you should also create a migration script to to insert it into the table

be_backup_inbound_sales_emails class-attribute instance-attribute
be_backup_inbound_sales_emails = (
    "be_backup_inbound_sales_emails"
)
fr_backup_inbound_sales_emails class-attribute instance-attribute
fr_backup_inbound_sales_emails = (
    "fr_backup_inbound_sales_emails"
)
fr_enable_callback_button_on_email_capture_step class-attribute instance-attribute
fr_enable_callback_button_on_email_capture_step = (
    "fr_enable_callback_button_on_email_capture_step"
)
fr_enable_callback_button_on_first_step class-attribute instance-attribute
fr_enable_callback_button_on_first_step = (
    "fr_enable_callback_button_on_first_step"
)
fr_enable_chat class-attribute instance-attribute
fr_enable_chat = 'fr_enable_chat'
fr_number_of_daily_email_capture_leads class-attribute instance-attribute
fr_number_of_daily_email_capture_leads = (
    "fr_number_of_daily_email_capture_leads"
)
fr_number_of_daily_quotes_and_stuck_leads class-attribute instance-attribute
fr_number_of_daily_quotes_and_stuck_leads = (
    "fr_number_of_daily_quotes_and_stuck_leads"
)
fr_warning_in_contact_modal class-attribute instance-attribute
fr_warning_in_contact_modal = 'fr_warning_in_contact_modal'
inbound_sales_emails_to_exclude class-attribute instance-attribute
inbound_sales_emails_to_exclude = (
    "inbound_sales_emails_to_exclude"
)

PUBLIC_GROWTH_SETTINGS module-attribute

PUBLIC_GROWTH_SETTINGS = [
    fr_enable_chat,
    fr_warning_in_contact_modal,
    fr_enable_callback_button_on_first_step,
    fr_enable_callback_button_on_email_capture_step,
]

hubspot

HubspotCountries module-attribute

HubspotCountries = Literal[
    "France", "Belgium", "Spain", "Canada"
]

HubspotLanguages module-attribute

HubspotLanguages = Literal[
    "French", "English", "Dutch", "Spanish"
]

last_origin_type

LastOriginType module-attribute

LastOriginType = Literal['Meeting Request', 'Referral']

prospect_request_type

ProspectRequestType module-attribute

ProspectRequestType = Literal[
    "meeting_request",
    "callback",
    "email",
    "chat",
    "account_creation_stuck",
    "quote_request",
    "email_capture",
]

referral_type

ReferralType module-attribute

ReferralType = Literal[
    "Partner Referral",
    "Customer Referral",
    "Former Member Referral",
]

self_serve_feedback

SelfServeFeedbackTypeEnum

Bases: AlanBaseEnum

Type of self-serve feedback

company class-attribute instance-attribute
company = 'company'
individual_fpt class-attribute instance-attribute
individual_fpt = 'individual_fpt'
individual_freelancer class-attribute instance-attribute
individual_freelancer = 'individual_freelancer'
individual_private class-attribute instance-attribute
individual_private = 'individual_private'
individual_retiree class-attribute instance-attribute
individual_retiree = 'individual_retiree'
other_individual class-attribute instance-attribute
other_individual = 'other_individual'
unknown class-attribute instance-attribute
unknown = 'unknown'

self_serve_flow

SelfServeFlowStatusEnum

Bases: AlanBaseEnum

Status of self-serve flow

completed class-attribute instance-attribute
completed = 'completed'
contract_created class-attribute instance-attribute
contract_created = 'contract_created'
expired class-attribute instance-attribute
expired = 'expired'
in_progress class-attribute instance-attribute
in_progress = 'in_progress'
ready_to_sign class-attribute instance-attribute
ready_to_sign = 'ready_to_sign'
signed class-attribute instance-attribute
signed = 'signed'

SelfServeFlowTypeEnum

Bases: AlanBaseEnum

Type of self-serve flow

company class-attribute instance-attribute
company = 'company'

components.growth.public.utils

country_code

check_country_code module-attribute

check_country_code = check_country_code

hubspot

hubspot_country_to_country_code module-attribute

hubspot_country_to_country_code = (
    hubspot_country_to_country_code
)

hubspot_language_to_lang module-attribute

hubspot_language_to_lang = hubspot_language_to_lang

load_settings

data_init

load_growth_settings module-attribute
load_growth_settings = load_growth_settings

phone_number

clean_phone_number module-attribute

clean_phone_number = clean_phone_number

is_fake_phone_number module-attribute

is_fake_phone_number = is_fake_phone_number

verify_email

verify_email module-attribute

verify_email = verify_email