Integrations Overview
The Integrations page (/integrations) is your single landing for connecting Kinderpedia to external services. Each tile represents a provider — click to connect, disconnect, or reconfigure.
Two scopes of integration
Kinderpedia has two distinct integration stores, surfaced on the same page but stored separately:
| Scope | Table | Examples | Visible to |
|---|---|---|---|
| School-level | integrations | WhatsApp, WeChat, DocuSign, Meta, GTM | All staff with integrations.manage |
| Per-user | user_integrations | Google Calendar, Google Drive, Zoom | Only the user who connected it |
The tile UI is identical, but a per-user connection only affects your own account. So if your colleague connects their Google Calendar, you still see your own calendar's status on your tile.
What you can connect today
| Provider | Scope | Used for |
|---|---|---|
| DocuSign | School | Native envelope signing on contracts |
| Google Calendar | Per-user | Two-way sync of lead activities |
| Google Drive | Per-user | Auto-archive signed contracts |
| Zoom | Per-user | Per-meeting room provisioning on activities |
| Meta (Messenger + Instagram) | School | Page + IG DM via Embedded Signup |
| WhatsApp Business | School | Per-school WABA messaging |
| WeChat OA | School | Service Account messaging |
| Telegram | School | Bot messaging |
| Viber | School | Viber Bot messaging |
| Google Tag Manager | School | dataLayer events on public forms |
| Meta Conversions API | School | Server-side conversion sync for ad attribution + ROI tracking |
Permissions
All school-level integrations require integrations.manage (admins auto-have it). Per-user integrations are owned by the connecting user — no permission check beyond auth.
A few special-purpose permissions for action-flows:
whatsapp.send/wechat.send/telegram.send/viber.send— needed to send on each channel (per-channel scoping so you can give Sales WhatsApp without WeChat)chat.manage— needed to block senders (any channel)docusign.send— needed to send a contract via DocuSign envelope
Connection lifecycle
not_connected → (connect flow) → connected → (token expires / revoked) → error
↓
(re-auth) → connectedThe tile shows the current state with a colored pill:
- Green "Connected" — credentials valid, ready to use
- Amber "Action needed" — connection partially complete (e.g. webhook subscription pending)
- Red "Error" — last operation failed, message in tooltip
- Grey "Not connected" — never set up
Hover the tile for the last successful action timestamp + the last error if any.
Credentials encryption
All third-party credentials — whether per-school (e.g. WhatsApp) or per-user (e.g. Google Calendar) — are encrypted at rest. Only the connection flow sees them in plaintext.
The API never returns credentials to the frontend. Only metadata (non-sensitive fields like webhook_subscription_pending or connected_via) is exposed.
Disconnecting
Each tile has a Disconnect action. What it does:
- Tries a graceful API call to the provider (e.g.
DELETE /channels/stopon Google watches,revokeon Zoom). - Sets the row to
status = disconnected. - Clears encrypted credentials.
- Keeps metadata + the row itself for audit/history.
Disconnecting does NOT delete data the integration produced. Synced calendar events stay on Google. Sent envelopes stay on DocuSign. The link is severed, not the artifacts.
Re-connecting
If a token expires or gets revoked, the tile flips to "Error" and re-clicking it walks through the full connection flow again. We don't try to silently refresh expired creds — the failure surface is loud on purpose.
Audit log
Every connect, disconnect, and credential update fires an audit_logs entry:
integration_connected— provider, who, metadata snapshotintegration_disconnected— provider, whointegration_credentials_updated— provider, who (no creds in the log itself)
For per-user integrations, the audit log includes the connecting user's id so you can see "who connected what."