resolveIdentifier GraphQL Mutation

Created: Tue 29 Jul 2025 08:58:00 CEST
Document Version: 1.0 - Initial API requirements
Security Classification: Internal Technical Documentation
Target Audience: Backend Developers, API Developers
Author: Paul Wisén

Overview

The resolveIdentifier mutation is a critical endpoint that the Director service (s.plings.io) calls to verify and resolve Plings identifiers into routing decisions. This endpoint performs cryptographic verification, retrieves object context, and returns routing instructions.

GraphQL Schema

input ResolveIdentifierInput {
  type: String!         # Tag type: 'plgs', 'mfr', etc.
  identifier: String!   # Full identifier (e.g., "plgs_1_12345")
  classPointer: String  # Optional class pointer for verification
  scanMetadata: ScanMetadataInput
}

input ScanMetadataInput {
  timestamp: DateTime!
  ipAddress: String
  userAgent: String
  referer: String
  geoLocation: GeoLocationInput
}

input GeoLocationInput {
  latitude: Float
  longitude: Float
  accuracy: Float
  consent: Boolean!
}

type ResolveIdentifierResponse {
  success: Boolean!
  routing: RoutingDecision!
  object: ObjectContext
  scanEvent: ScanEvent
  error: ErrorResponse
}

type RoutingDecision {
  action: RoutingAction!      # REDIRECT, SHOW_INFO, ERROR
  destination: String         # URL to redirect to
  parameters: [Parameter!]    # Additional URL parameters
  cacheTTL: Int              # Cache duration in seconds
}

enum RoutingAction {
  REDIRECT      # Redirect to destination URL
  SHOW_INFO     # Show information page
  ERROR         # Show error page
}

type ObjectContext {
  objectId: String!
  status: ObjectStatus!
  owner: OwnerInfo
  manufacturer: ManufacturerInfo
  class: ObjectClassInfo
  location: LocationInfo
}

enum ObjectStatus {
  ACTIVE
  FOR_SALE
  FOR_RENT
  LOST
  ARCHIVED
  UNKNOWN
}

type Parameter {
  key: String!
  value: String!
}

Request Flow

Director (s.plings.io) → Backend API (api.plings.io)
    ↓
1. Extract parameters from QR scan
2. Call resolveIdentifier mutation
3. Backend performs:
   - Manufacturer validation
   - Cryptographic verification
   - Object lookup
   - Context retrieval
   - Routing decision
4. Return routing instructions
5. Director redirects user

Implementation Requirements

1. Manufacturer Verification

2. Object Resolution

3. Routing Logic

Based on object context, determine destination:

Object Status Destination Parameters
FOR_SALE market.plings.io oid, price, seller
FOR_RENT rent.plings.io oid, rate, owner
LOST plings.io/found oid, reward, contact
UNKNOWN plings.io/create ikey, suggested_class
ACTIVE plings.io/object oid, view_mode

4. Scan Event Logging

Every scan must be logged with:

5. Performance Requirements

Example Request

mutation ResolveIdentifier($input: ResolveIdentifierInput!) {
  resolveIdentifier(input: $input) {
    success
    routing {
      action
      destination
      parameters {
        key
        value
      }
      cacheTTL
    }
    object {
      objectId
      status
      owner {
        name
        verified
      }
      class {
        name
        category
      }
    }
    scanEvent {
      id
      timestamp
    }
    error {
      code
      message
    }
  }
}

Variables:

{
  "input": {
    "type": "plgs",
    "identifier": "plgs_1_abc123xyz",
    "classPointer": "4K7mX9abDcE",
    "scanMetadata": {
      "timestamp": "2025-07-29T12:00:00Z",
      "ipAddress": "192.168.1.1",
      "userAgent": "Mozilla/5.0...",
      "geoLocation": {
        "latitude": 59.3293,
        "longitude": 18.0686,
        "accuracy": 10.5,
        "consent": true
      }
    }
  }
}

Response Examples

Success - Known Object for Sale

{
  "data": {
    "resolveIdentifier": {
      "success": true,
      "routing": {
        "action": "REDIRECT",
        "destination": "https://market.plings.io/item",
        "parameters": [
          { "key": "oid", "value": "obj_123abc" },
          { "key": "src", "value": "scan" },
          { "key": "ref", "value": "plgs_1_abc123xyz" }
        ],
        "cacheTTL": 300
      },
      "object": {
        "objectId": "obj_123abc",
        "status": "FOR_SALE",
        "owner": {
          "name": "John's Bike Shop",
          "verified": true
        },
        "class": {
          "name": "Mountain Bike",
          "category": "Sports Equipment"
        }
      },
      "scanEvent": {
        "id": "scan_789xyz",
        "timestamp": "2025-07-29T12:00:00Z"
      }
    }
  }
}

Success - Unknown Identifier

{
  "data": {
    "resolveIdentifier": {
      "success": true,
      "routing": {
        "action": "REDIRECT",
        "destination": "https://plings.io/create",
        "parameters": [
          { "key": "ikey", "value": "plgs_999_unknown" },
          { "key": "src", "value": "scan" },
          { "key": "suggested", "value": "generic-item" }
        ],
        "cacheTTL": 3600
      },
      "object": null,
      "scanEvent": {
        "id": "scan_456def",
        "timestamp": "2025-07-29T12:00:01Z"
      }
    }
  }
}

Error - Invalid Identifier

{
  "data": {
    "resolveIdentifier": {
      "success": false,
      "routing": {
        "action": "ERROR",
        "destination": "https://plings.io/error",
        "parameters": [
          { "key": "code", "value": "INVALID_IDENTIFIER" }
        ],
        "cacheTTL": 86400
      },
      "error": {
        "code": "INVALID_IDENTIFIER",
        "message": "The identifier format is invalid"
      }
    }
  }
}

Security Considerations

  1. Rate Limiting: Implement per-IP rate limits (100 req/min)
  2. Input Validation: Strict validation of all parameters
  3. Authentication: Director service must authenticate with API key
  4. Encryption: All communication over HTTPS
  5. Privacy: Hash IP addresses, require consent for geolocation

Implementation Priority

  1. Phase 1 (MVP): Basic identifier validation and routing
  2. Phase 2: Full object context and status-based routing
  3. Phase 3: Scan analytics and geolocation features
  4. Phase 4: Advanced caching and performance optimization