Skip to content

PRD: Device registration, management & peripherals

ModuleDevice (CORE-04)PRD IDPRD-DEV-001
StatusIn-progressOwnerDevice squad
Date2026-05-19Versionv0.1
Packages@nx/commerce · @nx/signal · apps/client · sale-renderer · sale-mainURDDEV · MON · PRN · SCN · SBX · NFC

TL;DR

Gives an organization a single place to register, manage, and monitor the hardware that runs KICKO - POS terminals, mobile and web apps, and their peripherals. Every device gets a stable identity (x-device-info header, auto-registered on first login), an optional merchant assignment, a controlled status lifecycle, and a searchable back-office fleet view; printers, scanners, SoundBox, SoftPOS, and a 5-minute heartbeat hang off that record. The result: owners can see and control their whole fleet, and the runtime always knows which device a session belongs to.

1. Context & Problem

Merchants run KICKO on a mix of POS terminals, mobile apps, and web clients, each with attached peripherals (printers, scanners, SoundBox). A Device entity and its D_YYYYMMDD_<snowflakeId> identifier exist in the commerce model, but owners have no back-office surface to manage their fleet, and the runtime does not consistently produce or reference a device record. Without this, an owner cannot list or audit their hardware, a session cannot be reliably tied to a physical device, and there is no controlled lifecycle between "registered" and "retired".

This increment closes the gap on two fronts: a full back-office device page for managing the fleet, and runtime device identity (the x-device-info header plus auto-registration on login) so every session resolves to a device record. The peripheral and health concerns build on this device record rather than standing alone.

2. Goals & Non-Goals

Goals

  • A back-office device page (list, create, edit) with a sectioned form: general information, hardware config, software config, and other settings.
  • Runtime device identity via the x-device-info header; a device record is auto-registered and activated on first app login, and reused for existing devices.
  • Optional merchant assignment on a device - a device hangs off the organization with an optional assignment to one merchant.
  • Device discoverability through the search stack (Typesense device collection with description-field search).
  • A controlled status lifecycle (NEW → ACTIVATED → DEACTIVATED → SUSPENDED → ARCHIVED) with soft-delete and per-organization code uniqueness.
  • The peripheral & health stack built on the device record: printer (ESC/POS), barcode scanner, SoundBox, and a heartbeat-driven health view with remote deactivation.

Non-Goals

  • VNPAY Terminal backend API wiring (table exists; backend not connected - QE finding).
  • Label printer integration and Windows POS terminal support.
  • SoftPOS / NFC contactless acceptance - Planned (P3).
  • Cash drawer control and an advanced peripheral driver-management UI.
  • Kitchen display, waiter/service, and delivery apps.

3. Success Metrics

MetricTarget / signal
Identity coverage100% of app sessions resolve to a device record via x-device-info (no orphan sessions)
Auto-registrationFirst login on a new device creates exactly one device record; subsequent logins reuse it
Fleet visibilityOwners can list, search, and edit every registered device from the back office
Health accuracyOnline/offline status matches the 5-min heartbeat / 15-min offline threshold
Peripheral reliabilityPrint/scan/SoundBox failures surface a clear error; payment never blocked by a disconnected SoundBox

4. Personas & Use Cases

PersonaGoal
OwnerRegister, manage, and monitor the device fleet; assign devices to merchants; remotely deactivate a compromised device
ManagerView devices and health, configure peripherals within scope
CashierOperate the POS on an activated device; pair and use printer / scanner / SoundBox

Core scenarios: an owner registers a device (or it auto-registers on first login) → assigns it to a merchant and activates it → the runtime carries device identity in x-device-info → peripherals pair to the device → the owner monitors health via heartbeat and can remotely deactivate.

5. User Stories

  • As an owner, I want a back-office page to list, create, and edit my devices, so that I can manage my whole fleet in one place.
  • As an owner, I want a device to auto-register and activate on first app login, so that staff don't have to register hardware manually.
  • As an owner, I want to assign a device to a merchant (optionally), so that I can scope a device to a business unit.
  • As an owner, I want to search devices by name, identifier, code, status, and type, so that I can find a specific unit quickly.
  • As an owner, I want each device to carry a stable identity in the x-device-info header, so that every session is tied to a known device.
  • As a cashier, I want printer, scanner, and SoundBox to pair to my device, so that I can print receipts, scan products, and hear payment confirmations.
  • As an administrator, I want to see device health and remotely deactivate a compromised device, so that I can protect the fleet.

6. Functional Requirements

