## Summary Bundled plugins now persist shared runtime state in project-scoped PostgreSQL tables instead of maintaining independent SQLite authority. Reports, CLI Printing Press, Compound Engineering, Roadmap, Even Realities, and WhatsApp all follow the same ownership and startup contract as Fusion core. ## Design decisions - Plugin schema hooks run through the host’s PostgreSQL owner and enforce project isolation. - The SDK exposes the host contract needed by bundled plugins without importing engine internals. - Legacy Roadmap ownership fixtures use the supported empty-owner sentinel, preserving current composite primary/foreign keys while exercising backfill behavior. - The lockfile travels with the Even Realities PostgreSQL dependency so packaged installs remain reproducible. ## Validation - All six affected plugin builds pass. - Affected plugin suites pass: 773 tests across Printing Press, Compound Engineering, Even Realities, Reports, Roadmap, and WhatsApp. - `pnpm test:gate` passes all 478 gate tests. - This PR changes 40 files. ## Stack - Depends on #2110 → #2109 → #2108. - The documentation/release PR completes the stack. Related: #2105 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Breaking Changes** * PostgreSQL is now required for runtime storage; SQLite files are used only as one-time migration inputs. * The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed. * **New Features** * Added project-isolated PostgreSQL storage for plugins, reports, tasks, notifications, and other plugin data. * Added agent tools for reports and CLI service drafts. * Added PostgreSQL schema initialization support for plugin authors. * **Bug Fixes** * Improved migration and recovery of legacy plugin state. * Prevented cross-project data access and strengthened transactional schema updates. * **Documentation** * Updated storage, migration, deployment, plugin authoring, CLI, and dashboard guidance for PostgreSQL. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
WhatsApp Chat Plugin
WhatsApp Web (Baileys) bridge for Fusion. It pairs with your phone (QR or pairing code), keeps a background connection alive, forwards inbound direct text messages to a Fusion AI session, and sends the assistant reply back to WhatsApp.
No Meta Cloud app, webhook URL, verify token, or Graph API credentials are required.
Setup
- Enable/install the plugin in Plugin Manager.
- Configure
allowedSenders(empty means nobody is allowed). - Choose
pairingMode:qr(default): fetch QR from/api/plugins/fusion-plugin-whatsapp-chat/qrand scan in WhatsApp.code: setpairingPhoneNumber(E.164 digits without+) and request code via/pair-code.
- Confirm
/statusreportsconnected.
Settings
pairingMode:qrorcode.pairingPhoneNumber: E.164 digits without+(used forcodemode).allowedSenders: allowed WhatsApp JIDs or E.164 digits.agentSystemPrompt: system prompt for replies.historyTurnLimit: persisted turn window (default40).dedupeRetentionDays: replay-protection retention window for inbound message IDs (default7days). Rows older than this are pruned lazily whenever a new inbound message is processed.
Routes
GET /api/plugins/fusion-plugin-whatsapp-chat/statusGET /api/plugins/fusion-plugin-whatsapp-chat/qrPOST /api/plugins/fusion-plugin-whatsapp-chat/pair-codePOST /api/plugins/fusion-plugin-whatsapp-chat/logout
Storage and lifecycle
- Starts socket on
onLoad, stops ononUnload. - Persists transcript and dedupe state in:
whatsapp_chat_sessionswhatsapp_chat_dedupe
- Persists Baileys auth state in:
whatsapp_auth_credswhatsapp_auth_keys
- After restart, plugin reconnects automatically when auth is valid.
Troubleshooting
- Stuck
awaiting-qr: fetch a fresh QR and scan promptly. loggedOut: call/logout(or wait for clear) and re-pair.- Pair code not generated: ensure
pairingPhoneNumberis E.164 digits without+. - No replies: check
allowedSenders; empty list blocks all inbound messages by design.
Compliance warning
Baileys is an unofficial WhatsApp Web protocol client. Use may violate WhatsApp Terms of Service. This plugin is intended for self-hosted, single-user use at your own risk.