> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sensorup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CAM Assets Subgraph Reference

> Technical reference for the su-cam-assets subgraph providing Connected Asset Management operations including asset types, properties, and hierarchy.

# CAM Assets Subgraph Reference

The `su-cam-assets` subgraph provides Connected Asset Management (CAM) capabilities for managing asset types, asset properties, and asset hierarchy in connected operations.

## Subgraph Information

* **Name**: `su-cam-assets`
* **Routing URL**: `https://mijlot8lad.execute-api.us-west-2.amazonaws.com/poc/graphql`
* **Last Updated**: 2025-11-03
* **SDL**: [View Schema](../schemas/sdl/su-cam-assets.graphql)

## Overview

CAM Assets manages the foundational structure for connected operations:

* **Asset Types**: Define schemas for different kinds of operational assets
* **Asset Properties**: Custom attributes and their data types
* **Asset Hierarchy**: Parent-child relationships between assets
* **Camera Assets**: Specialized operations for camera and detection assets
* **Batch Operations**: Large-scale asset creation and updates
* **Geospatial**: Full GeoJSON support for asset locations

## Key Concepts

### Asset Types

Asset types define the structure and schema for operational assets:

* **Properties**: Custom attributes (name, data type, required, default value)
* **Extensions**: External data source integrations
* **Status Tracking**: Configuration for asset state management
* **Hierarchy Rules**: Parent-child relationship constraints

### Assets

Assets are instances of asset types representing operational entities:

* **Sites**: Top-level geographic locations
* **Equipment**: Major operational assets
* **Components**: Sub-components within equipment
* **Wells**: Oil and gas well assets
* **Pipelines**: Pipeline infrastructure

### Asset Hierarchy

Assets can be organized in parent-child relationships:

* Multi-level organizational structures
* Inherited properties and configurations
* Hierarchical queries and filtering
* Geographic nesting (e.g., equipment within sites)

## Core Types

### CamAssets

Main entry point for querying assets:

```graphql theme={null}
type CamAssets {
  byId(id: ID!): CamAsset
  all(
    first: Int
    after: String
    filter: CamAssetFilter
    fullTextSearch: CamAssetFullTextSearch
    sortBy: CamAssetSortBy
    withExtensions: [ID]
    includeDelta: Boolean
  ): CamAssetsConnection
}
```

### CamAsset

Individual asset instance:

```graphql theme={null}
type CamAsset {
  id: ID!
  name: String!
  description: String
  assetTypeId: ID!
  active: Boolean!
  geometry: GeoJSONGeometry
  properties: JSONObject
  parent: CamAssetReference
  children: [CamAssetReference]
  status: CamAssetStatus
  extensionData: [CamAssetExtensionData]
  audit: AuditInfo
}
```

### AssetTypes

Manage asset type definitions:

```graphql theme={null}
type AssetTypes {
  byId(assetTypeId: ID!): AssetType
  all(
    first: Int
    after: String
    filter: AssetTypeFilter
    sortBy: AssetTypeSortBy
  ): AssetTypesConnection
}
```

### AssetType

Asset type definition:

```graphql theme={null}
type AssetType {
  assetTypeId: ID!
  name: String!
  description: String
  properties: [AssetTypeProperty!]
  extensions: [AssetTypeExtension!]
  parentAssetTypes: [ID!]
  childAssetTypes: [ID!]
  audit: AuditInfo
}
```

### AssetTypeProperty

Property definition within an asset type:

```graphql theme={null}
type AssetTypeProperty {
  id: ID!
  name: String!
  dataType: PropertyDataType!
  required: Boolean!
  defaultValue: String
  validation: PropertyValidation
  displayOrder: Int
}
```

## Query Operations

### camAssets

Query assets by type:

```graphql theme={null}
query GetAssetsByType($assetTypeId: ID!) {
  camAssets(assetTypeId: $assetTypeId) {
    all(first: 20) {
      edges {
        node {
          id
          name
          assetTypeId
          properties
          geometry {
            type
            coordinates
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
```

### assetTypes

Query available asset types:

```graphql theme={null}
query GetAssetTypes {
  assetTypes {
    all(first: 100) {
      edges {
        node {
          assetTypeId
          name
          description
          properties {
            id
            name
            dataType
            required
          }
        }
      }
    }
  }
}
```

### camAssetReferences

Lightweight asset references for dropdowns:

```graphql theme={null}
query GetAssetReferences {
  camAssetReferences {
    all(first: 100) {
      edges {
        node {
          id
          name
          assetTypeId
        }
      }
    }
  }
}
```

### camEngine

Query CAM engine configuration and datasets:

```graphql theme={null}
query GetCamEngine {
  camEngine {
    datasets {
      id
      name
      assetTypeId
      sourceType
      lastUpdated
    }
    configuration {
      key
      value
    }
  }
}
```

### camAssetsDatasets

Get datasets for a specific tenant:

```graphql theme={null}
query GetDatasets($group: ID!) {
  camAssetsDatasets(group: $group) {
    dataset
    displayName
    assetTypeId
    recordCount
  }
}
```

### assetConfigs

