Use Case: Mobile Rapid Object Capture
Use Case: Mobile Rapid Object Capture
Created: Mon 07 Jul 2025 12:12:17 CEST
Updated: Thu 11 Jun 2026 22:13:27 CEST - Full rewrite: documented implemented MVP single-object rapid capture flow, write-behind queue semantics, and prefetch cache; moved unimplemented batch session ideas to Future section
Document Version: 2.0 - Implemented rapid capture flow
Security Classification: Internal Technical Documentation
Target Audience: iOS Developers, Frontend Developers, Backend Developers
Author: Paul Wisén
Overview
This document describes the mobile-optimized rapid object capture workflow in the Plings native iOS app. The implemented MVP flow is single-object rapid capture: scan an unknown tag, photograph the object, optionally name it, place it spatially, and return to the scanner — all in under one second of perceived wait time. The write-behind queue is what makes >10 objects per minute achievable: the next capture begins before the previous object has finished uploading.
User Story
As a mobile user, I want to quickly photograph and register objects in succession so that I can digitize my physical inventory without form-filling or waiting for each upload to complete.
Actors
- Mobile User: Person using the native iOS app for object capture
- System: Plings-iOS app + GraphQL API (api.plings.io)
- Container: Spatial context (shelf, room, box) where objects are being captured
Preconditions
- User is authenticated and has organization context
- Camera and NFC permissions are granted
- At least one Plings tag is available to scan
- Network connectivity (online capture; offline queue support planned — see Future section)
Implemented Flow: Single-Object Rapid Capture
1. Scan Unknown Tag
The scanner is the home screen. When the user scans a tag that resolves to UNKNOWN_SPECIFIC or UNKNOWN_GENERAL, the create flow opens immediately with the tag pre-assigned. No separate “enter tag ID” step exists.
2. Camera Opens Immediately
After an unknown tag scan, the camera launches without any intermediate screen. The user photographs the object. This is the only mandatory capture; a name and spatial context can be added in the next step but are not required to proceed.
3. Optional Name + Server Auto-Name
The user can type a name or leave the field empty. If left empty, the server generates a name on createObject using the pattern:
[Organisation name] [Object class name] [Tag short code]
For example: Grön Teknik Cykel 4K7mX9. The auto-name is visible immediately once the object syncs.
4. Spatial Placement
The last-used container is pre-suggested and pre-selected so that repeated captures into the same space require zero interaction for placement. The user can:
- Accept the suggestion — tap Save, placement is set.
- Scan a container tag — tap “Scan container”, scan any tag that belongs to a container object; the container is resolved and pre-filled.
- Pick from list — browse
potentialContainersresults for nearby or recently used containers. - Drag to place — the drag-to-place relationship picker lets the user choose the spatial relationship type (IN is preselected as the fast path; ON / LEFT_OF / RIGHT_OF / ABOVE / UNDER / NEXT_TO zones; ATTACHED_TO chip).
createObject is called with spatialParentId + spatialRelationshipType included in the same mutation. No separate spatial assignment step is needed for the common case.
5. Save Enqueues — Scanner Returns in <1 s
Tapping Save:
- Enqueues a
createObjectjob in the write-behind queue (persisted to disk immediately). - Enqueues an
uploadObjectImagesjob (depends on thecreateObjectjob completing first — see queue semantics below). - Returns the user to the scanner screen. The object appears in the “pending” state in any object list.
The user can scan the next tag while the previous object is still uploading.
Write-Behind Queue
The queue is the architectural feature that enables rapid successive capture. Its semantics:
| Property | Behaviour |
|---|---|
| Storage | Disk-persisted (survives app restart and crashes) |
| Order | FIFO — jobs execute in the order they were enqueued |
| Dependency | uploadObjectImages is always enqueued after createObject for the same object. The executor does not start an image upload until the corresponding createObject has completed and returned an objectId. All object_images rows require an existing object. |
| Retry | Exponential back-off on network/server errors. Transient failures are retried automatically. |
| Terminal failure | Jobs that exhaust retries (e.g., API returns a permanent error) are moved to the needs-attention list — a visible section in the app’s inbox/notification area. The user sees which objects need attention and can retry or discard manually. |
| Concurrency | The processor drains the queue sequentially (one job at a time) to avoid overwhelming the API and to preserve dependency order. |
Read Cache with Neighbor Prefetch
When the user views an object, the cache preemptively fetches:
- The object’s container (spatial parent) and its sibling objects (
getSpatialChildrenof the parent). - Low-resolution images of those siblings.
This means that navigating into a container after viewing one of its objects is typically instant. The cache is in-memory + disk-backed and has a configurable TTL. Stale cache entries are refreshed in the background when the user navigates to them (the known-tag fast path described in Tag Scanning Integration).
GraphQL Operations Used
| Operation | When called | Notes |
|---|---|---|
resolveIdentifier |
On every tag scan | Mutation — see tag-scanning-integration.md |
createObject |
Dequeued from write queue | Includes tagInstanceKey, tagData, spatialParentId, spatialRelationshipType, autoGenerateName |
uploadObjectImages |
Dequeued after createObject completes | GraphQL multipart; requires objectId |
potentialContainers |
Container picker | Returns nearby / recently used containers |
getSpatialChildren |
Prefetch on object view | Populates cache for sibling navigation |
getObjectDetailsComplete |
Object detail view | Full object data |
myOrganizations |
Session bootstrap | Needed for auto-name context |
createObjectWithTagdoes not exist in the API. Tag data is passed as fields onCreateObjectInput(tagInstanceKey+tagData).
User Experience Targets
- >10 objects/minute: achieved by returning to the scanner in <1 s and queuing uploads async.
- Minimal interaction per object: camera auto-focuses, server auto-names, last container pre-suggested.
- No data loss on crash: disk-persistent queue ensures in-flight jobs survive app restart.
- Clear error visibility: terminal failures surface in needs-attention list, not silently dropped.
Related Documentation
- Tag Scanning Integration — scan-first entry point and resolveIdentifier mutation
- Create Object Use Case — web creation flow
- System Overview — write-behind queue + prefetch cache in native client architecture
Future: Batch Sessions
The items below are not implemented. No session API exists. They are preserved here as design intent for when batch workflows are built.
Batch Session Concept
A batch session would group multiple object captures under a shared session ID, enabling:
- Progress tracking across captures (e.g., “12 of ~30 items scanned”)
- Session recovery after interruption: if the app is force-closed mid-session, a “Resume session” banner appears on relaunch showing pending captures
- Batch summary screen: review all created objects, rename, adjust placement, or discard before finalising
- Bulk spatial assignment: set container once for the whole session
Bulk Operations (Future API)
# Not implemented — proposed
mutation CreateObjectsBatch($inputs: [CreateObjectInput!]!) {
createObjectsBatch(inputs: $inputs) {
created { id, name }
failed { input, error }
}
}
Offline Mode (Future)
Full offline capture (scan + photo without any network) would store jobs locally and sync when connectivity is restored. The current write-behind queue already handles intermittent connectivity; full offline support requires pre-loading organization context and class data before going offline.
AI-Assisted Naming (Future)
On-device vision model suggests an object name from the photo before the user confirms. The suggestion is editable and the server auto-name remains as fallback.