Skip to content

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:

  1. Topic enum is expanded — the central.adapter_scripts table must include test_connection and list_remote_outlets in 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;
    

  2. Provider connection exists — the provider (e.g. revel) must have a connection configured with credentials via PUT /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

  1. Create scripts/adapters/{provider}/test_connection.js
  2. Create scripts/adapters/{provider}/list_remote_outlets.js
  3. Create docs/guides/adapters/{provider}.md (see revel.md as template)
  4. Deploy: MYSQL_URI="..." ./script/deploy-adapter-scripts.sh
  5. 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.