@rashidee/co2 1.2.5

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.
Files changed (190) hide show
  1. package/dist/index.js +25449 -0
  2. package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
  3. package/drizzle/0001_wise_wolf_cub.sql +13 -0
  4. package/drizzle/0002_secret_spyke.sql +16 -0
  5. package/drizzle/0003_workspace_config_singleton.sql +16 -0
  6. package/drizzle/0004_terminal_claim_v120.sql +11 -0
  7. package/drizzle/0005_brainstorm_v124.sql +10 -0
  8. package/drizzle/0006_project_v140.sql +6 -0
  9. package/drizzle/0007_prd_wizard_v124.sql +14 -0
  10. package/drizzle/0008_workflow_artifact_v126.sql +24 -0
  11. package/drizzle/0009_project_import_v150.sql +7 -0
  12. package/drizzle/0010_quality_v151.sql +3 -0
  13. package/drizzle/meta/0000_snapshot.json +1335 -0
  14. package/drizzle/meta/0001_snapshot.json +1416 -0
  15. package/drizzle/meta/0002_snapshot.json +1510 -0
  16. package/drizzle/meta/_journal.json +83 -0
  17. package/package.json +41 -0
  18. package/plugin/.claude-plugin/marketplace.json +36 -0
  19. package/plugin/.claude-plugin/plugin.json +22 -0
  20. package/plugin/README.md +625 -0
  21. package/plugin/SKILLS.md +350 -0
  22. package/plugin/co2.svg +5 -0
  23. package/plugin/commands/brainstorm-loop.md +129 -0
  24. package/plugin/skills/conductor-defect/SKILL.md +898 -0
  25. package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
  26. package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
  27. package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
  28. package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
  29. package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
  30. package/plugin/skills/depgen-k8s/SKILL.md +468 -0
  31. package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
  32. package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
  33. package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
  34. package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
  35. package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
  36. package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
  37. package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
  38. package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
  39. package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
  40. package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
  41. package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
  42. package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
  43. package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
  44. package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
  45. package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
  46. package/plugin/skills/modelgen-relational/SKILL.md +707 -0
  47. package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
  48. package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
  49. package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
  50. package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
  51. package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
  52. package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
  53. package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
  54. package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
  55. package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
  56. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
  57. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
  58. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
  59. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
  60. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
  61. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
  62. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
  63. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
  64. package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
  65. package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
  66. package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
  67. package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
  68. package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
  69. package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
  70. package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
  71. package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
  72. package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
  73. package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
  74. package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
  75. package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
  76. package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
  77. package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
  78. package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
  79. package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
  80. package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
  81. package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
  82. package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
  83. package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
  84. package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
  85. package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
  86. package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
  87. package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
  88. package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
  89. package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
  90. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
  91. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
  92. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
  93. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
  94. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
  95. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
  96. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
  97. package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
  98. package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
  99. package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
  100. package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
  101. package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
  102. package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
  103. package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
  104. package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
  105. package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
  106. package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
  107. package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
  108. package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
  109. package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
  110. package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
  111. package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
  112. package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
  113. package/plugin/skills/testgen-functional/SKILL.md +1381 -0
  114. package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
  115. package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
  116. package/plugin/skills/util-projectinit/SKILL.md +307 -0
  117. package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
  118. package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
  119. package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
  120. package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
  121. package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
  122. package/plugin/skills/util-projectsync/SKILL.md +501 -0
  123. package/plugin/skills/util-updprd/SKILL.md +324 -0
  124. package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
  125. package/plugin/skills/util-ustagger/SKILL.md +154 -0
  126. package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
  127. package/static/assets/arc-DRKw7sjs.js +1 -0
  128. package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
  129. package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
  130. package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
  131. package/static/assets/channel-C2nVbuwv.js +1 -0
  132. package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
  133. package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
  134. package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
  135. package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
  136. package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
  137. package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
  138. package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
  139. package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
  140. package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
  141. package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
  142. package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
  143. package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
  144. package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
  145. package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
  146. package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
  147. package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
  148. package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
  149. package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
  150. package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
  151. package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
  152. package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
  153. package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
  154. package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
  155. package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
  156. package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
  157. package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
  158. package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
  159. package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
  160. package/static/assets/graph-C9eacEi8.js +1 -0
  161. package/static/assets/index-LZSQkLE2.css +41 -0
  162. package/static/assets/index-y7XDSgMG.js +495 -0
  163. package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
  164. package/static/assets/init-Gi6I4Gst.js +1 -0
  165. package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
  166. package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
  167. package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
  168. package/static/assets/katex-C5jXJg4s.js +257 -0
  169. package/static/assets/layout-DEXfKzaS.js +1 -0
  170. package/static/assets/linear-CLO--ryk.js +1 -0
  171. package/static/assets/map-Czzmt4hB.js +1 -0
  172. package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
  173. package/static/assets/ordinal-Cboi1Yqb.js +1 -0
  174. package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
  175. package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
  176. package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
  177. package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
  178. package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
  179. package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
  180. package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
  181. package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
  182. package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
  183. package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
  184. package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
  185. package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
  186. package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
  187. package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
  188. package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
  189. package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
  190. package/static/index.html +24 -0
