Inventory software becomes unreliable when it treats every reader event as a completed business transaction. RFID readers may report the same tag many times per second. Barcodes may be scanned twice. Devices lose connectivity. Product identifiers are sometimes incomplete or reused. The architecture needs to convert noisy physical observations into deliberate, auditable actions.
1. Separate the system into layers
A practical application has a device adapter, scan-processing service, workflow rules, local persistence, synchronization, and user interface. The device adapter translates vendor SDK callbacks into a small internal event. It should not decide whether inventory moves from one location to another.
The processing service normalizes identifiers, applies a short duplicate window, and sends accepted observations to the active workflow. Workflow rules validate item, location, user, quantity, and operation. Only then does the system create a durable transaction.
2. Define identifier rules explicitly
Decide what an EPC, barcode, serial number, SKU, asset tag, and location label mean in the data model. Do not assume the scanned value is always the primary database key. A lookup layer can map an external identifier to the internal item or asset while preserving the original value for audit and troubleshooting.
Normalization must match the identifier standard. Trimming whitespace may be safe for a typed barcode, while changing case or removing leading zeros can corrupt a valid code. Store the raw read when it has diagnostic value and the normalized identifier used for matching.
3. Handle duplicates at the correct level
RFID duplicate filtering is usually time based and device-session specific. A tag observed repeatedly within a short window may become one accepted scan. That does not mean the same tag can never be processed again; a later inventory cycle or a deliberate rescan may be valid.
Business-level idempotency is separate. Give each committed operation a stable identifier. If synchronization retries the same transaction, the server should recognize it instead of applying the movement twice.
4. Make offline operation a first-class state
Handheld applications should write accepted operations to local SQLite before reporting success to the user. A queue records the transaction identifier, payload, creation time, device, user, and sync state. The interface can show pending and failed counts so offline work remains visible.
Synchronization sends a bounded batch and marks acknowledgements transactionally. Network failure should leave unacknowledged rows pending. A permanent validation rejection should record the server response and require resolution rather than retrying forever.
5. Design feedback for a noisy environment
Warehouse users cannot study a subtle toast message after every scan. Use distinct audio, vibration, color, and concise text for accepted, duplicate, rejected, and offline-queued states. The latest accepted item and running count should remain visible. Error recovery needs a direct action: rescan the location, choose a reason, or review the exception queue.
6. Preserve an audit trail
An audit record should answer who, what, when, where, on which device, under which workflow, and with which external identifier. Corrections should create compensating records or documented adjustments rather than silently rewriting history. This is essential when inventory counts affect purchasing, compliance, or customer orders.
7. Secure devices and data
Use authenticated APIs, short-lived credentials where practical, encrypted transport, and least-privilege device accounts. Do not embed permanent database passwords in a mobile application. Protect local data according to its sensitivity and provide a way to revoke or retire a lost device.
Architecture checklist
- Vendor SDK behavior is isolated behind a device adapter.
- Identifier normalization rules are documented and tested.
- Reader duplicate filtering and business idempotency are separate.
- Accepted work is stored locally before success feedback.
- Synchronization can retry without applying a transaction twice.
- Users can see pending, failed, and rejected operations.
- Every committed change has a useful audit trail.
The best scanning system does not merely read quickly. It gives users confidence that every accepted scan produced exactly one correct, recoverable business action.