← All examples
EventsSQLiteValidation

Record customer events in SQLite

Subscribe to a named event and keep a durable application record without turning the workflow into a web of callback code.

This workflow listens for customer.updated, validates every publication, and writes the accepted event to a separate application database. The event can come from services.events.emit() in another loaded workflow or from WOML’s authenticated event ingress.

The workflow

WOML
<woml>
  <workflow
    id="customer-event-ledger"
    name="Customer event ledger"
    description="Record validated customer updates in SQLite."
    version="1.0.0"
  >
    <config concurrency="4" queue="customer-events" />

    <triggers>
      <event id="customerUpdated" name="customer.updated">
        <schema>
          {
            "type": "object",
            "required": ["customerId", "change"],
            "properties": {
              "customerId": { "type": "string" },
              "change": { "type": "string" }
            },
            "additionalProperties": false
          }
        </schema>
      </event>
    </triggers>

    <steps>
      <step id="recordEvent" name="Record customer update">
        <script>
          const db = services.db({
            driver: "sqlite",
            connection: "./data/customer-events.sqlite"
          });

          await db.execute({
            text: `
              CREATE TABLE IF NOT EXISTS customer_events (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                customer_id TEXT NOT NULL,
                change TEXT NOT NULL,
                recorded_at TEXT NOT NULL
              )
            `
          }, { name: "ensure-customer-events-table" });

          const recordedAt = new Date().toISOString();
          const result = await db.insert({
            table: "customer_events",
            values: {
              customer_id: context.payload.customerId,
              change: context.payload.change,
              recorded_at: recordedAt
            }
          }, { name: "record-customer-event" });

          return {
            customerId: context.payload.customerId,
            recordedAt,
            rowId: result.lastInsertId
          };
        </script>
      </step>
    </steps>
  </workflow>
</woml>

Run it

Create the data directory before activation, then validate and run the workflow alongside any publishers that emit customer.updated.

Terminal
mkdir -p data
woml check customer-event-ledger.woml
woml run customer-event-ledger.woml

The SQLite file is application data and must remain separate from WOML’s runtime-state database. Parameterized database helpers and stable operation names keep the write explicit and supervised.