#RequirementURD ref
FR-1Register a device with i18n name, type, and organization; auto-generate the D_YYYYMMDD_<snowflakeId> identifierURD-DEV-001..003
FR-2Status lifecycle NEW → ACTIVATED → DEACTIVATED → SUSPENDED → ARCHIVED; only valid transitions; soft-deleteURD-DEV-004..009
FR-3Device code, when provided, is unique within the organizationURD-DEV-011
FR-4A device is auto-registered and activated on first app login; existing devices are reusedURD-DEV-013
FR-5Search devices by name, identifier, code, status, and type (Typesense collection)URD-DEV-014
FR-6Assign / unassign a device to a merchant; assignment is optionalURD-DEV-016
FR-7Record hardware and software information per deviceURD-DEV-017..018
FR-8Device identity carried in the x-device-info header on API callsURD-MON-001
FR-9Heartbeat every 5 min; offline after 15 min; health view (online/offline, last seen, app version); remote deactivationURD-MON-001..005
FR-10Printer (ESC/POS), barcode scanner, and SoundBox pair to a device and surface clear errors on failureURD-PRN · URD-SCN · URD-SBX
FR-11SoftPOS / NFC contactless acceptance on Android via VNPAY KYC (Planned)URD-NFC-001..004

Full requirement text and acceptance criteria live in the Device URD. This PRD references them rather than restating them.

7. Non-Functional Requirements

AreaRequirement
Data integrityA device hangs off the organization with an optional merchant assignment; identifiers are immutable; records use soft-delete
IdentityEvery API call carries device identity in x-device-info; one active session per device
Tenancy & authzOperations scoped per organization (and merchant where assigned); API access requires authentication (JWT or Basic Auth)
Performance / scaleDevice search is index-backed (Typesense); heartbeat cadence (5 min) bounds write load
ResilienceA disconnected SoundBox never blocks payment; print/scan failures surface, never silently drop
i18nDevice name and user-facing labels are bilingual ({ en, vi }); ESC/POS prints Vietnamese via code page 28

8. UX & Flows

Key screens: the back-office device page in apps/client - list/table, create, edit, and a sectioned form (general, hardware config, software config, other settings), under the authenticated root navigation. POS peripheral flows (scanning, printing, SoundBox, SoftPOS) live in sale-renderer with the Tauri native layer in sale-main.

9. Data & Domain

EntityRole
DeviceThe device record - i18n name, type, status, identifier, organization, optional merchant relation, hardware/software info
Hardware infoManufacturer, model, serial, IMEI, MAC, processor, RAM, storage, screen, battery
Software infoOS, OS version, app version, firmware, last update, peripheral drivers
Device sessionAn active session linked to a device, opened on login
Device search collectionTypesense collection indexing devices (incl. description fields)

Conceptual only - full schema and invariants in the commerce domain model.

10. Dependencies & Assumptions

Depends on

  • Commerce (@nx/commerce) - owns the Device entity, organization ownership, optional merchant assignment, hardware/software info, and the status lifecycle.
  • Signal (@nx/signal) - real-time edge for device/payment events and the device search collection.
  • Client apps - apps/client (back-office management), sale-renderer (POS UI), sale-main (Tauri native USB/NFC/printer/scanner plugins).

Assumptions

  • The organization exists; a merchant exists when assignment is used.
  • The app sends a stable machine UID in the x-device-info header.
  • Certified hardware (VNPAY V-POS, Sunmi T2) is available for POS-terminal scenarios.

11. Risks & Open Questions

Risk / questionMitigation / status
Duplicate device records if x-device-info is unstable across loginsAuto-register reuses an existing record by machine UID; identifier is immutable
VNPAY Terminal backend not wired (table exists)Out of scope - flagged QE finding; tracked for a later increment
SoftPOS / NFC depends on VNPAY KYC and Android hardwarePlanned (P3); option hidden on iOS, blocked when NFC unavailable
Heartbeat write load at fleet scaleBounded by 5-min cadence; revisit cadence if load grows
Remote wipe when a device is offlineQueued and applied on next reconnect

12. Release Plan & Launch Criteria

AspectPlan
PhaseDEV / POS / PRN / SCN / MON = P2 (In-progress); MOB / WEB / SBX = P1 (Built); NFC = P3 (Planned) - see URD feature catalog
RolloutAll organizations; no feature flag
MigrationModel cleanup - organizerId removed, merchant relation added, unique index corrected; no data backfill required
Launch criteriaBack-office list/create/edit verified; first-login auto-registration verified; x-device-info identity resolves on every session; device search returns expected results
MonitoringAuto-registration rate, orphan-session count, heartbeat online/offline accuracy, peripheral error rate

13. FAQ

Do I have to register every device manually? No - a device auto-registers and activates on first app login, and existing devices are reused. The back-office page is for managing and editing the fleet.

Does a device belong to a merchant or an organization? It belongs to the organization, with an optional assignment to one merchant. There is no organizerId column on the model.

What identifies a device at runtime? The x-device-info header (a machine UID), which replaced the old deviceId field.

Will a disconnected SoundBox block a payment? No - if the SoundBox is disconnected, the payment still succeeds; the announcement is silently skipped.

Is SoftPOS available now? No - SoftPOS / NFC is Planned (P3), Android-only, and requires VNPAY KYC.

References

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.