Object Creation Requirements

Overview

This document specifies the UI/UX requirements for creating new objects in the Plings system. The system supports dual creation modes: detailed single-object creation and rapid mobile batch creation. Users can register physical items with metadata, images, Plings identifier tags, and spatial relationships within the Universal Object Graph System.

Current Implementation Status

βœ… Implemented Features

  • CreateObjectModal: Complete single object creation form with advanced features
  • Essential Fields: Name, description, object type, tag instance key
  • Image Upload System: Full multi-image upload with camera, drag-drop, and file picker
    • Camera Integration: Live camera capture with photo review
    • Drag & Drop: Visual drop zone with file validation
    • Multiple Images: Support for up to 10 images per object
    • Image Management: Remove, reorder, and designate main image
    • Background Upload: Non-blocking uploads while user continues form
    • Image Preview: Real-time thumbnail grid with progress indicators
  • Validation: Client-side form validation with error messages
  • GraphQL Integration: CREATE_OBJECT mutation with complete object creation
  • Spatial Context: Supports creating objects within containers
  • Organization Context: Objects assigned to user organizations

πŸ†• NEW: Enhanced Create Object Features (2025-07-07)

The Create Object system has been significantly enhanced with four new advanced features:

βœ… Background AI Image Processing

βœ… Geographical Location (LAT/LON) Tracking

βœ… Square Image Cropping

  • Use Case: UC-302: Square Image Cropping
  • Requirements: Square Image Cropping Requirements
  • API Integration: applySquareCropping, getCroppingSuggestions mutations/queries
  • Features: AI-powered subject detection, intelligent crop suggestions, manual override
  • UX: Real-time crop preview with confidence indicators and manual adjustment tools

βœ… Sub-Container Overview Images

  • Use Case: UC-303: Sub-Container Overview Images
  • Requirements: Sub-Container Overview Requirements
  • API Integration: generateContainerOverview, getContainerOverview mutations/queries
  • Features: Spatial layout visualization, type diversity selection for large containers, β€œ+N more” indicators
  • UX: Visual container previews in spatial navigation with smart object selection

πŸ”— Tool Sharing Economy Integration

Integration Flow: All new features integrate seamlessly into the existing CreateObjectModal with progressive enhancement - users get enhanced functionality without disrupting the core creation experience.

⚠️ Partially Implemented

  • Entry Points: QuickActions component exists but only placeholder actions
  • Object Types: Hardcoded dropdown instead of dynamic class system

❌ Missing Features (Priority Order)

  1. Tag Scanning: No QR/NFC scanning integration
  2. Set Creation Workflow: No β€œCreate as Set?” decision point
  3. Mobile Batch Mode: Complete mobile batch creation interface
  4. Object Class System: Dynamic class search and selection
  5. Real-time Updates: Live dashboard updates during creation
  6. Advanced Validation: Tag conflict resolution, duplicate detection

Creation Modes

The Plings system supports two distinct object creation workflows:

Single Object Mode (Desktop/Detailed)

  • Purpose: Comprehensive object registration with full metadata
  • Platform: Primarily desktop/tablet with full keyboard access
  • Features: Complete form fields, multiple images, detailed properties
  • Use Case: Important items requiring detailed documentation

Multi-Object Mode (Mobile/Batch)

  • Purpose: Rapid capture of many objects in sequence
  • Platform: Mobile devices with camera access
  • Features: Camera-first workflow, tag scanning, minimal metadata
  • Use Case: Organizing spaces, inventory capture, bulk registration
  • Processing: Objects created with β€œunprocessed” status for later desktop refinement

User Stories

Primary User Story: As a user, I want to create a digital record of my physical objects so that I can track, organize, and manage my items across different organizations.

Secondary User Stories:

  • As a user, I want to upload multiple images of my object so that I can visually identify it later
  • As a user, I want to scan Plings identifier tags to automatically link physical tags with digital records
  • As a user, I want to specify the location of my object so that I can find it physically
  • As a user, I want to set object properties so that I can categorize and search for it effectively
  • As a user, I want to assign the object to an organization so that I can manage access permissions
  • As a mobile user, I want to rapidly create many objects using camera capture and tag scanning
  • As a user, I want objects created in batch mode to be processable later on desktop for detailed metadata

Entry Points

1. Dashboard Quick Actions

  • Location: Main Dashboard (/dashboard)
  • UI Element: β€œAdd Object” card in Quick Actions section
  • Current Implementation: ⚠️ Placeholder only - console.log action
  • Behavior: Should open object creation modal (not connected)

2. Objects Dashboard

  • Location: Objects Dashboard (/objects)
  • UI Element: β€œCreate Object” button (to be implemented)
  • Behavior: Opens object creation modal

3. Spatial Context (Batch Mode)

  • Location: Within Spatial Navigator containers
  • UI Element: β€œCreate Objects Here” action in container context
  • Behavior: Opens mobile batch creation mode with pre-filled container location

4. Mobile Batch Entry

  • Location: Mobile app camera interface
  • UI Element: Camera with β€œBatch Create” mode
  • Behavior: Rapid photo + tag scanning workflow

Camera Mode Distinction

The object creation system uses camera functionality for two distinct purposes that must be clearly separated in the UI:

Photo Capture Mode

  • Purpose: Take images of the physical object for visual identification
  • UI Element: β€œπŸ“· Add Photos” button
  • Camera Behavior: Standard photo capture with gallery preview
  • Output: Image files stored for object visualization
  • User Experience: Click to capture, review, retake, or add more photos

Tag Scanning Mode

  • Purpose: Read Plings identifier QR codes or NFC tags
  • UI Element: β€œπŸ·οΈ Scan Tag” button
  • Camera Behavior: QR/barcode detection with URL processing
  • Output: Plings identifier data (Instance Key, Class Key, Path)
  • User Experience: Point camera at tag, automatic detection and processing

Critical Security Implementation

URL Interception Pattern (Required):

// QR Scanner Mode - Never navigate to URLs
async function scanPlingsTag() {
  const qrResult = await scanQRCode(); // Returns string
  
  if (qrResult.startsWith('https://scan.plings.io/s?')) {
    // Parse URL parameters without navigation
    const url = new URL(qrResult);
    const tagType = url.searchParams.get('t');
    const instanceKey = url.searchParams.get('i');
    const classKey = url.searchParams.get('c');
    const path = url.searchParams.get('p');
    
    // Extract 4-char short code for human identification
    const shortCode = instanceKey.substring(0, 4);
    
    return {
      tagType, instanceKey, classKey, path, shortCode,
      isManufacturerTag: !!classKey
    };
  } else {
    throw new Error("Not a valid Plings identifier");
  }
}

