Adapter Scripts — Developer Guide¶
Overview¶
POS adapter scripts are JavaScript files that run inside the Go service via goja (pure Go JS engine). Each script handles one task for one POS provider — e.g. "test Revel connection" or "list Revel outlets".
Scripts live in Git (scripts/adapters/) and are deployed to central.adapter_scripts in the database.
Directory Structure¶
scripts/adapters/
revel/
test_connection.js
list_remote_outlets.js
deliverect/
test_connection.js
list_remote_outlets.js
...
Each file must have a JSDoc header with @provider and @topic:
/**
* @provider revel
* @topic test_connection
* @version 1.0.0
*/
function transform(input, context) {
// ...
}
Quick Start¶
1. Write a script¶
Create scripts/adapters/{provider}/{topic}.js. See adapter-script-contracts.md for input/output shapes per topic.
2. Validate (dry run)¶
./script/deploy-adapter-scripts.sh --dry-run
Output:
Found 2 script(s):
revel test_connection v1.0.0 scripts/adapters/revel/test_connection.js
revel list_remote_outlets v1.0.0 scripts/adapters/revel/list_remote_outlets.js
--dry-run: no changes written.
3. Deploy to database¶
MYSQL_URI="user:pass@tcp(host:port)/dbname" ./script/deploy-adapter-scripts.sh
This upserts each script into central.adapter_scripts with status = 'active'.
4. Test via API¶
# Test connection (uses test_connection.js)
curl -X POST http://localhost:8080/api/v1/provider-connections/revel/test \
-H "X-Tenant-ID: your-tenant-uuid"
# List remote outlets (uses list_remote_outlets.js)
curl http://localhost:8080/api/v1/provider-connections/revel/remote-outlets \
-H "X-Tenant-ID: your-tenant-uuid"
Development Workflow¶
Edit .js file → deploy to DB → test via API → iterate
Typical loop during development:
# 1. Edit the script
vim scripts/adapters/revel/test_connection.js
# 2. Deploy (takes ~1 second)
MYSQL_URI="..." ./script/deploy-adapter-scripts.sh
# 3. Test
curl -X POST http://localhost:8080/api/v1/provider-connections/revel/test \
-H "X-Tenant-ID: ..."
# 4. Check output, go back to step 1
No Go recompile needed — only the JS script changes.
Prerequisites¶
Before deploying scripts, ensure:
-
Topic enum is expanded — the
central.adapter_scriptstable must includetest_connectionandlist_remote_outletsin its topic enum. This is done via dashboard-app migration:ALTER TABLE central.adapter_scripts MODIFY COLUMN topic ENUM( 'sync_outlet','sync_products','order_dispatch','order_status_update', 'test_connection','list_remote_outlets' ) NOT NULL; -
Provider connection exists — the provider (e.g.
revel) must have a connection configured with credentials viaPUT /api/v1/provider-connections/revel.
Script API Reference¶
Input (passed to every script)¶
input = {
providerSlug: "revel",
baseUrl: "https://xyz.revelup.com",
apiKey: "abc123",
apiSecret: "secret456",
webhookUrl: "https://...",
config: { /* JSON from provider_connections.config */ }
}
Context helpers¶
// HTTP GET
var resp = context.http.get(url, { "Header-Name": "value" });
// HTTP POST
var resp = context.http.post(url, { key: "value" }, { "Header-Name": "value" });
// HTTP PUT
var resp = context.http.put(url, { key: "value" }, { "Header-Name": "value" });
// HTTP DELETE
var resp = context.http.delete(url, { "Header-Name": "value" });
// Response shape (all methods)
resp.statusCode // number: 200, 401, etc.
resp.body // object: parsed JSON (or string if not JSON)
// Logging
context.log("debug message");
Output per topic¶
| Topic | Return Shape |
|---|---|
test_connection |
{ success: bool, message: string } |
list_remote_outlets |
[{ id: string, name: string, address?: string }] |
sync_outlet |
TODO — see contracts |
sync_products |
TODO — see contracts |
order_dispatch |
TODO — see contracts |
order_status_update |
TODO — see contracts |
Debugging Tips¶
Script errors¶
If a script throws an error or returns an unexpected shape, the API response includes the error message:
{
"code": 500,
"isSuccess": false,
"message": "failed to list remote outlets",
"detail": "execute script: transform() error: Error: Failed to list establishments: HTTP 401"
}
Common issues¶
| Problem | Cause | Fix |
|---|---|---|
| "no adapter script available" | Script not in DB or wrong status | Run deploy script |
| "Data truncated for column 'topic'" | Topic enum not expanded | Run ALTER TABLE migration |
| Script timeout (30s) | Slow POS API or infinite loop | Check API response time, add pagination limits |
| "connection failed" in test | Wrong baseUrl or credentials | Check provider_connections config |
resp.body is a string not object |
POS API returned non-JSON | Check Content-Type, handle string response |
View deployed scripts¶
SELECT provider, topic, version, status, LENGTH(script) AS script_size,
created_at, updated_at
FROM central.adapter_scripts
ORDER BY provider, topic;
Adding a New Provider¶
- Create
scripts/adapters/{provider}/test_connection.js - Create
scripts/adapters/{provider}/list_remote_outlets.js - Create
docs/guides/adapters/{provider}.md(see revel.md as template) - Deploy:
MYSQL_URI="..." ./script/deploy-adapter-scripts.sh - Test via API
No Go code changes required.
Production Deployment¶
In CI/CD (Cloud Build), add a step after service deploy:
- name: 'gcr.io/cloud-builders/go'
args: ['run', 'cmd/deploy-scripts/main.go', '--dir=scripts/adapters']
env:
- 'MYSQL_URI=$$MYSQL_URI'
This ensures scripts are always in sync with the deployed code.
Related Docs¶
- Adapter Script Contracts — input/output shapes per topic
- POS Adapter Architecture — overall architecture and phases
- POS Adapter Guidelines — transformation rules for AI generation
- Per-provider guides: Revel | Deliverect | Atlas Kitchen | Lightspeed