@alvera-ai/platform-sdk 0.12.1 → 0.13.0-next.gf3d2a4a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/AGENTS.md +121 -19
- package/.agent/account_management.md +79 -38
- package/.agent/action_logs.md +144 -0
- package/.agent/action_status_updaters.md +237 -53
- package/.agent/ai_agents.md +149 -53
- package/.agent/ai_sandbox.md +11 -4
- package/.agent/async.md +16 -6
- package/.agent/connected_apps.md +116 -4
- package/.agent/cookbook/_fixtures/README.md +9 -9
- package/.agent/cookbook/_fixtures/{payment_risk/_compliance_screenings_payment_risk_compliance_screening.liquid → payments/_compliance_screenings_payments_compliance_screening.liquid} +1 -1
- package/.agent/cookbook/_fixtures/{payment_risk/_compliance_screenings_payment_risk_mdm.liquid → payments/_compliance_screenings_payments_mdm.liquid} +1 -1
- package/.agent/cookbook/_fixtures/{payment_risk/_payment_accounts_payment_risk_mdm.liquid → payments/_payment_accounts_payments_mdm.liquid} +1 -1
- package/.agent/cookbook/_fixtures/{payment_risk/_payment_accounts_payment_risk_payment_account.liquid → payments/_payment_accounts_payments_payment_account.liquid} +1 -1
- package/.agent/cookbook/_fixtures/{accounts_receivable/_customers_accounts_receivable_customer.liquid → subscription/_customers_subscription_customer.liquid} +1 -1
- package/.agent/cookbook/_fixtures/{accounts_receivable/_customers_accounts_receivable_mdm.liquid → subscription/_customers_subscription_mdm.liquid} +1 -1
- package/.agent/cookbook/_setup/foundation.md +24 -4
- package/.agent/cookbook/_setup/healthcare.md +24 -4
- package/.agent/cookbook/_setup/{payment_risk.md → payments.md} +51 -31
- package/.agent/cookbook/_setup/{accounts_receivable.md → subscription.md} +51 -31
- package/.agent/cookbook/action-status-updaters.md +25 -18
- package/.agent/cookbook/bulk-ingest.md +15 -15
- package/.agent/cookbook/dunning-sms-for-delinquent.md +21 -21
- package/.agent/cookbook/{custom-tables.md → generic-tables.md} +44 -41
- package/.agent/cookbook/invite-team.md +19 -13
- package/.agent/cookbook/kyc-notification-on-account-activation.md +26 -26
- package/.agent/cookbook/marketing-campaign-send.md +1003 -0
- package/.agent/cookbook/rest-fetch.md +9 -9
- package/.agent/cookbook/sanctions-screening-with-agent-review.md +22 -22
- package/.agent/cookbook/system-templates.md +15 -15
- package/.agent/cookbook/triage-prospects-by-priority.md +17 -17
- package/.agent/cookbook/welcome-sms-for-customers.md +21 -21
- package/.agent/data_activation_clients.md +177 -42
- package/.agent/data_sources.md +55 -37
- package/.agent/datalakes.md +30 -17
- package/.agent/debugging.md +48 -14
- package/.agent/errors.md +39 -17
- package/.agent/generic_tables.md +150 -51
- package/.agent/interoperability_contracts.md +114 -15
- package/.agent/mdm.md +171 -93
- package/.agent/messages.md +252 -0
- package/.agent/templates.md +21 -4
- package/.agent/tool-call-configs.md +1 -1
- package/.agent/tools.md +150 -60
- package/.agent/type_naming.md +79 -18
- package/.agent/workflows.md +408 -62
- package/LICENSE +21 -93
- package/README.md +2 -2
- package/dist/bin/platform-sdk.mjs +53 -1
- package/dist/bin/platform-sdk.mjs.map +1 -1
- package/dist/index.d.mts +582 -66
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +654 -105
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -6
- /package/.agent/cookbook/_fixtures/{accounts_receivable → subscription}/stripe_customers_batch1.csv +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Capability: pull records from a third-party REST API on demand"
|
|
3
3
|
summary: A capability walk for pull-based ingestion. Register a REST-API tool with its auth (Bearer here; an OAuth2 refresh-token variant is shown too), bind it to a contract and a Data Activation Client whose `tool_call` names the path to fetch, trigger a fetch (`api.dataActivationClients.runManually`), and verify the rows landed. The platform calls the API for you — no file to upload.
|
|
4
|
-
industry:
|
|
4
|
+
industry: subscription
|
|
5
5
|
slug: rest-fetch
|
|
6
6
|
vitest_source:
|
|
7
|
-
- integration-tests/tests/
|
|
7
|
+
- integration-tests/tests/subscription/run-dac-fetch.test.ts
|
|
8
8
|
- integration-tests/tests/foundation/oauth2-dac-fetch.test.ts
|
|
9
|
-
- integration-tests/tests/
|
|
9
|
+
- integration-tests/tests/subscription/bootstrap.test.ts
|
|
10
10
|
status: green
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -31,7 +31,7 @@ body) for the reference.
|
|
|
31
31
|
|
|
32
32
|
# Walkthrough
|
|
33
33
|
|
|
34
|
-
The `_setup/
|
|
34
|
+
The `_setup/subscription.md` bootstrap left `api`, `tenantSlug`,
|
|
35
35
|
`datalakeSlug`, and `ctx.datalakeId` populated. The fetch targets a mock Stripe
|
|
36
36
|
API; locally that is the integration stack's WireMock on `localhost:8080`.
|
|
37
37
|
|
|
@@ -84,17 +84,17 @@ vendored production Stripe customer + MDM templates.
|
|
|
84
84
|
const { readFileSync } = await import('node:fs')
|
|
85
85
|
const { join } = await import('node:path')
|
|
86
86
|
const customerTemplate = readFileSync(
|
|
87
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
87
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_customer.liquid'),
|
|
88
88
|
'utf8',
|
|
89
89
|
)
|
|
90
90
|
const mdmTemplate = readFileSync(
|
|
91
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
91
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_mdm.liquid'),
|
|
92
92
|
'utf8',
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
const { data: contract } = await api.interoperabilityContracts.create(tenantSlug, datalakeSlug, {
|
|
96
96
|
name: `Stripe REST Customer Contract ${runSuffix}`,
|
|
97
|
-
description: 'Stripe customer fetch →
|
|
97
|
+
description: 'Stripe customer fetch → Subscription Customer.',
|
|
98
98
|
resource_type: 'customer',
|
|
99
99
|
template_config: { type: 'custom', body: customerTemplate },
|
|
100
100
|
mdm_input_config: { type: 'custom', body: mdmTemplate },
|
|
@@ -240,7 +240,7 @@ if (!oauthTool.id) {
|
|
|
240
240
|
|
|
241
241
|
- `data_activation_clients.md` §6.3 — `.runManually` + the pull-based reference
|
|
242
242
|
- `tools.md` — the `rest_api` tool body, `bearer` vs `oauth2` auth
|
|
243
|
-
- `_setup/
|
|
244
|
-
- `integration-tests/tests/
|
|
243
|
+
- `_setup/subscription.md` — the bootstrap this walk starts from
|
|
244
|
+
- `integration-tests/tests/subscription/run-dac-fetch.test.ts`,
|
|
245
245
|
`integration-tests/tests/foundation/oauth2-dac-fetch.test.ts` — the green tests
|
|
246
246
|
these calls are lifted from
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Disambiguate gray-zone sanctions screenings via an LLM agent
|
|
3
3
|
summary: End-to-end agent-driven workflow — a chat-completion LLM agent disambiguates gray-zone-scored sanctions screenings into a verified/blocked verdict, the workflow's decision interpolates that verdict, two SMS actions (one per verdict) fan out, and the run is verified row-by-row. A clearly-clear screening is filtered out before the agent ever sees it.
|
|
4
|
-
industry:
|
|
4
|
+
industry: payments
|
|
5
5
|
slug: sanctions-screening-with-agent-review
|
|
6
6
|
vitest_source:
|
|
7
|
-
- integration-tests/tests/
|
|
8
|
-
- integration-tests/tests/
|
|
9
|
-
- integration-tests/tests/
|
|
10
|
-
- integration-tests/tests/
|
|
11
|
-
- integration-tests/tests/
|
|
12
|
-
- integration-tests/tests/
|
|
13
|
-
- integration-tests/tests/
|
|
7
|
+
- integration-tests/tests/payments/sanctions-review-workflow.test.ts
|
|
8
|
+
- integration-tests/tests/payments/interoperability-contracts.test.ts
|
|
9
|
+
- integration-tests/tests/payments/run-dac-single.test.ts
|
|
10
|
+
- integration-tests/tests/payments/create-dac.test.ts
|
|
11
|
+
- integration-tests/tests/payments/tools.test.ts
|
|
12
|
+
- integration-tests/tests/payments/data-sources.test.ts
|
|
13
|
+
- integration-tests/tests/payments/bootstrap.test.ts
|
|
14
14
|
status: green
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -49,8 +49,8 @@ reaches the agent and fans out to a verdict-keyed SMS, the
|
|
|
49
49
|
clearly-clear screening is filtered out before any agent call.
|
|
50
50
|
|
|
51
51
|
The scenario is anchored to
|
|
52
|
-
`platform/integration-tests/tests/
|
|
53
|
-
— a green end-to-end test. The setup file `_setup/
|
|
52
|
+
`platform/integration-tests/tests/payments/sanctions-review-workflow.test.ts`
|
|
53
|
+
— a green end-to-end test. The setup file `_setup/payments.md`
|
|
54
54
|
already provisioned the tenant + datalake + tenant-scoped client;
|
|
55
55
|
this cookbook starts from there.
|
|
56
56
|
|
|
@@ -67,7 +67,7 @@ this cookbook starts from there.
|
|
|
67
67
|
| Compliance Screening interop contract | build |
|
|
68
68
|
| Manual-upload DAC | build |
|
|
69
69
|
|
|
70
|
-
The setup file `_setup/
|
|
70
|
+
The setup file `_setup/payments.md` already provisioned the
|
|
71
71
|
tenant + datalake + tenant-scoped client; this cookbook starts
|
|
72
72
|
from there.
|
|
73
73
|
|
|
@@ -355,7 +355,7 @@ ctx.manualUploadToolId = manualUploadToolResp.data.id!
|
|
|
355
355
|
|
|
356
356
|
The interoperability contract is the row-shaping rule: a Liquid
|
|
357
357
|
template that maps an inbound Atomic FI compliance-screening row
|
|
358
|
-
into a
|
|
358
|
+
into a payments `ComplianceScreening` upsert. This cookbook
|
|
359
359
|
loads the production Atomic FI compliance-screening + MDM
|
|
360
360
|
templates from the vendored fixtures directory.
|
|
361
361
|
|
|
@@ -370,17 +370,17 @@ master-data resolution keys on to find-or-create the LegalEntity
|
|
|
370
370
|
const { readFileSync } = await import('node:fs')
|
|
371
371
|
const { join } = await import('node:path')
|
|
372
372
|
const csTemplate = readFileSync(
|
|
373
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
373
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'payments/_compliance_screenings_payments_compliance_screening.liquid'),
|
|
374
374
|
'utf8',
|
|
375
375
|
)
|
|
376
376
|
const mdmTemplate = readFileSync(
|
|
377
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
377
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'payments/_compliance_screenings_payments_mdm.liquid'),
|
|
378
378
|
'utf8',
|
|
379
379
|
)
|
|
380
380
|
|
|
381
381
|
const contractResp = await api.interoperabilityContracts.create(tenantSlug, datalakeSlug, {
|
|
382
382
|
name: `Cookbook Atomic FI Compliance Screening Contract ${runSuffix}`,
|
|
383
|
-
description: 'Atomic FI compliance-screenings →
|
|
383
|
+
description: 'Atomic FI compliance-screenings → Payments ComplianceScreening (custom Liquid + MDM input).',
|
|
384
384
|
resource_type: 'compliance_screening',
|
|
385
385
|
template_config: { type: 'custom', body: csTemplate },
|
|
386
386
|
mdm_input_config: { type: 'custom', body: mdmTemplate },
|
|
@@ -669,7 +669,7 @@ if (!verdictBody.includes('[verified]')) {
|
|
|
669
669
|
# Rollback
|
|
670
670
|
|
|
671
671
|
The cookbook doctest harness does not currently tear down created
|
|
672
|
-
resources. The `_setup/
|
|
672
|
+
resources. The `_setup/payments.md` setup file's
|
|
673
673
|
runSuffix-scoped tenant / datalake / user names mean each run is
|
|
674
674
|
naturally isolated; the seeded local DB is cheap to reset
|
|
675
675
|
(`mix ecto.reset` on the platform repo).
|
|
@@ -678,7 +678,7 @@ naturally isolated; the seeded local DB is cheap to reset
|
|
|
678
678
|
|
|
679
679
|
After this cookbook's thirteen steps run green:
|
|
680
680
|
|
|
681
|
-
- A
|
|
681
|
+
- A payments tenant exists with a payments-domain
|
|
682
682
|
datalake
|
|
683
683
|
- An SMS tool, a chat-completion LLM tool, a Sanctions Review AI
|
|
684
684
|
agent (qwen3-vl:8b-instruct, verified/blocked response schema), and a
|
|
@@ -705,10 +705,10 @@ entirely — is demonstrated end-to-end, not merely provisioned.
|
|
|
705
705
|
|
|
706
706
|
# See also
|
|
707
707
|
|
|
708
|
-
- `_setup/
|
|
708
|
+
- `_setup/payments.md` — the inlined bootstrap that
|
|
709
709
|
provisions the tenant + datalake this cookbook starts from
|
|
710
710
|
- `kyc-notification-on-account-activation.md` — the
|
|
711
|
-
static-decision
|
|
711
|
+
static-decision payments cookbook; same SMS wiring, full
|
|
712
712
|
data-activation chain, no agent
|
|
713
713
|
- `score-leads-with-llm-categorization.md`,
|
|
714
714
|
`contact-us-triage-with-llm.md` — the foundation and healthcare
|
|
@@ -723,11 +723,11 @@ entirely — is demonstrated end-to-end, not merely provisioned.
|
|
|
723
723
|
agent-output decision interpolation
|
|
724
724
|
- `.agent/interoperability_contracts.md` — custom contract shape,
|
|
725
725
|
`template_config` vs `mdm_input_config`
|
|
726
|
-
- `.agent/cookbook/_fixtures/
|
|
726
|
+
- `.agent/cookbook/_fixtures/payments/` — the vendored Atomic
|
|
727
727
|
FI compliance-screening / MDM Liquid templates §007 loads
|
|
728
|
-
- `integration-tests/tests/
|
|
728
|
+
- `integration-tests/tests/payments/sanctions-review-workflow.test.ts` —
|
|
729
729
|
the anchor green test these snippets are lifted from
|
|
730
|
-
- `integration-tests/tests/
|
|
730
|
+
- `integration-tests/tests/payments/interoperability-contracts.test.ts`,
|
|
731
731
|
`run-dac-single.test.ts`, `create-dac.test.ts`, `tools.test.ts`,
|
|
732
732
|
`data-sources.test.ts` — the per-resource create + ingest
|
|
733
733
|
snippets §005–§010 are lifted from
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Capability: discover the platform's built-in row-mapping templates"
|
|
3
3
|
summary: A capability walk for system-template discovery. List the Liquid templates the platform ships for your datalake's data domain (`api.templates.systemTemplates`), read the human-readable catalog (`api.templates.metadata`), and pull one template's detail (`api.templates.metadataDetails`) — so you can start an interoperability contract from a platform template instead of hand-writing Liquid. Read-only; creates nothing.
|
|
4
|
-
industry:
|
|
4
|
+
industry: subscription
|
|
5
5
|
slug: system-templates
|
|
6
6
|
vitest_source:
|
|
7
|
-
- integration-tests/tests/
|
|
8
|
-
- integration-tests/tests/
|
|
7
|
+
- integration-tests/tests/subscription/system-templates.test.ts
|
|
8
|
+
- integration-tests/tests/subscription/bootstrap.test.ts
|
|
9
9
|
status: green
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -19,8 +19,8 @@ from a vetted template instead of hand-written Liquid.
|
|
|
19
19
|
|
|
20
20
|
- `systemTemplates(tenantSlug, datalakeSlug)` — the machine-readable list:
|
|
21
21
|
`{ data: [{ path, content, output_schema }] }`. The list is **filtered to your
|
|
22
|
-
datalake's data domain** plus globals — a
|
|
23
|
-
never appears in an
|
|
22
|
+
datalake's data domain** plus globals — a payments or healthcare template
|
|
23
|
+
never appears in an subscription datalake.
|
|
24
24
|
- `metadata(tenantSlug, datalakeSlug)` — the same catalog as a markdown summary.
|
|
25
25
|
- `metadataDetails(tenantSlug, datalakeSlug, basename, intent)` — one template's
|
|
26
26
|
detail by basename + intent.
|
|
@@ -31,18 +31,18 @@ differ by domain. See `templates.md` for the reference, and
|
|
|
31
31
|
|
|
32
32
|
# Walkthrough
|
|
33
33
|
|
|
34
|
-
The `_setup/
|
|
34
|
+
The `_setup/subscription.md` bootstrap already provisioned the tenant +
|
|
35
35
|
datalake and left `api`, `tenantSlug`, and `datalakeSlug` populated. This walk
|
|
36
36
|
starts from there.
|
|
37
37
|
|
|
38
38
|
## 001 — list the system templates in scope for this datalake
|
|
39
39
|
|
|
40
40
|
`systemTemplates` returns every platform-shipped Liquid template visible to this
|
|
41
|
-
datalake: the templates for its data domain (here, `
|
|
41
|
+
datalake: the templates for its data domain (here, `subscription`) plus
|
|
42
42
|
domain-agnostic globals (e.g. the SNS delivery-status poller). Each entry has a
|
|
43
43
|
`path`, the Liquid `content`, and an `output_schema` (`null` when the template
|
|
44
44
|
has no companion schema). The list is domain-scoped — templates for other data
|
|
45
|
-
domains (`healthcare`, `
|
|
45
|
+
domains (`healthcare`, `payments`, `foundation`, …) are filtered out, so you
|
|
46
46
|
only see what is usable here.
|
|
47
47
|
|
|
48
48
|
```typescript
|
|
@@ -53,14 +53,14 @@ if (paths.length === 0) {
|
|
|
53
53
|
throw new Error('expected the platform to ship at least one system template')
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// The
|
|
57
|
-
const arAnchor = 'data_activation/interoperability/
|
|
56
|
+
// The subscription anchor template is present...
|
|
57
|
+
const arAnchor = 'data_activation/interoperability/subscription/stripe/customers_subscription_customer'
|
|
58
58
|
if (!paths.some((p) => p.includes(arAnchor))) {
|
|
59
59
|
throw new Error(`expected the AR customer template (${arAnchor}) in the list`)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// ...and templates for other data domains are filtered out of an AR datalake.
|
|
63
|
-
const otherDomains = ['healthcare', '
|
|
63
|
+
const otherDomains = ['healthcare', 'payments', 'foundation', 'core_banking', 'service_commerce', 'trading']
|
|
64
64
|
const leaked = paths.filter((p) => otherDomains.some((d) => p.split('/').includes(d)))
|
|
65
65
|
if (leaked.length > 0) {
|
|
66
66
|
throw new Error(`cross-domain templates leaked into an AR datalake: ${leaked.join(', ')}`)
|
|
@@ -78,7 +78,7 @@ const { data: catalog } = await api.templates.metadata(tenantSlug, datalakeSlug)
|
|
|
78
78
|
if (typeof catalog !== 'string' || catalog.length === 0) {
|
|
79
79
|
throw new Error('expected a non-empty markdown template catalog')
|
|
80
80
|
}
|
|
81
|
-
if (!catalog.includes('
|
|
81
|
+
if (!catalog.includes('customers_subscription_customer')) {
|
|
82
82
|
throw new Error('expected the AR customer template named in the catalog markdown')
|
|
83
83
|
}
|
|
84
84
|
```
|
|
@@ -95,7 +95,7 @@ copies the template into a contract's `template_config`.
|
|
|
95
95
|
const { data: detail } = await api.templates.metadataDetails(
|
|
96
96
|
tenantSlug,
|
|
97
97
|
datalakeSlug,
|
|
98
|
-
'
|
|
98
|
+
'customers_subscription_customer',
|
|
99
99
|
'data_activation_interoperability',
|
|
100
100
|
)
|
|
101
101
|
if (typeof detail !== 'string' || detail.length === 0) {
|
|
@@ -124,6 +124,6 @@ if (typeof detail !== 'string' || detail.length === 0) {
|
|
|
124
124
|
|
|
125
125
|
- `templates.md` — the `api.templates.*` reference (wire shapes, intents)
|
|
126
126
|
- `interoperability_contracts.md` — how a template becomes a live row mapping
|
|
127
|
-
- `_setup/
|
|
128
|
-
- `integration-tests/tests/
|
|
127
|
+
- `_setup/subscription.md` — the bootstrap this walk starts from
|
|
128
|
+
- `integration-tests/tests/subscription/system-templates.test.ts` — the
|
|
129
129
|
green test these calls are lifted from
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Triage inbound AR prospects into priority bands via an LLM agent and route each to a tailored SMS
|
|
3
|
-
summary: End-to-end agent-driven workflow over the
|
|
4
|
-
industry:
|
|
3
|
+
summary: End-to-end agent-driven workflow over the subscription customer dataset — a chat-completion LLM agent classifies each customer into a priority band (high/medium/low) by account type, the workflow's decision interpolates the agent's band, three SMS actions (one per band) fan out, and the run is verified row-by-row so every Workflow Execution Log carries exactly one matched action and two skipped.
|
|
4
|
+
industry: subscription
|
|
5
5
|
slug: triage-prospects-by-priority
|
|
6
6
|
vitest_source:
|
|
7
|
-
- integration-tests/tests/
|
|
8
|
-
- integration-tests/tests/
|
|
9
|
-
- integration-tests/tests/
|
|
10
|
-
- integration-tests/tests/
|
|
11
|
-
- integration-tests/tests/
|
|
12
|
-
- integration-tests/tests/
|
|
13
|
-
- integration-tests/tests/
|
|
7
|
+
- integration-tests/tests/subscription/agent-lead-triage.test.ts
|
|
8
|
+
- integration-tests/tests/subscription/interoperability-contracts.test.ts
|
|
9
|
+
- integration-tests/tests/subscription/run-dac-single.test.ts
|
|
10
|
+
- integration-tests/tests/subscription/create-dac.test.ts
|
|
11
|
+
- integration-tests/tests/subscription/tools.test.ts
|
|
12
|
+
- integration-tests/tests/subscription/data-sources.test.ts
|
|
13
|
+
- integration-tests/tests/subscription/bootstrap.test.ts
|
|
14
14
|
status: green
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -40,8 +40,8 @@ row-by-row — every Workflow Execution Log carries exactly one matched action
|
|
|
40
40
|
and two `:skipped`.
|
|
41
41
|
|
|
42
42
|
The scenario is anchored to
|
|
43
|
-
`platform/integration-tests/tests/
|
|
44
|
-
The setup file `_setup/
|
|
43
|
+
`platform/integration-tests/tests/subscription/agent-lead-triage.test.ts`.
|
|
44
|
+
The setup file `_setup/subscription.md` already provisioned the tenant +
|
|
45
45
|
datalake + tenant-scoped client; this cookbook starts from there.
|
|
46
46
|
|
|
47
47
|
# Composition
|
|
@@ -230,17 +230,17 @@ which §008's context-mapping feeds the agent.
|
|
|
230
230
|
const { readFileSync } = await import('node:fs')
|
|
231
231
|
const { join } = await import('node:path')
|
|
232
232
|
const customerTemplate = readFileSync(
|
|
233
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
233
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_customer.liquid'),
|
|
234
234
|
'utf8',
|
|
235
235
|
)
|
|
236
236
|
const mdmTemplate = readFileSync(
|
|
237
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
237
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_mdm.liquid'),
|
|
238
238
|
'utf8',
|
|
239
239
|
)
|
|
240
240
|
|
|
241
241
|
const contractResp = await api.interoperabilityContracts.create(tenantSlug, datalakeSlug, {
|
|
242
242
|
name: `Cookbook Stripe Customer Contract ${runSuffix}`,
|
|
243
|
-
description: 'Stripe customers →
|
|
243
|
+
description: 'Stripe customers → Subscription Customer (custom Liquid + MDM input).',
|
|
244
244
|
resource_type: 'customer',
|
|
245
245
|
template_config: { type: 'custom', body: customerTemplate },
|
|
246
246
|
mdm_input_config: { type: 'custom', body: mdmTemplate },
|
|
@@ -499,7 +499,7 @@ for (const wel of ourWels) {
|
|
|
499
499
|
# Rollback
|
|
500
500
|
|
|
501
501
|
The cookbook doctest harness does not currently tear down created resources. The
|
|
502
|
-
`_setup/
|
|
502
|
+
`_setup/subscription.md` setup file's runSuffix-scoped names keep each run
|
|
503
503
|
isolated; the seeded local DB is cheap to reset (`mix ecto.reset` on the platform
|
|
504
504
|
repo).
|
|
505
505
|
|
|
@@ -521,7 +521,7 @@ After this cookbook runs green:
|
|
|
521
521
|
|
|
522
522
|
# See also
|
|
523
523
|
|
|
524
|
-
- `_setup/
|
|
524
|
+
- `_setup/subscription.md` — the inlined bootstrap this cookbook starts from
|
|
525
525
|
- `dunning-sms-for-delinquent.md` — the static-decision AR counterpart (same
|
|
526
526
|
customer chain, one fixed action, no agent)
|
|
527
527
|
- `score-leads-with-llm-categorization.md` — the foundation analogue (leads into
|
|
@@ -529,5 +529,5 @@ After this cookbook runs green:
|
|
|
529
529
|
- `ai-agent-invoke.md` — the capability doc for the agent + tool surface this uses
|
|
530
530
|
- `.agent/workflows.md` — agent-driven workflow primitive; `workflow_ai_agents`,
|
|
531
531
|
`context_mapping_config`, agent-output decision interpolation
|
|
532
|
-
- `integration-tests/tests/
|
|
532
|
+
- `integration-tests/tests/subscription/agent-lead-triage.test.ts` — the
|
|
533
533
|
anchor green test these snippets are lifted from
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Send a welcome SMS to newly contracted customers with a billing-portal link
|
|
3
3
|
summary: End-to-end standard workflow — provision a Welcome SMS workflow over the AR customer dataset, ingest two Stripe customer rows (one with a phone on file, one without) through a customer interop contract, run the workflow so the phone filter routes each row, read the rendered SMS back from the message dataset, and close the connected-app reply loop. No agent, no LLM.
|
|
4
|
-
industry:
|
|
4
|
+
industry: subscription
|
|
5
5
|
slug: welcome-sms-for-customers
|
|
6
6
|
vitest_source:
|
|
7
|
-
- integration-tests/tests/
|
|
8
|
-
- integration-tests/tests/
|
|
9
|
-
- integration-tests/tests/
|
|
10
|
-
- integration-tests/tests/
|
|
11
|
-
- integration-tests/tests/
|
|
12
|
-
- integration-tests/tests/
|
|
13
|
-
- integration-tests/tests/
|
|
7
|
+
- integration-tests/tests/subscription/standard-workflow.test.ts
|
|
8
|
+
- integration-tests/tests/subscription/interoperability-contracts.test.ts
|
|
9
|
+
- integration-tests/tests/subscription/run-dac-single.test.ts
|
|
10
|
+
- integration-tests/tests/subscription/create-dac.test.ts
|
|
11
|
+
- integration-tests/tests/subscription/tools.test.ts
|
|
12
|
+
- integration-tests/tests/subscription/data-sources.test.ts
|
|
13
|
+
- integration-tests/tests/subscription/bootstrap.test.ts
|
|
14
14
|
status: green
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -42,10 +42,10 @@ message dataset, and finally resolves the connected-app deep-link
|
|
|
42
42
|
the SMS carries — closing the SMS → reply loop.
|
|
43
43
|
|
|
44
44
|
The scenario is anchored to
|
|
45
|
-
`platform/integration-tests/tests/
|
|
45
|
+
`platform/integration-tests/tests/subscription/standard-workflow.test.ts`
|
|
46
46
|
— a green end-to-end test (§1–§8) that exercises this exact shape.
|
|
47
47
|
This cookbook is a prose re-presentation of what that test walks.
|
|
48
|
-
The setup file `_setup/
|
|
48
|
+
The setup file `_setup/subscription.md` already provisioned
|
|
49
49
|
the tenant, datalake, and industry-admin client; this cookbook
|
|
50
50
|
starts from there.
|
|
51
51
|
|
|
@@ -61,7 +61,7 @@ starts from there.
|
|
|
61
61
|
| Stripe Customer interop contract | build |
|
|
62
62
|
| Manual-upload DAC | build |
|
|
63
63
|
|
|
64
|
-
The setup file `_setup/
|
|
64
|
+
The setup file `_setup/subscription.md` already
|
|
65
65
|
provisioned the tenant + datalake + tenant-scoped client; this
|
|
66
66
|
cookbook starts from there.
|
|
67
67
|
|
|
@@ -261,17 +261,17 @@ customer or an existing one.
|
|
|
261
261
|
const { readFileSync } = await import('node:fs')
|
|
262
262
|
const { join } = await import('node:path')
|
|
263
263
|
const customerTemplate = readFileSync(
|
|
264
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
264
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_customer.liquid'),
|
|
265
265
|
'utf8',
|
|
266
266
|
)
|
|
267
267
|
const mdmTemplate = readFileSync(
|
|
268
|
-
join(process.env.COOKBOOK_FIXTURES_DIR!, '
|
|
268
|
+
join(process.env.COOKBOOK_FIXTURES_DIR!, 'subscription/_customers_subscription_mdm.liquid'),
|
|
269
269
|
'utf8',
|
|
270
270
|
)
|
|
271
271
|
|
|
272
272
|
const contractResp = await api.interoperabilityContracts.create(tenantSlug, datalakeSlug, {
|
|
273
273
|
name: `Cookbook Stripe Customer Contract ${runSuffix}`,
|
|
274
|
-
description: 'Stripe customers →
|
|
274
|
+
description: 'Stripe customers → Subscription Customer (custom Liquid + MDM input).',
|
|
275
275
|
resource_type: 'customer',
|
|
276
276
|
template_config: { type: 'custom', body: customerTemplate },
|
|
277
277
|
mdm_input_config: { type: 'custom', body: mdmTemplate },
|
|
@@ -549,7 +549,7 @@ if (!tracked.message?.opened_at || !tracked.message?.form_submitted_at) {
|
|
|
549
549
|
# Rollback
|
|
550
550
|
|
|
551
551
|
The cookbook doctest harness does not currently tear down created
|
|
552
|
-
resources. The `_setup/
|
|
552
|
+
resources. The `_setup/subscription.md` setup file's
|
|
553
553
|
runSuffix-scoped tenant / datalake / user names mean each run is
|
|
554
554
|
naturally isolated; the seeded local DB is cheap to reset
|
|
555
555
|
(`mix ecto.reset` on the platform repo).
|
|
@@ -558,8 +558,8 @@ naturally isolated; the seeded local DB is cheap to reset
|
|
|
558
558
|
|
|
559
559
|
After this cookbook's thirteen steps run green:
|
|
560
560
|
|
|
561
|
-
- An
|
|
562
|
-
|
|
561
|
+
- An subscription tenant exists with an
|
|
562
|
+
subscription-domain datalake
|
|
563
563
|
- An SMS tool, a Welcome billing-portal connected app, and a
|
|
564
564
|
Welcome SMS standard workflow (status `live`, `customer`
|
|
565
565
|
dataset) are registered
|
|
@@ -583,7 +583,7 @@ end-to-end, not merely provisioned.
|
|
|
583
583
|
|
|
584
584
|
# See also
|
|
585
585
|
|
|
586
|
-
- `_setup/
|
|
586
|
+
- `_setup/subscription.md` — the inlined bootstrap that
|
|
587
587
|
provisions the tenant + datalake this cookbook starts from
|
|
588
588
|
- `dunning-sms-for-delinquent.md` — the sibling AR cookbook; same
|
|
589
589
|
customer-dataset shape, a stricter phone + tax-id filter
|
|
@@ -597,11 +597,11 @@ end-to-end, not merely provisioned.
|
|
|
597
597
|
interop contract → DAC ingestion chain
|
|
598
598
|
- `.agent/workflows.md` — standard workflow primitive (filter +
|
|
599
599
|
decision + actions), `context_datasets`, `workflows.run`
|
|
600
|
-
- `.agent/cookbook/_fixtures/
|
|
600
|
+
- `.agent/cookbook/_fixtures/subscription/` — the vendored
|
|
601
601
|
Stripe customer / MDM Liquid templates §006 loads
|
|
602
|
-
- `integration-tests/tests/
|
|
602
|
+
- `integration-tests/tests/subscription/standard-workflow.test.ts` —
|
|
603
603
|
the anchor green test (§1–§8) these snippets are lifted from
|
|
604
|
-
- `integration-tests/tests/
|
|
604
|
+
- `integration-tests/tests/subscription/interoperability-contracts.test.ts`,
|
|
605
605
|
`run-dac-single.test.ts`, `create-dac.test.ts`, `tools.test.ts`,
|
|
606
606
|
`data-sources.test.ts` — the per-resource create + ingest
|
|
607
607
|
snippets §004–§009 are lifted from
|