Skip to content

Models

components.payment_gateway.subcomponents.authorizations.models.authorization_request

AuthorizationRequest

Bases: BaseModel

This model is used to manage the lifecycle of an authorization request.

__table_args__ class-attribute instance-attribute

__table_args__ = (
    UniqueConstraint(
        "provider",
        "external_id",
        name="authorization_request__unique_external_id_per_provider",
    ),
    {"schema": PAYMENT_GATEWAY_SCHEMA_NAME},
)

__tablename__ class-attribute instance-attribute

__tablename__ = 'authorization_request'

authorization_metadata class-attribute instance-attribute

authorization_metadata = mapped_column(
    JSONB(none_as_null=True), nullable=False
)

Metadata passed around between layers.

Note: 'metadata' is reserved so use 'entry_metadata' instead.

external_id class-attribute instance-attribute

external_id = mapped_column(
    String(255), nullable=False, index=True
)

ID used by the external payment service provider to identify the transaction.

provider class-attribute instance-attribute

provider = mapped_column(
    AlanBaseEnumTypeDecorator(PaymentServiceProvider),
    nullable=False,
)

The payment service provider that manages the transaction.

status class-attribute instance-attribute

status = mapped_column(
    AlanBaseEnumTypeDecorator(AuthorizationRequestStatus),
    nullable=False,
)

The status of the authorization request.

validate_provider class-attribute instance-attribute

validate_provider = create_validator('provider')

components.payment_gateway.subcomponents.authorizations.models.expense_category

ExpenseCategory

Bases: BaseModel

An Expense Category is a high level concept to categorize expenses (or payments), as its name implies. A given payment can match several categories, for example food expenses, grocery stores, payments made abroad, payments made on Sunday, etc.

Expense Limits are typically in limited number for a given application. They are not linked to a specific card, account, or payment method.

Each payment must belong to at least one Expense Category to be authorized.

__table_args__ class-attribute instance-attribute

__table_args__ = {'schema': PAYMENT_GATEWAY_SCHEMA_NAME}

__tablename__ class-attribute instance-attribute

__tablename__ = 'expense_category'

code class-attribute instance-attribute

code = mapped_column(
    String(64), nullable=False, unique=True, index=True
)

Machine-readable code of the category, unique within the system.

description class-attribute instance-attribute

description = mapped_column(Text, nullable=True)

Description of the category.

is_terminated property

is_terminated

name class-attribute instance-attribute

name = mapped_column(String(255), nullable=False)

Human-readable name of the category.

reference class-attribute instance-attribute

reference = mapped_column(Text, nullable=True)

Application-specific reference to the category.

terminated_at class-attribute instance-attribute

terminated_at = mapped_column(DateTime, nullable=True)

Termination is done at the initiative of the business layer. Expense categories in terminal state cannot be modified or used anymore.

components.payment_gateway.subcomponents.authorizations.models.expense_tracker

ExpenseTracker

Bases: BaseModel

Companion model to LineOfCredit.

We keep the credits limit and the expensed credits in a separate model to limit database contention during relayed authorization requests. See:

https://www.notion.so/alaninsurance/Eng-Plan-Authorization-Relay-1b21426e8be78075853fc403a0dffe40?pvs=4#1bd1426e8be7802eb8d7e85d1c1b01eb ⧉

__table_args__ class-attribute instance-attribute

__table_args__ = {'schema': PAYMENT_GATEWAY_SCHEMA_NAME}

__tablename__ class-attribute instance-attribute

__tablename__ = 'expense_tracker'

available_credits

available_credits()
Source code in components/payment_gateway/subcomponents/authorizations/models/expense_tracker.py
@available_credits.expression  # type: ignore[no-redef]
def available_credits(cls) -> int:
    return cls.credits_limit - cls.expensed_credits

credits_limit class-attribute instance-attribute

credits_limit = mapped_column(
    Integer, nullable=False, default=0, server_default="0"
)

Credits limit for the Line of Credit (in minor units).

This represents the maximum amount of credits that can be expensed during the current period.

expensed_credits class-attribute instance-attribute

expensed_credits = mapped_column(
    Integer, nullable=False, default=0, server_default="0"
)

Expensed credits for the Line of Credit (in minor units).

This represents the total amount of credits that have been expensed so far during the current period.

line_of_credit class-attribute instance-attribute

line_of_credit = relationship(
    "LineOfCredit",
    back_populates="expense_tracker",
    uselist=False,
)

line_of_credit_id class-attribute instance-attribute

line_of_credit_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(
        f"{PAYMENT_GATEWAY_SCHEMA_NAME}.line_of_credit.id"
    ),
    index=True,
    unique=True,
    nullable=False,
)

components.payment_gateway.subcomponents.authorizations.models.helpers

load_all_models

load_all_models()
Source code in components/payment_gateway/subcomponents/authorizations/models/helpers.py
def load_all_models() -> list[type[DbModel]]:
    from components.payment_gateway.subcomponents.authorizations.models.authorization_request import (
        AuthorizationRequest,
    )
    from components.payment_gateway.subcomponents.authorizations.models.expense_category import (
        ExpenseCategory,
    )
    from components.payment_gateway.subcomponents.authorizations.models.expense_tracker import (
        ExpenseTracker,
    )
    from components.payment_gateway.subcomponents.authorizations.models.line_of_credit import (
        LineOfCredit,
    )

    return [
        AuthorizationRequest,
        ExpenseCategory,
        ExpenseTracker,
        LineOfCredit,
    ]

components.payment_gateway.subcomponents.authorizations.models.line_of_credit

LineOfCredit

Bases: BaseModel

A Line of Credit is a high level concept to manage expenses made by a given owner. Each Line of Credit belongs to an Expense Category.

For each Expense Category a payment belongs to, there must be a matching Line of Credit with sufficient credits to cover the payment. Credits are tracked in a companion model ExpenseTracker for performance reasons.

__table_args__ class-attribute instance-attribute

__table_args__ = (
    Index(
        "line_of_credit__unique_owner_per_expense_category",
        "expense_category_id",
        "owner_type",
        "owner_ref",
        unique=True,
        postgresql_where=text("terminated_at IS NULL"),
    ),
    {"schema": PAYMENT_GATEWAY_SCHEMA_NAME},
)

__tablename__ class-attribute instance-attribute

__tablename__ = 'line_of_credit'

expense_category class-attribute instance-attribute

expense_category = relationship(
    ExpenseCategory,
    foreign_keys=expense_category_id,
    uselist=False,
)

expense_category_id class-attribute instance-attribute

expense_category_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    index=True,
    nullable=False,
)

expense_tracker class-attribute instance-attribute

expense_tracker = relationship(
    ExpenseTracker,
    back_populates="line_of_credit",
    uselist=False,
)

is_terminated property

is_terminated

owner_ref class-attribute instance-attribute

owner_ref = mapped_column(
    UUID(as_uuid=True), nullable=False, index=True
)

Application-specific reference to the owner of the line of credit.

owner_type class-attribute instance-attribute

owner_type = mapped_column(
    String(64), nullable=False, index=True
)

Application-specific type of owner for the line of credit.

terminated_at class-attribute instance-attribute

terminated_at = mapped_column(DateTime, nullable=True)

Termination is done at the initiative of the business layer. Lines of Credit in terminal state cannot be modified or used anymore.