link-registry¶
Cloud Run / CQS queue name: link-registry
Legacy name: link-service (deprecated)
Tech stack: Quarkus (Java 21, GraalVM native build), Gradle, Cloud Spanner, Liquibase
link-registry is the source of record for ESL assignment and link data on the platform. It owns three tightly related DTO types: storeesl, which represents the physical ESL-to-store assignment (which barcode lives in which store and of which ESL type); link.v2, which captures the three-way mapping between a store item, an ESL barcode, and a design source; and store, which provides the identity and metadata for each store known to the platform. It does not own storeeslstatus — that DTO is owned and written by pricer-server. link-registry consumes storeeslstatus to react to terminal lifecycle states and drive cleanup.
DTO Ownership¶
| DTO | Version | Why this service owns it |
|---|---|---|
storeesl |
v1 | ESL physical assignment: barcode, store ID, ESL type reference, link department. Created when an ESL is assigned to a store; deleted when unassigned or on terminal lifecycle state. |
link |
v2 (v1 deprecated) | Item↔ESL↔design mapping. link.v2 introduces explicit variant typing (Single, EccSingle, MultiItem, FloatingCanvas) and removes the ambiguous eccmodel_id from the Single variant. See ADR-003. |
store |
v1 | Store identity and metadata: id, external_id, is_reference_store. ID pattern t/{tenantid}/s/{storeid}. |
CQS Subscriptions¶
| DTO | Version | What the service does on change |
|---|---|---|
storeeslstatus |
v1 | Watch for terminal lifecycle states (LOST, OFFBOARDED). On a terminal state, delete the corresponding storeesl — which in turn signals pricer-server to delete the storeeslstatus DTO (see deletion cascade below). |
Note (CQS config): In the
poc-changequeue-serviceapplication.yml, alink-registryqueue also appears as a subscriber tolink.v1. That is a transitional configuration used during the v1→v2 migration to allow the service to self-consume its own legacy DTO for backfill purposes. It is not a permanent subscription pattern.
Processing Logic¶
Inbound (REST):
- Store operator actions (assigning/unassigning an ESL to a store) arrive via the REST API, are validated, persisted to Cloud Spanner, and published as
storeesl.v1andlink.v2DTOs.
Deletion cascade (storeeslstatus → storeesl → storeeslstatus):
storeeslstatus is written by pricer-server (ADR-006, [project-owner-equals-writer]). When pricer-server transitions an ESL to a terminal state — LOST (30-day unreachable timeout, firmware auto-reset) or OFFBOARDED (successful operator-initiated offboard) — link-registry reacts via CQS:
- pricer-server PUTs
storeeslstatuswithstate = LOSTorOFFBOARDED. link-registryreceives the CQS notification, reads the status, sees a terminal state, and deletes the correspondingstoreeslrecord. Anylink.v2records pointing at that barcode are also cleaned up by the same path.- pricer-server observes the
storeesldeletion via DTOflow and deletes its ownstoreeslstatusDTO — closing the cascade. (See pricer-server.md for the writer-side rule.)
This split avoids any shared-ownership of storeeslstatus: pricer-server is the sole writer; link-registry only reads and triggers cleanup of the related storeesl it owns.
v1 → v2 migration (ADR-003): link.v1 is fully deprecated. link.v2 adds explicit variant typing so downstream evaluators and renderers can route unambiguously without inspecting internal fields. During the migration window both versions are published; downstream services should migrate to link.v2. link.v1 will be retired once all consumers are migrated.
Alias patterns: The link DTO exposes a by_storeesl alias (t/{tenantid}/s/{storeid}/esls/{barcode}/link) that allows services to subscribe to link changes for a specific ESL barcode. studio-link-evaluator and the renderers use this alias to scope their consumption.
Database: Cloud Spanner provides the relational store. Liquibase migrations are executed in the deployment pipeline before each environment deploy — not at application startup.
Related services¶
- pricer-server — writes
storeeslstatusthat drives the deletion cascade above; readsstoreeslandeslimagedirectly from CQS to deliver images to hardware - studio-link-evaluator — subscribes to
link.v2to trigger CEL evaluation per ESL - studio-renderer — subscribes to
storeesl.v1to react to ESL assignment changes - ecclink-projector — subscribes to
link.v2to project ECC-specific link data