@breadstone/archipel-mcp 0.0.22 → 0.0.25
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/README.md +32 -13
- package/data/guides/ai-text-generation.md +16 -24
- package/data/guides/caching.md +33 -0
- package/data/guides/email-delivery.md +27 -1
- package/data/guides/email-templates.md +49 -39
- package/data/guides/esigning-integration.md +11 -5
- package/data/guides/health-indicators.md +220 -0
- package/data/guides/index.md +2 -0
- package/data/guides/queue-infrastructure.md +329 -0
- package/data/guides/telemetry-and-observability.md +20 -0
- package/data/packages/platform-analytics/api/Class.AnalyticsClientPort.md +20 -0
- package/data/packages/platform-analytics/api/Class.AnalyticsHealthIndicator.md +78 -0
- package/data/packages/platform-analytics/api/Class.AppInsightsAnalyticsClient.md +24 -0
- package/data/packages/platform-analytics/api/Class.DatadogAnalyticsClient.md +24 -0
- package/data/packages/platform-analytics/api/Class.NoopAnalyticsClient.md +24 -0
- package/data/packages/platform-analytics/api/Class.SentryAnalyticsClient.md +24 -0
- package/data/packages/platform-analytics/api/index.md +1 -0
- package/data/packages/platform-analytics/index.md +25 -1
- package/data/packages/platform-authentication/api/Class.AuthenticationHealthIndicator.md +68 -0
- package/data/packages/platform-authentication/api/Interface.IMfaSubjectUpdate.md +1 -1
- package/data/packages/platform-authentication/api/index.md +2 -1
- package/data/packages/platform-authentication/index.md +25 -1
- package/data/packages/platform-blob-storage/api/Class.BlobHealthIndicator.md +7 -7
- package/data/packages/platform-blob-storage/api/Class.BlobModule.md +2 -2
- package/data/packages/platform-blob-storage/api/Interface.IAwsS3BlobProviderRegistration.md +3 -3
- package/data/packages/platform-blob-storage/api/Interface.IAzureBlobProviderRegistration.md +3 -3
- package/data/packages/platform-blob-storage/api/Interface.IBlobModuleOptions.md +5 -5
- package/data/packages/platform-blob-storage/api/Interface.ICustomBlobProviderRegistration.md +3 -3
- package/data/packages/platform-blob-storage/api/Interface.IVercelBlobProviderRegistration.md +3 -3
- package/data/packages/platform-blob-storage/api/TypeAlias.IBlobProviderRegistration.md +1 -1
- package/data/packages/platform-blob-storage/api/index.md +1 -1
- package/data/packages/platform-blob-storage/index.md +19 -14
- package/data/packages/platform-caching/api/Class.MemoryLayeredCache.md +10 -10
- package/data/packages/platform-caching/api/Class.NoopCacheMetricsRecorder.md +6 -6
- package/data/packages/platform-caching/api/Class.RedisLayeredCache.md +13 -13
- package/data/packages/platform-caching/api/Interface.ILayeredCache.md +9 -9
- package/data/packages/platform-caching/api/Interface.ILayeredCacheOptions.md +6 -6
- package/data/packages/platform-caching/api/Variable.CACHE_DEFAULT_TTL_MS.md +14 -0
- package/data/packages/platform-caching/api/Variable.CACHE_MAX_ENTRIES.md +14 -0
- package/data/packages/platform-caching/api/Variable.CACHE_STALE_WHILE_REVALIDATE.md +14 -0
- package/data/packages/platform-caching/api/Variable.PLATFORM_CACHING_CONFIG_ENTRIES.md +14 -0
- package/data/packages/platform-caching/api/Variable.REDIS_CONFIG_ENTRIES.md +14 -0
- package/data/packages/platform-caching/api/Variable.REDIS_KEY_PREFIX.md +14 -0
- package/data/packages/platform-caching/api/Variable.REDIS_TTL_SECONDS.md +14 -0
- package/data/packages/platform-caching/api/Variable.REDIS_URL.md +14 -0
- package/data/packages/platform-caching/api/index.md +13 -0
- package/data/packages/platform-caching/index.md +47 -1
- package/data/packages/platform-configuration/api/Function.createConfigKey.md +1 -1
- package/data/packages/platform-core/api/Class.HttpLoggerMiddleware.md +3 -3
- package/data/packages/platform-core/api/Function.maskSensitive.md +26 -0
- package/data/packages/platform-core/api/Function.maskSensitiveFields.md +26 -0
- package/data/packages/platform-core/api/index.md +2 -0
- package/data/packages/platform-core/index.md +11 -0
- package/data/packages/platform-database/api/Class.DatabaseHealthIndicator.md +8 -6
- package/data/packages/platform-database/api/Class.DatabaseModule.md +3 -3
- package/data/packages/platform-database/api/Class.RepositoryBase.md +20 -20
- package/data/packages/platform-database/api/Function.paginator.md +1 -1
- package/data/packages/platform-database/api/Interface.IDatabaseModuleConfig.md +3 -3
- package/data/packages/platform-database/api/TypeAlias.DelegateArgs.md +1 -1
- package/data/packages/platform-database/api/TypeAlias.DelegateReturnTypes.md +1 -1
- package/data/packages/platform-database/api/TypeAlias.PaginateFunction.md +1 -1
- package/data/packages/platform-database/api/Variable.DATABASE_MODULE_CONFIG.md +1 -1
- package/data/packages/platform-database/index.md +17 -5
- package/data/packages/platform-documents/api/Class.DocumentEngine.md +9 -5
- package/data/packages/platform-documents/index.md +1 -1
- package/data/packages/platform-esigning/api/Class.AdobeSignEsigningProvider.md +24 -0
- package/data/packages/platform-esigning/api/Class.DocuSignEsigningProvider.md +24 -0
- package/data/packages/platform-esigning/api/Class.DropboxSignEsigningProvider.md +24 -0
- package/data/packages/platform-esigning/api/Class.EsigningClientPort.md +20 -0
- package/data/packages/platform-esigning/api/Class.EsigningHealthIndicator.md +78 -0
- package/data/packages/platform-esigning/api/Class.InternalEsigningProvider.md +24 -0
- package/data/packages/platform-esigning/api/index.md +1 -0
- package/data/packages/platform-esigning/index.md +26 -2
- package/data/packages/platform-health/api/Class.HealthModule.md +42 -0
- package/data/packages/platform-health/api/Class.HealthOrchestrator.md +64 -0
- package/data/packages/platform-health/api/Interface.IHealthCheckResult.md +46 -0
- package/data/packages/platform-health/api/Interface.IHealthIndicator.md +41 -0
- package/data/packages/platform-health/api/Variable.HEALTH_INDICATORS_TOKEN.md +14 -0
- package/data/packages/platform-health/api/index.md +26 -0
- package/data/packages/platform-health/index.md +19 -8
- package/data/packages/platform-intelligence/api/Class.IntelligenceHealthIndicator.md +78 -0
- package/data/packages/platform-intelligence/api/index.md +1 -0
- package/data/packages/platform-intelligence/index.md +24 -1
- package/data/packages/platform-logging/api/Class.ContextLogger.md +152 -0
- package/data/packages/platform-logging/api/Class.LoggerModule.md +8 -2
- package/data/packages/platform-logging/api/Class.RequestContextStore.md +90 -0
- package/data/packages/platform-logging/api/Class.RequestIdMiddleware.md +68 -0
- package/data/packages/platform-logging/api/Interface.IRequestContext.md +34 -0
- package/data/packages/platform-logging/api/Variable.REQUEST_ID_HEADER.md +14 -0
- package/data/packages/platform-logging/api/index.md +11 -1
- package/data/packages/platform-logging/index.md +89 -7
- package/data/packages/platform-mailing/api/Class.MailHealthIndicator.md +5 -5
- package/data/packages/platform-mailing/api/Class.MailModule.md +28 -1
- package/data/packages/platform-mailing/api/Class.MailVerificationService.md +49 -16
- package/data/packages/platform-mailing/api/Class.SmtpConnectionVerifier.md +84 -0
- package/data/packages/platform-mailing/api/Interface.IMailModuleOptions.md +36 -0
- package/data/packages/platform-mailing/api/index.md +3 -1
- package/data/packages/platform-mailing/index.md +64 -8
- package/data/packages/platform-mapping/api/Class.MappingBuilder.md +110 -0
- package/data/packages/platform-mapping/api/Class.MappingError.md +56 -0
- package/data/packages/platform-mapping/api/Class.MappingModule.md +46 -0
- package/data/packages/platform-mapping/api/Class.MappingNotRegisteredError.md +52 -0
- package/data/packages/platform-mapping/api/Class.MappingProfileBase.md +52 -0
- package/data/packages/platform-mapping/api/Class.MappingService.md +284 -0
- package/data/packages/platform-mapping/api/Class.TypeMappingNotRegisteredError.md +53 -0
- package/data/packages/platform-mapping/api/Function.createMappingKey.md +39 -0
- package/data/packages/platform-mapping/api/Interface.IMappingBuilder.md +76 -0
- package/data/packages/platform-mapping/api/Interface.IMappingKey.md +58 -0
- package/data/packages/platform-mapping/api/Interface.IMappingProfile.md +32 -0
- package/data/packages/platform-mapping/api/TypeAlias.Constructor.md +28 -0
- package/data/packages/platform-mapping/api/index.md +38 -0
- package/data/packages/platform-mapping/index.md +1 -1
- package/data/packages/platform-mcp/api/Class.McpHealthIndicator.md +78 -0
- package/data/packages/platform-mcp/api/index.md +1 -0
- package/data/packages/platform-mcp/index.md +24 -1
- package/data/packages/platform-openapi/api/Function.SwaggerFeature.md +2 -2
- package/data/packages/platform-openapi/api/Function.getSwaggerFeatureMetadata.md +2 -2
- package/data/packages/platform-payments/api/Class.LemonSqueezyClient.md +24 -0
- package/data/packages/platform-payments/api/Class.MollieClient.md +24 -0
- package/data/packages/platform-payments/api/Class.PaddleClient.md +24 -0
- package/data/packages/platform-payments/api/Class.PaymentClientPort.md +20 -0
- package/data/packages/platform-payments/api/Class.PaymentHealthIndicator.md +78 -0
- package/data/packages/platform-payments/api/Class.StripeClient.md +28 -4
- package/data/packages/platform-payments/api/index.md +1 -0
- package/data/packages/platform-payments/index.md +26 -2
- package/data/packages/platform-queue/api/Class.AzureQueue.md +221 -0
- package/data/packages/platform-queue/api/Class.BullMqQueue.md +220 -0
- package/data/packages/platform-queue/api/Class.MemoryQueue.md +194 -0
- package/data/packages/platform-queue/api/Class.QueueError.md +51 -0
- package/data/packages/platform-queue/api/Class.QueueHealthIndicator.md +68 -0
- package/data/packages/platform-queue/api/Class.QueueJobNotFoundError.md +43 -0
- package/data/packages/platform-queue/api/Class.QueueJobStateError.md +48 -0
- package/data/packages/platform-queue/api/Class.QueueValidationError.md +43 -0
- package/data/packages/platform-queue/api/Interface.IAzureQueueOptions.md +48 -0
- package/data/packages/platform-queue/api/Interface.IBullMqQueueOptions.md +45 -0
- package/data/packages/platform-queue/api/Interface.IMemoryQueueOptions.md +32 -0
- package/data/packages/platform-queue/api/Interface.IQueue.md +173 -0
- package/data/packages/platform-queue/api/Interface.IQueueJob.md +139 -0
- package/data/packages/platform-queue/api/TypeAlias.QueueJobStatus.md +14 -0
- package/data/packages/platform-queue/api/Variable.AZURE_CONFIG_ENTRIES.md +17 -0
- package/data/packages/platform-queue/api/Variable.AZURE_CONNECTION_STRING.md +14 -0
- package/data/packages/platform-queue/api/Variable.AZURE_RECEIVE_WAIT_MS.md +21 -0
- package/data/packages/platform-queue/api/Variable.BULLMQ_CONFIG_ENTRIES.md +17 -0
- package/data/packages/platform-queue/api/Variable.BULLMQ_PREFIX.md +18 -0
- package/data/packages/platform-queue/api/Variable.BULLMQ_REDIS_URL.md +21 -0
- package/data/packages/platform-queue/api/Variable.PLATFORM_QUEUE_CONFIG_ENTRIES.md +17 -0
- package/data/packages/platform-queue/api/Variable.QUEUE_JOB_STATUS.md +30 -0
- package/data/packages/platform-queue/api/Variable.QUEUE_MAX_JOBS.md +21 -0
- package/data/packages/platform-queue/api/index.md +49 -0
- package/data/packages/platform-queue/index.md +168 -0
- package/data/packages/platform-resources/api/Class.BlobResourceStrategy.md +195 -0
- package/data/packages/platform-resources/api/Class.EmbeddedResourceStrategy.md +215 -0
- package/data/packages/platform-resources/api/Class.FileResourceStrategy.md +190 -0
- package/data/packages/platform-resources/api/Class.ResourceManager.md +477 -0
- package/data/packages/platform-resources/api/Class.ResourceModule.md +46 -0
- package/data/packages/platform-resources/api/Class.ResourceNotFoundError.md +60 -0
- package/data/packages/platform-resources/api/Interface.IBlobResourceStrategyConfig.md +28 -0
- package/data/packages/platform-resources/api/Interface.IBlobServiceAdapter.md +40 -0
- package/data/packages/platform-resources/api/Interface.IFileResourceStrategyConfig.md +72 -0
- package/data/packages/platform-resources/api/Interface.IResourceManagerConfig.md +89 -0
- package/data/packages/platform-resources/api/Interface.IResourceMetadata.md +94 -0
- package/data/packages/platform-resources/api/Interface.IResourceResult.md +34 -0
- package/data/packages/platform-resources/api/Interface.IResourceStrategy.md +134 -0
- package/data/packages/platform-resources/api/index.md +29 -0
- package/data/packages/platform-resources/index.md +1 -1
- package/data/packages/platform-telemetry/api/Class.OtelSdkHolder.md +21 -3
- package/data/packages/platform-telemetry/api/Class.TelemetryHealthIndicator.md +78 -0
- package/data/packages/platform-telemetry/api/index.md +1 -0
- package/data/packages/platform-telemetry/index.md +25 -1
- package/data/patterns/config-pattern.md +5 -3
- package/package.json +2 -2
- package/src/tools/registerGetConfigPatternTool.js +1 -1
- package/src/tools/registerGetDtoPatternTool.js +1 -1
- package/src/tools/registerGetErrorHandlingPatternTool.js +1 -1
- package/src/tools/registerGetGuardPatternTool.js +1 -1
- package/src/tools/registerGetMappingPatternTool.js +1 -1
- package/src/tools/registerGetModulePatternTool.js +1 -1
- package/src/tools/registerGetQueryPatternTool.js +1 -1
- package/src/tools/registerGetRepositoryPatternTool.js +1 -1
- package/src/tools/registerGetTestingPatternTool.js +1 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Queue Infrastructure
|
|
3
|
+
description: Add job queue infrastructure to your NestJS application with in-memory FIFO, BullMQ (Redis), and Azure Service Bus providers.
|
|
4
|
+
order: 25
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Queue Infrastructure
|
|
8
|
+
|
|
9
|
+
This guide covers job queue infrastructure with `platform-queue`: choosing between in-memory, Redis-backed, and Azure Service Bus backends, managing job lifecycles, handling errors, and switching providers without code changes.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @breadstone/archipel-platform-queue
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For BullMQ (Redis), also install the SDK:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add bullmq
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For Azure Service Bus:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @azure/service-bus
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
### Core Variables
|
|
36
|
+
|
|
37
|
+
```env
|
|
38
|
+
QUEUE_MAX_JOBS=10000
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`QUEUE_MAX_JOBS` is optional and only applies to `MemoryQueue`. When omitted, the default of `10_000` is used.
|
|
42
|
+
|
|
43
|
+
### BullMQ Variables
|
|
44
|
+
|
|
45
|
+
```env
|
|
46
|
+
BULLMQ_REDIS_URL=redis://localhost:6379
|
|
47
|
+
BULLMQ_PREFIX=myapp:
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`BULLMQ_REDIS_URL` is required when using `BullMqQueue`. `BULLMQ_PREFIX` is optional (defaults to empty string).
|
|
51
|
+
|
|
52
|
+
### Azure Service Bus Variables
|
|
53
|
+
|
|
54
|
+
```env
|
|
55
|
+
AZURE_CONNECTION_STRING=Endpoint=sb://my-namespace.servicebus.windows.net/;SharedAccessKeyName=...;SharedAccessKey=...
|
|
56
|
+
AZURE_RECEIVE_WAIT_MS=5000
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`AZURE_CONNECTION_STRING` is required when using `AzureQueue`. `AZURE_RECEIVE_WAIT_MS` is optional (defaults to `5000`).
|
|
60
|
+
|
|
61
|
+
### Using Config Keys
|
|
62
|
+
|
|
63
|
+
Import the typed config keys and pass them to your module registration:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { PLATFORM_QUEUE_CONFIG_ENTRIES } from '@breadstone/archipel-platform-queue';
|
|
67
|
+
import { BULLMQ_CONFIG_ENTRIES } from '@breadstone/archipel-platform-queue/bullmq';
|
|
68
|
+
import { AZURE_CONFIG_ENTRIES } from '@breadstone/archipel-platform-queue/azure';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Concepts
|
|
74
|
+
|
|
75
|
+
`platform-queue` provides a generic `IQueue<TPayload>` interface with three implementations:
|
|
76
|
+
|
|
77
|
+
| Implementation | Backend | Persistence | Best for |
|
|
78
|
+
| -------------- | ------------------ | ----------- | ------------------------------------------- |
|
|
79
|
+
| `MemoryQueue` | In-memory | No | Development, testing, single-instance apps |
|
|
80
|
+
| `BullMqQueue` | Redis via BullMQ | Yes | Multi-instance deployments, distributed jobs|
|
|
81
|
+
| `AzureQueue` | Azure Service Bus | Yes | Enterprise cloud messaging, peek-lock |
|
|
82
|
+
|
|
83
|
+
All implementations share the same `IQueue` contract, so switching providers requires only changing the import and constructor options — no business logic changes.
|
|
84
|
+
|
|
85
|
+
### Job Lifecycle
|
|
86
|
+
|
|
87
|
+
Every job follows a four-state lifecycle:
|
|
88
|
+
|
|
89
|
+
```mermaid
|
|
90
|
+
stateDiagram-v2
|
|
91
|
+
[*] --> pending : enqueue()
|
|
92
|
+
pending --> processing : dequeue()
|
|
93
|
+
processing --> completed : markCompleted()
|
|
94
|
+
processing --> failed : markFailed()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Each `IQueueJob` carries full metadata: `id`, `queueName`, `payload`, `status`, `attempts`, `createdAt`, `processedAt`, `completedAt`, `failedAt`, and an optional `errorMessage`.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## In-Memory Queue
|
|
102
|
+
|
|
103
|
+
### Basic Setup
|
|
104
|
+
|
|
105
|
+
`MemoryQueue` ships with the core entry point and requires no extra dependencies:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { Module } from '@nestjs/common';
|
|
109
|
+
import { MemoryQueue } from '@breadstone/archipel-platform-queue';
|
|
110
|
+
|
|
111
|
+
@Module({
|
|
112
|
+
providers: [
|
|
113
|
+
{
|
|
114
|
+
provide: 'IQueue',
|
|
115
|
+
useFactory: () => new MemoryQueue({ maxJobs: 5_000 }),
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
exports: ['IQueue'],
|
|
119
|
+
})
|
|
120
|
+
export class QueueModule {}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Capacity Eviction
|
|
124
|
+
|
|
125
|
+
When the total number of jobs across all named queues exceeds `maxJobs`, the oldest completed or failed jobs are evicted automatically. Pending and processing jobs are never evicted.
|
|
126
|
+
|
|
127
|
+
> **When to use:** Development, automated tests, or single-instance services where persistence is not required.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## BullMQ (Redis)
|
|
132
|
+
|
|
133
|
+
### Basic Setup
|
|
134
|
+
|
|
135
|
+
`BullMqQueue` creates Redis-backed queues that survive process restarts and can be shared across multiple instances:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { Module } from '@nestjs/common';
|
|
139
|
+
import { BullMqQueue } from '@breadstone/archipel-platform-queue/bullmq';
|
|
140
|
+
|
|
141
|
+
@Module({
|
|
142
|
+
providers: [
|
|
143
|
+
{
|
|
144
|
+
provide: 'IQueue',
|
|
145
|
+
useFactory: () =>
|
|
146
|
+
new BullMqQueue({
|
|
147
|
+
redisUrl: 'redis://localhost:6379',
|
|
148
|
+
prefix: 'myapp:',
|
|
149
|
+
}),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
exports: ['IQueue'],
|
|
153
|
+
})
|
|
154
|
+
export class QueueModule {}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### How It Works
|
|
158
|
+
|
|
159
|
+
Each named queue lazily creates its own BullMQ `Queue` and `Worker` instance. When `dequeue()` is called, the worker picks the next available job using a one-time token. Job tokens are tracked internally so that `markCompleted()` and `markFailed()` can transition jobs to their terminal state.
|
|
160
|
+
|
|
161
|
+
### Graceful Shutdown
|
|
162
|
+
|
|
163
|
+
`BullMqQueue` implements `OnModuleDestroy` and automatically closes all queues and workers when the NestJS module is destroyed. No manual cleanup is needed.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Azure Service Bus
|
|
168
|
+
|
|
169
|
+
### Basic Setup
|
|
170
|
+
|
|
171
|
+
`AzureQueue` integrates with Azure Service Bus using peek-lock message handling:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { Module } from '@nestjs/common';
|
|
175
|
+
import { AzureQueue } from '@breadstone/archipel-platform-queue/azure';
|
|
176
|
+
|
|
177
|
+
@Module({
|
|
178
|
+
providers: [
|
|
179
|
+
{
|
|
180
|
+
provide: 'IQueue',
|
|
181
|
+
useFactory: () =>
|
|
182
|
+
new AzureQueue({
|
|
183
|
+
connectionString: 'Endpoint=sb://...',
|
|
184
|
+
receiveWaitMs: 5_000,
|
|
185
|
+
}),
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
exports: ['IQueue'],
|
|
189
|
+
})
|
|
190
|
+
export class QueueModule {}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### How It Works
|
|
194
|
+
|
|
195
|
+
Senders and receivers are lazily created per queue name and cached for the lifetime of the instance. `enqueue()` sends a message to the queue, `dequeue()` receives the next message with peek-lock, `markCompleted()` completes the message, and `markFailed()` dead-letters it.
|
|
196
|
+
|
|
197
|
+
### Graceful Shutdown
|
|
198
|
+
|
|
199
|
+
`AzureQueue` implements `OnModuleDestroy` and automatically closes all senders, receivers, and the underlying `ServiceBusClient` when the module is destroyed.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Usage in Services
|
|
204
|
+
|
|
205
|
+
Inject the `IQueue` token and use the same API regardless of the underlying provider:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
209
|
+
import { IQueue, QUEUE_JOB_STATUS } from '@breadstone/archipel-platform-queue';
|
|
210
|
+
|
|
211
|
+
@Injectable()
|
|
212
|
+
export class InvoiceService {
|
|
213
|
+
// #region Fields
|
|
214
|
+
|
|
215
|
+
private readonly _queue: IQueue;
|
|
216
|
+
|
|
217
|
+
// #endregion
|
|
218
|
+
|
|
219
|
+
// #region Ctor
|
|
220
|
+
|
|
221
|
+
constructor(@Inject('IQueue') queue: IQueue) {
|
|
222
|
+
this._queue = queue;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// #endregion
|
|
226
|
+
|
|
227
|
+
// #region Methods
|
|
228
|
+
|
|
229
|
+
public async scheduleInvoice(invoiceId: number): Promise<void> {
|
|
230
|
+
await this._queue.enqueue('invoices', { invoiceId });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public async processNext(): Promise<void> {
|
|
234
|
+
const job = await this._queue.dequeue<{ invoiceId: number }>('invoices');
|
|
235
|
+
|
|
236
|
+
if (!job) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
// ... process the invoice
|
|
242
|
+
await this._queue.markCompleted(job.id);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
await this._queue.markFailed(job.id, (error as Error).message);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// #endregion
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Error Handling
|
|
255
|
+
|
|
256
|
+
All queue implementations throw domain-specific errors that extend `QueueError`:
|
|
257
|
+
|
|
258
|
+
| Error Class | When Thrown |
|
|
259
|
+
| ----------------------- | ------------------------------------------------------- |
|
|
260
|
+
| `QueueValidationError` | Empty or whitespace-only queue name or error message |
|
|
261
|
+
| `QueueJobNotFoundError` | Job ID does not exist in the underlying store |
|
|
262
|
+
| `QueueJobStateError` | Job is in the wrong state for the requested transition |
|
|
263
|
+
|
|
264
|
+
Handle these in your service layer or map them centrally via an exception filter:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { QueueJobNotFoundError, QueueJobStateError } from '@breadstone/archipel-platform-queue';
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await this._queue.markCompleted(jobId);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
if (error instanceof QueueJobNotFoundError) {
|
|
273
|
+
this._logger.warn(`Job ${jobId} not found — may have been evicted.`);
|
|
274
|
+
} else if (error instanceof QueueJobStateError) {
|
|
275
|
+
this._logger.warn(`Job ${jobId} is not in processing state.`);
|
|
276
|
+
} else {
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Listing Jobs
|
|
285
|
+
|
|
286
|
+
Use `getJobs()` to retrieve all jobs for a named queue. This is useful for admin dashboards or monitoring:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
const jobs = await this._queue.getJobs('invoices');
|
|
290
|
+
|
|
291
|
+
const pending = jobs.filter((j) => j.status === QUEUE_JOB_STATUS.pending);
|
|
292
|
+
const failed = jobs.filter((j) => j.status === QUEUE_JOB_STATUS.failed);
|
|
293
|
+
|
|
294
|
+
this._logger.log(`Queue 'invoices': ${pending.length} pending, ${failed.length} failed`);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Switching Providers
|
|
300
|
+
|
|
301
|
+
Swap the provider by changing the import — no business logic changes needed:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// Before: in-memory
|
|
305
|
+
import { MemoryQueue } from '@breadstone/archipel-platform-queue';
|
|
306
|
+
useFactory: () => new MemoryQueue({ maxJobs: 10_000 }),
|
|
307
|
+
|
|
308
|
+
// After: Redis
|
|
309
|
+
import { BullMqQueue } from '@breadstone/archipel-platform-queue/bullmq';
|
|
310
|
+
useFactory: () => new BullMqQueue({ redisUrl: 'redis://localhost:6379' }),
|
|
311
|
+
|
|
312
|
+
// After: Azure Service Bus
|
|
313
|
+
import { AzureQueue } from '@breadstone/archipel-platform-queue/azure';
|
|
314
|
+
useFactory: () => new AzureQueue({ connectionString: 'Endpoint=sb://...' }),
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Best Practices
|
|
320
|
+
|
|
321
|
+
| Practice | Why |
|
|
322
|
+
| ------------------------------------------- | --------------------------------------------------------------------- |
|
|
323
|
+
| Use `MemoryQueue` only for dev and tests | Data is lost on restart; not suitable for production workloads |
|
|
324
|
+
| Set `maxJobs` for `MemoryQueue` | Prevents unbounded memory growth in long-running processes |
|
|
325
|
+
| Always handle `markFailed` | Ensures failed jobs are properly tracked and not stuck in processing |
|
|
326
|
+
| Use typed payloads with generics | `enqueue<T>()` and `dequeue<T>()` keep your job data type-safe |
|
|
327
|
+
| Rely on `OnModuleDestroy` for cleanup | Both `BullMqQueue` and `AzureQueue` close connections automatically |
|
|
328
|
+
| Keep queue names short and descriptive | e.g. `invoices`, `emails`, `reports` — avoid deeply nested names |
|
|
329
|
+
| Wrap queue calls in services | Never call `IQueue` directly from controllers |
|
|
@@ -135,6 +135,26 @@ export class PaymentService {
|
|
|
135
135
|
|
|
136
136
|
All log entries automatically include `requestId` for request-level correlation.
|
|
137
137
|
|
|
138
|
+
### ContextLogger (from platform-logging)
|
|
139
|
+
|
|
140
|
+
For services that need automatic request context enrichment without manual `requestId` plumbing, use `ContextLogger` from `platform-logging`:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { ContextLogger } from '@breadstone/archipel-platform-logging';
|
|
144
|
+
|
|
145
|
+
@Injectable()
|
|
146
|
+
export class OrderService {
|
|
147
|
+
private readonly _logger = new ContextLogger(OrderService.name);
|
|
148
|
+
|
|
149
|
+
public async processOrder(orderId: string): Promise<void> {
|
|
150
|
+
this._logger.log('Processing order', { orderId });
|
|
151
|
+
// Automatically includes requestId + userId from RequestContextStore
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Pair with `RequestIdMiddleware` to propagate the `x-request-id` header across the request lifecycle. See the [platform-logging docs](../packages/platform-logging/) for setup details.
|
|
157
|
+
|
|
138
158
|
---
|
|
139
159
|
|
|
140
160
|
## Automatic Operation Instrumentation
|
|
@@ -120,6 +120,26 @@ Clear the current user context.
|
|
|
120
120
|
|
|
121
121
|
***
|
|
122
122
|
|
|
123
|
+
### ping()
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
ping(): Promise<boolean>;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Defined in: [contracts/AnalyticsClientPort.ts:69](https://github.com/RueDeRennes/archipel/blob/main/libs/platform-analytics/src/contracts/AnalyticsClientPort.ts#L69)
|
|
130
|
+
|
|
131
|
+
Lightweight readiness check for the analytics provider.
|
|
132
|
+
Override in adapters to verify SDK initialization.
|
|
133
|
+
Defaults to `true` if not overridden.
|
|
134
|
+
|
|
135
|
+
#### Returns
|
|
136
|
+
|
|
137
|
+
`Promise`\<`boolean`\>
|
|
138
|
+
|
|
139
|
+
`true` if the provider is ready.
|
|
140
|
+
|
|
141
|
+
***
|
|
142
|
+
|
|
123
143
|
### setUser()
|
|
124
144
|
|
|
125
145
|
```ts
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Class: AnalyticsHealthIndicator'
|
|
3
|
+
generated: true
|
|
4
|
+
editUrl: false
|
|
5
|
+
---
|
|
6
|
+
# Class: AnalyticsHealthIndicator
|
|
7
|
+
|
|
8
|
+
Defined in: health/AnalyticsHealthIndicator.ts:17
|
|
9
|
+
|
|
10
|
+
Health indicator for the analytics infrastructure.
|
|
11
|
+
Calls [AnalyticsClientPort.ping](Class.AnalyticsClientPort#ping) to verify provider readiness.
|
|
12
|
+
|
|
13
|
+
## Implements
|
|
14
|
+
|
|
15
|
+
- `IHealthIndicator`
|
|
16
|
+
|
|
17
|
+
## Constructors
|
|
18
|
+
|
|
19
|
+
### Constructor
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
new AnalyticsHealthIndicator(analyticsClient?): AnalyticsHealthIndicator;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Defined in: health/AnalyticsHealthIndicator.ts:27
|
|
26
|
+
|
|
27
|
+
#### Parameters
|
|
28
|
+
|
|
29
|
+
| Parameter | Type |
|
|
30
|
+
| ------ | ------ |
|
|
31
|
+
| `analyticsClient?` | [`AnalyticsClientPort`](Class.AnalyticsClientPort) |
|
|
32
|
+
|
|
33
|
+
#### Returns
|
|
34
|
+
|
|
35
|
+
`AnalyticsHealthIndicator`
|
|
36
|
+
|
|
37
|
+
## Properties
|
|
38
|
+
|
|
39
|
+
### key
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
readonly key: string = 'analytics';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Defined in: health/AnalyticsHealthIndicator.ts:35
|
|
46
|
+
|
|
47
|
+
Unique key identifying the indicator
|
|
48
|
+
|
|
49
|
+
#### Implementation of
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
IHealthIndicator.key
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Methods
|
|
56
|
+
|
|
57
|
+
### check()
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
check(): Promise<HealthIndicatorResult<string>>;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Defined in: health/AnalyticsHealthIndicator.ts:48
|
|
64
|
+
|
|
65
|
+
Pings the analytics provider to verify readiness.
|
|
66
|
+
Returns disabled status when no client is configured.
|
|
67
|
+
|
|
68
|
+
#### Returns
|
|
69
|
+
|
|
70
|
+
`Promise`\<`HealthIndicatorResult`\<`string`\>\>
|
|
71
|
+
|
|
72
|
+
The health indicator result.
|
|
73
|
+
|
|
74
|
+
#### Implementation of
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
IHealthIndicator.check
|
|
78
|
+
```
|
|
@@ -193,6 +193,30 @@ OnModuleInit.onModuleInit
|
|
|
193
193
|
|
|
194
194
|
***
|
|
195
195
|
|
|
196
|
+
### ping()
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
ping(): Promise<boolean>;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Defined in: [contracts/AnalyticsClientPort.ts:69](https://github.com/RueDeRennes/archipel/blob/main/libs/platform-analytics/src/contracts/AnalyticsClientPort.ts#L69)
|
|
203
|
+
|
|
204
|
+
Lightweight readiness check for the analytics provider.
|
|
205
|
+
Override in adapters to verify SDK initialization.
|
|
206
|
+
Defaults to `true` if not overridden.
|
|
207
|
+
|
|
208
|
+
#### Returns
|
|
209
|
+
|
|
210
|
+
`Promise`\<`boolean`\>
|
|
211
|
+
|
|
212
|
+
`true` if the provider is ready.
|
|
213
|
+
|
|
214
|
+
#### Inherited from
|
|
215
|
+
|
|
216
|
+
[`AnalyticsClientPort`](Class.AnalyticsClientPort).[`ping`](Class.AnalyticsClientPort#ping)
|
|
217
|
+
|
|
218
|
+
***
|
|
219
|
+
|
|
196
220
|
### setUser()
|
|
197
221
|
|
|
198
222
|
```ts
|
|
@@ -170,6 +170,30 @@ OnModuleInit.onModuleInit
|
|
|
170
170
|
|
|
171
171
|
***
|
|
172
172
|
|
|
173
|
+
### ping()
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
ping(): Promise<boolean>;
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Defined in: [contracts/AnalyticsClientPort.ts:69](https://github.com/RueDeRennes/archipel/blob/main/libs/platform-analytics/src/contracts/AnalyticsClientPort.ts#L69)
|
|
180
|
+
|
|
181
|
+
Lightweight readiness check for the analytics provider.
|
|
182
|
+
Override in adapters to verify SDK initialization.
|
|
183
|
+
Defaults to `true` if not overridden.
|
|
184
|
+
|
|
185
|
+
#### Returns
|
|
186
|
+
|
|
187
|
+
`Promise`\<`boolean`\>
|
|
188
|
+
|
|
189
|
+
`true` if the provider is ready.
|
|
190
|
+
|
|
191
|
+
#### Inherited from
|
|
192
|
+
|
|
193
|
+
[`AnalyticsClientPort`](Class.AnalyticsClientPort).[`ping`](Class.AnalyticsClientPort#ping)
|
|
194
|
+
|
|
195
|
+
***
|
|
196
|
+
|
|
173
197
|
### setUser()
|
|
174
198
|
|
|
175
199
|
```ts
|
|
@@ -136,6 +136,30 @@ Clear the current user context.
|
|
|
136
136
|
|
|
137
137
|
***
|
|
138
138
|
|
|
139
|
+
### ping()
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
ping(): Promise<boolean>;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Defined in: [contracts/AnalyticsClientPort.ts:69](https://github.com/RueDeRennes/archipel/blob/main/libs/platform-analytics/src/contracts/AnalyticsClientPort.ts#L69)
|
|
146
|
+
|
|
147
|
+
Lightweight readiness check for the analytics provider.
|
|
148
|
+
Override in adapters to verify SDK initialization.
|
|
149
|
+
Defaults to `true` if not overridden.
|
|
150
|
+
|
|
151
|
+
#### Returns
|
|
152
|
+
|
|
153
|
+
`Promise`\<`boolean`\>
|
|
154
|
+
|
|
155
|
+
`true` if the provider is ready.
|
|
156
|
+
|
|
157
|
+
#### Inherited from
|
|
158
|
+
|
|
159
|
+
[`AnalyticsClientPort`](Class.AnalyticsClientPort).[`ping`](Class.AnalyticsClientPort#ping)
|
|
160
|
+
|
|
161
|
+
***
|
|
162
|
+
|
|
139
163
|
### setUser()
|
|
140
164
|
|
|
141
165
|
```ts
|
|
@@ -193,6 +193,30 @@ OnModuleInit.onModuleInit
|
|
|
193
193
|
|
|
194
194
|
***
|
|
195
195
|
|
|
196
|
+
### ping()
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
ping(): Promise<boolean>;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Defined in: [contracts/AnalyticsClientPort.ts:69](https://github.com/RueDeRennes/archipel/blob/main/libs/platform-analytics/src/contracts/AnalyticsClientPort.ts#L69)
|
|
203
|
+
|
|
204
|
+
Lightweight readiness check for the analytics provider.
|
|
205
|
+
Override in adapters to verify SDK initialization.
|
|
206
|
+
Defaults to `true` if not overridden.
|
|
207
|
+
|
|
208
|
+
#### Returns
|
|
209
|
+
|
|
210
|
+
`Promise`\<`boolean`\>
|
|
211
|
+
|
|
212
|
+
`true` if the provider is ready.
|
|
213
|
+
|
|
214
|
+
#### Inherited from
|
|
215
|
+
|
|
216
|
+
[`AnalyticsClientPort`](Class.AnalyticsClientPort).[`ping`](Class.AnalyticsClientPort#ping)
|
|
217
|
+
|
|
218
|
+
***
|
|
219
|
+
|
|
196
220
|
### setUser()
|
|
197
221
|
|
|
198
222
|
```ts
|
|
@@ -10,6 +10,7 @@ editUrl: false
|
|
|
10
10
|
| Class | Description |
|
|
11
11
|
| ------ | ------ |
|
|
12
12
|
| [AnalyticsClientPort](Class.AnalyticsClientPort) | Abstract port for analytics and error tracking clients. Each provider (Sentry, Application Insights, Datadog) must implement this contract so that the consuming application can switch providers without changing business logic. |
|
|
13
|
+
| [AnalyticsHealthIndicator](Class.AnalyticsHealthIndicator) | Health indicator for the analytics infrastructure. Calls [AnalyticsClientPort.ping](Class.AnalyticsClientPort#ping) to verify provider readiness. |
|
|
13
14
|
| [AnalyticsModule](Class.AnalyticsModule) | NestJS module providing generic analytics and error tracking infrastructure. The specific analytics provider (Sentry, Application Insights, Datadog) is selected via the options. |
|
|
14
15
|
| [AppInsightsAnalyticsClient](Class.AppInsightsAnalyticsClient) | Azure Application Insights implementation of the [AnalyticsClientPort](Class.AnalyticsClientPort). Uses the `applicationinsights` SDK for error tracking and analytics. |
|
|
15
16
|
| [DatadogAnalyticsClient](Class.DatadogAnalyticsClient) | Datadog implementation of the [AnalyticsClientPort](Class.AnalyticsClientPort). Uses the `dd-trace` SDK for error tracking and analytics. |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: platform-analytics
|
|
3
3
|
description: Provider-agnostic analytics and error tracking with pluggable clients.
|
|
4
4
|
order: 14
|
|
5
|
-
tags: [analytics, error-tracking, sentry, application-insights, datadog, observability, providers]
|
|
5
|
+
tags: [analytics, error-tracking, sentry, application-insights, datadog, observability, providers, health]
|
|
6
6
|
package: '@breadstone/archipel-platform-analytics'
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -168,6 +168,29 @@ This ensures no events are lost during application shutdown and prevents hanging
|
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
|
+
## Health Check
|
|
172
|
+
|
|
173
|
+
The `AnalyticsHealthIndicator` verifies that an `AnalyticsClientPort` is injected. If no analytics client is registered, it reports `disabled: true`. Import it from the `/health` subpath:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { AnalyticsHealthIndicator } from '@breadstone/archipel-platform-analytics/health';
|
|
177
|
+
import { HealthModule } from '@breadstone/archipel-platform-health';
|
|
178
|
+
|
|
179
|
+
@Module({
|
|
180
|
+
imports: [
|
|
181
|
+
AnalyticsModule.register({ /* ... */ }),
|
|
182
|
+
HealthModule.withIndicators([AnalyticsHealthIndicator]),
|
|
183
|
+
],
|
|
184
|
+
})
|
|
185
|
+
export class AppModule {}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
| Key | Check | Dependencies |
|
|
189
|
+
| --- | ----- | ------------ |
|
|
190
|
+
| `analytics` | `up` if `AnalyticsClientPort` injected, else `disabled` | `@Optional() AnalyticsClientPort` |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
171
194
|
## Exports Summary
|
|
172
195
|
|
|
173
196
|
| Export | Type | Description |
|
|
@@ -181,3 +204,4 @@ This ensures no events are lost during application shutdown and prevents hanging
|
|
|
181
204
|
| `AnalyticsLevel` | Type | Severity level union |
|
|
182
205
|
| `IAnalyticsBreadcrumb` | Interface | Breadcrumb entry model |
|
|
183
206
|
| `IAnalyticsUser` | Interface | User context model |
|
|
207
|
+
| `AnalyticsHealthIndicator` | Health | Analytics readiness check (`/health` subpath) |
|