@breadstone/archipel-mcp 0.0.10 → 0.0.13
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/ai-text-generation.md +361 -0
- package/data/guides/analytics-and-error-tracking.md +189 -0
- package/data/guides/authentication-and-authorization.md +657 -0
- package/data/guides/blob-storage.md +242 -0
- package/data/guides/caching.md +255 -0
- package/data/guides/cryptography-and-otp.md +240 -0
- package/data/guides/database-setup.md +546 -0
- package/data/guides/document-generation.md +174 -0
- package/data/guides/email-delivery.md +196 -0
- package/data/guides/esigning-integration.md +231 -0
- package/data/guides/getting-started.md +351 -0
- package/data/guides/implementing-ports.md +317 -0
- package/data/guides/index.md +62 -0
- package/data/guides/mcp-server.md +222 -0
- package/data/guides/openapi-and-feature-discovery.md +266 -0
- package/data/guides/payments-and-feature-gating.md +244 -0
- package/data/guides/resource-management.md +352 -0
- package/data/guides/telemetry-and-observability.md +190 -0
- package/data/guides/testing.md +319 -0
- package/data/guides/tsdoc-guidelines.md +45 -0
- package/data/packages/platform-database/api/Class.DatabaseModule.md +3 -5
- package/data/packages/platform-database/api/Class.DatabaseService.md +5 -4
- package/data/packages/platform-database/api/Class.PrismaService.md +8 -7
- package/data/packages/platform-database/api/Interface.IDatabaseModuleConfig.md +13 -1
- package/data/packages/platform-database/api/Interface.IPrismaServiceOptions.md +22 -0
- package/data/packages/platform-database/api/Variable.DATABASE_MODULE_CONFIG.md +14 -0
- package/data/packages/platform-database/api/Variable.DB_ACCELERATE_URL.md +14 -0
- package/data/packages/platform-database/api/Variable.DB_AUTO_CONNECTION.md +14 -0
- package/data/packages/platform-database/api/Variable.DB_OPTIMIZE.md +14 -0
- package/data/packages/platform-database/api/Variable.DB_OPTIMIZE_API_KEY.md +14 -0
- package/data/packages/platform-database/api/Variable.PLATFORM_DATABASE_CONFIG_ENTRIES.md +14 -0
- package/data/packages/platform-database/api/index.md +13 -1
- package/data/packages/platform-database/index.md +41 -18
- package/data/packages/platform-openapi/api/Class.SwaggerFeatureDiscovery.md +10 -6
- package/data/packages/platform-telemetry/api/Class.NoopTelemetryFacade.md +10 -10
- package/data/packages/platform-telemetry/api/Interface.ITelemetryFacade.md +1 -1
- package/package.json +1 -1
- package/src/GuidesLoader.d.ts +13 -0
- package/src/GuidesLoader.js +81 -0
- package/src/main.js +36 -198
- package/src/models/IGuideDoc.d.ts +15 -0
- package/src/models/IGuideDoc.js +3 -0
- package/src/tools/registerGetConfigPatternTool.d.ts +5 -0
- package/src/tools/registerGetConfigPatternTool.js +15 -0
- package/src/tools/registerGetDtoPatternTool.d.ts +5 -0
- package/src/tools/registerGetDtoPatternTool.js +15 -0
- package/src/tools/registerGetErrorHandlingPatternTool.d.ts +5 -0
- package/src/tools/registerGetErrorHandlingPatternTool.js +15 -0
- package/src/tools/registerGetGuardPatternTool.d.ts +5 -0
- package/src/tools/registerGetGuardPatternTool.js +15 -0
- package/src/tools/registerGetGuideTool.d.ts +6 -0
- package/src/tools/registerGetGuideTool.js +32 -0
- package/src/tools/registerGetMappingPatternTool.d.ts +5 -0
- package/src/tools/registerGetMappingPatternTool.js +34 -0
- package/src/tools/registerGetModulePatternTool.d.ts +5 -0
- package/src/tools/registerGetModulePatternTool.js +29 -0
- package/src/tools/registerGetPackageDocTool.d.ts +6 -0
- package/src/tools/registerGetPackageDocTool.js +43 -0
- package/src/tools/registerGetQueryPatternTool.d.ts +5 -0
- package/src/tools/registerGetQueryPatternTool.js +29 -0
- package/src/tools/registerGetRepositoryPatternTool.d.ts +5 -0
- package/src/tools/registerGetRepositoryPatternTool.js +29 -0
- package/src/tools/registerGetTestingPatternTool.d.ts +5 -0
- package/src/tools/registerGetTestingPatternTool.js +15 -0
- package/src/tools/registerListGuidesTool.d.ts +6 -0
- package/src/tools/registerListGuidesTool.js +22 -0
- package/src/tools/registerListPackagesTool.d.ts +6 -0
- package/src/tools/registerListPackagesTool.js +20 -0
- package/src/tools/registerSearchDocsTool.d.ts +6 -0
- package/src/tools/registerSearchDocsTool.js +35 -0
- package/src/tools/registerSearchGuidesTool.d.ts +6 -0
- package/src/tools/registerSearchGuidesTool.js +28 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Document Generation
|
|
3
|
+
description: Generate PDF and DOCX documents from templates with variable substitution and image processing.
|
|
4
|
+
order: 11
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Document Generation
|
|
8
|
+
|
|
9
|
+
This guide covers generating documents with `platform-documents`: template setup, variable substitution, image processing, and rendering to PDF or DOCX.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @breadstone/archipel-platform-documents
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Module Registration
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { Module } from '@nestjs/common';
|
|
25
|
+
import { DocumentModule } from '@breadstone/archipel-platform-documents';
|
|
26
|
+
|
|
27
|
+
@Module({
|
|
28
|
+
imports: [
|
|
29
|
+
DocumentModule.forRoot({
|
|
30
|
+
maxImageWidth: 1920,
|
|
31
|
+
maxImageHeight: 1080,
|
|
32
|
+
delimiters: { start: '[[', end: ']]' },
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
})
|
|
36
|
+
export class AppModule {}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Options
|
|
40
|
+
|
|
41
|
+
| Option | Default | Description |
|
|
42
|
+
| ---------------- | ------- | ------------------------------------------------- |
|
|
43
|
+
| `maxImageWidth` | `1920` | Maximum width for embedded images (in pixels) |
|
|
44
|
+
| `maxImageHeight` | `1080` | Maximum height for embedded images (in pixels) |
|
|
45
|
+
| `delimiters` | `[[ ]]` | Start and end delimiters for template variables |
|
|
46
|
+
| `debug` | `false` | Enable verbose logging for the rendering pipeline |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Creating Templates
|
|
51
|
+
|
|
52
|
+
Templates are document files (DOCX) with placeholder variables. By default, placeholders use double brackets:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Dear [[customerName]],
|
|
56
|
+
|
|
57
|
+
Your order [[orderId]] has been confirmed.
|
|
58
|
+
Total: [[orderTotal]]
|
|
59
|
+
|
|
60
|
+
Thank you for your business.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
You can change the delimiter format:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
DocumentModule.forRoot({
|
|
67
|
+
delimiters: { start: '{{', end: '}}' },
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Rendering Documents
|
|
74
|
+
|
|
75
|
+
Use `DocumentEngine` to render templates with data:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { Injectable } from '@nestjs/common';
|
|
79
|
+
import { DocumentEngine } from '@breadstone/archipel-platform-documents';
|
|
80
|
+
|
|
81
|
+
@Injectable()
|
|
82
|
+
export class InvoiceService {
|
|
83
|
+
private readonly _documentEngine: DocumentEngine;
|
|
84
|
+
|
|
85
|
+
constructor(documentEngine: DocumentEngine) {
|
|
86
|
+
this._documentEngine = documentEngine;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public async generateInvoice(orderId: string, data: Record<string, unknown>): Promise<Buffer> {
|
|
90
|
+
return this._documentEngine.render({
|
|
91
|
+
template: 'invoice-template.docx',
|
|
92
|
+
data: {
|
|
93
|
+
customerName: data['customerName'],
|
|
94
|
+
orderId,
|
|
95
|
+
orderTotal: data['total'],
|
|
96
|
+
date: new Date().toLocaleDateString(),
|
|
97
|
+
},
|
|
98
|
+
format: 'pdf', // or 'docx'
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Supported Output Formats
|
|
105
|
+
|
|
106
|
+
| Format | Renderer | Description |
|
|
107
|
+
| ------ | ------------- | ------------------------------------- |
|
|
108
|
+
| `pdf` | PDF Renderer | Convert template to PDF |
|
|
109
|
+
| `docx` | DOCX Renderer | Keep as DOCX with filled placeholders |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Image Processing
|
|
114
|
+
|
|
115
|
+
The `SharpImageProcessor` automatically optimizes embedded images:
|
|
116
|
+
|
|
117
|
+
- Resizes images that exceed `maxImageWidth` or `maxImageHeight`
|
|
118
|
+
- Preserves aspect ratio
|
|
119
|
+
- Compresses images for smaller file sizes
|
|
120
|
+
|
|
121
|
+
This is useful for templates that include dynamic images (logos, product photos, signatures).
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Serving Documents via HTTP
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Controller, Get, Res, Param } from '@nestjs/common';
|
|
129
|
+
import { Response } from 'express';
|
|
130
|
+
|
|
131
|
+
@Controller('invoices')
|
|
132
|
+
export class InvoiceController {
|
|
133
|
+
private readonly _invoiceService: InvoiceService;
|
|
134
|
+
|
|
135
|
+
constructor(invoiceService: InvoiceService) {
|
|
136
|
+
this._invoiceService = invoiceService;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@Get(':orderId/pdf')
|
|
140
|
+
public async downloadInvoice(@Param('orderId') orderId: string, @Res() res: Response): Promise<void> {
|
|
141
|
+
const pdf = await this._invoiceService.generateInvoice(orderId, {
|
|
142
|
+
/* ... */
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
res.set({
|
|
146
|
+
'Content-Type': 'application/pdf',
|
|
147
|
+
'Content-Disposition': `attachment; filename="invoice-${orderId}.pdf"`,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
res.send(pdf);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Debug Mode
|
|
158
|
+
|
|
159
|
+
Enable debug logging to trace the rendering pipeline:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
DocumentModule.forRoot({
|
|
163
|
+
debug: true,
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
This logs each step of the rendering process: template loading, placeholder parsing, variable substitution, image processing, and final output generation.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Next Steps
|
|
172
|
+
|
|
173
|
+
- See the [Blob Storage](/guides/blob-storage) guide for storing generated documents
|
|
174
|
+
- Browse the [platform-documents API reference](/packages/platform-documents/api/) for complete method signatures
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Email Delivery
|
|
3
|
+
description: Send transactional emails with multiple providers, template engines, and email verification flows.
|
|
4
|
+
order: 8
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Email Delivery
|
|
8
|
+
|
|
9
|
+
This guide covers sending emails with `platform-mailing`: choosing a delivery provider, configuring template rendering, sending transactional emails, and integrating email verification flows.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @breadstone/archipel-platform-mailing
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Choose a Delivery Strategy
|
|
22
|
+
|
|
23
|
+
`platform-mailing` supports multiple email providers. You select the strategy via environment variables — no code changes required to switch providers.
|
|
24
|
+
|
|
25
|
+
| Strategy | Value for `MAIL_DELIVERY_STRATEGY` | When to use |
|
|
26
|
+
| ------------ | ---------------------------------- | ------------------------------------ |
|
|
27
|
+
| **SMTP** | `smtp` | Any SMTP server (self-hosted, relay) |
|
|
28
|
+
| **Postmark** | `postmark` | Postmark transactional email |
|
|
29
|
+
| **Resend** | `resend` | Resend API |
|
|
30
|
+
| **SendGrid** | `sendgrid` | Twilio SendGrid |
|
|
31
|
+
| **Mailgun** | `mailgun` | Mailgun API |
|
|
32
|
+
| **Log** | `log` | Development only — logs to console |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Module Registration
|
|
37
|
+
|
|
38
|
+
`MailModule` is a global module. Register it once in your root module:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { Module } from '@nestjs/common';
|
|
42
|
+
import { MailModule } from '@breadstone/archipel-platform-mailing';
|
|
43
|
+
|
|
44
|
+
@Module({
|
|
45
|
+
imports: [MailModule],
|
|
46
|
+
})
|
|
47
|
+
export class AppModule {}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The module reads all configuration from environment variables. No `register()` call is needed.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Configuration
|
|
55
|
+
|
|
56
|
+
### Core Variables
|
|
57
|
+
|
|
58
|
+
```env
|
|
59
|
+
MAIL_DELIVERY_STRATEGY=resend
|
|
60
|
+
MAIL_TEMPLATE_STRATEGY=file
|
|
61
|
+
MAIL_TEMPLATE_ENGINE_FORMAT=html
|
|
62
|
+
MAIL_FROM_ADDRESS=noreply@yourapp.com
|
|
63
|
+
MAIL_FROM_NAME=YourApp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Provider-Specific Variables
|
|
67
|
+
|
|
68
|
+
#### SMTP
|
|
69
|
+
|
|
70
|
+
```env
|
|
71
|
+
MAIL_SMTP_HOST=smtp.example.com
|
|
72
|
+
MAIL_SMTP_PORT=587
|
|
73
|
+
MAIL_SMTP_USER=user@example.com
|
|
74
|
+
MAIL_SMTP_PASS=password
|
|
75
|
+
MAIL_SMTP_SECURE=true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Resend
|
|
79
|
+
|
|
80
|
+
```env
|
|
81
|
+
MAIL_RESEND_API_KEY=re_...
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Postmark
|
|
85
|
+
|
|
86
|
+
```env
|
|
87
|
+
MAIL_POSTMARK_API_KEY=...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### SendGrid
|
|
91
|
+
|
|
92
|
+
```env
|
|
93
|
+
MAIL_SENDGRID_API_KEY=SG...
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Mailgun
|
|
97
|
+
|
|
98
|
+
```env
|
|
99
|
+
MAIL_MAILGUN_API_KEY=key-...
|
|
100
|
+
MAIL_MAILGUN_DOMAIN=mg.yourapp.com
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Template Strategies
|
|
104
|
+
|
|
105
|
+
Templates can be loaded from the filesystem or from blob storage:
|
|
106
|
+
|
|
107
|
+
| Strategy | Value for `MAIL_TEMPLATE_STRATEGY` | Description |
|
|
108
|
+
| -------- | ---------------------------------- | ------------------------------------------- |
|
|
109
|
+
| **File** | `file` | Load templates from a local directory |
|
|
110
|
+
| **Blob** | `blob` | Load templates from `platform-blob-storage` |
|
|
111
|
+
|
|
112
|
+
For file-based templates, place your `.html` or `.txt` files in the configured template directory.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Sending Emails
|
|
117
|
+
|
|
118
|
+
Inject `MailService` to send emails with templates:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { Injectable } from '@nestjs/common';
|
|
122
|
+
import { MailService } from '@breadstone/archipel-platform-mailing';
|
|
123
|
+
|
|
124
|
+
@Injectable()
|
|
125
|
+
export class NotificationService {
|
|
126
|
+
private readonly _mailService: MailService;
|
|
127
|
+
|
|
128
|
+
constructor(mailService: MailService) {
|
|
129
|
+
this._mailService = mailService;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public async sendWelcomeEmail(email: string, userName: string): Promise<void> {
|
|
133
|
+
await this._mailService.send({
|
|
134
|
+
to: email,
|
|
135
|
+
subject: 'Welcome to YourApp',
|
|
136
|
+
template: 'welcome',
|
|
137
|
+
context: {
|
|
138
|
+
userName,
|
|
139
|
+
dashboardUrl: 'https://yourapp.com/dashboard',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The `template` field is the template name (without extension). The `context` object is passed to the template engine for variable substitution.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Email Verification
|
|
151
|
+
|
|
152
|
+
`MailVerificationService` provides a complete email verification flow:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { Injectable } from '@nestjs/common';
|
|
156
|
+
import { MailVerificationService } from '@breadstone/archipel-platform-mailing';
|
|
157
|
+
import { VerificationService } from '@breadstone/archipel-platform-authentication';
|
|
158
|
+
|
|
159
|
+
@Injectable()
|
|
160
|
+
export class RegistrationService {
|
|
161
|
+
private readonly _mailVerification: MailVerificationService;
|
|
162
|
+
private readonly _verification: VerificationService;
|
|
163
|
+
|
|
164
|
+
constructor(mailVerification: MailVerificationService, verification: VerificationService) {
|
|
165
|
+
this._mailVerification = mailVerification;
|
|
166
|
+
this._verification = verification;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public async sendVerificationEmail(userId: string, email: string): Promise<void> {
|
|
170
|
+
const token = await this._verification.exhibitToken({ userId, email });
|
|
171
|
+
|
|
172
|
+
await this._mailVerification.sendVerification(email, token);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Health Checks
|
|
180
|
+
|
|
181
|
+
`MailHealthIndicator` is registered automatically and verifies connectivity to the configured mail provider. It appears in your `/health` endpoint alongside other health indicators.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Development Tips
|
|
186
|
+
|
|
187
|
+
- Use `MAIL_DELIVERY_STRATEGY=log` during local development to see email content in the console without sending real emails.
|
|
188
|
+
- Use the **blob** template strategy when templates are shared across multiple services or managed by a CMS.
|
|
189
|
+
- Template variables use the format defined by the template engine. Place templates in a well-organized directory structure (e.g., `templates/mail/welcome.html`).
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Next Steps
|
|
194
|
+
|
|
195
|
+
- See the [Authentication & Authorization](/guides/authentication-and-authorization) guide for integrating email verification into the login flow
|
|
196
|
+
- Browse the [platform-mailing API reference](/packages/platform-mailing/api/) for complete method signatures
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: E-Signing Integration
|
|
3
|
+
description: Integrate electronic signature workflows with DocuSign, Adobe Sign, Dropbox Sign, SignNow, or an internal provider.
|
|
4
|
+
order: 12
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# E-Signing Integration
|
|
8
|
+
|
|
9
|
+
This guide covers electronic signature workflows with `platform-esigning`: provider setup, creating signing requests, tracking signer status, and handling webhook notifications.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
yarn add @breadstone/archipel-platform-esigning
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Choose a Provider
|
|
22
|
+
|
|
23
|
+
`platform-esigning` abstracts e-signing operations behind a `EsigningClientPort`. Supported providers:
|
|
24
|
+
|
|
25
|
+
| Provider | Description |
|
|
26
|
+
| ---------------- | ---------------------------------------- |
|
|
27
|
+
| **DocuSign** | Industry-standard e-signature platform |
|
|
28
|
+
| **Adobe Sign** | Adobe Acrobat Sign integration |
|
|
29
|
+
| **Dropbox Sign** | Dropbox (formerly HelloSign) integration |
|
|
30
|
+
| **SignNow** | SignNow e-signature platform |
|
|
31
|
+
| **Internal** | Custom/self-managed signing |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Module Registration
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Module } from '@nestjs/common';
|
|
39
|
+
import { EsigningModule } from '@breadstone/archipel-platform-esigning';
|
|
40
|
+
import { DocuSignClient } from './adapters/DocuSignClient';
|
|
41
|
+
import { PrismaSigningRequestAdapter } from './adapters/PrismaSigningRequestAdapter';
|
|
42
|
+
import { DOCUSIGN_CONFIG_ENTRIES } from './env';
|
|
43
|
+
|
|
44
|
+
@Module({
|
|
45
|
+
imports: [
|
|
46
|
+
EsigningModule.register({
|
|
47
|
+
provider: DocuSignClient,
|
|
48
|
+
persistence: PrismaSigningRequestAdapter,
|
|
49
|
+
configEntries: [...DOCUSIGN_CONFIG_ENTRIES],
|
|
50
|
+
}),
|
|
51
|
+
],
|
|
52
|
+
})
|
|
53
|
+
export class AppModule {}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
```env
|
|
61
|
+
ESIGNING_API_BASE_URL=https://demo.docusign.net/restapi
|
|
62
|
+
ESIGNING_API_KEY=your-api-key
|
|
63
|
+
ESIGNING_WEBHOOK_SECRET=your-webhook-secret
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Implementing the Client Port
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { Injectable } from '@nestjs/common';
|
|
72
|
+
import {
|
|
73
|
+
EsigningClientPort,
|
|
74
|
+
type ISigningRequest,
|
|
75
|
+
type ISigningSession,
|
|
76
|
+
type ISignedDocument,
|
|
77
|
+
} from '@breadstone/archipel-platform-esigning';
|
|
78
|
+
|
|
79
|
+
@Injectable()
|
|
80
|
+
export class DocuSignClient extends EsigningClientPort {
|
|
81
|
+
public async createSigningSession(request: ISigningRequest): Promise<ISigningSession> {
|
|
82
|
+
// Call DocuSign API to create an envelope
|
|
83
|
+
// Return normalized signing session with redirect URLs
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public async getSigningStatus(sessionId: string): Promise<ISigningSession> {
|
|
87
|
+
// Fetch signing status from DocuSign
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public async downloadSignedDocument(sessionId: string): Promise<ISignedDocument> {
|
|
91
|
+
// Download the completed document from DocuSign
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async cancelSigningSession(sessionId: string): Promise<void> {
|
|
95
|
+
// Void the envelope in DocuSign
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Implementing the Persistence Port
|
|
103
|
+
|
|
104
|
+
Track signing request state in your database:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Injectable } from '@nestjs/common';
|
|
108
|
+
import { EsigningPersistencePort, type ISigningRequest } from '@breadstone/archipel-platform-esigning';
|
|
109
|
+
import { PrismaService } from '@breadstone/archipel-platform-database';
|
|
110
|
+
|
|
111
|
+
@Injectable()
|
|
112
|
+
export class PrismaSigningRequestAdapter extends EsigningPersistencePort {
|
|
113
|
+
private readonly _prisma: PrismaService;
|
|
114
|
+
|
|
115
|
+
constructor(prisma: PrismaService) {
|
|
116
|
+
super();
|
|
117
|
+
this._prisma = prisma;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public async save(request: ISigningRequest): Promise<void> {
|
|
121
|
+
await this._prisma.signingRequest.upsert({
|
|
122
|
+
where: { id: request.id },
|
|
123
|
+
create: {
|
|
124
|
+
id: request.id,
|
|
125
|
+
userId: request.userId,
|
|
126
|
+
documentId: request.documentId,
|
|
127
|
+
status: request.status,
|
|
128
|
+
providerSessionId: request.providerSessionId,
|
|
129
|
+
},
|
|
130
|
+
update: {
|
|
131
|
+
status: request.status,
|
|
132
|
+
providerSessionId: request.providerSessionId,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public async findById(id: string): Promise<ISigningRequest | null> {
|
|
138
|
+
return this._prisma.signingRequest.findUnique({ where: { id } });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public async findByUserId(userId: string): Promise<ReadonlyArray<ISigningRequest>> {
|
|
142
|
+
return this._prisma.signingRequest.findMany({ where: { userId } });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Creating a Signing Request
|
|
150
|
+
|
|
151
|
+
Use `EsigningService` to orchestrate the signing workflow:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { Injectable } from '@nestjs/common';
|
|
155
|
+
import { EsigningService } from '@breadstone/archipel-platform-esigning';
|
|
156
|
+
|
|
157
|
+
@Injectable()
|
|
158
|
+
export class ContractService {
|
|
159
|
+
private readonly _esigningService: EsigningService;
|
|
160
|
+
|
|
161
|
+
constructor(esigningService: EsigningService) {
|
|
162
|
+
this._esigningService = esigningService;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public async sendForSigning(userId: string, documentUrl: string, signerEmail: string): Promise<string> {
|
|
166
|
+
const session = await this._esigningService.createSession({
|
|
167
|
+
userId,
|
|
168
|
+
documentUrl,
|
|
169
|
+
signers: [
|
|
170
|
+
{
|
|
171
|
+
email: signerEmail,
|
|
172
|
+
name: 'Signer',
|
|
173
|
+
order: 1,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
callbackUrl: 'https://yourapp.com/webhooks/esigning',
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return session.signingUrl; // Redirect the user to this URL
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Handling Webhooks
|
|
187
|
+
|
|
188
|
+
E-signing providers send webhook events when documents are signed, declined, or expired:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { Controller, Post, Req, Headers, RawBodyRequest } from '@nestjs/common';
|
|
192
|
+
import { EsigningService } from '@breadstone/archipel-platform-esigning';
|
|
193
|
+
import { Request } from 'express';
|
|
194
|
+
|
|
195
|
+
@Controller('webhooks/esigning')
|
|
196
|
+
export class EsigningWebhookController {
|
|
197
|
+
private readonly _esigningService: EsigningService;
|
|
198
|
+
|
|
199
|
+
constructor(esigningService: EsigningService) {
|
|
200
|
+
this._esigningService = esigningService;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@Post()
|
|
204
|
+
public async handleWebhook(
|
|
205
|
+
@Req() request: RawBodyRequest<Request>,
|
|
206
|
+
@Headers('x-webhook-signature') signature: string,
|
|
207
|
+
): Promise<void> {
|
|
208
|
+
await this._esigningService.handleWebhook(request.rawBody!, signature);
|
|
209
|
+
// The service verifies the signature, updates the signing request status,
|
|
210
|
+
// and emits domain events for your application to react to.
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Best Practices
|
|
218
|
+
|
|
219
|
+
1. **Always verify webhook signatures.** Never trust webhook payloads without signature validation.
|
|
220
|
+
2. **Use the persistence port.** Track signing request state to handle retries, status queries, and auditing.
|
|
221
|
+
3. **Implement idempotent webhook handlers.** Providers may deliver the same event multiple times.
|
|
222
|
+
4. **Store signed documents.** Use `platform-blob-storage` to archive completed signed documents.
|
|
223
|
+
5. **Handle expiration.** Set up a scheduled job to check for expired signing sessions and notify users.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Next Steps
|
|
228
|
+
|
|
229
|
+
- See the [Document Generation](/guides/document-generation) guide for creating documents to send for signing
|
|
230
|
+
- See the [Blob Storage](/guides/blob-storage) guide for storing signed documents
|
|
231
|
+
- Browse the [platform-esigning API reference](/packages/platform-esigning/api/) for complete method signatures
|