import DataLoader from 'dataloader';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
import { FinancialEntitiesProvider } from '../../financial-entities/providers/financial-entities.provider.js';
import { TaxCategoriesProvider } from '../../financial-entities/providers/tax-categories.provider.js';
import type { SecurityBusinessDescriptors, SecurityBusinessRow, SecurityIdentifierType } from '../types.js';
/**
 * A source's name for a security, *within an owner*.
 *
 * The owner is not optional: `(owner_id, identifier_type, identifier_value)` is what the relation
 * is unique on, and reads span the request's whole business scope. A key without it cannot
 * identify one security business.
 */
export type IdentifierKey = {
    ownerId: string;
    type: SecurityIdentifierType;
    value: string;
};
export declare class SecurityBusinessesProvider {
    private db;
    private adminContextProvider;
    private financialEntitiesProvider;
    private businessesProvider;
    private taxCategoriesProvider;
    constructor(db: TenantAwareDBClient, adminContextProvider: AdminContextProvider, financialEntitiesProvider: FinancialEntitiesProvider, businessesProvider: BusinessesProvider, taxCategoriesProvider: TaxCategoriesProvider);
    private batchSecurityBusinessesByIds;
    getSecurityBusinessByIdLoader: DataLoader<string, import("../__generated__/security-businesses.types.js").IGetSecurityBusinessesByIdsResult | null, string>;
    private allSecurityBusinessesPromise;
    /**
     * Every security business of the acting tenant. Cached per request because charge typing and
     * account resolution ask for it on every transaction they touch.
     */
    getAllSecurityBusinesses(): Promise<SecurityBusinessRow[]>;
    getAllSecurityBusinessIds(): Promise<Set<string>>;
    isSecurityBusiness(businessId: string): Promise<boolean>;
    private batchSecurityBusinessesByIdentifiers;
    getSecurityBusinessByIdentifierLoader: DataLoader<IdentifierKey, import("../__generated__/security-businesses.types.js").IGetAllSecurityBusinessesResult | null, string>;
    private batchIdentifiersByBusinessIds;
    getIdentifiersByBusinessIdLoader: DataLoader<string, import("../__generated__/security-businesses.types.js").IGetSecurityIdentifiersByBusinessIdsResult[], string>;
    /** The security businesses already created for these ISINs, keyed by ISIN. */
    getSecurityBusinessesByIsins(isins: readonly string[]): Promise<Map<string, SecurityBusinessRow>>;
    private getSecurityBusinessByIsin;
    /**
     * The business a security is represented by, creating it on first sight.
     *
     * Idempotent by ISIN — see `createSecurityBusiness` for how a race is settled.
     */
    ensureSecurityBusiness(descriptors: SecurityBusinessDescriptors): Promise<SecurityBusinessRow>;
    /**
     * The same for a batch, in one lookup: an ingest introduces a whole portfolio at once, and
     * asking per ISIN whether it exists costs a round trip for every security every scrape.
     * Only the ISINs with no business yet are created.
     */
    ensureSecurityBusinesses(descriptorsList: readonly SecurityBusinessDescriptors[]): Promise<Map<string, SecurityBusinessRow>>;
    /**
     * Creates the business behind a security, assuming the caller has established there is none.
     *
     * Concurrent ingests race on the (owner_id, isin) unique index, and the loser rolls its whole
     * transaction back — financial entity and business included — then re-reads the winner's row,
     * so a race can't leave a half-built business behind. That fallback is also what makes the
     * caller's "there is none" only have to be true at the time it looked.
     *
     * Sort code, IRS code, country and tax category are inherited from the tenant's general
     * foreign-securities business, so a security behaves like it everywhere those fields drive
     * reporting.
     */
    private createSecurityBusiness;
    linkIdentifier(businessId: string, identifierType: SecurityIdentifierType, identifierValue: string): Promise<void>;
    clearCache(): void;
}