Why URL Interception is Critical:

  • Prevents navigation: App stays in control, no accidental browser redirects
  • Enables Lost & Found: System can record scan events for tracking
  • Security: Validates URL format before processing parameters
  • Universal Access: Anyone can scan codes even without Plings app installed

Single Object Mode (Desktop/Detailed)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Create New Object                                    βœ• β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  [Image Upload Area]                                    β”‚
β”‚                                                         β”‚
β”‚  Object Name: [___________________________]             β”‚
β”‚  Description: [___________________________]             β”‚
β”‚               [___________________________]             β”‚
β”‚                                                         β”‚
β”‚  Organization: [Dropdown β–Ό]                            β”‚
β”‚  Location: [Location Selector]                         β”‚
β”‚                                                         β”‚
β”‚  Object Class: [Search/Select β–Ό]                       β”‚
β”‚                                                         β”‚
β”‚  Properties:                                            β”‚
β”‚  [Dynamic property fields based on class]              β”‚
β”‚                                                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                      [Cancel]  [Create Object]         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Size: Large modal (max-width: 768px)
  • Position: Centered on screen
  • Backdrop: Semi-transparent overlay with click-to-close
  • Responsive: Full-screen on mobile devices
  • Scroll: Scrollable content area if content exceeds viewport

Tag Integration & Naming System

Tag Type Detection

The system automatically determines object classification based on scanned tag data:

function determineObjectType(tagData) {
  if (!tagData) {
    // Untagged object
    return { 
      type: 'untagged', 
      objectClass: 'Unknown',
      identifier: getNextSequential() // "1", "2", "3"
    };
  }
  
  if (tagData.classKey) {
    // Producer-issued tag (1% - IKEA, ACME, etc.)
    return { 
      type: 'producer', 
      objectClass: 'specific',
      identifier: tagData.shortCode, // "AuZx"
      hasMetadata: true 
    };
  } else {
    // General Plings tag (99% - user-purchased tags)
    return { 
      type: 'general', 
      objectClass: 'Generic',
      identifier: tagData.shortCode, // "CuUY"
      hasMetadata: false 
    };
  }
}

Naming Algorithm

Format: [Organization] + [User Input] + [Identifier]

function generateObjectName(organizationName, userInput, tagData) {
  const identifier = tagData ? tagData.shortCode : getNextSequential();
  return `${organizationName} ${userInput} ${identifier}`;
}

Examples:

  • General tag: β€œPauls lamp CuUY” (99% of cases)
  • Producer tag: β€œPauls lamp AuZx” (1% of cases)
  • Untagged: β€œPauls lamp 1” (sequential numbering)
  • User types β€œIKEA lamp”: β€œPauls IKEA lamp CuUY”

Tag Scenarios

1. General Plings Tags (99% of use cases)

  • Source: User-purchased Plings tags from store
  • Class Information: None - tag only provides Instance Key
  • ObjectClass: β€œGeneric” (cryptographically verifiable Plings class)
  • User Experience: Scan tag β†’ User provides classification
  • Naming: β€œPauls [user input] [4-char code]”

2. Producer-Issued Tags (1% of use cases)

  • Source: Manufacturer-embedded tags (IKEA, ACME, etc.)
  • Class Information: Full path hierarchy (e.g., ikea.furniture.lighting)
  • ObjectClass: Specific manufacturer class
  • User Experience: Scan tag β†’ Rich metadata potentially available
  • Naming: β€œPauls [user input] [4-char code]” (manufacturer info stored separately)

3. Untagged Objects

  • Source: Objects too small for tags or user choice
  • Class Information: None
  • ObjectClass: β€œUnknown” (Plings default for untagged)
  • User Experience: Manual entry only
  • Naming: β€œPauls [user input] [sequential number]”

Short Code Integration

4-Character Human-Readable Codes:

  • Source: First 4 characters of Base58-encoded Instance Key
  • Purpose: Enable physical tag identification (β€œFind tag CuUY”)
  • Collision Rate: ~1 in 11 million (acceptable for practical use)
  • Character Set: Base58 (avoids 0, O, I, l for readability)
  • Display: Prominent on physical tags and in UI

Form Fields Specification

1. Tag Integration Section

Priority: High Position: Top of modal Requirements:

  • Separate buttons: β€œπŸ“· Add Photos” and β€œπŸ·οΈ Scan Tag”
  • Visual distinction: Clear icons and labels for each camera mode
  • Tag display: Show scanned tag info (short code, type, manufacturer if applicable)
  • Tag editing: Allow manual tag entry or tag removal
  • Security: URL interception for all Plings identifier processing

2. Image Upload Section

Priority: High
Position: After tag section
Requirements:

  • Drag-and-drop upload area with visual drop zone indicators
  • Multiple input methods:
    • πŸ“ Browse Files button - Opens file picker for existing photos
    • πŸ“· Camera button - Opens camera interface for live photo capture
    • Drag & Drop - Direct file drag from computer/file manager
  • Camera Integration:
    • Direct camera access via getUserMedia API
    • Live camera viewfinder with capture button
    • Multiple photo capture in sequence
    • Photo review with retake option
    • Immediate local storage - Photos stored in browser memory/IndexedDB
    • Background upload - Automatic upload while user continues form
  • Multi-image support (up to 10 images per object)
  • Image preview grid with thumbnails and reordering
  • Main image designation (first image auto-marked as β€œMain”)
  • Individual image management:
    • Reorder images by drag-and-drop
    • Delete individual images with confirmation
    • Replace specific images with retake option
  • Image validation:
    • Supported formats: JPEG, PNG, WebP
    • Maximum size: 5MB per image
    • Maximum total: 50MB per object
    • Real-time validation feedback

Camera Interface Specifications

Desktop/Tablet Camera Interface

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“· Camera Capture                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  [LIVE CAMERA VIEWFINDER]          β”‚
β”‚                                     β”‚
β”‚  πŸ“Έ Tap anywhere to capture         β”‚
β”‚                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  [πŸ”„ Switch Camera] [⚑ Flash]      β”‚
β”‚  [πŸ“· Capture] [❌ Close]           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Photo Review Interface

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“· Photo Captured                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  [CAPTURED IMAGE PREVIEW]          β”‚
β”‚                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  [πŸ”„ Retake] [βœ… Keep] [βž• Add More]β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Image Upload Strategy & User Experience

🎯 Goal: User never waits for image uploads - seamless, non-blocking experience

