Example 05

Telecom billing disputes

Dispute handling depends on usage records, bills and adjustments that agree with each other.

Status
illustrative
Industry
Telecom
Language
Go
Framework
go test
CI
any
Fulfilment
BUILD_DATASET
Profile
telecom-billing

About this example

All data is synthetic. DataNivra provisions approved test data into a customer-controlled target; it does not run these tests. Credentials for the target are never returned by DataNivra — your runner holds its own.

Why test data matters

Dispute handling depends on usage records, bills and adjustments that agree with each other.

What is requested

telecom-billing@1 with TEL_EVERYDAY_USAGE × 300, TEL_DISPUTED_BILLS × 100.

Policy gates

Within the profile maximums; synthetic-only.

What is provisioned

A certified synthetic dataset in the profile's approved target.

Expected output

AUTO_APPROVED for a developer; the test polls until READY.

Cleanup

The finally/teardown block calls POST /v1/test-data/requests/{id}/release.

Files

  • request.yaml
  • billing_test.go

Run

  1. A tenant administrator defines and a second person approves the profile (datanivra test-data define ../../profiles/telecom-billing.yaml --submit, then datanivra policies approve).
  2. datanivra test-data validate request.yaml && datanivra test-data plan request.yaml
  3. Run the example with DATANIVRA_BASE_URL and a session or workload token.

Files

Exactly as they are in the examples repository. Every value is a synthetic placeholder; nothing here is a credential.

request.yaml

# yaml-language-server: $schema=../../../../packages/contracts/schemas/v1/manifests/test-data-request.schema.json
# DataNivra test-data-request manifest (apiVersion datanivra.io/v1alpha1). Validate: datanivra test-data validate <file>
apiVersion: datanivra.io/v1alpha1
kind: TestDataRequest
metadata:
  name: telecom-billing-disputes
spec:
  profile: { name: telecom-billing, version: 1 }
  scenarios:
    - { scenario_code: TEL_EVERYDAY_USAGE, count: 300 }
    - { scenario_code: TEL_DISPUTED_BILLS, count: 100 }

examples/test-data-api/scenarios/05-telecom-billing-disputes/request.yaml

billing_test.go

// Telecom billing disputes — Go testing with the REST API (no Go SDK exists).
// DataNivra provisions approved data; your tests use the approved target with their own credentials.
package billing

import (
	"bytes"
	"encoding/json"
	"net/http"
	"os"
	"testing"
	"time"
)

type testDataRequest struct {
	ID    string `json:"id"`
	State string `json:"state"`
}

func call(method, url string, body []byte) (*http.Response, error) {
	req, err := http.NewRequest(method, url, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("DATANIVRA_TOKEN"))
	req.Header.Set("Content-Type", "application/json")
	return http.DefaultClient.Do(req)
}

func TestDisputedBillsAreAdjusted(t *testing.T) {
	api := os.Getenv("DATANIVRA_BASE_URL") + "/v1/test-data/requests"
	body := []byte(`{"profile":{"name":"telecom-billing","version":1},` +
		`"scenarios":[{"scenario_code":"TEL_EVERYDAY_USAGE","count":300},{"scenario_code":"TEL_DISPUTED_BILLS","count":100}]}`)
	resp, err := call(http.MethodPost, api, body)
	if err != nil || resp.StatusCode != http.StatusCreated {
		t.Fatalf("request failed: %v", err)
	}
	var created testDataRequest
	_ = json.NewDecoder(resp.Body).Decode(&created)
	defer call(http.MethodPost, api+"/"+created.ID+"/release", []byte(`{"reason_code":"TEST_RUN_FINISHED"}`))
	for i := 0; i < 120 && created.State != "READY"; i++ {
		time.Sleep(5 * time.Second)
		r, _ := call(http.MethodGet, api+"/"+created.ID, nil)
		_ = json.NewDecoder(r.Body).Decode(&created)
	}
	if created.State != "READY" {
		t.Fatalf("test data not ready: %s", created.State)
	}
	// Exercise your billing service against the approved target here.
}

examples/test-data-api/scenarios/05-telecom-billing-disputes/billing_test.go

The profile it uses: telecom-billing

A tenant administrator defines this profile and a second person approves it; requests can only ask for what it allows. All profiles

telecom-billing.yaml

# yaml-language-server: $schema=../../../packages/contracts/schemas/v1/manifests/test-data-profile.schema.json
# DataNivra test-data-profile manifest (apiVersion datanivra.io/v1alpha1). Validate: datanivra test-data validate <file>
# Placeholder ids (00000000-0000-4000-8000-0000000000NN): replace with your ids.
# 01 = approved target environment, 11 = certified dataset, 21 = customer agent,
# 99 = workload identity trust (datanivra workload-identities list).
apiVersion: datanivra.io/v1alpha1
kind: TestDataProfile
metadata:
  name: telecom-billing
  description: Synthetic subscribers, usage records and bills
spec:
  fulfilment: BUILD_DATASET
  build:
    business_domain: subscribers and billing
    pack_id: telecom
    dataset_kind: SYNTHETIC_ONLY
    target_environment_id: 00000000-0000-4000-8000-000000000001
    retention_days: 1
    max_total_records: 1300
    scenarios:
      - {
          pack_id: telecom,
          scenario_code: TEL_EVERYDAY_USAGE,
          kind: NORMAL,
          default_count: 500,
          max_count: 1000,
        }
      - {
          pack_id: telecom,
          scenario_code: TEL_DISPUTED_BILLS,
          kind: RARE,
          default_count: 50,
          max_count: 200,
        }
      - {
          pack_id: telecom,
          scenario_code: TEL_DUPLICATE_CDRS,
          kind: DUPLICATE,
          default_count: 20,
          max_count: 100,
          included_by_default: false,
        }

examples/test-data-api/profiles/telecom-billing.yaml