Setup Data Workflow - Developer Guide¶
Complete guide for creating and configuring service plans, bundles, and dependencies through GraphQL.
Overview¶
This guide shows you how to set up the complete data infrastructure for the ABS Platform using GraphQL mutations. This is typically done during initial system setup or when creating new service offerings.
Phase 1: Core Dependencies¶
1.1 Agent Config (Basic Plan)¶
Create the agent configuration that defines service behavior.
⚠️ CRITICAL - Agent Version and Reference:
The version and serviceAgent fields must reference actual agents that exist in the ABS Platform:
- version - Must match the agent implementation version:
- ✅ Correct:
"2.0.0"(if bss-agent-v2.ts version 2.0.0 exists) - ❌ Wrong:
"3.0.0"(if agent version doesn't exist) -
❌ Wrong:
"latest"(use explicit version numbers) -
serviceAgent - Must reference an actual agent file:
- ✅ Correct:
"bss-agent-v2.ts"(if this agent exists in src/agents/) - ❌ Wrong:
"bss-agent-v3.ts"(if agent doesn't exist) - ❌ Wrong:
"custom-agent.ts"(if not implemented)
Why? The platform loads and executes the specified agent. Using incorrect references will cause: - Service plan creation failures - Runtime errors during workflow execution - Agent method call failures
Available Agents: Check your codebase (src/agents/) for available agents before creating configurations.
GraphQL Mutation:
mutation CreateBSSAgentConfigV2 {
createAgentConfig(input: {
agentConfigId: "bss-agent-config-v2-003"
name: "Battery Swap Service Agent Configuration v2"
version: "2.0.0"
description: "Agent configuration for Battery Swap Service with delegation pattern v2"
serviceAgent: "bss-agent-v2.ts"
createdBy: "system"
}) {
_id
agentConfigId
name
version
serviceAgent
}
}
Expected Response:
{
"data": {
"createAgentConfig": {
"_id": "507f1f77bcf86cd799439011",
"agentConfigId": "bss-agent-config-v2-003",
"name": "Battery Swap Service Agent Configuration v2",
"version": "2.0.0",
"serviceAgent": "bss-agent-v2.ts"
}
}
}
1.2 Contract Terms (Basic Plan)¶
Define the legal and financial terms for the service.
GraphQL Mutation:
mutation CreateKenyaPremiumTerms {
createCommonTerms(input: {
termsId: "terms-kenya-premium"
serviceName: "Kenya BSS Premium Terms"
serviceDescription: "Premium contract terms for Kenya battery swap services with enhanced features"
serviceDurationDays: 30
billingCycle: "MONTHLY"
billingCurrency: "KES"
monthlyFee: 0.0
depositAmount: 15000.0
monthlyQuota: -1.0
cancellationNoticeDays: 14
earlyTerminationFee: 0.0
refundPolicy: "FULL_REFUND"
liabilityLimit: 100000.0
insuranceRequired: true
damageDeposit: 8000.0
governingLaw: "Laws of Kenya"
disputeResolution: "COURT"
createdBy: "system"
}) {
_id
termsId
serviceName
depositAmount
liabilityLimit
}
}
Expected Response:
{
"data": {
"createCommonTerms": {
"_id": "507f1f77bcf86cd799439012",
"termsId": "terms-kenya-premium",
"serviceName": "Kenya BSS Premium Terms",
"depositAmount": 15000.0,
"liabilityLimit": 100000.0
}
}
}
1.3 FSMs (Reuse existing)¶
Note: Use existing FSMs from setup guide. No mutations needed:
- fsm-bss-service-cycle-a - Service lifecycle state machine
- fsm-bss-payment-cycle-a - Payment lifecycle state machine
Phase 2: Service Infrastructure¶
⚠️ CRITICAL - Service ID Naming Conventions:
When creating services, you must follow these naming patterns for the system to correctly identify and route services:
- Swap Station Services - MUST include
swap-stationin theserviceId: - ✅ Correct:
svc-swap-station-network-kenya-a - ❌ Wrong:
svc-station-network-kenya-a -
❌ Wrong:
svc-swap-network-kenya-a -
Battery Fleet Services - MUST include
battery-fleetin theserviceId: - ✅ Correct:
svc-battery-fleet-kenya-premium-a - ❌ Wrong:
svc-battery-kenya-premium-a - ❌ Wrong:
svc-fleet-kenya-premium-a
Why? The platform uses these keywords to identify service types and apply correct business logic for allocation, tracking, and billing.
2.1 Create Swap Network Service¶
Define the swap station network access service.
GraphQL Mutation:
mutation CreateSwapNetworkService {
createService(input: {
serviceId: "svc-swap-station-network-kenya-a"
name: "Kenya Swap Network Access"
description: "Access to Kenya national battery swap station network"
assetType: "FLEET"
assetReference: "68e3bbe86709bc6528de883f"
usageMetric: "ACCESS"
usageUnit: "station-access"
usageUnitPrice: 0.0
accessControl: "{\"access_type\": \"network\", \"network_id\": \"kenya-swap-network\", \"access_hours\": \"24/7\", \"coverage_area\": \"Kenya\"}"
}) {
_id
serviceId
name
assetType
}
}
Expected Response:
{
"data": {
"createService": {
"_id": "507f1f77bcf86cd799439013",
"serviceId": "svc-swap-station-network-kenya-a",
"name": "Kenya Swap Network Access",
"assetType": "FLEET"
}
}
}
2.2 Create Premium Battery Fleet Service¶
Define the premium battery fleet access service.
GraphQL Mutation:
mutation CreatePremiumBatteryFleetService {
createService(input: {
serviceId: "svc-battery-fleet-kenya-premium-a"
name: "Kenya Premium Battery Fleet"
description: "Access to Kenya premium battery fleet inventory"
assetType: "FLEET"
assetReference: "8e36a376709bc6528de8735"
usageMetric: "COUNT"
usageUnit: "battery-swap"
usageUnitPrice: 0.0
accessControl: "{\"battery_types\": [\"72V-45Ah-premium\", \"60V-30Ah-premium\", \"84V-60Ah-premium\"], \"quality_tier\": \"premium\", \"allocation_priority\": \"high\"}"
}) {
_id
serviceId
name
assetType
usageUnitPrice
}
}
Expected Response:
{
"data": {
"createService": {
"_id": "507f1f77bcf86cd799439014",
"serviceId": "svc-battery-fleet-kenya-premium-a",
"name": "Kenya Premium Battery Fleet",
"assetType": "FLEET",
"usageUnitPrice": 0.0
}
}
}
2.3 Create Service Bundle¶
Bundle multiple services together into a package.
GraphQL Mutation:
mutation CreateSwapFreedomBundle {
createServiceBundle(input: {
bundleId: "bundle-swap-freedom-a"
name: "Swap Freedom Package"
description: "Premium unlimited swap package with network and premium battery fleet access"
version: "1.0.0"
status: "ACTIVE"
serviceIds: ["svc-swap-station-network-kenya-b", "svc-battery-fleet-kenya-premium-a"]
createdBy: "bss_admin"
}) {
_id
bundleId
name
services {
_id
serviceId
name
assetType
usageUnitPrice
}
}
}
Expected Response:
{
"data": {
"createServiceBundle": {
"_id": "507f1f77bcf86cd799439015",
"bundleId": "bundle-swap-freedom-a",
"name": "Swap Freedom Package",
"services": [
{
"_id": "507f1f77bcf86cd799439013",
"serviceId": "svc-swap-station-network-kenya-b",
"name": "Kenya Swap Network Access",
"assetType": "FLEET",
"usageUnitPrice": 0.0
},
{
"_id": "507f1f77bcf86cd799439014",
"serviceId": "svc-battery-fleet-kenya-premium-a",
"name": "Kenya Premium Battery Fleet",
"assetType": "FLEET",
"usageUnitPrice": 0.0
}
]
}
}
}
Phase 3: Template & Plan¶
3.1 Create Service Plan Template¶
Define the template that will be used to create service plans.
GraphQL Mutation:
mutation CreateWeeklyFreedomTemplate {
createServicePlanTemplate(input: {
templateId: "bss-template-weekly-freedom-nairobi-v3"
name: "Nairobi Weekly Freedom BSS Template v3"
description: "ServicePlanTemplate for Nairobi weekly freedom battery swap service using BSS Agent v3"
version: "2.0.0"
status: "ACTIVE"
countryCode: "KE"
legalJurisdiction: "Nairobi County, Kenya"
billingCurrency: "KES"
contractTermsId: "terms-kenya-premium"
serviceBundleId: "bundle-swap-freedom-a"
serviceCycleFsmId: "fsm-bss-service-cycle-newest-a"
paymentCycleFsmId: "fsm-bss-payment-cycle-newest-a"
agentConfigId: "bss-agent-config-v2-002"
serviceConfigurations: [
{
serviceId: "svc-battery-fleet-kenya-premium-a"
initialQuota: 100000000.0
maxQuota: 100000000.0
rateLimitPerDay: 100000000.0
autoRenewal: true
overageAllowed: false
overageRate: null
}
{
serviceId: "svc-swap-network-kenya-a"
initialQuota: 100000000.0
maxQuota: 100000000.0
rateLimitPerDay: 100000000.0
autoRenewal: true
overageAllowed: false
overageRate: null
}
]
createdBy: "bss_admin"
}) {
_id
templateId
name
version
status
countryCode
legalJurisdiction
billingCurrency
contractTermsId
serviceBundleId
serviceConfigurations {
serviceId
initialQuota
maxQuota
rateLimitPerDay
autoRenewal
overageAllowed
}
agentConfig {
_id
agentConfigId
name
version
serviceAgent
}
}
}
Expected Response:
{
"data": {
"createServicePlanTemplate": {
"_id": "507f1f77bcf86cd799439016",
"templateId": "bss-template-weekly-freedom-nairobi-v3",
"name": "Nairobi Weekly Freedom BSS Template v3",
"version": "2.0.0",
"status": "ACTIVE",
"countryCode": "KE",
"legalJurisdiction": "Nairobi County, Kenya",
"billingCurrency": "KES",
"contractTermsId": "terms-kenya-premium",
"serviceBundleId": "bundle-swap-freedom-a",
"serviceConfigurations": [
{
"serviceId": "svc-battery-fleet-kenya-premium-a",
"initialQuota": 100000000.0,
"maxQuota": 100000000.0,
"rateLimitPerDay": 100000000.0,
"autoRenewal": true,
"overageAllowed": false
},
{
"serviceId": "svc-swap-network-kenya-a",
"initialQuota": 100000000.0,
"maxQuota": 100000000.0,
"rateLimitPerDay": 100000000.0,
"autoRenewal": true,
"overageAllowed": false
}
],
"agentConfig": {
"_id": "507f1f77bcf86cd799439011",
"agentConfigId": "bss-agent-config-v2-002",
"name": "Battery Swap Service Agent Configuration v2",
"version": "2.0.0",
"serviceAgent": "bss-agent-v2.ts"
}
}
}
}
3.2 Query Single Template (Optional)¶
Retrieve a specific template by ID.
GraphQL Query:
query GetTemplate($templateId: String!) {
servicePlanTemplate(templateId: $templateId) {
_id
templateId
name
version
status
serviceConfigurations {
serviceId
initialQuota
maxQuota
}
}
}
Variables:
{
"templateId": "bss-template-weekly-freedom-nairobi-v3"
}
3.3 Create Service Plan¶
Create an active service plan for a customer based on the template.
GraphQL Mutation:
mutation CreateWeeklyFreedomServicePlan {
createServicePlan(input: {
servicePlanId: "bss-plan-weekly-freedom-nairobi-v2-plan4"
customerId: "customer-002"
templateId: "bss-template-weekly-freedom-nairobi-v3"
templateVersion: "2.0.0"
currency: "KES"
}) {
_id
servicePlanId
customerId
templateId
templateVersion
currency
serviceState
paymentState
serviceAccountId
paymentAccountId
serviceStates {
serviceId
currentAsset
quota
used
}
planState {
status
lastBilledAt
nextBillAt
}
agentState
createdAt
updatedAt
}
}
Expected Response:
{
"data": {
"createServicePlan": {
"_id": "507f1f77bcf86cd799439017",
"servicePlanId": "bss-plan-weekly-freedom-nairobi-v2-plan4",
"customerId": "customer-002",
"templateId": "bss-template-weekly-freedom-nairobi-v3",
"templateVersion": "2.0.0",
"currency": "KES",
"serviceState": "INITIAL",
"paymentState": "INITIAL",
"serviceAccountId": "SA_1234567890_abc123",
"paymentAccountId": "PA_1234567890_def456",
"serviceStates": [],
"planState": {
"status": "DRAFT",
"lastBilledAt": null,
"nextBillAt": null
},
"agentState": {},
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-01-15T08:00:00Z"
}
}
}
Complete Setup Flow¶
Step-by-Step Execution Order¶
- Phase 1 - Dependencies (Run once per configuration)
- Create Agent Config
- Create Contract Terms
-
Verify FSMs exist
-
Phase 2 - Services (Run once per service offering)
- Create Swap Network Service
- Create Battery Fleet Service
-
Create Service Bundle
-
Phase 3 - Template & Plans (Template once, Plans per customer)
- Create Service Plan Template
- Create Service Plan (repeat for each customer)
Common Queries¶
Query All Templates¶
GraphQL Query:
query GetAllTemplates {
servicePlanTemplates {
_id
templateId
name
version
status
}
}
Query Service Plan by ID¶
GraphQL Query:
query GetServicePlan($servicePlanId: String!) {
servicePlan(servicePlanId: $servicePlanId) {
_id
servicePlanId
customerId
templateId
serviceState
paymentState
serviceStates {
serviceId
quota
used
currentAsset
}
}
}
Variables:
{
"servicePlanId": "bss-plan-weekly-freedom-nairobi-v2-plan4"
}
Query Service Bundle¶
GraphQL Query:
query GetServiceBundle($bundleId: String!) {
serviceBundle(bundleId: $bundleId) {
_id
bundleId
name
services {
serviceId
name
assetType
usageUnitPrice
}
}
}
Variables:
{
"bundleId": "bundle-swap-freedom-a"
}
GraphQL Endpoint Configuration¶
Using GraphQL Playground¶
Endpoint:
http://localhost:4000/graphql
Headers:
{
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
Using cURL¶
Example:
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{"query": "mutation { createAgentConfig(input: {...}) { _id } }"}'
Common Errors¶
| Error | Cause | Solution |
|---|---|---|
Duplicate key error |
ID already exists | Use unique IDs or query existing records |
Reference not found |
Dependent record missing | Create dependencies first (Phase 1 & 2 before 3) |
Validation error |
Invalid field value | Check field types and constraints |
Unauthorized |
Missing/invalid token | Verify API token in headers |
Service not routing correctly |
Missing keyword in serviceId | Ensure swap-station or battery-fleet is in serviceId |
Asset allocation fails |
Wrong service type identifier | Verify serviceId follows naming conventions (see Best Practices) |
Agent not found |
Invalid serviceAgent reference | Check src/agents/ for available agents, use correct filename |
Agent version mismatch |
Wrong version number | Verify agent implementation version matches config version |
Service plan fails to execute |
Agent config points to missing agent | Ensure agent exists before creating service plans |
Best Practices¶
ID Conventions¶
- Agent Config:
bss-agent-config-v2-XXX - ⚠️ version must match actual agent implementation version
- ⚠️ serviceAgent must reference existing agent file (e.g., bss-agent-v2.ts)
- Terms:
terms-{country}-{tier} - Service:
- Swap Station:
svc-swap-station-{network/type}-{location}-{version}⚠️ MUST include "swap-station" - Battery Fleet:
svc-battery-fleet-{location}-{tier}-{version}⚠️ MUST include "battery-fleet" - Bundle:
bundle-{name}-{version} - Template:
bss-template-{name}-{location}-{version} - Plan:
bss-plan-{name}-{location}-{version}-planN
Versioning¶
- Use semantic versioning for templates and configs
- Increment version on breaking changes
- Keep old versions for backward compatibility
- Agent versions MUST match implementation: Before creating AgentConfig with version
2.0.0, verify that version exists in the agent code
Agent Configuration¶
- Always verify agent exists: Check
src/agents/directory before referencing inserviceAgentfield - Use explicit versions: Never use
"latest"or dynamic version strings - Test agent compatibility: Ensure agent version supports the service plan template features
- Document agent dependencies: Note which templates require which agent versions
Testing¶
- Create test records with
test-prefix - Verify queries return expected data
- Test service plan creation with test template
- Clean up test data after validation
Next Steps¶
- Attendant Workflow Guide - Staff-operated swaps
- Rider Workflow Guide - Mobile app-driven swaps
- Odoo Sync Workflow - Payment integration
- Service State Management - Quota tracking