Upload Flow Design

User Action β†’ Immediate Response β†’ Background Process
─────────────────────────────────────────────────────
πŸ“· Take Photo β†’ βœ… Photo appears in grid β†’ πŸ”„ Upload starts silently
πŸ“ Add File   β†’ βœ… Thumbnail shows       β†’ πŸ”„ Upload starts silently  
πŸ–±οΈ Drag Drop  β†’ βœ… Preview grid updates  β†’ πŸ”„ Upload starts silently

User continues filling form while uploads happen in background

Technical Implementation Strategy

1. Immediate Local Storage

  • Browser Memory: Store image data as Blob objects in component state
  • IndexedDB Fallback: Persist large images to IndexedDB for reliability
  • Thumbnails: Generate instant thumbnails for immediate UI feedback
  • Preview Grid: Show images immediately using URL.createObjectURL()

2. Background Upload Process

  • Automatic Trigger: Upload starts immediately after image selection/capture
  • Queue Management: Multiple images uploaded in parallel (max 3 concurrent)
  • Progress Tracking: Silent progress indicators (subtle spinner on thumbnails)
  • Error Handling: Retry failed uploads automatically, show errors only if persistent

3. State Management

interface ImageUploadState {
  localImages: {
    id: string;
    file: File | Blob;
    thumbnail: string;        // Data URL for immediate display
    uploadStatus: 'pending' | 'uploading' | 'completed' | 'failed';
    uploadProgress: number;   // 0-100
    cloudUrl?: string;        // Available when upload completes
  }[];
}

4. User Experience Indicators

  • βœ… Immediate: Image appears in grid instantly
  • πŸ”„ Uploading: Subtle progress indicator on thumbnail corner
  • βœ… Uploaded: Green checkmark when upload completes
  • ❌ Failed: Red indicator with retry option
  • πŸ“± Offline: Queue for upload when connection returns

5. Form Submission Strategy

  • Option A (Recommended): Wait for uploads before enabling submit button
  • Option B: Allow submission with pending uploads, handle async completion
  • Validation: Ensure at least uploaded URLs or local files before object creation

Technical Implementation

  • Browser API: navigator.mediaDevices.getUserMedia()
  • Camera Constraints: { video: { facingMode: 'environment' } } for back camera
  • Capture Method: Canvas-based image capture from video stream
  • Upload API: Direct to Supabase Storage with progress callbacks
  • Fallback: File input with capture="environment" attribute for older browsers
  • Permissions: Request camera permission with clear user messaging
  • Offline Support: Service worker caching for upload queue persistence

Performance Optimizations

  • Image Compression: Compress images before upload (maintain quality <2MB)
  • Parallel Uploads: Multiple simultaneous uploads for faster completion
  • Thumbnail Generation: Instant local thumbnails for immediate feedback
  • Memory Management: Clean up blob URLs and IndexedDB when not needed
  • Network Awareness: Adjust upload quality based on connection speed

3. Object Name Field

Type: Text input
Required: No (auto-generated if empty)
Auto-naming Strategy:

  • Default base name: β€œObject” if no user input
  • With tag: β€œObject (CuUY)” using first 4 characters of tag
  • Duplicate handling: Auto-increment within organization scope
    • β€œObject” β†’ β€œObject 2” β†’ β€œObject 3” etc.
    • β€œLamp” β†’ β€œLamp 2” β†’ β€œLamp 3” etc.
    • β€œObject (CuUY)” β†’ β€œObject (CuUY) 2” if tag name conflicts User Input:
  • Optional: User can provide custom name
  • Live preview: Show final name with auto-numbering as user types
  • Override: User input always takes precedence over auto-generation Validation:
  • Maximum 100 characters when provided
  • Trim whitespace
  • No special characters restrictions Placeholder: β€œObject name (optional - auto-generated if empty)”
    Help Text: β€œLeave empty to auto-generate name, or provide custom name”

Auto-naming Examples

User Input β†’ Tag β†’ Existing Names β†’ Generated Name
─────────────────────────────────────────────────────
(empty)    β†’ none  β†’ none           β†’ "Object"
(empty)    β†’ CuUY  β†’ none           β†’ "Object (CuUY)"
(empty)    β†’ none  β†’ ["Object"]     β†’ "Object 2"
"Lamp"     β†’ none  β†’ ["Lamp"]       β†’ "Lamp 2"  
"Lamp"     β†’ CuUY  β†’ none           β†’ "Lamp (CuUY)"
(empty)    β†’ AuZx  β†’ ["Object (AuZx)"] β†’ "Object (AuZx) 2"

4. Description Field

Type: Textarea
Required: No (intentionally optional for rapid creation) Strategy:

  • Leave empty by default - Most users won’t fill this during rapid object creation
  • Post-creation refinement - Users can add descriptions later via object management modal
  • AI enhancement - Future: AI can suggest descriptions based on uploaded images Validation:
  • Maximum 500 characters when provided
  • Character counter display Placeholder: β€œDescription (optional - can be added later)”
    Rows: 3
    Resizable: Yes Help Text: β€œOptional - you can add or edit this later”

4. Organization Selection

Type: Dropdown/Select
Required: Yes
Behavior:

  • Default to user’s primary organization
  • Show only organizations where user has create permissions
  • If only one organization, pre-select and disable field Empty State: β€œSelect an organization”

5. Location Selection

Type: Custom location selector component
Required: No (defaults to current spatial navigator container) Default Behavior:

  • Default Location: Current object selected in spatial navigator
  • Default Relationship: Automatically determined based on container type (IN for rooms, ON for surfaces)
  • Spatial Context: New objects inherit organization and permissions from default container

Location Selector Features:

  • Default Display: Shows current spatial navigator location with relationship type
  • Change Location Button: Opens camera-based location scanning
  • Camera Scanning: QR/NFC scanner to identify target container/object
  • Relationship Selection: UI to choose spatial relationship type after scanning
  • Spatial Breadcrumb: Shows full spatial hierarchy for selected location

Camera-Based Location Selection Workflow

