Use Case: Tag Scanning Integration in Object Creation
Use Case: Tag Scanning Integration in Object Creation
Created: Mon 07 Jul 2025 12:12:17 CEST
Updated: Wed 09 Jul 2025 09:17:00 CEST - Added dual tag scanning functionality documentation
Updated: Thu 11 Jun 2026 22:13:27 CEST - Added native app scan-first section; corrected GraphQL examples to match implemented API
Document Version: 2.0 - Native iOS scan-first flow + corrected API examples
Security Classification: Internal Technical Documentation
Target Audience: Frontend Developers, iOS Developers, Backend Developers
Author: Paul Wisén
Overview
This document describes the integration of QR code and NFC tag scanning within the object creation workflow. The tag scanning system serves a dual purpose: enabling users to associate physical identifiers with digital objects AND facilitating spatial relationship assignment when objects are created within containers.
Dual Functionality
- Tag Association: Link physical QR/NFC identifiers to new digital objects
- Spatial Context: When creating objects within containers, scanning existing container tags establishes immediate spatial relationships
User Stories
Primary: Tag Association
As a user, I want to scan QR codes or NFC tags while creating objects so that I can immediately link physical identifiers to my digital objects without a separate tagging step.
Secondary: Spatial Context
As a user, I want to scan container tags during object creation so that I can immediately place new objects in their correct spatial location.
Actors
- User: Person creating objects with physical identifiers
- System: Plings application with camera/NFC capabilities
- Physical Identifier: QR code sticker or NFC tag
Preconditions
- User has camera permissions enabled (for QR scanning)
- User has NFC permissions enabled (for NFC scanning)
- User is in the object creation modal/workflow
- Physical identifier is available and unassigned
Workflow Diagram
Continue Detection] E --> D D -->|Yes| F[Call resolveIdentifier API] F --> G{Tag Status?} G -->|KNOWN_OBJECT| H[Show 'Tag belongs to [Object]' Dialog] H --> I{User in Container?} I -->|Yes| J[Show Spatial Options:
'Set as current location?'
'Set as normal location?'] I -->|No| K[Show General Options:
'View this object?'
'Continue creating new?'] J --> L[Update Spatial Relationships] K --> M[Navigate to Object Detail] G -->|UNKNOWN_SPECIFIC| N[Show 'Unknown Specific Class' Dialog
Pre-fill ObjectClass] G -->|UNKNOWN_GENERAL| O[Show 'Unknown General' Dialog
Generic Creation Options] G -->|ERROR| P[Show Error Message
Allow Retry or Manual Entry] N --> Q[User Chooses 'Create New Object'] O --> Q Q --> R[Continue Object Creation Flow
with Tag Pre-assigned] R --> S[Complete Object Creation
Tag Automatically Linked] L --> T[Spatial Relationship Established] M --> U[View Existing Object] P --> V[Fallback to Manual Entry] style A fill:#e1f5fe style B fill:#fff3e0 style G fill:#f3e5f5 style H fill:#e8f5e8 style N fill:#fff8e1 style O fill:#fff8e1 style P fill:#ffebee
Native App: Scan-First Entry Point
In the native iOS app (Plings-iOS), the scanner is not a button inside a modal — it is the home screen. The app opens directly into an active scan session; no tap is required to begin scanning.
Identifiers are minted independently of objects; an object is materialized lazily on first scan/use. See Identifier–Object Lifecycle. This is why a scanned tag may be valid yet have no object yet — and why “tag existing object” is offered for both generic and class-specific tags.
Inverted Flow
In the web app, scanning is initiated from a creation modal. In the native app, creation is initiated from a scan result. The scanner is the persistent entry point for all object interactions.
NFC in the Native App
iOS requires an explicit NFC session start — the OS does not scan continuously in the background. In Plings-iOS, a single tap on the scan button (always visible, always in reach) starts an NFC session. QR scanning uses the in-app camera and is continuous. In practice:
- QR: point camera, tag is detected automatically.
- NFC: one tap → “Hold near tag” prompt → tap tag → result.
Move Flow via Scan
The move flow is also scan-driven: scan the object to move → tap “Flytta” → scan the destination tag → the drag-to-place relationship picker opens with the container pre-populated. The user drags the object to the correct zone (IN / ON / LEFT_OF / RIGHT_OF / ABOVE / UNDER / NEXT_TO) or taps ATTACHED_TO. No manual identifier entry at any point.
Basic Flow
1. Initiate Object Creation
- Entry Point: User opens CreateObjectModal from Dashboard QuickActions or object grids
- Initial State: Modal displays with scan button prominently positioned in header area
- Context Awareness: System detects if user is within a container context
2. Enable Tag Scanning
- Activation: Single “Scan Tag” button triggers camera interface
- Dual Purpose Display: Button shows “Scan Tag” with context hint based on creation location
- Camera Launch: Native camera interface opens with QR/NFC detection overlay
3. Scan Physical Identifier
- Real-time Detection: System continuously scans for QR codes and NFC tags
- Visual Feedback: Scanner overlay highlights detected codes with success/error states
- Capture Confirmation: User receives immediate feedback on successful scan
4. Handle Scan Results
- Tag Resolution: System calls
resolveIdentifier()to determine tag status - Branch Logic: Flow diverges based on known vs unknown tag results
- Context Integration: Known container tags trigger spatial relationship workflows
5. Complete Object Creation
- Tag Association: New object automatically linked to scanned identifier
- Multiple Tag Support: Object can accept additional tags for backup/redundancy
- Spatial Assignment: If container tag scanned, object placed in spatial context
- Success Confirmation: User sees complete object with tag(s) and location assigned
Alternative Flows
A1: Known Object Tag Scanned
Trigger: Scanning tag that belongs to existing object Dialog Flow:
- Recognition: “This tag belongs to [Object Name]”
- Context Options:
- If in container: “Set as current location?” / “Set as normal location?”
- If general: “View this object?” / “Continue creating new object?”
- Spatial Assignment: User can establish immediate spatial relationships
A2: Unknown Tag Format
Trigger: Scanning unrecognized or malformed identifier Error Handling:
- Validation Failure: “Tag format not recognized”
- Recovery Options: Manual entry, try again, or skip tag assignment
- Graceful Degradation: Object creation continues without tag
A3: Tag Already Assigned (Conflict)
Trigger: Scanning tag already linked to different object Conflict Resolution:
- Conflict Detection: “This tag is already assigned to [Other Object]”
- User Choice: Transfer tag, create without tag, or scan different tag
- Audit Trail: All tag reassignments logged for security
A4: Multiple Tag Support
Trigger: Object already has assigned tags Multiple Tag Handling:
- Additional Tag Assignment: “Add this tag as backup/secondary identifier?”
- Tag Type Selection: Choose tag role (primary, backup, verification, etc.)
- Tag Management: Display all assigned tags with their purposes
Technical Implementation
Frontend Components
- ScanButton: Primary scan trigger in CreateObjectModal header
- CameraInterface: QR/NFC detection overlay with visual feedback
- TagResolutionDialog: Handles known/unknown tag workflows
- SpatialContextPrompt: Manages spatial relationship assignment dialogs
GraphQL Integration
# Core tag resolution — this is a MUTATION, not a query.
# The gateway and native apps both call this to resolve a scanned tag.
mutation ResolveIdentifier($input: ResolveIdentifierInput!) {
resolveIdentifier(input: $input) {
success
routing {
action # REDIRECT | ERROR
destination
parameters { key, value }
cacheTTL
}
error { code, message }
}
}
# Input fields for resolveIdentifier:
# type String — tag transport: "q" | "n" | "r" | "b"
# identifier String — Base58 instance key from tag URL
# path String — HD wallet path from tag URL
# classPointer String? — optional cp parameter from tag URL
# scanMetadata { timestamp: ISO8601 }
# Object creation with tag pre-assigned
mutation CreateObject($input: CreateObjectInput!) {
createObject(input: $input) {
id
name
spatialParent { id, name }
}
}
# CreateObjectInput fields that carry tag data:
# tagInstanceKey String — instance key of the scanned tag
# tagData {
# instanceKey String
# classKey String
# path String
# shortCode String
# isManufacturerTag Boolean
# }
# spatialParentId String?
# spatialRelationshipType SpatialRelationshipType?
# autoGenerateName Boolean
# Note: images are NOT included here. Upload them separately after
# the object exists (all object_images rows require an object).
# Image upload — call AFTER createObject succeeds
mutation UploadObjectImages($objectId: ID!, $images: [Upload!]!) {
uploadObjectImages(objectId: $objectId, images: $images) {
id
url
}
}
Not implemented — proposed only:
createObjectWithTag,assignSpatialRelationshipByTag,objectTagsquery. Do not use these in new code; they do not exist in the API.
# Spatial relationship for CURRENT_* positions
mutation CreateSpatialRelationship($input: CreateSpatialRelationshipInput!) {
createSpatialRelationship(input: $input) {
id
type
fromObject { id, name }
toObject { id, name }
}
}
# Spatial relationship for NORMAL_* (expected) positions
mutation CreateNormalSpatialRelationship($input: CreateNormalSpatialRelationshipInput!) {
createNormalSpatialRelationship(input: $input) {
id
type
fromObject { id, name }
toObject { id, name }
}
}
# Move an object to a new spatial parent
mutation MoveObject($input: MoveObjectInput!) {
moveObject(input: $input) {
id
spatialParent { id, name }
}
}
Security Considerations
- Cryptographic Validation: All scanned tags validated against HD wallet signatures
- Permission Verification: Tag assignment requires edit permissions on target object
- Audit Logging: All scan events and tag assignments tracked for security analysis
Related Documentation
- PlingsIdentifier System - Core identifier specification
- HD Wallet Identifier Creation - Cryptographic identifier generation
- Identifier Scan Flow - Scanning workflow details
- Create Object Use Case - Object creation integration
Implementation Status
✅ Currently Available
- Basic Infrastructure: Camera permissions and QR detection libraries
- Modal Integration: CreateObjectModal structure supports scan button placement
- GraphQL Foundation: Core mutations support tag assignment during creation
⚠️ In Development
- Scan Button Implementation: UI component for scan trigger
- Camera Interface: QR/NFC detection overlay and user experience
- Dialog System: Known/unknown tag resolution workflows
❌ Planned Features
- Advanced Conflict Resolution: Comprehensive tag reassignment workflows
- Offline Scanning: Queue scanned tags for later processing
- Manufacturer Integration: Handle pre-registered tag validation
- Bulk Tag Processing: Batch assign multiple tags during creation
Open Items
- Finalize scan button placement and visual design
- Implement camera overlay with detection feedback
- Define complete dialog flow for all tag resolution scenarios
- Add spatial relationship assignment via container tag scanning
Last Updated: Thu Jul 10 09:18:47 CEST 2025 - Added multiple tag support documentation and standardized relationship name to IDENTIFIES
Updated: Thu 12 Jun 2026 23:47:35 CEST - Added cross-link to Identifier–Object Lifecycle principle