Query tenant-specific configurations:

```graphql theme={null}
query GetConfigs($group: ID!) {
  assetConfigs(group: $group) {
    all {
      id
      value
      updatedAt
    }
  }
}
```

### generateBatchUpsertUploadUrl

Generate presigned S3 URL for batch operations:

```graphql theme={null}
query GenerateUploadUrl($input: GenerateBatchUpsertUploadUrlInput!) {
  generateBatchUpsertUploadUrl(input: $input) {
    uploadUrl
    batchUpsertReference
    expiresAt
  }
}
```

### camCatalog

Query catalog configuration for a group:

```graphql theme={null}
query GetCatalog($group: ID!) {
  camCatalog(group: $group) {
    catalogId
    assetTypes {
      assetTypeId
      name
    }
  }
}
```

### assetAuditing

Access audit trail information:

```graphql theme={null}
query GetAssetAudit {
  assetAuditing {
    history(assetId: "asset-123") {
      version
      eventType
      eventTime
      updatedBy
    }
  }
}
```

## Mutation Operations

### createAsset

Create a new asset:

```graphql theme={null}
mutation CreateAsset($input: CreateAssetInput!, $correlationId: ID) {
  createAsset(input: $input, correlationId: $correlationId) {
    asset {
      id
      name
      assetTypeId
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### updateAsset

Update an existing asset:

```graphql theme={null}
mutation UpdateAsset($input: UpdateAssetInput!, $correlationId: ID) {
  updateAsset(input: $input, correlationId: $correlationId) {
    asset {
      id
      name
      properties
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### updateAssetProperty

Update specific asset properties:

```graphql theme={null}
mutation UpdateAssetProperty($input: UpdateAssetPropertyInput!, $correlationId: ID) {
  updateAssetProperty(input: $input, correlationId: $correlationId) {
    asset {
      id
      properties
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### updateAssetGeometry

Update asset geolocation:

```graphql theme={null}
mutation UpdateAssetGeometry($input: UpdateAssetGeometryInput!, $correlationId: ID) {
  updateAssetGeometry(input: $input, correlationId: $correlationId) {
    asset {
      id
      geometry {
        type
        coordinates
      }
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### createAssetStatus

Create asset status record:

```graphql theme={null}
mutation CreateAssetStatus($input: CreateAssetStatusInput!, $correlationId: ID) {
  createAssetStatus(input: $input, correlationId: $correlationId) {
    assetStatus {
      assetId
      statusId
      label
      setAt
      setBy
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### manageCamAssets

Batch operations for assets:

```graphql theme={null}
mutation ManageAssets {
  manageCamAssets(dryRun: false) {
    batchUpsert(batchUpsertReference: "ref-from-upload") {
      success
      processedCount
      errors {
        row
        message
      }
    }
  }
}
```

### setAssetConfig

Update tenant configuration:

```graphql theme={null}
mutation SetConfig($group: ID!, $id: ID!, $value: JSONObject!) {
  setAssetConfig(group: $group, id: $id, value: $value) {
    config {
      id
      value
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### reloadCamAssetsDatasets

Reload datasets from external sources:

```graphql theme={null}
mutation ReloadDatasets($group: ID!) {
  reloadCamAssetsDatasets(group: $group) {
    dataset
    displayName
    recordCount
  }
}
```

### updateAssetStatus

Update asset status:

```graphql theme={null}
mutation UpdateAssetStatus($input: UpdateAssetStatusInput!, $correlationId: ID) {
  updateAssetStatus(input: $input, correlationId: $correlationId) {
    asset {
      id
      status {
        statusId
        label
      }
    }
  }
}
```

### deleteAssetStatus

Delete asset status record:

```graphql theme={null}
mutation DeleteAssetStatus($input: DeleteAssetStatusInput!, $correlationId: ID) {
  deleteAssetStatus(input: $input, correlationId: $correlationId) {
    asset {
      id
    }
  }
}
```

### deleteAsset

Delete an asset:

```graphql theme={null}
mutation DeleteAsset($input: DeleteAssetInput!, $correlationId: ID) {
  deleteAsset(input: $input, correlationId: $correlationId) {
    correlationId
  }
}
```

### createAssetType

Create a new asset type:

```graphql theme={null}
mutation CreateAssetType($input: CreateAssetTypeInput!) {
  createAssetType(input: $input) {
    assetType {
      assetTypeId
      name
    }
  }
}
```

### updateAssetType

Update an asset type:

```graphql theme={null}
mutation UpdateAssetType($input: UpdateAssetTypeInput!) {
  updateAssetType(input: $input) {
    assetType {
      assetTypeId
      name
    }
  }
}
```

### activateAssetType

Activate an asset type:

```graphql theme={null}
mutation ActivateAssetType($input: ActivateAssetTypeInput!) {
  activateAssetType(input: $input) {
    assetType {
      assetTypeId
      active
    }
  }
}
```

### deleteAssetType

Delete an asset type:

```graphql theme={null}
mutation DeleteAssetType($input: DeleteAssetTypeInput!) {
  deleteAssetType(input: $input) {
    correlationId
  }
}
```

### flushCamStreamDatasetDelta

Flush streaming dataset delta:

```graphql theme={null}
mutation FlushDatasetDelta($streamDatasetId: ID!) {
  flushCamStreamDatasetDelta(streamDatasetId: $streamDatasetId)
}
```

### deleteAssetConfig

Delete asset configuration:

```graphql theme={null}
mutation DeleteAssetConfig($group: ID!, $id: ID!) {
  deleteAssetConfig(group: $group, id: $id) {
    correlationId
  }
}
```

## Deprecated Operations

The following legacy operations are deprecated in favor of the unified `camAssets` query:

* `assetSites` → Use `camAssets(assetTypeId: "site")`
* `assetEquipments` → Use `camAssets(assetTypeId: "equipment")`
* `assetComponents` → Use `camAssets(assetTypeId: "component")`
* `assetWells` → Use `camAssets(assetTypeId: "well")`
* `assetPipelines` → Use `camAssets(assetTypeId: "pipeline")`
* `assetUnattributeds` → Use `camAssets` without assetTypeId filter

## Filtering and Sorting

### CamAssetFilter

Filter assets by various criteria:

```graphql theme={null}
input CamAssetFilter {
  active: Boolean
  assetTypeIds: [ID!]
  parentId: ID
  geometry: GeoJSONGeometryFilter
  properties: JSONObject
  extensionIds: [ID!]
}
```

### CamAssetFullTextSearch

Search assets by text:

```graphql theme={null}
input CamAssetFullTextSearch {
  text: String!
  fields: [String!]  # Search specific fields
}
```

### CamAssetSortBy

Sort asset results:

```graphql theme={null}
input CamAssetSortBy {
  field: CamAssetSortField!
  direction: SortDirection!
}

enum CamAssetSortField {
  NAME
  CREATED_AT
  UPDATED_AT
  ASSET_TYPE_ID
}
```

## GeoJSON Support

Full GeoJSON geometry types supported:

```graphql theme={null}
union GeoJSONGeometry =
  | GeoJSONPoint
  | GeoJSONLineString
  | GeoJSONPolygon
  | GeoJSONMultiPoint
  | GeoJSONMultiLineString
  | GeoJSONMultiPolygon
  | GeoJSONGeometryCollection
```

### Example Geometries

**Point:**

```json theme={null}
{
  "type": "Point",
  "coordinates": [-114.0719, 51.0447]
}
```

**Polygon:**

```json theme={null}
{
  "type": "Polygon",
  "coordinates": [[
    [-114.073, 51.045],
    [-114.071, 51.045],
    [-114.071, 51.044],
    [-114.073, 51.044],
    [-114.073, 51.045]
  ]]
}
```

## Audit Information

All assets include audit metadata:

```graphql theme={null}
type AuditInfo {
  createdAt: DateTime!
  createdBy: UserReference
  updatedAt: DateTime
  updatedBy: UserReference
  version: Int
}
```

## Error Handling

Mutations return standardized error types:

```graphql theme={null}
type AssetMutationResult {
  asset: CamAsset
  correlationId: ID
  errors: [AssetMutationError!]
}

type AssetMutationError implements MutationError {
  message: String!
  type: String!
}
```

Common error types:

* `DUPLICATE_ID`: Asset ID already exists
* `INVALID_PARENT`: Parent asset not found or invalid type
* `INVALID_PROPERTY`: Property validation failed
* `INVALID_GEOMETRY`: GeoJSON geometry is malformed
* `MISSING_REQUIRED`: Required field not provided
* `INVALID_ASSET_TYPE`: Asset type does not exist

## Extension System

Assets can integrate with external data sources through extensions:

```graphql theme={null}
type AssetTypeExtension {
  id: ID!
  name: String!
  sourceType: ExtensionSourceType!
  connectionDetails: AssetTypeExtensionConnectionDetails
  stateSyncProperties: [AssetTypeExtensionStateSyncProperty!]
  statusProperties: [AssetTypeExtensionStatusProperty!]
}

enum ExtensionSourceType {
  DATABASE
  API
  FILE
  STREAM
}
```

## Batch Operations

### Upload Flow

1. Generate presigned S3 upload URL
2. Upload CSV/JSONL file to S3
3. Trigger batch upsert with reference
4. Monitor processing status

### File Formats

**CSV:**

```csv theme={null}
id,name,assetTypeId,properties.operator,geometry.coordinates
site-001,Station A,site,ACME Energy,"[-114.0719,51.0447]"
```

**JSONL:**

```jsonl theme={null}
{"id":"site-001","name":"Station A","assetTypeId":"site","properties":{"operator":"ACME Energy"},"geometry":{"type":"Point","coordinates":[-114.0719,51.0447]}}
```

## Related Resources

* **[CAM Assets Guide](../guides/cam-assets)** - Comprehensive usage guide
* **[Common Patterns](../common-patterns)** - Pagination and filtering
* **[Full SDL Schema](../schemas/sdl/su-cam-assets.graphql)** - Complete type definitions
* **[Core Platform Guide](../guides/core-platform)** - Maps and geospatial services