Step 1: Default Location Display

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“ Location                        β”‚
β”‚  Default: Kitchen Drawer (IN)       β”‚
β”‚  [πŸ“· Change Location]               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 2: Camera Scanner Interface

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  🏷️ Scan Container Tag             β”‚
β”‚  [QR CODE VIEWFINDER ACTIVE]       β”‚
β”‚                                     β”‚
β”‚  Point camera at container QR/NFC   β”‚
β”‚  [❌ Cancel] [⌨️ Manual Entry]      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 3: Relationship Type Selection

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“¦ Scanned: "Storage Box"          β”‚
β”‚                                     β”‚
β”‚  How should new object relate?      β”‚
β”‚  β—‹ IN Storage Box (inside)          β”‚
β”‚  ● ON Storage Box (on top)         β”‚
β”‚  β—‹ NEXT_TO Storage Box (beside)    β”‚
β”‚                                     β”‚
β”‚  [βœ… Confirm Location]              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 4: Positional Relationship Options (Advanced)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“¦ Target: Storage Box             β”‚
β”‚  πŸ“ Container: Workshop Shelf       β”‚
β”‚                                     β”‚
β”‚  Position relative to other objects? β”‚
β”‚  [πŸ” Scan Object] [⏭️ Skip]        β”‚
β”‚                                     β”‚
β”‚  If target has existing items:      β”‚
β”‚  β—‹ LEFT_OF Blue Box                β”‚
β”‚  β—‹ RIGHT_OF Red Tool               β”‚
β”‚  β—‹ No specific position            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technical Implementation

Spatial Navigator Integration:

// Access current spatial navigator state
const currentContainer = useSpatialNavigator();

// Default location assignment
const defaultLocation = {
  containerId: currentContainer.id,
  containerName: currentContainer.name,
  relationshipType: inferRelationshipType(currentContainer.type),
  spatialHierarchy: currentContainer.spatialHierarchy
};

function inferRelationshipType(containerType) {
  switch (containerType) {
    case 'Room':
    case 'Building': 
    case 'Container':
      return 'IN';
    case 'Desk':
    case 'Table':
    case 'Shelf':
    case 'Pallet':
      return 'ON';
    default:
      return 'IN'; // Safe default
  }
}

Camera Scanning Integration:

async function scanContainerTag() {
  try {
    const tagData = await scanPlingsTag(); // QR/NFC scanning
    const containerObject = await resolveTagToObject(tagData);
    
    return {
      containerId: containerObject.id,
      containerName: containerObject.name,
      tagData: tagData,
      availableRelationships: getValidRelationships(containerObject.type)
    };
  } catch (error) {
    // Fallback to manual container selection
    return showManualContainerPicker();
  }
}

Relationship Type Validation:

function getValidRelationships(containerType, currentContainer) {
  const relationships = [];
  
  // Parent relationships (always available for containers)
  if (containerType === 'Room' || containerType === 'Container') {
    relationships.push({ type: 'IN', label: 'Inside container' });
  }
  if (containerType === 'Surface' || containerType === 'Table') {
    relationships.push({ type: 'ON', label: 'On surface' });
  }
  
  // Positional relationships (if in same container as other objects)
  if (containerType === currentContainer?.type) {
    relationships.push(
      { type: 'LEFT_OF', label: 'To the left of' },
      { type: 'RIGHT_OF', label: 'To the right of' },
      { type: 'ABOVE', label: 'Above' },
      { type: 'UNDER', label: 'Below' },
      { type: 'NEXT_TO', label: 'Next to' }
    );
  }
  
  return relationships;
}

Integration: Links to spatial dashboard for location management

6. Object Class Selection

Type: Search/Select dropdown
Required: No
Features:

  • Searchable dropdown with autocomplete
  • Popular/recent classes at top
  • Create new class option (if permissions allow)
  • Class description tooltip Default: Generic β€œObject” class

7. Dynamic Properties

Type: Dynamic form fields
Behavior:

  • Properties populate based on selected Object Class
  • Different field types: text, number, date, boolean, select
  • Validation rules defined by class schema
  • Optional vs required properties clearly marked

Validation Rules

Client-Side Validation

  • Real-time validation on field blur
  • Form submission blocked until all required fields valid
  • Visual indicators for invalid fields (red border, error message)
  • Success indicators for valid fields (green checkmark)

Error Messages

  • Object Name: β€œObject name is required”
  • Organization: β€œPlease select an organization”
  • Image Upload: β€œFile size must be under 5MB” / β€œOnly image files are allowed”
  • Description: β€œDescription cannot exceed 500 characters”

Server-Side Validation

  • Duplicate name checking within organization
  • Permission validation for organization and location
  • Image file integrity checks
  • Class-specific property validation

User Interaction States

1. Initial State

  • Empty form with placeholder text
  • Upload area prominently displayed
  • Required fields clearly marked with asterisks
  • Primary action button disabled until required fields filled

2. Loading States

  • Image upload progress indicators
  • Form submission loading spinner
  • Disabled form during submission
  • β€œCreating object…” status message

3. Error States

  • Field validation errors inline
  • Server error messages at top of modal
  • Failed upload retry options
  • Preserve form data on errors

4. Success State

  • Success message display
  • Set Object Decision: β€œCreate as Set?” prompt after successful creation
  • Option to create another object
  • Option to view created object
  • Option to close modal and return to dashboard

5. Set Mode State

  • Visual indicator: β€œπŸ”— SET MODE: [Set Name]” header
  • Progress display: List of items already created in set
  • Current item: Form for creating next set item
  • Navigation options: [Next Item] [Finish Set] buttons
  • Auto-exit: After 10-15 minutes of inactivity

6. Batch Creation States (Mobile)

  • Session Active: Camera interface with β€œScan & Create” workflow
  • Queue Management: List view of captured objects awaiting creation
  • Upload Progress: Real-time progress indicators for batch processing
  • Conflict Resolution: Modal for handling tag conflicts during batch
  • Session Recovery: Resume interrupted batch sessions

7. Tag Scanning States

  • Camera Active: QR/NFC scanning interface with viewfinder
  • Scan Success: Tag information display with validation status
  • Conflict Detection: Warning UI for already-assigned tags
  • Resolution Options: UI for resolving tag conflicts
  • Manual Entry: Fallback for failed scans or manual tag input

8. Object Class Selection States

  • Search Interface: Autocomplete search with recent/popular classes
  • Hierarchy Navigation: Breadcrumb navigation for class categories
  • Create New Class: Modal for defining new ObjectClass (if permissions allow)
  • Class Properties: Dynamic form fields based on selected class
  • Validation Feedback: Real-time validation for class-specific properties

Integration Requirements

GraphQL Operations

Primary Mutation:

mutation CreateObject($input: CreateObjectInput!) {
  createObject(input: $input) {
    id
    name
    description
    organization {
      id
      name
    }
    location {
      id
      name
      spatialPath
    }
    images {
      id
      url
      isMain
    }
    createdAt
  }
}