@@ -0,0 +1,468 @@
1
+ # Messaging Patterns — RabbitMQ Pub/Sub
2
+
3
+ This reference describes the standalone RabbitMQ pub/sub messaging layer for inter-system
4
+ communication. This is **independent** from Laravel's internal event system and from
5
+ queue batching — it provides explicit publisher/consumer services that modules call to
6
+ communicate with external systems.
7
+
8
+ ---
9
+
10
+ ## Architecture Overview
11
+
12
+ ```
13
+ ┌─────────────────────────────────────────────┐
14
+ │ RabbitMQ Broker │
15
+ │ │
16
+ ┌──────────┐ │ ┌──────────────────┐ ┌───────────────┐ │ ┌──────────────┐
17
+ │ Module │ publish │ │ app.events │ │ app.commands │ │ consume │ External │
18
+ │ │────────►│ │ (TopicExchange) │ │ (DirectExch.) │ │────────►│ System A │
19
+ │ Service │ │ └────────┬─────────┘ └───────┬───────┘ │ └──────────────┘
20
+ └──────────┘ │ │ │ │
21
+ │ ┌─────▼──────┐ ┌─────▼──────┐ │
22
+ │ │ Queue: │ │ Queue: │ │
23
+ │ │ order.* │ │ inventory │ │
24
+ │ └─────┬──────┘ │ .sync │ │
25
+ │ │ └─────┬──────┘ │
26
+ ┌──────────┐ consume │ │ │ │ ┌──────────────┐
27
+ │ This │◄─────────│───────────┘ └─────────│────────►│ External │
28
+ │ App │ │ │ │ System B │
29
+ └──────────┘ │ ┌──────────────────┐ │ └──────────────┘
30
+ │ │ app.dlx │ │
31
+ │ │ (Dead Letter) │ │
32
+ │ └──────────────────┘ │
33
+ └─────────────────────────────────────────────┘
34
+ ```
35
+
36
+ **Key concepts:**
37
+ - **Topic Exchange** (`app.events.exchange`) — pub/sub event broadcasting with routing key
38
+ patterns (e.g., `order.exported`, `order.cancelled`)
39
+ - **Direct Exchange** (`app.commands.exchange`) — point-to-point command delivery to a
40
+ specific queue (e.g., `inventory.sync`)
41
+ - **Dead Letter Exchange** (`app.dlx.exchange`) — failed messages routed here after max
42
+ retries for investigation and replay
43
+
44
+ ---
45
+
46
+ ## Composer Dependencies
47
+
48
+ ```json
49
+ {
50
+ "require": {
51
+ "vladimir-yuldashev/laravel-queue-rabbitmq": "^14.0",
52
+ "php-amqplib/php-amqplib": "^3.7"
53
+ }
54
+ }
55
+ ```
56
+
57
+ > **Note:** `laravel-queue-rabbitmq` provides the queue driver for consuming messages
58
+ > as Laravel jobs. `php-amqplib` provides low-level AMQP access for advanced exchange
59
+ > patterns (topic/direct publishing with routing keys).
60
+
61
+ ---
62
+
63
+ ## Application Configuration
64
+
65
+ ### .env
66
+
67
+ ```env
68
+ RABBITMQ_HOST=localhost
69
+ RABBITMQ_PORT=5672
70
+ RABBITMQ_USER=guest
71
+ RABBITMQ_PASSWORD=guest
72
+ RABBITMQ_VHOST=/
73
+ RABBITMQ_QUEUE=default
74
+ ```
75
+
76
+ ### config/queue.php (rabbitmq connection)
77
+
78
+ ```php
79
+ 'rabbitmq' => [
80
+ 'driver' => 'rabbitmq',
81
+ 'queue' => env('RABBITMQ_QUEUE', 'default'),
82
+ 'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class,
83
+ 'hosts' => [
84
+ [
85
+ 'host' => env('RABBITMQ_HOST', '127.0.0.1'),
86
+ 'port' => env('RABBITMQ_PORT', 5672),
87
+ 'user' => env('RABBITMQ_USER', 'guest'),
88
+ 'password' => env('RABBITMQ_PASSWORD', 'guest'),
89
+ 'vhost' => env('RABBITMQ_VHOST', '/'),
90
+ ],
91
+ ],
92
+ 'options' => [
93
+ 'ssl_options' => [
94
+ 'cafile' => env('RABBITMQ_SSL_CAFILE'),
95
+ 'local_cert' => env('RABBITMQ_SSL_LOCALCERT'),
96
+ 'local_key' => env('RABBITMQ_SSL_LOCALKEY'),
97
+ 'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
98
+ ],
99
+ 'queue' => [
100
+ 'exchange' => env('RABBITMQ_EXCHANGE', ''),
101
+ 'exchange_type' => env('RABBITMQ_EXCHANGE_TYPE', 'direct'),
102
+ 'exchange_routing_key' => env('RABBITMQ_EXCHANGE_ROUTING_KEY', ''),
103
+ ],
104
+ 'heartbeat' => 30,
105
+ ],
106
+ ],
107
+ ```
108
+
109
+ ### config/messaging.php (custom exchange configuration)
110
+
111
+ ```php
112
+ return [
113
+ 'exchanges' => [
114
+ 'events' => env('MESSAGING_EVENTS_EXCHANGE', 'app.events.exchange'),
115
+ 'commands' => env('MESSAGING_COMMANDS_EXCHANGE', 'app.commands.exchange'),
116
+ 'dead_letter' => env('MESSAGING_DLX_EXCHANGE', 'app.dlx.exchange'),
117
+ ],
118
+
119
+ 'queues' => [
120
+ 'order_events' => 'app.events.order',
121
+ 'inventory_sync' => 'app.commands.inventory-sync',
122
+ 'dead_letter' => 'app.dlq',
123
+ ],
124
+ ];
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Package Structure
130
+
131
+ ```
132
+ app/
133
+ └── Services/
134
+ └── Messaging/
135
+ ├── RabbitMQInfrastructure.php # Exchange, queue, binding declarations
136
+ ├── MessagePublisher.php # Generic publisher service
137
+ └── Consumers/
138
+ └── SampleEventConsumer.php # Sample consumer job
139
+ ```
140
+
141
+ ---
142
+
143
+ ## RabbitMQ Infrastructure Setup
144
+
145
+ Service to declare exchanges, queues, and bindings at application boot:
146
+
147
+ ```php
148
+ namespace App\Services\Messaging;
149
+
150
+ use PhpAmqpLib\Channel\AMQPChannel;
151
+ use PhpAmqpLib\Connection\AMQPStreamConnection;
152
+ use PhpAmqpLib\Wire\AMQPTable;
153
+
154
+ class RabbitMQInfrastructure
155
+ {
156
+ private AMQPChannel $channel;
157
+
158
+ public function __construct()
159
+ {
160
+ $connection = new AMQPStreamConnection(
161
+ config('queue.connections.rabbitmq.hosts.0.host'),
162
+ config('queue.connections.rabbitmq.hosts.0.port'),
163
+ config('queue.connections.rabbitmq.hosts.0.user'),
164
+ config('queue.connections.rabbitmq.hosts.0.password'),
165
+ config('queue.connections.rabbitmq.hosts.0.vhost'),
166
+ );
167
+ $this->channel = $connection->channel();
168
+ }
169
+
170
+ public function declareInfrastructure(): void
171
+ {
172
+ $eventsExchange = config('messaging.exchanges.events');
173
+ $commandsExchange = config('messaging.exchanges.commands');
174
+ $dlxExchange = config('messaging.exchanges.dead_letter');
175
+
176
+ // Declare exchanges
177
+ $this->channel->exchange_declare($eventsExchange, 'topic', false, true, false);
178
+ $this->channel->exchange_declare($commandsExchange, 'direct', false, true, false);
179
+ $this->channel->exchange_declare($dlxExchange, 'fanout', false, true, false);
180
+
181
+ // Dead letter queue
182
+ $this->channel->queue_declare('app.dlq', false, true, false, false);
183
+ $this->channel->queue_bind('app.dlq', $dlxExchange);
184
+
185
+ // Sample event queue (Topic Exchange) — subscribe to order.* events
186
+ $this->channel->queue_declare(
187
+ config('messaging.queues.order_events'),
188
+ false, true, false, false,
189
+ false,
190
+ new AMQPTable(['x-dead-letter-exchange' => $dlxExchange])
191
+ );
192
+ $this->channel->queue_bind(
193
+ config('messaging.queues.order_events'),
194
+ $eventsExchange,
195
+ 'order.*'
196
+ );
197
+
198
+ // Sample command queue (Direct Exchange) — inventory sync
199
+ $this->channel->queue_declare(
200
+ config('messaging.queues.inventory_sync'),
201
+ false, true, false, false,
202
+ false,
203
+ new AMQPTable(['x-dead-letter-exchange' => $dlxExchange])
204
+ );
205
+ $this->channel->queue_bind(
206
+ config('messaging.queues.inventory_sync'),
207
+ $commandsExchange,
208
+ 'inventory.sync'
209
+ );
210
+ }
211
+ }
212
+ ```
213
+
214
+ Register as an Artisan command for setup:
215
+ ```php
216
+ namespace App\Console\Commands;
217
+
218
+ use App\Services\Messaging\RabbitMQInfrastructure;
219
+ use Illuminate\Console\Command;
220
+
221
+ class SetupRabbitMQCommand extends Command
222
+ {
223
+ protected $signature = 'rabbitmq:setup';
224
+ protected $description = 'Declare RabbitMQ exchanges, queues, and bindings';
225
+
226
+ public function handle(RabbitMQInfrastructure $infra): int
227
+ {
228
+ $infra->declareInfrastructure();
229
+ $this->info('RabbitMQ infrastructure declared successfully.');
230
+ return self::SUCCESS;
231
+ }
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Publisher Service
238
+
239
+ ```php
240
+ namespace App\Services\Messaging;
241
+
242
+ use Illuminate\Support\Facades\Log;
243
+ use PhpAmqpLib\Channel\AMQPChannel;
244
+ use PhpAmqpLib\Connection\AMQPStreamConnection;
245
+ use PhpAmqpLib\Message\AMQPMessage;
246
+
247
+ class MessagePublisher
248
+ {
249
+ private AMQPChannel $channel;
250
+
251
+ public function __construct()
252
+ {
253
+ $connection = new AMQPStreamConnection(
254
+ config('queue.connections.rabbitmq.hosts.0.host'),
255
+ config('queue.connections.rabbitmq.hosts.0.port'),
256
+ config('queue.connections.rabbitmq.hosts.0.user'),
257
+ config('queue.connections.rabbitmq.hosts.0.password'),
258
+ config('queue.connections.rabbitmq.hosts.0.vhost'),
259
+ );
260
+ $this->channel = $connection->channel();
261
+ }
262
+
263
+ /**
264
+ * Publish a domain event to the topic exchange.
265
+ * Consumers subscribe via routing key patterns (e.g., "order.*").
266
+ */
267
+ public function publishEvent(string $routingKey, array $event): void
268
+ {
269
+ Log::info("Publishing event [{$routingKey}]", $event);
270
+
271
+ $message = new AMQPMessage(
272
+ json_encode($event),
273
+ ['content_type' => 'application/json', 'delivery_mode' => 2]
274
+ );
275
+
276
+ $this->channel->basic_publish(
277
+ $message,
278
+ config('messaging.exchanges.events'),
279
+ $routingKey
280
+ );
281
+ }
282
+
283
+ /**
284
+ * Send a command to the direct exchange for point-to-point delivery.
285
+ */
286
+ public function sendCommand(string $routingKey, array $command): void
287
+ {
288
+ Log::info("Sending command [{$routingKey}]", $command);
289
+
290
+ $message = new AMQPMessage(
291
+ json_encode($command),
292
+ ['content_type' => 'application/json', 'delivery_mode' => 2]
293
+ );
294
+
295
+ $this->channel->basic_publish(
296
+ $message,
297
+ config('messaging.exchanges.commands'),
298
+ $routingKey
299
+ );
300
+ }
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## Consumer Job
307
+
308
+ Consumers are implemented as Laravel queue jobs consumed via `laravel-queue-rabbitmq`:
309
+
310
+ ```php
311
+ namespace App\Jobs\Consumers;
312
+
313
+ use Illuminate\Bus\Queueable;
314
+ use Illuminate\Contracts\Queue\ShouldQueue;
315
+ use Illuminate\Foundation\Bus\Dispatchable;
316
+ use Illuminate\Queue\InteractsWithQueue;
317
+ use Illuminate\Queue\SerializesModels;
318
+ use Illuminate\Support\Facades\Log;
319
+
320
+ class OrderEventConsumer implements ShouldQueue
321
+ {
322
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
323
+
324
+ public int $tries = 3;
325
+ public int $backoff = 5;
326
+
327
+ public function __construct(
328
+ public readonly array $payload,
329
+ ) {}
330
+
331
+ public function handle(): void
332
+ {
333
+ Log::info('Received order event', $this->payload);
334
+ // Process the event — e.g., notify downstream systems, update read models
335
+ }
336
+
337
+ public function failed(\Throwable $exception): void
338
+ {
339
+ Log::error('Failed to process order event', [
340
+ 'payload' => $this->payload,
341
+ 'error' => $exception->getMessage(),
342
+ ]);
343
+ }
344
+ }
345
+ ```
346
+
347
+ For low-level AMQP consumption (bypassing Laravel queues):
348
+ ```php
349
+ // Custom Artisan command for consuming from specific queues
350
+ namespace App\Console\Commands;
351
+
352
+ use Illuminate\Console\Command;
353
+ use PhpAmqpLib\Connection\AMQPStreamConnection;
354
+
355
+ class ConsumeOrderEventsCommand extends Command
356
+ {
357
+ protected $signature = 'rabbitmq:consume-order-events';
358
+ protected $description = 'Consume messages from the order events queue';
359
+
360
+ public function handle(): int
361
+ {
362
+ $connection = new AMQPStreamConnection(
363
+ config('queue.connections.rabbitmq.hosts.0.host'),
364
+ config('queue.connections.rabbitmq.hosts.0.port'),
365
+ config('queue.connections.rabbitmq.hosts.0.user'),
366
+ config('queue.connections.rabbitmq.hosts.0.password'),
367
+ config('queue.connections.rabbitmq.hosts.0.vhost'),
368
+ );
369
+
370
+ $channel = $connection->channel();
371
+ $channel->basic_qos(0, 10, false);
372
+
373
+ $channel->basic_consume(
374
+ config('messaging.queues.order_events'),
375
+ '',
376
+ false, false, false, false,
377
+ function ($msg) {
378
+ $payload = json_decode($msg->body, true);
379
+ $this->info("Received: " . json_encode($payload));
380
+
381
+ // Process...
382
+
383
+ $msg->ack();
384
+ }
385
+ );
386
+
387
+ $this->info('Waiting for order events...');
388
+ while ($channel->is_consuming()) {
389
+ $channel->wait();
390
+ }
391
+
392
+ return self::SUCCESS;
393
+ }
394
+ }
395
+ ```
396
+
397
+ ---
398
+
399
+ ## Usage from Modules
400
+
401
+ Modules inject `MessagePublisher` to send messages to external systems.
402
+ This is **separate** from Laravel's `event()` helper, which handles in-process
403
+ inter-module events.
404
+
405
+ ```php
406
+ namespace Modules\Order\Services;
407
+
408
+ use App\Services\Messaging\MessagePublisher;
409
+ use Modules\Order\Contracts\OrderServiceInterface;
410
+ use Modules\Order\Models\Order;
411
+
412
+ class OrderService implements OrderServiceInterface
413
+ {
414
+ public function __construct(
415
+ private readonly MessagePublisher $publisher,
416
+ ) {}
417
+
418
+ public function exportOrder(string $orderId): void
419
+ {
420
+ $order = Order::findOrFail($orderId);
421
+
422
+ // ... export logic ...
423
+
424
+ // Publish event to external systems via RabbitMQ
425
+ $this->publisher->publishEvent('order.exported', [
426
+ 'order_id' => $order->id,
427
+ 'customer_id' => $order->customer_id,
428
+ 'exported_at' => now()->toIso8601String(),
429
+ ]);
430
+ }
431
+ }
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Error Handling
437
+
438
+ ### Retry with Dead Letter Queue
439
+
440
+ Queues are configured with `x-dead-letter-exchange` pointing to `app.dlx.exchange`.
441
+ When a message fails after the configured retry attempts, it is routed to the dead
442
+ letter queue (`app.dlq`) for manual investigation.
443
+
444
+ ### Failed Jobs Table
445
+
446
+ Laravel's `failed_jobs` table catches jobs that exhaust all retries:
447
+ ```bash
448
+ php artisan queue:failed
449
+ php artisan queue:retry <id>
450
+ php artisan queue:flush
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Operational Notes
456
+
457
+ - **Connection pooling**: Use `AMQPLazyConnection` to establish connections on-demand
458
+ rather than at boot time.
459
+ - **Heartbeat**: Set `heartbeat: 30` in queue config to detect dropped connections
460
+ within 60 seconds (2x heartbeat interval).
461
+ - **Consumer prefetch**: Set `basic_qos(0, 10, false)` for slow consumers to avoid
462
+ message starvation across instances.
463
+ - **Publisher confirms**: Enable `confirm_select()` on the channel in production to
464
+ guarantee message delivery to the broker.
465
+ - **Monitoring**: Monitor the dead letter queue (`app.dlq`) for failed messages.
466
+ Integrate with your alerting system to notify on DLQ accumulation.
467
+ - **Queue naming convention**: All messaging queues use the `app.*` prefix. Batch
468
+ queues use the default Laravel queue naming. These namespaces must not overlap.