Flow: Item–ESL Linking¶
Trigger: Store worker scans an ESL barcode and associates it with a retail item in the Plaza Mobile app Key services: link-registry, studio-link-evaluator, studio-renderer, eslimage-merger, pricer-server Key DTOs: storeesl, link.v2, studiolink, storeitemvalues, studioeslimage, ecceslimage, eslimage
This is the core end-to-end pipeline of the system. When a store worker physically walks the store with the Plaza Mobile app and scans an ESL barcode then selects an item, the entire chain from association to pixel-on-glass is set in motion. link-registry records the pairing, studio-link-evaluator resolves which design should be shown (evaluating CEL rules against live item data and any configured scenario overrides), studio-renderer produces a rendered PNG, eslimage-merger selects the authoritative image from potentially multiple renderer outputs, and pricer-server (the on-premise gateway) consumes the final eslimage directly from CQS and transmits it to the physical ESL over the in-store RF/IR network. The flow is fully reactive: each service subscribes to CQS notifications for the DTOs it depends on, so there is no orchestrator and no polling. Idempotency is achieved because every service writes its output DTO only when the computed result actually differs from the current stored state — a duplicate notification does not re-trigger downstream work.
Steps¶
-
Store worker → Plaza Mobile app: The store worker opens Plaza Mobile, points the camera at an ESL, and scans its barcode. They then search for or scan the product they want to associate with that ESL and confirm the pairing.
-
Plaza Mobile → link-registry: Plaza Mobile calls the
link-registryAPI with the ESL barcode and item identifier.link-registryvalidates both identifiers, resolves the store context (tenant ID, store ID), and determines the applicable rendering system (Studio or ECC) based on tenant configuration. -
link-registry → DTOflow (storeesl + link.v2):
link-registrywrites two DTOs atomically. First it creates or updates thestoreeslDTO (id:t/{tenantid}/s/{storeid}/esls/{barcode}) recording the ESL hardware type, department, and tenant/store scope. Second it writes thelink.v2DTO (id:t/{tenantid}/s/{storeid}/links/{linkid}) with the StudioSinglevariant containing the item reference and an optionalforced_design_id. Theby_storeeslalias onlink.v2(att/{tenantid}/s/{storeid}/esls/{barcode}/link) enables per-barcode subscriptions. -
DTOflow (CQS) → studio-link-evaluator: CQS emits a change notification on
link.v2.studio-link-evaluatorsubscribes tolink.v2changes. It fetches the updatedlink.v2, the relevantcommunicationpack(containing scenario override rules expressed in CEL), and the currentstoreitemvaluesfor the linked item. It evaluates the CEL expression to determine the winning design: ifforced_design_idis set that design wins unconditionally; otherwise the scenario rules may select a design based on item attributes (e.g. promotional flag → promotional design). -
studio-link-evaluator → DTOflow (studiolink):
studio-link-evaluatorwrites astudiolinkDTO (id suffix/studio) capturing the resolvedforced_design_id, item reference, barcode, and render context. Theby_storeesl,by_item,by_design, andby_canvasdesignaliases enable downstream services to subscribe efficiently. If the evaluation result is identical to the currentstudiolink, no write is performed and the pipeline stops here. -
DTOflow (CQS) → studio-renderer: CQS emits a change notification on
studiolink.studio-rendererfetches thestudiolink, the resolveddesignDTO, and thestoreitemvaluesfor the item. It instantiates every bound property field with the item's live data. -
studio-renderer → dtoflow-lfs + DTOflow (studioeslimage):
studio-rendererrenders the design layout with live item data into a PNG at the ESL's native resolution and rotation. It uploads the PNG to dtoflow-lfs (receiving afile_path) and writes astudioeslimageDTO (id patht/{tenantid}/s/{storeid}/esls/{barcode}/pages/{pagenum}/studioimage). If an ECC renderer also has output for this ESL (ecceslimage), both images coexist briefly until the merger resolves them. -
DTOflow (CQS) → eslimage-merger: CQS notifies
eslimage-mergerof the newstudioeslimage. The merger fetches bothstudioeslimageandecceslimage(if any) for this barcode+page. Merge priority: Studio output wins if present; ECC output is used as fallback; if neither exists theeslimageDTO is deleted. The merger writes theeslimageDTO (id suffix/image) pointing to the winningfile_pathand recording the source kind (studioorecc). -
DTOflow (CQS) → pricer-server: CQS notifies
pricer-serverof the new or updatedeslimage.pricer-serverfetches theeslimageto get thefile_pathandrotation, fetches thestoreeslDTO to resolve the ESL's hardware type, and reads theesldriverto determine display rotation. -
pricer-server → ESL hardware:
pricer-serverdownloads the PNG from dtoflow-lfs, applies the combined rotation (esldriver.rendering.displayRotation+eslimage.rotation), and pushes it over the in-store RF/IR network to the physical ESL. The ESL renders the image on its e-ink display and acknowledges receipt.pricer-serverrecords the acknowledgment in its internal state DB and PUTsstoreeslstatuswith stateOK.
Sequence diagram¶
sequenceDiagram
participant W as Store Worker
participant App as Plaza Mobile
participant LR as link-registry
participant DTOflow
participant SLE as studio-link-evaluator
participant SR as studio-renderer
participant Merger as eslimage-merger
participant PS as pricer-server
participant ESL as Physical ESL
W->>App: Scan ESL barcode + select item
App->>LR: Link ESL barcode to item
LR->>DTOflow: Write storeesl DTO
LR->>DTOflow: Write link.v2 DTO (Studio/Single)
DTOflow-->>SLE: CQS: link.v2 changed
SLE->>DTOflow: Fetch link.v2, communicationpack, storeitemvalues
Note over SLE: Evaluate CEL → resolve winning design
SLE->>DTOflow: Write studiolink DTO
DTOflow-->>SR: CQS: studiolink changed
SR->>DTOflow: Fetch studiolink, design, storeitemvalues
SR->>DTOflow: Upload PNG → dtoflow-lfs
SR->>DTOflow: Write studioeslimage DTO
DTOflow-->>Merger: CQS: studioeslimage changed
Merger->>DTOflow: Fetch studioeslimage + ecceslimage (if any)
Note over Merger: Studio wins; write merged result
Merger->>DTOflow: Write eslimage DTO
DTOflow-->>PS: CQS: eslimage changed
PS->>DTOflow: Fetch eslimage, storeesl, esldriver
PS->>ESL: Push PNG over RF/IR (rotation applied)
ESL-->>PS: Acknowledge image received
PS->>DTOflow: Write storeeslstatus → OK
Key DTOs involved¶
| DTO | Role in this flow | Page |
|---|---|---|
storeesl.v1 |
ESL identity record; binds barcode to hardware type and store; consumed by pricer-server for hardware routing | storeesl.v1 |
link.v2 |
Primary association between item and ESL; top-level Studio/ECC split; drives the whole pipeline | link.v2 |
communicationpack.v1 |
Contains tenant-level CEL scenario rules that studio-link-evaluator uses to select the winning design | communicationpack.v1 |
storeitemvalues.v1 |
Live key-value item data (price, name, flags) fetched during evaluation and rendering | storeitemvalues.v1 |
studiolink.v1 |
Evaluated render instruction: resolved design + item + barcode; triggers studio-renderer | studiolink.v1 |
design.v1 |
Published immutable label layout fetched by studio-renderer | design.v1 |
studioeslimage.v1 |
Studio renderer output (PNG path + rotation); input to eslimage-merger | studioeslimage.v1 |
ecceslimage.v1 |
ECC renderer output (PNG path + rotation); fallback input to eslimage-merger | ecceslimage.v1 |
eslimage.v1 |
Merged authoritative page image; consumed by pricer-server | eslimage.v1 |
storeeslstatus.v1 |
pricer-server-owned lifecycle status; transitions to OK on successful image acknowledgment | storeeslstatus.v1 |
Related flows¶
- Design Publication — a design change triggers re-evaluation starting at step 4 of this flow
- Item Update — an item data change triggers re-evaluation starting at step 4 of this flow, with an early-exit if evaluation is unchanged
- ESL Hardware Lifecycle — the
storeeslDTO created in step 3 is the anchor for the ESL's entire hardware lifecycle