File Upload Integration

  • Service: Supabase Storage
  • Bucket: object-images
  • Path Structure: objects/{objectId}/{imageId}
  • Processing: Automatic thumbnail generation
  • Security: RLS policies for access control

Real-time Updates

  • Subscription: objectCreated to update dashboards
  • Cache Updates: Apollo Client cache updates
  • Optimistic UI: Immediate UI updates before server response

Set Object Creation

Set Object Definition

Set Objects are physical items sold/conceptualized as a collection with shared identity, using PART_OF relationships. Distinguished from assemblies (functional components) and collections (user-organized groupings).

Examples: Glove pairs, tool sets, chess sets, dinnerware sets, computer bundles

Key Characteristics:

  • Set container has its own images showing complete set
  • Individual components inherit ownership from set
  • Components instantiated only when needed (separation, repair, individual tagging)
  • Each component can have its own Plings identifier tag

Set Creation Workflow

Decision Point: Create as Set

After successful object creation, system prompts:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  βœ“ "Pauls ski gloves" created          β”‚
β”‚                                     β”‚
β”‚  Create as Set?                      β”‚
β”‚  Add individual items to this set    β”‚
β”‚                                     β”‚
β”‚  [Yes, Create Set] [No, Keep Single] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

If β€œYes, Create Set”:

  1. Original object becomes set container
  2. System suggests refined set name (β€œPauls ski gloves” β†’ β€œPauls ski gloves set”)
  3. Enter Set Mode for creating child objects

Set Mode Interface

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ”— SET MODE: Ski Gloves Set        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Creating items for this set...     β”‚
β”‚                                     β”‚
β”‚  Items in set:                      β”‚
β”‚  βœ“ Left ski glove (CuUY)           β”‚
β”‚                                     β”‚
β”‚  Current item: Right ski glove      β”‚
β”‚  [πŸ“· Photo] [🏷️ Scan Tag: AuZx]    β”‚
β”‚                                     β”‚
β”‚  [Next Item] [Finish Set]           β”‚
β”‚  ↳ Continue    ↳ Complete & exit    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Navigation Options:

  • Next Item: Tooltip β€œCreate this item and add another to the set”
  • Finish Set: Tooltip β€œCreate this item and complete the set”
  • Auto-exit: After 10-15 minutes of inactivity
  • Navigation exit: Leaving creation flow completes the set

Tag Migration Logic

Scenario A: Set Created with Tag

1. Create "Pauls ski gloves" with tag CuUY
2. Convert to set β†’ Set container has tag CuUY
3. Create child "Left ski glove" with same tag CuUY
   β†’ Tag automatically moves from set to child
4. Create child "Right ski glove" with new tag AuZx
5. Set becomes digital-only container (no physical tag)

Scenario B: Tag Assignment Rules

function handleTagScan(scannedTag, currentSetId) {
  if (scannedTag.pointsTo === currentSetId) {
    // Tag currently points to the set - move it to this child
    moveTagToChild(scannedTag, currentChildObject);
    return "Tag moved from set to this item";
  } else if (scannedTag.pointsTo !== null) {
    // Tag points to different object
    throw new Error("Tag already assigned to another object");
  } else {
    // New/unassigned tag
    assignTagToChild(scannedTag, currentChildObject);
  }
}

Tag Conflict Handling:

  • βœ… Tag points to current set β†’ Move to child
  • βœ… Unassigned tag β†’ Assign to child
  • ❌ Tag points to different object β†’ β€œTag already assigned to [ObjectName]”
  • ❌ Tag points to child of different set β†’ β€œTag belongs to different set”

Smart Naming Suggestions

AI-Assisted Child Naming:

function suggestChildNames(setName, existingChildren) {
  // Pattern-based suggestions
  if (setName.includes("padlock")) {
    return [`key ${existingChildren.length + 1} to padlock`];
  } else if (setName.includes("gloves")) {
    return ["left glove", "right glove"];
  } else if (setName.includes("tool set")) {
    return ["hammer", "screwdriver", "wrench"]; // Based on common tools
  }
  // Fallback pattern
  return [`item ${existingChildren.length + 1}`];
}

Naming Examples:

  • Set: β€œPauls padlock with keys” β†’ Refined: β€œPauls padlock”
  • Children: β€œkey 1 to padlock”, β€œkey 2 to padlock”, β€œkey 3 to padlock”
  • Set: β€œPauls ski gloves” β†’ Children: β€œleft ski glove”, β€œright ski glove”

Set Integration with Batch Mode

Mobile Batch Interface with Set Support:

πŸ“± Mobile Batch Interface:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“· Photo captured βœ“                β”‚
β”‚  🏷️ Tag: AuZx scanned              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  This object is:                    β”‚
β”‚  [Create as Set]                    β”‚
β”‚  [Add to "Ski Gloves"]             β”‚  
β”‚  [Create as New Object]             β”‚
β”‚                                     β”‚
β”‚  [πŸ” Search types...]               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Batch Mode Set Options:

  • Create as Set: Start new set with this object
  • Add to [SetName]: Add as child to existing set in current session
  • Create as New Object: Independent object (exit any active set mode)

Data Model Implementation

Set Container Object:

{
  "id": "obj_set_001",
  "name": "Pauls ski gloves",
  "isSet": true,
  "images": ["set-complete-photo.jpg"],
  "organization": "pauls-org",
  "status": ["active"]
}

Child Objects with PART_OF Relationship:

{
  "id": "obj_child_001",
  "name": "left ski glove",
  "isSet": false,
  "tagData": {
    "instanceKey": "CuUY3NBUo...",
    "shortCode": "CuUY"
  },
  "relationships": {
    "PART_OF": "obj_set_001"
  }
}

GraphQL Mutations for Sets:

# Convert object to set
mutation ConvertToSet($objectId: ID!, $setName: String!) {
  convertToSet(objectId: $objectId, setName: $setName) {
    id
    name
    isSet
    children { id name }
  }
}

# Create child object in set
mutation CreateSetChild($setId: ID!, $input: CreateObjectInput!) {
  createSetChild(setId: $setId, input: $input) {
    id
    name
    setParent { id name }
    tagData { shortCode instanceKey }
  }
}

# Complete set creation
mutation CompleteSet($setId: ID!) {
  completeSet(setId: $setId) {
    id
    name
    isComplete
    children { id name }
  }
}

Mobile Batch Creation Complete Specification

Mobile Batch Interface Design

