Architecture
Overview
Keelstone has three layers that work together:
| Layer | Technology | Role |
|---|---|---|
| Excel Add-in | Office.js taskpane | User-facing shell; launches flows, writes to workbook |
| App Server | Node.js on Railway | Auth relay, org config, document merge |
| Salesforce | Managed package + your flows | Business logic, data, LWC components |
Request flow
User clicks action tile
↓
Taskpane opens Office dialog
↓
flow-host.html loads in dialog
↓
Fetches /api/orgs/config (Node server) → gets SF access token
↓
Loads lightning.out.js from Salesforce org
↓
$Lightning.use() → $Lightning.createComponent('lightning:flow', ...)
↓
cmp.startFlow(flowApiName, [])
↓
Your Screen Flow runs
↓
LWC component fires KEELSTONE_INSERT event
↓
flow-host.html → Office.context.ui.messageParent()
↓
Taskpane receives message → writes .xlsx to workbook
Authentication
Keelstone uses External Client App (ECA) OAuth with JWT tokens. The managed package installs an ECA in your org automatically via a post-install Apex job. No manual OAuth setup is required.
The access token is:
- Stored server-side per user session
- Injected as an
Authorization: Bearerheader on all XHR calls from the dialog to Salesforce - Never exposed to the flow or LWC code directly
Lightning Out
Flows run via Lightning Out, which embeds Aura/LWC components in external pages. The bridge application kstone:KeelstoneOutApp is installed by the managed package and exposes the Lightning Out endpoint.
The dialog URL must use the .lightning.force.com domain (not .my.salesforce.com) — Keelstone handles this conversion automatically.
Event transport
LWC components inside flows communicate with Excel through two parallel channels:
LWC component
├─ window.parent.postMessage(payload, '*') ← iframe render path
└─ document.dispatchEvent('keelstoneinsert') ← inline render path
flow-host.html listens on both
└─ Office.context.ui.messageParent(payload)
Excel taskpane
└─ DialogMessageReceived → writes to workbook
Both channels fire for every event. Keelstone normalizes whichever one arrives first; the second is ignored.
Packages
| Package | Namespace | Purpose |
|---|---|---|
Keelstone | kstone | Managed package — installed in customer orgs. Contains the Keelstone_Action__c object, Apex infrastructure, and Lightning Out bridge app. |
Keelstone-Samples | (none) | Unmanaged sample package — optional. Contains the accountSearch, excelTemplate, and queryBuilderLwc components, sample flows, and a starter Excel template. |