@felloh-org/lambda-wrapper 1.11.192 → 1.11.193

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 CHANGED
@@ -1,4 +1,231 @@
1
- # Lambda Wrapper [![release](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml/badge.svg)](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml)
1
+ # Lambda Wrapper
2
2
 
3
- A function wrapper to wrap all of our lambdas and provide core functionality, monitoring and logging + time saving tooling to all of our serverless services.
3
+ [![release](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml/badge.svg)](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml)
4
4
 
5
+ A shared library for Felloh serverless projects that provides core functionality including dependency injection, logging, request handling, database entities, and response models for AWS Lambda functions.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @felloh-org/lambda-wrapper
11
+ # or
12
+ yarn add @felloh-org/lambda-wrapper
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```javascript
18
+ import { LambdaWrapper, DEFINITIONS, ResponseModel } from '@felloh-org/lambda-wrapper';
19
+
20
+ const configuration = {
21
+ SERVICE_NAME: 'my-service',
22
+ };
23
+
24
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
25
+ const logger = di.get(DEFINITIONS.LOGGER);
26
+ const warehouse = di.get(DEFINITIONS.WAREHOUSE);
27
+
28
+ logger.info('Processing request');
29
+
30
+ // Your handler logic here
31
+
32
+ return new ResponseModel({ message: 'Success' }, 200).generate();
33
+ });
34
+ ```
35
+
36
+ ## Features
37
+
38
+ ### Lambda Wrapper
39
+
40
+ The core wrapper provides:
41
+
42
+ - **Dependency Injection** - Access services via `di.get(DEFINITIONS.SERVICE_NAME)`
43
+ - **Automatic Error Handling** - Catches and formats errors consistently
44
+ - **Request Parsing** - Parses body, query params, path params, and headers
45
+ - **Logging & Metrics** - Built-in logging with automatic metric collection
46
+ - **Warm-up Support** - Handles `serverless-plugin-warmup` events automatically
47
+
48
+ ### Built-in Services
49
+
50
+ Access these via `di.get(DEFINITIONS.SERVICE_NAME)`:
51
+
52
+ | Service | Definition | Description |
53
+ |---------|------------|-------------|
54
+ | Logger | `DEFINITIONS.LOGGER` | Structured logging with metric support |
55
+ | Request | `DEFINITIONS.REQUEST` | Parsed request data (body, params, headers) |
56
+ | Warehouse | `DEFINITIONS.WAREHOUSE` | TypeORM database connection manager |
57
+ | Authentication | `DEFINITIONS.AUTHENTICATION` | JWT authentication and user context |
58
+ | EventBridge | `DEFINITIONS.EVENT_BRIDGE` | AWS EventBridge event publishing |
59
+ | Secrets | `DEFINITIONS.SECRETS` | AWS Secrets Manager integration |
60
+ | HTTP | `DEFINITIONS.HTTP` | HTTP client for external requests |
61
+ | Webhook | `DEFINITIONS.WEBHOOK` | Webhook dispatch service |
62
+ | User | `DEFINITIONS.USER` | User service utilities |
63
+ | AuditLogger | `DEFINITIONS.AUDIT_LOGGER` | Audit trail logging |
64
+
65
+ ### Response Model
66
+
67
+ All Lambda responses are standardised:
68
+
69
+ ```javascript
70
+ import { ResponseModel } from '@felloh-org/lambda-wrapper';
71
+
72
+ // Success response
73
+ return new ResponseModel({ users: [...] }, 200).generate();
74
+
75
+ // Error response
76
+ return new ResponseModel({}, 400)
77
+ .setErrors([{ field: 'email', message: 'Invalid email' }])
78
+ .generate();
79
+ ```
80
+
81
+ Response format:
82
+
83
+ ```json
84
+ {
85
+ "statusCode": 200,
86
+ "headers": {
87
+ "Content-Type": "application/json",
88
+ "Access-Control-Allow-Origin": "*"
89
+ },
90
+ "body": {
91
+ "data": { ... },
92
+ "errors": [],
93
+ "meta": {
94
+ "code": 200,
95
+ "reason": "OK",
96
+ "message": "Success",
97
+ "request_id": "uuid"
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ### Database Entities (TypeORM)
104
+
105
+ The library includes TypeORM entities organised by domain:
106
+
107
+ | Domain | Description |
108
+ |--------|-------------|
109
+ | `payment` | Transactions, refunds, chargebacks, payment links, providers |
110
+ | `user` | Users, organisations, roles, features, webhooks |
111
+ | `bank` | Accounts, ledgers, settlements, disbursals |
112
+ | `agent-data` | Bookings, components, suppliers |
113
+ | `acquirer` | BIN data, batches, adjustments |
114
+ | `aisp` | Open banking transactions and connections |
115
+ | `nuapay` | Nuapay integration entities |
116
+ | `nuvei` | Nuvei payment processor entities |
117
+ | `trust-payments` | Trust Payments integration |
118
+ | `total-processing` | Total Processing integration |
119
+ | `planet` | Planet payment processor entities |
120
+ | `saltedge` | Saltedge banking integration |
121
+ | `basis-theory` | Tokenisation entities |
122
+ | `go-cardless` | GoCardless Direct Debit |
123
+ | `marketing` | Marketing contacts and ESUs |
124
+
125
+ ### EventBridge Events
126
+
127
+ Publish events to AWS EventBridge:
128
+
129
+ ```javascript
130
+ import { LambdaWrapper, DEFINITIONS, TransactionCustomerReceipt } from '@felloh-org/lambda-wrapper';
131
+
132
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
133
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
134
+
135
+ const event = new TransactionCustomerReceipt();
136
+ event.setCustomerEmail('customer@example.com');
137
+ event.setOrgName('Acme Travel');
138
+ event.setAmount(150000);
139
+ event.setCurrencyMajorUnit('GBP');
140
+ event.setId('txn_123');
141
+
142
+ await eventBridge.send(event);
143
+ });
144
+ ```
145
+
146
+ See [Event Documentation](./docs/events/README.md) for all available events.
147
+
148
+ ### Dependency Injection
149
+
150
+ Create custom services by extending `DependencyAwareClass`:
151
+
152
+ ```javascript
153
+ import { DependencyAwareClass, DEFINITIONS } from '@felloh-org/lambda-wrapper';
154
+
155
+ class MyCustomService extends DependencyAwareClass {
156
+ async doSomething() {
157
+ const logger = this.di.get(DEFINITIONS.LOGGER);
158
+ const warehouse = this.di.get(DEFINITIONS.WAREHOUSE);
159
+
160
+ // Your service logic
161
+ }
162
+ }
163
+
164
+ // Register in configuration
165
+ const configuration = {
166
+ DEPENDENCIES: {
167
+ MY_SERVICE: MyCustomService,
168
+ },
169
+ };
170
+ ```
171
+
172
+ ## Development
173
+
174
+ ### Commands
175
+
176
+ ```bash
177
+ # Build for production (webpack)
178
+ yarn build
179
+
180
+ # Build for TypeORM migrations (babel)
181
+ yarn build:orm
182
+
183
+ # Run linter
184
+ yarn lint
185
+
186
+ # Run tests with coverage
187
+ yarn test
188
+
189
+ # Run database migrations
190
+ yarn orm:migration:run
191
+
192
+ # Generate a new migration
193
+ yarn orm:migration:generate <name>
194
+
195
+ # Revert last migration
196
+ yarn orm:revert
197
+
198
+ # Create database schemas
199
+ yarn orm:schema:create
200
+ ```
201
+
202
+ ### Environment Variables
203
+
204
+ | Variable | Description |
205
+ |----------|-------------|
206
+ | `SERVICE_NAME` | Service identifier for logging and events |
207
+ | `EVENT_BRIDGE_ARN` | AWS EventBridge bus ARN |
208
+ | `DB_HOST` | Database host |
209
+ | `DB_PORT` | Database port |
210
+ | `DB_USERNAME` | Database username |
211
+ | `DB_PASSWORD` | Database password |
212
+ | `DB_DATABASE` | Database name |
213
+
214
+ ### Project Structure
215
+
216
+ ```
217
+ src/
218
+ ├── config/ # Dependency definitions
219
+ ├── dependency-injection/ # DI implementation
220
+ ├── entity/ # TypeORM entities by domain
221
+ ├── event/ # EventBridge event classes
222
+ ├── migration/ # Database migrations by schema
223
+ ├── model/ # Response and data models
224
+ ├── service/ # Core services
225
+ ├── util/ # Utility functions
226
+ └── wrapper/ # Lambda wrapper implementation
227
+ ```
228
+
229
+ ## License
230
+
231
+ MIT
@@ -0,0 +1,50 @@
1
+ # EventBridge Events
2
+
3
+ This directory contains documentation for all EventBridge events available in the lambda-wrapper.
4
+
5
+ ## Available Events
6
+
7
+ | Event | Detail Type | Description |
8
+ |-------|-------------|-------------|
9
+ | [TransactionCustomerReceipt](./transaction-customer-receipt.md) | `transaction:customer:receipt` | Sends payment confirmation email to customer |
10
+ | [TransactionCompleteEmailEvent](./transaction-complete-email.md) | `transaction:complete:email` | Triggers transaction completion notification |
11
+ | [UserRegistration](./user-registration.md) | `user:registration` | Triggered when a new user registers |
12
+ | [UserPasswordChanged](./user-password-changed.md) | `user:password:changed` | Triggered when a user changes their password |
13
+ | [CSVEmail](./csv-export-link.md) | `csv:export-link` | Sends CSV export download link via email |
14
+ | [POSCRequestEmail](./posc-request.md) | `posc:request` | Sends POSC request notification |
15
+ | [BaseEvent](./base-event.md) | Custom | Base class for creating custom events |
16
+
17
+ ## Quick Start
18
+
19
+ ```javascript
20
+ import { LambdaWrapper, DEFINITIONS, TransactionCustomerReceipt } from '@felloh-org/lambda-wrapper';
21
+
22
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
23
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
24
+
25
+ const event = new TransactionCustomerReceipt();
26
+ event.setCustomerEmail('customer@example.com');
27
+ event.setOrgName('Acme Travel Ltd');
28
+ event.setAmount(150000);
29
+ event.setCurrencyMajorUnit('GBP');
30
+ event.setId('txn_abc123xyz');
31
+
32
+ await eventBridge.send(event);
33
+ });
34
+ ```
35
+
36
+ ## Creating Custom Events
37
+
38
+ For events not covered by the built-in classes, use `BaseEvent`:
39
+
40
+ ```javascript
41
+ import { BaseEvent } from '@felloh-org/lambda-wrapper';
42
+
43
+ const event = new BaseEvent('custom:event:type');
44
+ event.setDetailParam('data', { foo: 'bar' });
45
+ event.setUserBy({ id: 'usr_123', email: 'user@example.com' });
46
+
47
+ await eventBridge.send(event);
48
+ ```
49
+
50
+ See [BaseEvent documentation](./base-event.md) for more details.
@@ -0,0 +1,107 @@
1
+ # BaseEvent Class
2
+
3
+ The `BaseEvent` class is the foundation for all EventBridge events in the lambda-wrapper. Use it to create custom events or extend it for reusable event types.
4
+
5
+ ## Event Structure
6
+
7
+ All events follow this base structure:
8
+
9
+ ```json
10
+ {
11
+ "Source": "your-service-name",
12
+ "EventBusName": "your-event-bus-arn",
13
+ "DetailType": "your:event:type",
14
+ "Time": "2024-01-15T10:30:00.000Z",
15
+ "Detail": {
16
+ "your": "data",
17
+ "userBy": {
18
+ "id": "usr_abc123xyz",
19
+ "email": "user@example.com"
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ ## Base Methods
26
+
27
+ | Method | Description |
28
+ |--------|-------------|
29
+ | `getBase()` | Returns the complete event payload with stringified Detail |
30
+ | `setDetailType(type)` | Sets the event type (e.g., `user:registration`) |
31
+ | `setDetailParam(key, value)` | Sets a key-value pair in the Detail object |
32
+ | `setDetail(detail)` | Replaces the entire Detail object |
33
+ | `setUserBy(user)` | Sets the user who initiated the action |
34
+
35
+ ## Creating a Custom Event
36
+
37
+ ```javascript
38
+ import { BaseEvent } from '@felloh-org/lambda-wrapper';
39
+
40
+ // Option 1: Use BaseEvent directly
41
+ const event = new BaseEvent('custom:event:type');
42
+ event.setDetailParam('data', {
43
+ field1: 'value1',
44
+ field2: 'value2'
45
+ });
46
+ event.setUserBy({ id: 'usr_123', email: 'user@example.com' });
47
+
48
+ const payload = event.getBase();
49
+ ```
50
+
51
+ ## Extending BaseEvent
52
+
53
+ For reusable event types, create a custom class:
54
+
55
+ ```javascript
56
+ import { BaseEvent } from '@felloh-org/lambda-wrapper';
57
+
58
+ class MyCustomEvent extends BaseEvent {
59
+ constructor() {
60
+ super();
61
+ this.setDetailType('my:custom:event');
62
+ this.setDetailParam('data', {});
63
+ }
64
+
65
+ setCustomField(value) {
66
+ this.base.Detail.data.custom_field = value;
67
+ }
68
+
69
+ setAnotherField(value) {
70
+ this.base.Detail.data.another_field = value;
71
+ }
72
+ }
73
+
74
+ export default MyCustomEvent;
75
+ ```
76
+
77
+ ## Sending Events
78
+
79
+ All events are dispatched via the `EventBridgeService`:
80
+
81
+ ```javascript
82
+ import { LambdaWrapper, DEFINITIONS, BaseEvent } from '@felloh-org/lambda-wrapper';
83
+
84
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
85
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
86
+
87
+ const event = new BaseEvent('custom:event:type');
88
+ event.setDetailParam('data', { foo: 'bar' });
89
+
90
+ await eventBridge.send(event);
91
+ });
92
+ ```
93
+
94
+ ## Environment Variables
95
+
96
+ The BaseEvent class uses these environment variables:
97
+
98
+ | Variable | Description |
99
+ |----------|-------------|
100
+ | `SERVICE_NAME` | Used as the event `Source` |
101
+ | `EVENT_BRIDGE_ARN` | Used as the `EventBusName` |
102
+
103
+ ## Notes
104
+
105
+ - The `Detail` object is automatically stringified when calling `getBase()`
106
+ - The `Time` field is automatically set to the current timestamp on construction
107
+ - Use specific event classes (e.g., `TransactionCustomerReceipt`) when available for better type safety and validation
@@ -0,0 +1,91 @@
1
+ # csv:export-link Event Specification
2
+
3
+ This event triggers an email containing a link to download a CSV export file.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "csv:export-link",
11
+ "detail": {
12
+ "data": {
13
+ "email": "user@example.com",
14
+ "download_url": "https://example.com/exports/file.csv",
15
+ "export_type": "transactions",
16
+ "organisation_name": "Acme Travel Ltd",
17
+ "file_name": "transactions-2024-01.csv"
18
+ },
19
+ "userBy": {
20
+ "id": "usr_abc123xyz",
21
+ "email": "user@example.com"
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Field Reference
28
+
29
+ | Field | Type | Required | Description |
30
+ |-------|------|----------|-------------|
31
+ | `data` | object | **Yes** | The export data for the email |
32
+ | `data.email` | string | **Yes** | Recipient email address |
33
+ | `data.download_url` | string | **Yes** | URL to download the CSV file |
34
+ | `data.export_type` | string | No | Type of export (e.g., `transactions`, `payments`, `settlements`) |
35
+ | `data.organisation_name` | string | No | Organisation name for the email |
36
+ | `data.file_name` | string | No | Name of the exported file |
37
+ | `userBy` | object | No | The user who requested the export |
38
+
39
+ ## Usage Example
40
+
41
+ ```javascript
42
+ import { CSVEmail } from '@felloh-org/lambda-wrapper';
43
+
44
+ const event = new CSVEmail();
45
+
46
+ // Set the export data
47
+ event.setDetailParam('data', {
48
+ email: 'user@example.com',
49
+ download_url: 'https://example.com/exports/file.csv',
50
+ export_type: 'transactions',
51
+ organisation_name: 'Acme Travel Ltd',
52
+ file_name: 'transactions-2024-01.csv'
53
+ });
54
+
55
+ // Set who requested the export
56
+ event.setUserBy({
57
+ id: 'usr_abc123xyz',
58
+ email: 'user@example.com'
59
+ });
60
+
61
+ // Get the event payload for EventBridge
62
+ const payload = event.getBase();
63
+ ```
64
+
65
+ ## Sending the Event
66
+
67
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
68
+
69
+ ```javascript
70
+ import { LambdaWrapper, DEFINITIONS, CSVEmail } from '@felloh-org/lambda-wrapper';
71
+
72
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
73
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
74
+
75
+ const event = new CSVEmail();
76
+ event.setDetailParam('data', {
77
+ email: 'user@example.com',
78
+ download_url: 'https://example.com/exports/file.csv',
79
+ export_type: 'transactions',
80
+ organisation_name: 'Acme Travel Ltd',
81
+ file_name: 'transactions-2024-01.csv'
82
+ });
83
+
84
+ await eventBridge.send(event);
85
+ });
86
+ ```
87
+
88
+ ## Notes
89
+
90
+ - The download URL should be a pre-signed URL or a secure link with appropriate expiration
91
+ - The `data` object can include additional context fields as needed by the email template
@@ -0,0 +1,99 @@
1
+ # posc:request Event Specification
2
+
3
+ This event triggers a POSC (Payment on Statement of Credit) request notification email.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "posc:request",
11
+ "detail": {
12
+ "data": {
13
+ "email": "recipient@example.com",
14
+ "organisation_name": "Acme Travel Ltd",
15
+ "request_id": "posc_abc123xyz",
16
+ "amount": 150000,
17
+ "currency": "GBP",
18
+ "customer_name": "John Doe",
19
+ "booking_reference": "BOOK-12345"
20
+ },
21
+ "userBy": {
22
+ "id": "usr_abc123xyz",
23
+ "email": "agent@example.com"
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ ## Field Reference
30
+
31
+ | Field | Type | Required | Description |
32
+ |-------|------|----------|-------------|
33
+ | `data` | object | **Yes** | The POSC request data |
34
+ | `data.email` | string | **Yes** | Recipient email address |
35
+ | `data.organisation_name` | string | **Yes** | Organisation name |
36
+ | `data.request_id` | string | **Yes** | Unique identifier for the POSC request |
37
+ | `data.amount` | integer | **Yes** | Request amount in minor units (e.g., pence/cents) |
38
+ | `data.currency` | string | **Yes** | ISO 4217 currency code |
39
+ | `data.customer_name` | string | No | Name of the customer |
40
+ | `data.booking_reference` | string | No | Associated booking reference |
41
+ | `userBy` | object | No | The user who initiated the request |
42
+
43
+ ## Usage Example
44
+
45
+ ```javascript
46
+ import { POSCRequestEmail } from '@felloh-org/lambda-wrapper';
47
+
48
+ const event = new POSCRequestEmail();
49
+
50
+ // Set the POSC request data
51
+ event.setDetailParam('data', {
52
+ email: 'recipient@example.com',
53
+ organisation_name: 'Acme Travel Ltd',
54
+ request_id: 'posc_abc123xyz',
55
+ amount: 150000,
56
+ currency: 'GBP',
57
+ customer_name: 'John Doe',
58
+ booking_reference: 'BOOK-12345'
59
+ });
60
+
61
+ // Set who initiated the request
62
+ event.setUserBy({
63
+ id: 'usr_abc123xyz',
64
+ email: 'agent@example.com'
65
+ });
66
+
67
+ // Get the event payload for EventBridge
68
+ const payload = event.getBase();
69
+ ```
70
+
71
+ ## Sending the Event
72
+
73
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
74
+
75
+ ```javascript
76
+ import { LambdaWrapper, DEFINITIONS, POSCRequestEmail } from '@felloh-org/lambda-wrapper';
77
+
78
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
79
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
80
+
81
+ const event = new POSCRequestEmail();
82
+ event.setDetailParam('data', {
83
+ email: 'recipient@example.com',
84
+ organisation_name: 'Acme Travel Ltd',
85
+ request_id: 'posc_abc123xyz',
86
+ amount: 150000,
87
+ currency: 'GBP',
88
+ customer_name: 'John Doe',
89
+ booking_reference: 'BOOK-12345'
90
+ });
91
+
92
+ await eventBridge.send(event);
93
+ });
94
+ ```
95
+
96
+ ## Notes
97
+
98
+ - The `amount` field should be in **minor units** (e.g., £1,500.00 = `150000` pence)
99
+ - POSC requests are typically used for payment reminders or follow-up notifications
@@ -0,0 +1,91 @@
1
+ # transaction:complete:email Event Specification
2
+
3
+ This event triggers an email notification when a transaction is completed.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "transaction:complete:email",
11
+ "detail": {
12
+ "data": {
13
+ "transaction_id": "txn_abc123xyz",
14
+ "amount": 150000,
15
+ "currency": "GBP",
16
+ "customer_email": "customer@example.com",
17
+ "organisation_name": "Acme Travel Ltd"
18
+ },
19
+ "userBy": {
20
+ "id": "usr_abc123xyz",
21
+ "email": "agent@example.com"
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Field Reference
28
+
29
+ | Field | Type | Required | Description |
30
+ |-------|------|----------|-------------|
31
+ | `data` | object | **Yes** | The transaction data for the email |
32
+ | `data.transaction_id` | string | **Yes** | Unique identifier for the transaction |
33
+ | `data.amount` | integer | **Yes** | Transaction amount in minor units (e.g., pence/cents) |
34
+ | `data.currency` | string | **Yes** | ISO 4217 currency code |
35
+ | `data.customer_email` | string | **Yes** | Recipient email address |
36
+ | `data.organisation_name` | string | **Yes** | Organisation name for the email |
37
+ | `userBy` | object | No | The user who initiated the action |
38
+
39
+ ## Usage Example
40
+
41
+ ```javascript
42
+ import { TransactionCompleteEmailEvent } from '@felloh-org/lambda-wrapper';
43
+
44
+ const event = new TransactionCompleteEmailEvent();
45
+
46
+ // Set the transaction data
47
+ event.setDetailParam('data', {
48
+ transaction_id: 'txn_abc123xyz',
49
+ amount: 150000,
50
+ currency: 'GBP',
51
+ customer_email: 'customer@example.com',
52
+ organisation_name: 'Acme Travel Ltd'
53
+ });
54
+
55
+ // Optionally set who initiated the action
56
+ event.setUserBy({
57
+ id: 'usr_abc123xyz',
58
+ email: 'agent@example.com'
59
+ });
60
+
61
+ // Get the event payload for EventBridge
62
+ const payload = event.getBase();
63
+ ```
64
+
65
+ ## Sending the Event
66
+
67
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
68
+
69
+ ```javascript
70
+ import { LambdaWrapper, DEFINITIONS, TransactionCompleteEmailEvent } from '@felloh-org/lambda-wrapper';
71
+
72
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
73
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
74
+
75
+ const event = new TransactionCompleteEmailEvent();
76
+ event.setDetailParam('data', {
77
+ transaction_id: 'txn_abc123xyz',
78
+ amount: 150000,
79
+ currency: 'GBP',
80
+ customer_email: 'customer@example.com',
81
+ organisation_name: 'Acme Travel Ltd'
82
+ });
83
+
84
+ await eventBridge.send(event);
85
+ });
86
+ ```
87
+
88
+ ## Notes
89
+
90
+ - The `amount` field should be in **minor units** (e.g., £1,500.00 = `150000` pence)
91
+ - The `data` object structure can be extended with additional fields as needed by the email template
@@ -0,0 +1,110 @@
1
+ # transaction:customer:receipt Event Specification
2
+
3
+ This event triggers a payment confirmation email to be sent to a customer after a successful transaction.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "transaction:customer:receipt",
11
+ "detail": {
12
+ "data": {
13
+ "customer_email": "customer@example.com",
14
+ "org_name": "Acme Travel Ltd",
15
+ "amount": 150000,
16
+ "currency_major_unit": "GBP",
17
+ "id": "txn_abc123xyz",
18
+ "method": "Card",
19
+ "booking_reference": "BOOK-12345",
20
+ "logo_url": "https://example.com/your-logo.png"
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Field Reference
27
+
28
+ | Field | Type | Required | Description |
29
+ |-------|------|----------|-------------|
30
+ | `customer_email` | string | **Yes** | Recipient email address |
31
+ | `org_name` | string | **Yes** | Organisation name displayed in the email |
32
+ | `amount` | integer | **Yes** | Transaction amount in minor units (e.g., pence/cents) |
33
+ | `currency_major_unit` | string | **Yes** | ISO 4217 currency code (e.g., `GBP`, `EUR`, `USD`) |
34
+ | `id` | string | **Yes** | Transaction ID displayed to the customer |
35
+ | `method` | string | No | Payment method (e.g., `Card`, `Bank Transfer`). Omit to hide this field. |
36
+ | `booking_reference` | string | No | Booking reference. Omit to hide this field. |
37
+ | `logo_url` | string | No | Custom logo URL. Defaults to Felloh logo if not provided. |
38
+
39
+ ## Usage Example
40
+
41
+ ```javascript
42
+ import { TransactionCustomerReceipt } from '@felloh-org/lambda-wrapper';
43
+
44
+ const event = new TransactionCustomerReceipt();
45
+
46
+ // Required fields
47
+ event.setCustomerEmail('customer@example.com');
48
+ event.setOrgName('Acme Travel Ltd');
49
+ event.setAmount(150000); // £1,500.00 in pence
50
+ event.setCurrencyMajorUnit('GBP');
51
+ event.setId('txn_abc123xyz');
52
+
53
+ // Optional fields
54
+ event.setMethod('Card');
55
+ event.setBookingReference('BOOK-12345');
56
+ event.setLogoUrl('https://example.com/your-logo.png');
57
+
58
+ // Get the event payload for EventBridge
59
+ const payload = event.getBase();
60
+ ```
61
+
62
+ ## Sending the Event
63
+
64
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
65
+
66
+ ```javascript
67
+ import { LambdaWrapper, DEFINITIONS, TransactionCustomerReceipt } from '@felloh-org/lambda-wrapper';
68
+
69
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
70
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
71
+
72
+ const event = new TransactionCustomerReceipt();
73
+ event.setCustomerEmail('customer@example.com');
74
+ event.setOrgName('Acme Travel Ltd');
75
+ event.setAmount(150000);
76
+ event.setCurrencyMajorUnit('GBP');
77
+ event.setId('txn_abc123xyz');
78
+
79
+ await eventBridge.send(event);
80
+ });
81
+ ```
82
+
83
+ ## Usage Example
84
+
85
+ ```javascript
86
+ import { TransactionCustomerReceipt } from '@felloh-org/lambda-wrapper';
87
+
88
+ const event = new TransactionCustomerReceipt();
89
+
90
+ // Required fields
91
+ event.setCustomerEmail('customer@example.com');
92
+ event.setOrgName('Acme Travel Ltd');
93
+ event.setAmount(150000); // £1,500.00 in pence
94
+ event.setCurrencyMajorUnit('GBP');
95
+ event.setId('txn_abc123xyz');
96
+
97
+ // Optional fields
98
+ event.setMethod('Card');
99
+ event.setBookingReference('BOOK-12345');
100
+ event.setLogoUrl('https://example.com/your-logo.png');
101
+
102
+ // Get the event payload for EventBridge
103
+ const payload = event.getBase();
104
+ ```
105
+
106
+ ## Notes
107
+
108
+ - The `amount` field should be in **minor units** (e.g., £1,500.00 = `150000` pence)
109
+ - The logo image should ideally be 40px in height for optimal display
110
+ - Optional fields (`method`, `booking_reference`, `logo_url`) can be omitted entirely from the payload
@@ -0,0 +1,83 @@
1
+ # user:password:changed Event Specification
2
+
3
+ This event is triggered when a user successfully changes their password.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "user:password:changed",
11
+ "detail": {
12
+ "user": {
13
+ "id": "usr_abc123xyz",
14
+ "email": "user@example.com"
15
+ },
16
+ "userBy": {
17
+ "id": "usr_abc123xyz",
18
+ "email": "user@example.com"
19
+ }
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Field Reference
25
+
26
+ | Field | Type | Required | Description |
27
+ |-------|------|----------|-------------|
28
+ | `user` | object | **Yes** | The user whose password was changed |
29
+ | `user.id` | string | **Yes** | Unique identifier for the user |
30
+ | `user.email` | string | **Yes** | Email address of the user |
31
+ | `userBy` | object | No | The user who initiated the password change |
32
+
33
+ ## Usage Example
34
+
35
+ ```javascript
36
+ import { UserPasswordChanged } from '@felloh-org/lambda-wrapper';
37
+
38
+ const event = new UserPasswordChanged();
39
+
40
+ // Set the user whose password was changed
41
+ event.setDetailParam('user', {
42
+ id: 'usr_abc123xyz',
43
+ email: 'user@example.com'
44
+ });
45
+
46
+ // Set who initiated the change (could be the user themselves or an admin)
47
+ event.setUserBy({
48
+ id: 'usr_abc123xyz',
49
+ email: 'user@example.com'
50
+ });
51
+
52
+ // Get the event payload for EventBridge
53
+ const payload = event.getBase();
54
+ ```
55
+
56
+ ## Sending the Event
57
+
58
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
59
+
60
+ ```javascript
61
+ import { LambdaWrapper, DEFINITIONS, UserPasswordChanged } from '@felloh-org/lambda-wrapper';
62
+
63
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
64
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
65
+
66
+ const event = new UserPasswordChanged();
67
+ event.setDetailParam('user', {
68
+ id: 'usr_abc123xyz',
69
+ email: 'user@example.com'
70
+ });
71
+ event.setUserBy({
72
+ id: 'usr_abc123xyz',
73
+ email: 'user@example.com'
74
+ });
75
+
76
+ await eventBridge.send(event);
77
+ });
78
+ ```
79
+
80
+ ## Notes
81
+
82
+ - This event is typically used to trigger confirmation emails or audit logging
83
+ - The `userBy` field helps distinguish between self-service password changes and admin-initiated changes
@@ -0,0 +1,87 @@
1
+ # user:registration Event Specification
2
+
3
+ This event is triggered when a new user registers in the system.
4
+
5
+ ## Event Structure
6
+
7
+ ```json
8
+ {
9
+ "source": "your-service-name",
10
+ "detail-type": "user:registration",
11
+ "detail": {
12
+ "user": {
13
+ "id": "usr_abc123xyz",
14
+ "email": "newuser@example.com",
15
+ "first_name": "John",
16
+ "last_name": "Doe"
17
+ },
18
+ "userBy": {
19
+ "id": "usr_admin123",
20
+ "email": "admin@example.com"
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Field Reference
27
+
28
+ | Field | Type | Required | Description |
29
+ |-------|------|----------|-------------|
30
+ | `user` | object | **Yes** | The user object containing registration details |
31
+ | `user.id` | string | **Yes** | Unique identifier for the new user |
32
+ | `user.email` | string | **Yes** | Email address of the new user |
33
+ | `user.first_name` | string | No | First name of the user |
34
+ | `user.last_name` | string | No | Last name of the user |
35
+ | `userBy` | object | No | The user who initiated the registration (if applicable) |
36
+
37
+ ## Usage Example
38
+
39
+ ```javascript
40
+ import { UserRegistration } from '@felloh-org/lambda-wrapper';
41
+
42
+ const event = new UserRegistration();
43
+
44
+ // Set the user details
45
+ event.setDetailParam('user', {
46
+ id: 'usr_abc123xyz',
47
+ email: 'newuser@example.com',
48
+ first_name: 'John',
49
+ last_name: 'Doe'
50
+ });
51
+
52
+ // Optionally set who initiated the registration
53
+ event.setUserBy({
54
+ id: 'usr_admin123',
55
+ email: 'admin@example.com'
56
+ });
57
+
58
+ // Get the event payload for EventBridge
59
+ const payload = event.getBase();
60
+ ```
61
+
62
+ ## Sending the Event
63
+
64
+ To dispatch this event via EventBridge, use the `EventBridgeService`:
65
+
66
+ ```javascript
67
+ import { LambdaWrapper, DEFINITIONS, UserRegistration } from '@felloh-org/lambda-wrapper';
68
+
69
+ export const handler = LambdaWrapper(configuration, async (di, request) => {
70
+ const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
71
+
72
+ const event = new UserRegistration();
73
+ event.setDetailParam('user', {
74
+ id: 'usr_abc123xyz',
75
+ email: 'newuser@example.com',
76
+ first_name: 'John',
77
+ last_name: 'Doe'
78
+ });
79
+
80
+ await eventBridge.send(event);
81
+ });
82
+ ```
83
+
84
+ ## Notes
85
+
86
+ - The `user` object structure can be extended with additional fields as needed
87
+ - Use `setUserBy()` to track which user (e.g., admin) initiated the registration if applicable
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felloh-org/lambda-wrapper",
3
- "version": "1.11.192",
3
+ "version": "1.11.193",
4
4
  "description": "Lambda wrapper for all Felloh Serverless Projects",
5
5
  "main": "dist/index.js",
6
6
  "engines": {