πŸ“± Mobile Batch Creation Interface:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“· Batch Create - Session #1       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  πŸ“Ή [CAMERA VIEWFINDER ACTIVE]     β”‚
β”‚                                     β”‚
β”‚  πŸ‘† Tap to capture object photo     β”‚
β”‚  🏷️ Hold to scan tag               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  πŸ“Š Session Progress: 3/∞ objects   β”‚
β”‚  πŸ“ Container: Kitchen drawer       β”‚
β”‚                                     β”‚
β”‚  Recent captures:                   β”‚
β”‚  β€’ Kitchen knife (CuUY) βœ“          β”‚
β”‚  β€’ Wooden spoon (untagged) βœ“       β”‚
β”‚  β€’ Salt shaker (pending scan)      β”‚
β”‚                                     β”‚
β”‚  [Quick Types: Tool | Utensil | πŸ”] β”‚
β”‚  [⏸️ Pause] [βœ… Complete Session]   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mobile Workflow States

1. Session Start

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Start Batch Creation               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  πŸ“ Location: Kitchen drawer        β”‚
β”‚  🏒 Organization: Paul's Home       β”‚
β”‚                                     β”‚
β”‚  πŸ“· Camera ready                    β”‚
β”‚  🏷️ Tag scanner ready              β”‚
β”‚                                     β”‚
β”‚  [πŸ“Έ Start Capturing]               β”‚
β”‚  [πŸ“‹ Resume Previous Session]       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Object Capture Flow

Step 1: Photo Capture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“Έ Object photo captured βœ“         β”‚
β”‚  [πŸ“· Retake] [βœ… Keep Photo]        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 2: Quick Classification
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  What is this object?               β”‚
β”‚  [πŸ”§ Tool] [🍴 Utensil] [πŸ“¦ Other] β”‚
β”‚  [πŸ” Search types...]               β”‚
β”‚  [🏷️ Scan Tag] [⏭️ Skip for now]   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 3: Quick Naming
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Name: kitchen knife                β”‚
β”‚  Suggested: "Paul's kitchen knife 4"β”‚
β”‚  [βœ… Accept] [✏️ Edit] [➑️ Next]    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. Tag Scanning Integration

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  🏷️ Scanning tag...                β”‚
β”‚  [QR CODE VIEWFINDER ACTIVE]       β”‚
β”‚                                     β”‚
β”‚  Point camera at QR/NFC tag        β”‚
β”‚  [πŸ“· Switch to Photo] [⏭️ Skip]     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tag Scanned Successfully:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  βœ… Tag CuUY scanned                β”‚
β”‚  🏷️ Generic Plings tag              β”‚
β”‚                                     β”‚
β”‚  Suggested name:                    β”‚
β”‚  "Paul's kitchen knife CuUY"       β”‚
β”‚  [βœ… Accept] [✏️ Edit]              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4. Batch Progress Management

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“Š Batch Session #1 Progress       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  βœ… Kitchen knife (CuUY)            β”‚
β”‚  βœ… Wooden spoon (5)                β”‚
β”‚  ⏳ Salt shaker (processing...)     β”‚
β”‚  ❌ Can opener (tag conflict)       β”‚
β”‚                                     β”‚
β”‚  πŸ“ˆ 4 objects | 3 complete | 1 errorβ”‚
β”‚  [πŸ”§ Fix Errors] [πŸ“Έ Add More]      β”‚
β”‚  [⏸️ Pause Session] [βœ… Complete]   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

5. Session Completion

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸŽ‰ Batch Session Complete!         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  βœ… Created 4 objects successfully  β”‚
β”‚  πŸ“ Location: Kitchen drawer        β”‚
β”‚  ⏱️ Duration: 5 minutes             β”‚
β”‚                                     β”‚
β”‚  Next steps:                        β”‚
β”‚  [πŸ–₯️ Refine on Desktop]            β”‚
β”‚  [πŸ“Έ Start New Session]             β”‚
β”‚  [πŸ“Š View Dashboard]                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mobile Performance Optimizations

Camera and Scanning

  • Native Camera Access: Direct camera API for photo capture and QR scanning
  • Background Processing: Compress and upload images while continuing capture
  • Offline Queuing: Store captures locally, sync when connection available
  • Battery Optimization: Efficient camera usage, auto-sleep after inactivity

Session Management

  • Auto-save: Save session progress every 30 seconds
  • Recovery: Resume interrupted sessions after app restart
  • Background Sync: Continue uploading when app backgrounded
  • Progress Indicators: Real-time progress for uploads and processing

Network Optimization

  • Batch Uploads: Group multiple objects for efficient network usage
  • Progressive Sync: Upload photos first, metadata second
  • Retry Logic: Automatic retry for failed uploads with exponential backoff
  • Data Usage: Compress images for mobile networks, full quality on WiFi

Touch Interaction Design

Camera Controls

  • Tap to Photo: Single tap anywhere on viewfinder to capture
  • Hold for Tag: Long press to switch to tag scanning mode
  • Swipe for History: Swipe up to see recent captures
  • Pinch to Zoom: Standard pinch zoom for camera viewfinder

Quick Actions

  • Type Buttons: Large touch targets (minimum 44px) for quick type selection
  • Drag to Reorder: Drag gesture to reorder objects in batch queue
  • Swipe to Delete: Swipe left on batch items to remove
  • Pull to Refresh: Pull down to refresh session status

Accessibility

  • Voice Control: Voice commands for hands-free operation
  • High Contrast: High contrast mode for camera viewfinder
  • Large Text: Respect system font size settings
  • Screen Reader: Full VoiceOver/TalkBack support for blind users

Error Handling for Mobile

Camera Errors

  • Permission Denied: Clear instructions to enable camera access
  • Hardware Failure: Fallback to photo library selection
  • Low Light: Flash toggle and manual exposure controls
  • Focus Issues: Tap-to-focus with visual feedback

Network Errors

  • Offline Mode: Continue capturing, queue for later sync
  • Upload Failures: Retry with exponential backoff, manual retry options
  • Server Errors: Clear error messages with retry instructions
  • Timeout Handling: Progressive timeout for poor connections

Tag Scanning Errors

  • Invalid QR: Clear feedback for non-Plings QR codes
  • Tag Conflicts: Intuitive conflict resolution interface
  • Manual Entry: Fallback manual tag input with validation
  • Scan Timeout: Auto-fallback to manual entry after failed scans

Accessibility Requirements

ARIA Labels

  • Modal properly labeled with aria-labelledby
  • Form fields with aria-describedby for help text
  • Upload area with aria-label
  • Error messages with aria-live regions

Keyboard Navigation

  • Tab order logical and intuitive
  • ESC key closes modal
  • Enter key submits form (when valid)
  • All interactive elements keyboard accessible

