Documentation
¶
Overview ¶
Package tenant resolves per-tenant Notifier instances on demand.
On every Send, the routes layer asks the resolver for a Notifier configured for (tenant, channel). The resolver looks up the active Provider row, fetches credentials from KMS, and constructs the matching provider impl from the library. No cache — credentials may rotate, and provider rows may change at runtime; the cost of one extra KMS Get per send is the price of correctness.
Phase 1: plivo (SMS/WhatsApp/Voice) + mail (SMTP). Other providers land as small functions that follow the same shape — the library already exposes 33 implementations; this package wraps them.
Index ¶
Constants ¶
const DefaultBrand = "hanzo"
DefaultBrand is the brand slug whose KMS credentials are used when the caller's brand has not configured an override. Lives in KMS at `brand/hanzo/plivo/*`.
const PlivoBrandKMSPathPrefix = "brand"
PlivoBrandKMSPathPrefix is the KMS path under which per-brand Plivo credentials live. Combined with brand slug:
brand/<slug>/plivo/auth-id brand/<slug>/plivo/auth-token brand/<slug>/plivo/sender-id brand/<slug>/plivo/from-email
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Credentials ¶
Credentials is the flat key/value bag the library providers consume. The KMS values land here as plain strings; envelope decoding happens inside kmsclient.
type PlivoConfig ¶ added in v1.6.6
type PlivoConfig struct {
// Brand is the slug whose credentials produced this config. When a
// brand override exists, Brand == the requested brand. When the
// resolver fell back to the Hanzo default, Brand == "hanzo".
// Callers use this to log which Plivo account actually sent.
Brand string
// AuthID is the Plivo Auth ID (account-level credential).
AuthID string
// AuthToken is the Plivo Auth Token (account-level credential).
AuthToken string
// SenderID is the source number / shortcode / alphanumeric ID that
// will appear as the From on the SMS.
SenderID string
// FromEmail is the email address the brand sends from when notify
// channel=email is wired to the same per-brand config. Optional.
FromEmail string
// Override is true when this config came from the requested brand's
// own KMS entries (not the Hanzo default). Used by the platform
// UI's "current effective provider" indicator.
Override bool
}
PlivoConfig is the resolved per-brand Plivo configuration. The SenderID doubles as the Plivo "Source" — either an E.164 number or a Powerpack UUID.
type PlivoResolver ¶ added in v1.6.6
type PlivoResolver struct {
// contains filtered or unexported fields
}
PlivoResolver resolves per-brand Plivo configuration via KMS. One instance per process is enough — the underlying KMSClient already memoizes secrets for 1m TTL.
func NewPlivoResolver ¶ added in v1.6.6
func NewPlivoResolver(kms *platform.KMSClient) (*PlivoResolver, error)
NewPlivoResolver returns a PlivoResolver bound to the given KMS client. A nil KMS client is rejected at boot — fail-closed.
func (*PlivoResolver) ResolvePlivoConfig ¶ added in v1.6.6
func (r *PlivoResolver) ResolvePlivoConfig(ctx context.Context, brand string) (*PlivoConfig, error)
ResolvePlivoConfig returns the Plivo credentials that should be used when sending for brand. The lookup order is:
- brand/<requested>/plivo/* — the brand's own override.
- brand/hanzo/plivo/* — the Hanzo default.
On step 1 the resolver does NOT short-circuit on any non-EOF error: a KMS access error against the requested brand falls through to the default ONLY when the error indicates "secret not found". Any other error (auth fail, transport, 5xx) is surfaced — silently degrading to the Hanzo creds for someone else's transient KMS outage would risk sending the wrong brand's SMS during the outage window.
On step 2 the resolver fail-closes: a missing or unreachable Hanzo default returns an error. notify callers surface 503.
The empty string for `brand` is rejected as a programming error — the platform plugin always injects X-Org-Id before this fires.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver is the entry point routes call. It owns the base app (to look up provider rows) and the platform-side KMS facade (to fetch credentials).
func New ¶
New returns a Resolver bound to the given app + KMS client. A nil KMS client is allowed; in that mode the resolver falls back to env var credentials, which is the local-dev / scratch-image path.
func (*Resolver) Resolve ¶
func (r *Resolver) Resolve(ctx context.Context, tenant, channel, service string, to []string) (notify.Notifier, string, error)
Resolve returns a notifier wired with credentials for (tenant, channel). service may be empty to take the tenant's default provider for the channel. The returned notifier targets `to` so caller can call Send directly — providers in the library are constructed with a fixed recipient list per the casdoor/nikoksr design.