Coverage for apps/integrations/catalog.py: 100%
15 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
1"""Code-level provider catalog (design D1).
3The *set of supported providers* (with category + scope) is a small, stable code constant tied
4to the adapters. What a tenant *configures* — enable flags, org/user creds — lives in the DB
5(`OrgIntegration`, `UserCredential`). Global platform integrations (Stripe/Twilio/SendGrid/
6Cognito/S3/reCAPTCHA) are NOT here — they stay env-configured (design D4).
7"""
9from __future__ import annotations
11from dataclasses import dataclass
13PER_ORG = "per_org"
14PER_USER = "per_user"
17@dataclass(frozen=True)
18class ProviderDef:
19 code: str
20 category: str # credit | aus | docmagic | lender | zapier | tireless
21 scope: str # per_org | per_user
22 label: str = ""
25PROVIDERS: dict[str, ProviderDef] = {
26 "meridianlink": ProviderDef("meridianlink", "credit", PER_USER, "MeridianLink Credit"),
27 "du": ProviderDef("du", "aus", PER_USER, "Fannie Mae Desktop Underwriter"),
28 "lpa": ProviderDef("lpa", "aus", PER_USER, "Freddie Mac Loan Product Advisor"),
29 "docmagic": ProviderDef("docmagic", "docmagic", PER_ORG, "DocMagic Disclosures"),
30 "zapier": ProviderDef("zapier", "zapier", PER_ORG, "Zapier Automations"),
31 # Tireless AI is just another provider in the catalog (ADR-001): the connection ships last.
32 "tireless": ProviderDef("tireless", "tireless", PER_ORG, "Tireless AI Processing"),
33}
36def get_provider(code: str) -> ProviderDef | None:
37 return PROVIDERS.get(code)
40def providers_by_category(category: str) -> list[ProviderDef]:
41 return [p for p in PROVIDERS.values() if p.category == category]