Screen Reader Support

  • Semantic HTML structure
  • Form field labels properly associated
  • Status messages announced
  • Progress indicators with text alternatives

Visual Accessibility

  • High contrast error states
  • Focus indicators on all interactive elements
  • Scalable text (respects user font size preferences)
  • Color not the only indicator of state

Technical Architecture

Complete Component Architecture

src/components/objects/creation/
β”œβ”€β”€ SingleObjectMode/
β”‚   β”œβ”€β”€ CreateObjectModal.tsx          # Main desktop modal container
β”‚   β”œβ”€β”€ sections/
β”‚   β”‚   β”œβ”€β”€ TagIntegrationSection.tsx  # Tag scanning and management
β”‚   β”‚   β”œβ”€β”€ ImageUploadSection.tsx     # Image upload and preview grid
β”‚   β”‚   β”œβ”€β”€ ObjectDetailsForm.tsx      # Name, description, organization fields
β”‚   β”‚   β”œβ”€β”€ LocationSelector.tsx       # Hierarchical location picker
β”‚   β”‚   β”œβ”€β”€ ObjectClassSelector.tsx    # Dynamic class search/selection
β”‚   β”‚   β”œβ”€β”€ PropertiesSection.tsx      # Dynamic property fields based on class
β”‚   β”‚   └── CreateObjectActions.tsx    # Cancel/Submit/Set conversion buttons
β”‚   β”œβ”€β”€ SetCreationWorkflow.tsx        # "Create as Set?" decision and flow
β”‚   └── SetModeInterface.tsx           # Set child object creation interface
β”œβ”€β”€ BatchMode/
β”‚   β”œβ”€β”€ BatchCameraInterface.tsx       # Mobile camera-first interface
β”‚   β”œβ”€β”€ BatchSessionManager.tsx        # Session state and progress tracking
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ QuickTypeButtons.tsx       # Recent/popular type quick selection
β”‚   β”‚   β”œβ”€β”€ TypeSearchModal.tsx        # Global ObjectClass search modal
β”‚   β”‚   β”œβ”€β”€ BatchProgressIndicator.tsx # Progress bar and object count
β”‚   β”‚   β”œβ”€β”€ BatchObjectCard.tsx        # Individual object in batch queue
β”‚   β”‚   └── ProcessingQueue.tsx        # Unprocessed objects management
β”‚   └── BatchCompletionScreen.tsx      # Batch summary and next actions
β”œβ”€β”€ Shared/
β”‚   β”œβ”€β”€ TagScanner.tsx                 # QR/NFC scanning with camera
β”‚   β”œβ”€β”€ TagConflictResolver.tsx        # Handle tag assignment conflicts
β”‚   β”œβ”€β”€ NamingService.tsx              # Smart naming algorithms and suggestions
β”‚   β”œβ”€β”€ ObjectClassSearch.tsx          # Global class search with autocomplete
β”‚   β”œβ”€β”€ ImageProcessor.tsx             # Image compression, validation, upload
β”‚   β”œβ”€β”€ LocationPicker.tsx             # Spatial hierarchy navigation
β”‚   β”œβ”€β”€ OrganizationSelector.tsx       # Organization context selection
β”‚   └── ValidationHelper.tsx           # Form validation and error handling
β”œβ”€β”€ EntryPoints/
β”‚   β”œβ”€β”€ QuickActionsIntegration.tsx    # Dashboard quick actions integration
β”‚   β”œβ”€β”€ SpatialContextCreation.tsx     # Create objects within containers
β”‚   β”œβ”€β”€ ObjectsDashboardEntry.tsx      # Objects page creation entry
β”‚   └── MobileAppEntry.tsx             # Mobile app batch creation entry
└── Analytics/
    β”œβ”€β”€ CreationTracking.tsx           # User behavior analytics
    β”œβ”€β”€ UsageMetrics.tsx               # Object type usage tracking
    └── PerformanceMonitor.tsx         # Creation performance monitoring

Component Implementation Priority

Phase 1: Enhanced Single Object Creation

  1. ImageUploadSection.tsx - Multi-image upload with drag-drop
  2. TagIntegrationSection.tsx - QR/NFC scanning integration
  3. ObjectClassSelector.tsx - Dynamic class search replacing hardcoded dropdown
  4. SetCreationWorkflow.tsx - β€œCreate as Set?” decision point

Phase 2: Complete Single Object Features

  1. TagConflictResolver.tsx - Handle tag assignment conflicts
  2. LocationSelector.tsx - Enhanced spatial hierarchy picker
  3. PropertiesSection.tsx - Dynamic fields based on selected ObjectClass
  4. QuickActionsIntegration.tsx - Connect dashboard entry points

Phase 3: Mobile Batch Creation

  1. BatchCameraInterface.tsx - Mobile camera-first rapid creation
  2. BatchSessionManager.tsx - Session persistence and recovery
  3. QuickTypeButtons.tsx - Recent/popular type quick access
  4. ProcessingQueue.tsx - Unprocessed object refinement

Phase 4: Advanced Features

  1. SetModeInterface.tsx - Complete set creation workflow
  2. NamingService.tsx - AI-assisted smart naming
  3. Analytics/ - Usage tracking and performance monitoring

State Management

  • Single Object Mode: React Hook Form for form state
  • Batch Mode: Custom reducer for batch session management
  • Global State: Apollo Client for server data and real-time updates
  • Tag State: Separate state for scanned identifier data
  • File State: Queue for image files with background upload
  • Validation: Zod schema validation for both modes

Error Handling

  • Form validation: Real-time validation with clear error messages
  • Network recovery: Retry logic for failed uploads
  • Tag scanning errors: Invalid QR code handling
  • Offline scenarios: Queue operations for later sync
  • Batch session recovery: Resume interrupted batch sessions

GraphQL Integration

Mutations Required:

# Single object creation
mutation CreateObject($input: CreateObjectInput!) {
  createObject(input: $input) {
    id
    name
    shortCode
    organization { id name }
    images { id url isMain }
    tagData { instanceKey shortCode isManufacturerTag }
  }
}

# Batch object creation
mutation CreateObjectBatch($objects: [CreateObjectInput!]!) {
  createObjectBatch(objects: $objects) {
    success
    objects { id name shortCode }
    failed { index error }
  }
}

# Update unprocessed object
mutation UpdateObjectMetadata($id: ID!, $input: UpdateObjectInput!) {
  updateObject(id: $id, input: $input) {
    id
    name
    status
    objectClass { id name }
  }
}

Subscriptions for Real-time Updates:

