@onlineapps/mq-client-core 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,39 @@ All notable changes to this package. Follows [Keep a Changelog](https://keepacha
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [3.2.0] — 2026-09-15
8
+
9
+ ### Added — dead-letter cesty pro rodiny `monitoring.*` a `telemetry.*` (d.475)
10
+
11
+ Sedm front, které konzumenti monitoringu čtou — `monitoring.workflow`,
12
+ `monitoring.services`, `monitoring.audit`,
13
+ `monitoring.infrastructure.health.events`, `telemetry.logs.queue`,
14
+ `telemetry.metrics.queue`, `telemetry.traces.queue` — dostalo
15
+ `x-dead-letter-exchange: ''` a `x-dead-letter-routing-key: '<prefix>.dlq'`, a obě
16
+ rodiny svou koncovou frontu: `monitoring.dlq` a `telemetry.dlq`, deklarované
17
+ stejným tvarem jako `workflow.dlq` a `delivery.dlq` (durable, `x-max-length`
18
+ 50000, žádné TTL, žádná další cesta). TTL ani strop žádné existující fronty se
19
+ nemění.
20
+
21
+ Je to mechanické pravidlo konfirmace `mq-consumer-contract` 003 bod 1 použité
22
+ podruhé, přesně jak bod 3 předepsal („`monitoring.*`, `telemetry.*` … dostanou
23
+ `<prefix>.dlq`, až jejich konzumenti přejdou na politiku knihovny") — nová
24
+ konfirmace k tomu nepatří. Do té doby brána d.259 ty konzumenty vůbec nepustila:
25
+ `consume()` odmítá frontu, jejíž deklarace neříká, kam s odmítnutou zprávou.
26
+
27
+ Ostatní rodiny téže věty — `registry.*`, `validation.*`, `infrastructure.*` —
28
+ cestu **nedostávají**: jejich konzumenti pořád potvrzují na vlastních surových
29
+ kanálech (`infra/api_services_registry/src/listeners/registry.listener.js`,
30
+ `infra/api_services_{registry,validator}/src/services/mqManager.js` — DL-007),
31
+ a `.dlq`, do které nikdo nezapisuje, je fronta bez pisatele.
32
+
33
+ Fronty zakládá `initInfrastructureQueues()` z deklarace samotné (prochází
34
+ `infrastructurePrefixes()` a klíče sekcí), takže obě nové vzniknou při nejbližším
35
+ bootu jejího jediného volajícího, `infra/api_gateway`. Běžící `monitoring.*`
36
+ a `telemetry.*` fronty nesou staré argumenty, takže je podle konfirmace 003 bodu
37
+ 4 čeká smazání a znovuzaložení ve vlně; do té doby je `assertQueue` nad nimi
38
+ s novou deklarací 406.
39
+
7
40
  ## [3.1.0] — 2026-09-15
8
41
 
9
42
  ### Added — `topology` nese i tři telemetrické fronty (d.461)
package/README.md CHANGED
@@ -218,7 +218,8 @@ carries `{ queue, messageCount, consumerCount }` and no arguments (measured, 202
218
218
 
219
219
  **A TERMINAL queue is consumed, and it is not an exception to that rule but its other
220
220
  half.** A queue something else dead-letters TO — `<service>.dlq`, `workflow.failed`,
221
- `workflow.dlq`, `delivery.dlq` — declares no onward route because the topology says it
221
+ `workflow.dlq`, `delivery.dlq`, `monitoring.dlq`, `telemetry.dlq` — declares no onward
222
+ route because the topology says it
222
223
  must not have one: a dead-letter route on a dead-letter queue closes a loop or starts a
223
224
  chain with no end (`api/docs/governance/confirmations/mq-consumer-contract.md` 002
224
225
  point 2, 003 point 2). So the gate asks a second question, `queueConfig.isDeadLetterTarget(queue)`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/mq-client-core",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "oa": {
6
6
  "category": "connector"
@@ -23,7 +23,7 @@
23
23
  "author": "OnlineApps",
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@onlineapps/logger-contract": "1.3.0",
26
+ "@onlineapps/logger-contract": "2.0.0",
27
27
  "@onlineapps/runtime-config": "1.2.0",
28
28
  "ajv": "^8.12.0",
29
29
  "amqplib": "^0.10.3"
@@ -613,6 +613,15 @@ module.exports = {
613
613
  *
614
614
  * CRITICAL: Monitoring is an infrastructure service, monitoring queues are infrastructure queues!
615
615
  * All services (both infrastructure and business) publish monitoring events here.
616
+ *
617
+ * Every QUEUE of this family dead-letters to `monitoring.dlq` over the DEFAULT
618
+ * exchange, where the routing key IS the destination queue's name — the mechanical
619
+ * rule of confirmation `mq-consumer-contract` 003 point 1, applied here by point 3
620
+ * ("`monitoring.*` … get `<prefix>.dlq` when their consumers move onto the library
621
+ * policy"). The exchanges declared alongside them carry no arguments and therefore
622
+ * no route: an exchange holds nothing to dead-letter.
623
+ *
624
+ * @see api/docs/governance/confirmations/mq-consumer-contract.md 003
616
625
  */
617
626
  monitoring: {
618
627
  /**
@@ -627,7 +636,9 @@ module.exports = {
627
636
  durable: true,
628
637
  arguments: {
629
638
  'x-message-ttl': 300000, // 5 minutes TTL
630
- 'x-max-length': 10000
639
+ 'x-max-length': 10000,
640
+ 'x-dead-letter-exchange': '', // Default exchange: routing key IS the queue name
641
+ 'x-dead-letter-routing-key': 'monitoring.dlq'
631
642
  }
632
643
  },
633
644
 
@@ -644,7 +655,9 @@ module.exports = {
644
655
  durable: true,
645
656
  arguments: {
646
657
  'x-message-ttl': 600000, // 10 minutes TTL (longer for service tracking)
647
- 'x-max-length': 20000
658
+ 'x-max-length': 20000,
659
+ 'x-dead-letter-exchange': '',
660
+ 'x-dead-letter-routing-key': 'monitoring.dlq'
648
661
  }
649
662
  },
650
663
 
@@ -657,7 +670,9 @@ module.exports = {
657
670
  durable: true,
658
671
  arguments: {
659
672
  'x-message-ttl': 300000,
660
- 'x-max-length': 50000
673
+ 'x-max-length': 50000,
674
+ 'x-dead-letter-exchange': '',
675
+ 'x-dead-letter-routing-key': 'monitoring.dlq'
661
676
  }
662
677
  },
663
678
 
@@ -674,11 +689,39 @@ module.exports = {
674
689
  /**
675
690
  * monitoring.infrastructure.health.events - the monitoring consumer's own copy of
676
691
  * the infrastructure health events, bound to the infrastructure.health.events
677
- * fanout exchange. Declared with `durable` and nothing else, exactly as the
678
- * consumer creates it.
692
+ * fanout exchange.
693
+ *
694
+ * It carried `durable` and nothing else — the arguments the consumer asserts it
695
+ * with (`infra/api_monitoring/src/consumer/index.js`, `assertQueue(queue,
696
+ * { durable: true })`). It keeps no TTL and no cap, because nothing decided it
697
+ * should have either; what it gains is the family's dead-letter route, without
698
+ * which `consume()` refuses to attach a consumer to it at all (d.259).
679
699
  */
680
700
  'infrastructure.health.events': {
681
- durable: true
701
+ durable: true,
702
+ arguments: {
703
+ 'x-dead-letter-exchange': '',
704
+ 'x-dead-letter-routing-key': 'monitoring.dlq'
705
+ }
706
+ },
707
+
708
+ /**
709
+ * monitoring.dlq - Dead letter queue of the whole monitoring family
710
+ *
711
+ * The end of this family's chain: the workflow, services and audit queues and the
712
+ * consumer's health-events copy all reject into it over the default exchange, so
713
+ * no binding has to exist for the route to work. Declared with the arguments every
714
+ * other dead-letter queue carries — durable, capped at the same 50k, no TTL and no
715
+ * onward route — because the operator's dashboard matches `*.dlq` and a message
716
+ * that expired there is a message nobody got to decide about (confirmation
717
+ * `mq-consumer-contract` 002 point 2, 003 point 1).
718
+ */
719
+ dlq: {
720
+ durable: true,
721
+ arguments: {
722
+ // No TTL for DLQ - messages should persist
723
+ 'x-max-length': 50000 // Higher limit for DLQ
724
+ }
682
725
  }
683
726
  },
684
727
 
@@ -690,8 +733,15 @@ module.exports = {
690
733
  * own name, and these three queues are bound to it
691
734
  * (`docs/standards/monitoring-queues.md`, `docs/architecture/monitoring.md`).
692
735
  *
693
- * The values are the ones the queues are created with today; this config is their
694
- * declaration, so whoever asserts them reads it here rather than retyping it.
736
+ * The TTL and the cap are the ones the queues are created with today; this config is
737
+ * their declaration, so whoever asserts them reads it here rather than retyping it.
738
+ *
739
+ * Each of the three dead-letters to `telemetry.dlq` over the DEFAULT exchange, where
740
+ * the routing key IS the destination queue's name — the mechanical rule of
741
+ * confirmation `mq-consumer-contract` 003 point 1, applied to this family by point 3
742
+ * as its consumer moves onto the library policy.
743
+ *
744
+ * @see api/docs/governance/confirmations/mq-consumer-contract.md 003
695
745
  */
696
746
  telemetry: {
697
747
  /** telemetry.logs.queue - OpenTelemetry log records, drained into Loki. */
@@ -699,7 +749,9 @@ module.exports = {
699
749
  durable: true,
700
750
  arguments: {
701
751
  'x-message-ttl': 60000, // 1 minute TTL for unprocessed messages
702
- 'x-max-length': 100000 // Max 100k messages in queue
752
+ 'x-max-length': 100000, // Max 100k messages in queue
753
+ 'x-dead-letter-exchange': '', // Default exchange: routing key IS the queue name
754
+ 'x-dead-letter-routing-key': 'telemetry.dlq'
703
755
  }
704
756
  },
705
757
 
@@ -708,7 +760,9 @@ module.exports = {
708
760
  durable: true,
709
761
  arguments: {
710
762
  'x-message-ttl': 60000,
711
- 'x-max-length': 100000
763
+ 'x-max-length': 100000,
764
+ 'x-dead-letter-exchange': '',
765
+ 'x-dead-letter-routing-key': 'telemetry.dlq'
712
766
  }
713
767
  },
714
768
 
@@ -717,7 +771,25 @@ module.exports = {
717
771
  durable: true,
718
772
  arguments: {
719
773
  'x-message-ttl': 60000,
720
- 'x-max-length': 100000
774
+ 'x-max-length': 100000,
775
+ 'x-dead-letter-exchange': '',
776
+ 'x-dead-letter-routing-key': 'telemetry.dlq'
777
+ }
778
+ },
779
+
780
+ /**
781
+ * telemetry.dlq - Dead letter queue of the whole telemetry family
782
+ *
783
+ * The three intake queues reject into it, and it rejects nowhere: same shape as
784
+ * `workflow.dlq`, `delivery.dlq` and `monitoring.dlq` — durable, capped at 50k, no
785
+ * TTL, no onward route. A telemetry record the intake cannot process is the one an
786
+ * operator most needs to look at, and a TTL here would delete it before they did.
787
+ */
788
+ dlq: {
789
+ durable: true,
790
+ arguments: {
791
+ // No TTL for DLQ - messages should persist
792
+ 'x-max-length': 50000 // Higher limit for DLQ
721
793
  }
722
794
  }
723
795
  },