@spinekit/integrations
A unified, mongokit-native connections hub for arc apps. A business links external providers (WhatsApp / email / SMS / Slack …) with encrypted credentials, tests the connection, and enables/disables them per company or branch.
It owns the connection model, the AES-GCM credential vault, the provider
registry, and the admin resource. Provider protocols come from the
kernels — @classytic/notifications (email/SMS transports) and
@classytic/social (Meta WhatsApp / Telegram / OAuth) — adapted behind provider
subpaths. Notification routing stays in @classytic/arc-notifications, which
pulls its live channels from this hub's activeChannels.
import { createIntegrationsModule } from '@spinekit/integrations';
import { emailProvider } from '@spinekit/integrations/providers/email';
import { whatsappMetaProvider } from '@spinekit/integrations/providers/whatsapp-meta';
createApp({
modules: [
createIntegrationsModule({
connection,
keyProvider, // host-owned AES key source
providers: [emailProvider, whatsappMetaProvider],
permissions: { view: requireHeadOfficeAdmin, manage: requireHeadOfficeAdmin },
}),
],
});
Layering
| Layer | Owns |
|---|---|
kernels (@classytic/notifications, @classytic/social) |
provider protocols (framework/DB-agnostic) |
@spinekit/integrations (this) |
connection model + credential vault + registry + admin resource |
@classytic/arc-notifications |
event → channel fan-out (channels pulled from activeChannels) |
| host | wiring, per-branch scope, KeyProvider |
Secrets
Secret fields (API keys, tokens) are AES-256-GCM encrypted at rest via a
host-supplied KeyProvider (env now, a secret manager later — swapping it is a
host change, not a code change). Non-secret fields stay plaintext config.
Reads NEVER return ciphertext — only config + a secretsSet flag map.
Extending
A new provider (Slack, a bulk-SMS gateway, a Twilio-brokered WhatsApp) is one new
subpath file implementing IntegrationProvider { credentialFields, capabilities, testConnection, buildChannel? } — no core change.