subscription ObjectCreated($organizationId: ID!) {
  objectCreated(organizationId: $organizationId) {
    id
    name
    status
    createdAt
  }
}

Real-time Updates

  • Subscription: objectCreated to update dashboards across devices
  • Cache Updates: Apollo Client cache updates for immediate UI refresh
  • Optimistic UI: Show objects immediately in batch mode
  • Background Sync: Upload and create objects while continuing capture
  • Conflict Resolution: Handle duplicate names and tag assignments

Class System Integration

ObjectClass Handling:

  • Phase 1: ObjectClass: null (MVP implementation)
  • Phase 2: β€œGeneric” class for Plings tags, β€œUnknown” for untagged
  • Phase 3: Full manufacturer class support with path hierarchy
  • Future: AI-suggested class assignments

Global Type Database:

  • Search across all ObjectClass definitions
  • Hierarchical class relationships (Lamp β†’ Lighting β†’ Electronics)
  • Multi-language class name support
  • Manufacturer-specific vs generic classes

Type Search Implementation:

// Search ObjectClasses for user input
function searchObjectTypes(query) {
  return apolloClient.query({
    query: SEARCH_OBJECT_CLASSES,
    variables: { search: query, limit: 10 }
  }).then(result => {
    return result.data.objectClasses.map(cls => ({
      id: cls.id,
      name: cls.name,
      description: cls.description,
      manufacturer: cls.manufacturer,
      isGeneric: !cls.manufacturer
    }));
  });
}

Progressive Implementation Phases

Phase 1: MVP (User Input Driven)

Capabilities:

  • User manual classification of objects
  • Basic tag scanning with URL interception
  • Simple naming algorithm: [Organization] + [User Input] + [Identifier]
  • ObjectClass: null (temporary)

User Experience:

  1. System asks: β€œWhat is it?”
  2. User responds: β€œlamp”, β€œtool”, β€œI don’t know”
  3. For unclear responses: Change to β€œWhat shall we call it?”
  4. System suggests: β€œShall we call it β€˜Pauls lamp CuUY’?”
  5. User confirms or edits

AI Integration for Unclear Responses:

  • User: β€œtool I use for cutting”
  • System queries AI: β€œWhat is a tool used for cutting called?”
  • AI suggests: β€œknife”, β€œscissors”, β€œsaw”
  • System asks: β€œIs it a knife, scissors, or something else?”
  • Final naming: β€œPauls knife CuUY”

Phase 2: Class System Integration

Capabilities:

  • Create β€œGeneric” ObjectClass for Plings-issued tags
  • Create β€œUnknown” ObjectClass for untagged objects
  • Global ObjectClass database for type standardization
  • Improved duplicate detection within organization scope

User Experience:

  • Type search shows global ObjectClass hierarchy
  • Standardized object classification
  • Multi-language support preparation

Phase 3: AI Enhancement

Capabilities:

  • AI image classification for object type suggestion
  • Brand detection from images
  • Auto-categorization with user override
  • Duplicate object detection

User Experience:

  • β€œWe think this is a lamp. Shall we call it β€˜Pauls lamp CuUY’?”
  • AI-suggested improvements to object metadata

Phase 4: Full Producer Integration

Capabilities:

  • Complete manufacturer tag support
  • Path hierarchy parsing for brand extraction
  • Rich metadata from producer-issued tags
  • Anti-counterfeiting verification

User Experience:

  • β€œThis IKEA lamp will be called β€˜Pauls IKEA lamp CuUY’”
  • Automatic metadata population from manufacturer data

Question Evolution Workflow

Adaptive User Input System

Initial Question: β€œWhat is it?”

Response Handling:

User Response β†’ System Action:
- "lamp" β†’ Suggest "Pauls lamp CuUY"
- "a lamp" β†’ Suggest "Pauls lamp CuUY" 
- "desk lamp" β†’ Suggest "Pauls desk lamp CuUY"
- "I don't know" β†’ Change to "What shall we call it?"
- "tool I use for cutting" β†’ AI query + "What shall we call it?"

AI Integration Pattern:

  1. Detect unclear response: Pattern matching for β€œI don’t know”, β€œtool for…”, β€œthing that…”
  2. Query AI assistant: β€œWhat is [user description] called?”
  3. Present options: Show AI suggestions as multiple choice
  4. Fallback to manual: β€œWhat shall we call it?” if AI fails
  5. Learn from patterns: Improve recognition for future similar responses

Future Enhancements

Advanced Batch Features

  • Bulk property assignment across batch
  • Voice input for rapid object naming
  • Predictive type suggestions based on container context
  • Offline batch processing with delayed sync

Template System

  • Save object configurations as templates
  • Pre-fill forms from templates
  • Organization-specific templates
  • Container-based default templates

Enhanced AI Capabilities

  • Multi-object scene analysis (β€œI see 3 books and 2 lamps”)
  • OCR for text on objects (model numbers, brands)
  • Similarity detection for grouping related objects
  • Predictive organization suggestions

Success Metrics

User Experience

  • Modal completion rate > 80%
  • Time to complete creation < 2 minutes
  • Error rate < 5%
  • User satisfaction score > 4.0/5.0

Technical Performance

  • Modal load time < 500ms
  • Image upload success rate > 95%
  • Form submission success rate > 98%
  • Mobile responsiveness score > 90%

Business Impact

  • Daily object creation rate
  • User retention after first object creation
  • Objects with images percentage
  • Objects with location data percentage

Primary Documentation Navigation

Document Integration

This file provides FRONTEND/UX SPECIFICATIONS for object creation features. For current development status, check the API Requirements & Coordination tracking table.

Role in Coordination Workflow:

  • Created when β€œFrontend Ready” status is set in coordination tracking
  • Used by frontend developers for component implementation
  • Referenced by backend teams to understand UI requirements and constraints
  • Integrated with backend technical specifications for complete feature definition

Frontend Team Responsibilities:

  • Use this document for UI/UX implementation details
  • Update when design specifications change
  • Link to backend APIs when integration points are defined
  • Update coordination table when components are ready for integration

Backend Team Usage:

  • Reference for understanding frontend requirements and constraints
  • Use for API design to ensure frontend compatibility
  • See Object Creation Backend Requirements for technical specifications

Project Management:

  • Track frontend readiness in API Requirements coordination table
  • Monitor frontend-backend integration progress
  • Coordinate between teams using centralized tracking

Frontend Requirements Last Updated: MΓ₯n 7 Jul 2025 10:35:15 CEST - Updated image upload system status from missing to fully implemented with all features working