@breadstone/archipel-mcp 0.0.23 → 0.0.26
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/data/guides/caching.md +33 -0
- package/data/guides/email-delivery.md +27 -1
- 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/index.md +1 -0
- 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 +10 -10
- 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 +113 -49
- package/data/packages/platform-database/api/Class.RepositoryBase2.md +171 -0
- package/data/packages/platform-database/api/Function.aggregate.md +33 -0
- package/data/packages/platform-database/api/Function.aggregateRaw.md +34 -0
- package/data/packages/platform-database/api/Function.count.md +33 -0
- package/data/packages/platform-database/api/Function.create.md +33 -0
- package/data/packages/platform-database/api/Function.createMany.md +33 -0
- package/data/packages/platform-database/api/Function.createManyAndReturn.md +35 -0
- package/data/packages/platform-database/api/Function.findFirst.md +35 -0
- package/data/packages/platform-database/api/Function.findFirstOrThrow.md +34 -0
- package/data/packages/platform-database/api/Function.findMany.md +32 -0
- package/data/packages/platform-database/api/Function.findManyPaged.md +34 -0
- package/data/packages/platform-database/api/Function.findRaw.md +34 -0
- package/data/packages/platform-database/api/Function.findUnique.md +32 -0
- package/data/packages/platform-database/api/Function.findUniqueOrThrow.md +34 -0
- package/data/packages/platform-database/api/Function.groupBy.md +33 -0
- package/data/packages/platform-database/api/Function.paginator.md +1 -1
- package/data/packages/platform-database/api/Function.pipe.md +34 -0
- package/data/packages/platform-database/api/Function.pipeAll.md +35 -0
- package/data/packages/platform-database/api/Function.query2.md +35 -0
- package/data/packages/platform-database/api/Function.remove.md +33 -0
- package/data/packages/platform-database/api/Function.removeMany.md +33 -0
- package/data/packages/platform-database/api/Function.update.md +33 -0
- package/data/packages/platform-database/api/Function.updateMany.md +33 -0
- package/data/packages/platform-database/api/Function.updateManyAndReturn.md +35 -0
- package/data/packages/platform-database/api/Function.upsert.md +33 -0
- package/data/packages/platform-database/api/Interface.IDatabaseModuleConfig.md +3 -3
- package/data/packages/platform-database/api/Interface.IRepositoryQuery2.md +45 -0
- package/data/packages/platform-database/api/TypeAlias.DelegateArgs.md +1 -1
- package/data/packages/platform-database/api/TypeAlias.DelegateOperations.md +29 -0
- 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/TypeAlias.RepositoryOperationsAll.md +19 -0
- package/data/packages/platform-database/api/TypeAlias.RepositoryOperationsBase.md +34 -0
- package/data/packages/platform-database/api/Variable.DATABASE_MODULE_CONFIG.md +1 -1
- package/data/packages/platform-database/api/index.md +29 -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 +18 -7
- 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-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-telemetry/api/Class.OtelSdkHolder.md +20 -2
- 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 +3 -1
- package/package.json +1 -1
package/data/guides/caching.md
CHANGED
|
@@ -24,6 +24,39 @@ yarn add ioredis
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
### Core Variables
|
|
30
|
+
|
|
31
|
+
```env
|
|
32
|
+
CACHE_DEFAULT_TTL_MS=60000
|
|
33
|
+
CACHE_MAX_ENTRIES=1000
|
|
34
|
+
CACHE_STALE_WHILE_REVALIDATE=false
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
All core variables are optional. When omitted, each cache instance uses the values passed directly to its constructor options.
|
|
38
|
+
|
|
39
|
+
### Redis Variables
|
|
40
|
+
|
|
41
|
+
```env
|
|
42
|
+
REDIS_URL=redis://localhost:6379
|
|
43
|
+
REDIS_KEY_PREFIX=app:
|
|
44
|
+
REDIS_TTL_SECONDS=300
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`REDIS_URL` is required when using `RedisLayeredCache`. The other variables are optional.
|
|
48
|
+
|
|
49
|
+
### Using Config Keys
|
|
50
|
+
|
|
51
|
+
Import the typed config keys and pass them to your module registration:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { PLATFORM_CACHING_CONFIG_ENTRIES } from '@breadstone/archipel-platform-caching';
|
|
55
|
+
import { REDIS_CONFIG_ENTRIES } from '@breadstone/archipel-platform-caching/redis';
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
27
60
|
## Concepts
|
|
28
61
|
|
|
29
62
|
`platform-caching` provides a generic `ILayeredCache<TKey, TValue>` interface with two implementations:
|
|
@@ -147,7 +147,33 @@ The `template` field is the template name (without extension). The `context` obj
|
|
|
147
147
|
|
|
148
148
|
---
|
|
149
149
|
|
|
150
|
-
##
|
|
150
|
+
## SMTP Connection Verification
|
|
151
|
+
|
|
152
|
+
`SmtpConnectionVerifier` verifies SMTP server connectivity and optionally sends a test email. It replaces the deprecated `MailVerificationService`.
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { Injectable } from '@nestjs/common';
|
|
156
|
+
import { SmtpConnectionVerifier } from '@breadstone/archipel-platform-mailing';
|
|
157
|
+
|
|
158
|
+
@Injectable()
|
|
159
|
+
export class HealthService {
|
|
160
|
+
constructor(private readonly _smtpVerifier: SmtpConnectionVerifier) {}
|
|
161
|
+
|
|
162
|
+
public async checkSmtpConnectivity(): Promise<boolean> {
|
|
163
|
+
return this._smtpVerifier.verifyConnection();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async sendTestEmail(to: string): Promise<boolean> {
|
|
167
|
+
return this._smtpVerifier.sendTestEmail(to);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Email Verification (Deprecated)
|
|
173
|
+
|
|
174
|
+
::: warning Deprecated
|
|
175
|
+
`MailVerificationService` is deprecated. Use `SmtpConnectionVerifier` for SMTP connectivity checks.
|
|
176
|
+
:::
|
|
151
177
|
|
|
152
178
|
`MailVerificationService` provides a complete email verification flow:
|
|
153
179
|
|
|
@@ -56,11 +56,17 @@ export class AppModule {}
|
|
|
56
56
|
|
|
57
57
|
## Configuration
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
Each provider requires its own set of environment variables. See the [platform-esigning package docs](../packages/platform-esigning/) for the full table per provider.
|
|
60
|
+
|
|
61
|
+
### Provider Environment Variables (Summary)
|
|
62
|
+
|
|
63
|
+
| Provider | Key Variables |
|
|
64
|
+
| -------------- | -------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| **DocuSign** | `DOCUSIGN_INTEGRATION_KEY`, `DOCUSIGN_SECRET_KEY`, `DOCUSIGN_ACCOUNT_ID`, `DOCUSIGN_BASE_URL` |
|
|
66
|
+
| **Adobe Sign** | `ADOBE_SIGN_INTEGRATION_KEY`, `ADOBE_SIGN_CLIENT_SECRET`, `ADOBE_SIGN_BASE_URL`, `ADOBE_SIGN_WEBHOOK_CLIENT_ID` (required) |
|
|
67
|
+
| **Dropbox Sign** | `DROPBOX_SIGN_API_KEY`, `DROPBOX_SIGN_CLIENT_ID` |
|
|
68
|
+
|
|
69
|
+
> **Breaking change:** `ADOBE_SIGN_WEBHOOK_CLIENT_ID` is now **required** for Adobe Sign webhook verification.
|
|
64
70
|
|
|
65
71
|
---
|
|
66
72
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Health Indicators
|
|
3
|
+
description: Integrate health checks from all Archipel platform libraries using the unified health indicator architecture.
|
|
4
|
+
order: 10
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Health Indicators
|
|
8
|
+
|
|
9
|
+
Every Archipel platform library ships an optional **health indicator** as a separate `/health` subpath export. Health indicators implement the `IHealthIndicator` interface from `platform-health` and can be registered with the `HealthModule` to build a unified `/health` endpoint for your application.
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart LR
|
|
15
|
+
subgraph App
|
|
16
|
+
HealthController --> HealthOrchestrator
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subgraph platform-health
|
|
20
|
+
HealthOrchestrator
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
subgraph Indicators
|
|
24
|
+
DatabaseHealthIndicator
|
|
25
|
+
BlobHealthIndicator
|
|
26
|
+
MailHealthIndicator
|
|
27
|
+
CachingHealthIndicator
|
|
28
|
+
QueueHealthIndicator
|
|
29
|
+
PaymentHealthIndicator
|
|
30
|
+
EsigningHealthIndicator
|
|
31
|
+
IntelligenceHealthIndicator
|
|
32
|
+
AnalyticsHealthIndicator
|
|
33
|
+
TelemetryHealthIndicator
|
|
34
|
+
AuthenticationHealthIndicator
|
|
35
|
+
McpHealthIndicator
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
HealthOrchestrator --> Indicators
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `HealthOrchestrator` aggregates all registered `IHealthIndicator` instances and returns a combined result. Each indicator reports its own key and status independently.
|
|
42
|
+
|
|
43
|
+
## Prerequisites
|
|
44
|
+
|
|
45
|
+
- `@breadstone/archipel-platform-health` installed
|
|
46
|
+
- `@nestjs/terminus` installed (peer dependency)
|
|
47
|
+
|
|
48
|
+
## IHealthIndicator Interface
|
|
49
|
+
|
|
50
|
+
Every health indicator implements this contract:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
interface IHealthIndicator {
|
|
54
|
+
/** Unique key identifying this indicator in the health response. */
|
|
55
|
+
readonly key: string;
|
|
56
|
+
|
|
57
|
+
/** Run the health check and return a Terminus HealthIndicatorResult. */
|
|
58
|
+
check(): HealthIndicatorResult | Promise<HealthIndicatorResult>;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Available Indicators
|
|
63
|
+
|
|
64
|
+
All 12 platform libraries provide a health indicator via their `/health` subpath:
|
|
65
|
+
|
|
66
|
+
| Library | Subpath Import | Class | Key | Check Behavior |
|
|
67
|
+
| ------- | -------------- | ----- | --- | -------------- |
|
|
68
|
+
| `platform-database` | `@breadstone/archipel-platform-database/health` | `DatabaseHealthIndicator` | `database` | Prisma `SELECT 1` ping |
|
|
69
|
+
| `platform-blob-storage` | `@breadstone/archipel-platform-blob-storage/health` | `BlobHealthIndicator` | `blob` | HTTP ping to blob URL (or `disabled` if unconfigured) |
|
|
70
|
+
| `platform-mailing` | `@breadstone/archipel-platform-mailing/health` | `MailHealthIndicator` | `mail` | Validates mail host, user, and port config |
|
|
71
|
+
| `platform-caching` | `@breadstone/archipel-platform-caching/health` | `CachingHealthIndicator` | `caching` | Always `up` |
|
|
72
|
+
| `platform-queue` | `@breadstone/archipel-platform-queue/health` | `QueueHealthIndicator` | `queue` | Always `up` |
|
|
73
|
+
| `platform-payments` | `@breadstone/archipel-platform-payments/health` | `PaymentHealthIndicator` | `payment` | Calls `PaymentClientPort.ping()` to verify provider connectivity |
|
|
74
|
+
| `platform-esigning` | `@breadstone/archipel-platform-esigning/health` | `EsigningHealthIndicator` | `esigning` | Calls `EsigningClientPort.ping()` to verify provider connectivity, reports `providerId` |
|
|
75
|
+
| `platform-intelligence` | `@breadstone/archipel-platform-intelligence/health` | `IntelligenceHealthIndicator` | `intelligence` | Checks `list().length > 0` on the capability registry, reports count |
|
|
76
|
+
| `platform-analytics` | `@breadstone/archipel-platform-analytics/health` | `AnalyticsHealthIndicator` | `analytics` | Calls `AnalyticsClientPort.ping()` to verify provider readiness |
|
|
77
|
+
| `platform-telemetry` | `@breadstone/archipel-platform-telemetry/health` | `TelemetryHealthIndicator` | `telemetry` | Checks `OtelSdkHolder.isInitialized` for SDK presence |
|
|
78
|
+
| `platform-authentication` | `@breadstone/archipel-platform-authentication/health` | `AuthenticationHealthIndicator` | `authentication` | Always `up` |
|
|
79
|
+
| `platform-mcp` | `@breadstone/archipel-platform-mcp/health` | `McpHealthIndicator` | `mcp` | Checks tool/resource/prompt registry counts, reports breakdown |
|
|
80
|
+
|
|
81
|
+
### Indicator Categories
|
|
82
|
+
|
|
83
|
+
**Active checks** — perform a real probe:
|
|
84
|
+
- `DatabaseHealthIndicator` — executes a SQL ping
|
|
85
|
+
- `BlobHealthIndicator` — sends an HTTP request to the blob URL
|
|
86
|
+
- `MailHealthIndicator` — validates configuration values
|
|
87
|
+
- `PaymentHealthIndicator` — calls `PaymentClientPort.ping()` (adapters can override for real API calls)
|
|
88
|
+
- `EsigningHealthIndicator` — calls `EsigningClientPort.ping()` (adapters can override for real API calls)
|
|
89
|
+
- `AnalyticsHealthIndicator` — calls `AnalyticsClientPort.ping()` (adapters can override for SDK readiness checks)
|
|
90
|
+
|
|
91
|
+
**State checks** — inspect in-memory state (zero-cost, no I/O):
|
|
92
|
+
- `IntelligenceHealthIndicator` — verifies at least one capability is registered
|
|
93
|
+
- `TelemetryHealthIndicator` — checks whether the OpenTelemetry SDK has been initialized
|
|
94
|
+
- `McpHealthIndicator` — verifies at least one tool/resource/prompt handler is registered
|
|
95
|
+
|
|
96
|
+
**Stub checks** — always report `up`:
|
|
97
|
+
- `CachingHealthIndicator`, `QueueHealthIndicator`, `AuthenticationHealthIndicator`
|
|
98
|
+
|
|
99
|
+
## Quick Start
|
|
100
|
+
|
|
101
|
+
### 1. Register Indicators
|
|
102
|
+
|
|
103
|
+
Use `HealthModule.withIndicators()` to register the indicators you need:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { Module } from '@nestjs/common';
|
|
107
|
+
import { HealthModule } from '@breadstone/archipel-platform-health';
|
|
108
|
+
import { DatabaseHealthIndicator } from '@breadstone/archipel-platform-database/health';
|
|
109
|
+
import { MailHealthIndicator } from '@breadstone/archipel-platform-mailing/health';
|
|
110
|
+
import { PaymentHealthIndicator } from '@breadstone/archipel-platform-payments/health';
|
|
111
|
+
import { CachingHealthIndicator } from '@breadstone/archipel-platform-caching/health';
|
|
112
|
+
|
|
113
|
+
@Module({
|
|
114
|
+
imports: [
|
|
115
|
+
// ... your feature modules
|
|
116
|
+
HealthModule.withIndicators([
|
|
117
|
+
DatabaseHealthIndicator,
|
|
118
|
+
MailHealthIndicator,
|
|
119
|
+
PaymentHealthIndicator,
|
|
120
|
+
CachingHealthIndicator,
|
|
121
|
+
]),
|
|
122
|
+
],
|
|
123
|
+
})
|
|
124
|
+
export class AppModule {}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 2. Expose a Health Endpoint
|
|
128
|
+
|
|
129
|
+
The `HealthOrchestrator` runs all registered indicators and returns an aggregated result:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { Controller, Get } from '@nestjs/common';
|
|
133
|
+
import { HealthOrchestrator } from '@breadstone/archipel-platform-health';
|
|
134
|
+
|
|
135
|
+
@Controller('health')
|
|
136
|
+
export class HealthController {
|
|
137
|
+
constructor(private readonly _health: HealthOrchestrator) {}
|
|
138
|
+
|
|
139
|
+
@Get()
|
|
140
|
+
public async check() {
|
|
141
|
+
return this._health.check();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 3. Example Response
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"status": "ok",
|
|
151
|
+
"details": {
|
|
152
|
+
"database": { "status": "up" },
|
|
153
|
+
"mail": { "status": "up" },
|
|
154
|
+
"payment": { "status": "up" },
|
|
155
|
+
"caching": { "status": "up" },
|
|
156
|
+
"intelligence": { "status": "up", "registeredCapabilities": 3 },
|
|
157
|
+
"mcp": { "status": "up", "tools": 5, "resources": 2, "prompts": 1 },
|
|
158
|
+
"telemetry": { "status": "up", "sdkInitialized": true }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
When a provider is not registered (e.g., no `PaymentClientPort` injected), the indicator reports:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"payment": { "status": "up", "disabled": true }
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
When a ping fails, the indicator reports `down` with error details:
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"payment": { "status": "down", "error": "ECONNREFUSED" }
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Writing a Custom Indicator
|
|
180
|
+
|
|
181
|
+
Implement `IHealthIndicator` to create a health check for your own services:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { Injectable } from '@nestjs/common';
|
|
185
|
+
import { IHealthIndicator } from '@breadstone/archipel-platform-health';
|
|
186
|
+
import type { HealthIndicatorResult } from '@nestjs/terminus';
|
|
187
|
+
|
|
188
|
+
@Injectable()
|
|
189
|
+
export class SearchHealthIndicator implements IHealthIndicator {
|
|
190
|
+
public readonly key = 'search';
|
|
191
|
+
|
|
192
|
+
public check(): HealthIndicatorResult<'search'> {
|
|
193
|
+
return { search: { status: 'up' } };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Register it alongside built-in indicators:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
HealthModule.withIndicators([
|
|
202
|
+
DatabaseHealthIndicator,
|
|
203
|
+
SearchHealthIndicator,
|
|
204
|
+
]);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Tree-Shaking
|
|
208
|
+
|
|
209
|
+
Health indicators are **not** included in the main library entry point. They are exported from a separate `/health` subpath, so they are fully tree-shakeable. If you don't import the health subpath, the indicator code and its `@nestjs/terminus` peer dependency are never bundled.
|
|
210
|
+
|
|
211
|
+
## Peer Dependencies
|
|
212
|
+
|
|
213
|
+
Each health indicator requires these optional peer dependencies:
|
|
214
|
+
|
|
215
|
+
| Package | Notes |
|
|
216
|
+
| ------- | ----- |
|
|
217
|
+
| `@breadstone/archipel-platform-health` | `IHealthIndicator` interface and `HealthModule` |
|
|
218
|
+
| `@nestjs/terminus` | `HealthIndicatorResult` type |
|
|
219
|
+
|
|
220
|
+
Both are listed as optional peer dependencies in each library's `package.json`.
|
package/data/guides/index.md
CHANGED
|
@@ -52,6 +52,8 @@ Practical guides for working with Archipel packages in your NestJS application.
|
|
|
52
52
|
| [Telemetry & Observability](./telemetry-and-observability) | OpenTelemetry metrics, distributed tracing, and structured logging. |
|
|
53
53
|
| [Analytics & Error Tracking](./analytics-and-error-tracking) | Capture errors and user context with Sentry, AppInsights, or Datadog. |
|
|
54
54
|
| [Caching](./caching) | In-memory LRU and Redis layered caches with TTL, stale-while-revalidate, and metrics. |
|
|
55
|
+
| [Queue Infrastructure](./queue-infrastructure) | In-memory FIFO, BullMQ (Redis), and Azure Service Bus job queues. |
|
|
56
|
+
| [Health Indicators](./health-indicators) | Integrate health checks from all platform libraries using the unified health architecture. |
|
|
55
57
|
|
|
56
58
|
## AI & Extensibility
|
|
57
59
|
|
|
@@ -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
|