@valentine-efagene/qshelter-common 2.0.83 → 2.0.84

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.
@@ -1,5 +1,7 @@
1
1
  export * from './notifications/notification-enums';
2
2
  export * from './notifications/notification-event';
3
3
  export * from './notifications/event-publisher';
4
+ export * from './payments/payment-event';
5
+ export * from './payments/payment-publisher';
4
6
  export * from './bus/event-bus.types';
5
7
  export * from './bus/event-bus.service';
@@ -2,6 +2,9 @@
2
2
  export * from './notifications/notification-enums';
3
3
  export * from './notifications/notification-event';
4
4
  export * from './notifications/event-publisher';
5
+ // Payment events and publisher (SNS-based)
6
+ export * from './payments/payment-event';
7
+ export * from './payments/payment-publisher';
5
8
  // Event bus (multi-transport delivery)
6
9
  export * from './bus/event-bus.types';
7
10
  export * from './bus/event-bus.service';
@@ -0,0 +1,2 @@
1
+ export * from './payment-event';
2
+ export * from './payment-publisher';
@@ -0,0 +1,2 @@
1
+ export * from './payment-event';
2
+ export * from './payment-publisher';
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Payment event types for the payment service queue
3
+ * These are internal service events, not user-facing notifications
4
+ */
5
+ export declare enum PaymentEventType {
6
+ WALLET_CREDITED = "wallet.credited",
7
+ WALLET_DEBITED = "wallet.debited",
8
+ WALLET_CREATED = "wallet.created",
9
+ ALLOCATE_TO_INSTALLMENTS = "payment.allocate_to_installments",
10
+ PROCESS_INSTALLMENT_PAYMENT = "payment.process_installment",
11
+ REFUND_PAYMENT = "payment.refund",
12
+ VIRTUAL_ACCOUNT_FUNDED = "virtualaccount.funded"
13
+ }
14
+ /**
15
+ * Metadata for payment events
16
+ */
17
+ export interface PaymentEventMeta {
18
+ /** Service that published the event */
19
+ source: string;
20
+ /** ISO timestamp of when event was created */
21
+ timestamp: string;
22
+ /** Correlation ID for distributed tracing */
23
+ correlationId?: string;
24
+ /** User ID */
25
+ userId?: string;
26
+ /** Tenant ID */
27
+ tenantId?: string;
28
+ }
29
+ /**
30
+ * Base payment event structure
31
+ */
32
+ export interface PaymentEvent<T = Record<string, unknown>> {
33
+ type: PaymentEventType;
34
+ payload: T;
35
+ meta: PaymentEventMeta;
36
+ }
37
+ /**
38
+ * Payload when wallet is credited
39
+ */
40
+ export interface WalletCreditedPayload {
41
+ walletId: string;
42
+ userId: string;
43
+ transactionId: string;
44
+ amount: number;
45
+ currency: string;
46
+ newBalance: number;
47
+ reference: string;
48
+ source: 'virtual_account' | 'manual' | 'refund';
49
+ }
50
+ /**
51
+ * Payload for allocating funds to installments
52
+ */
53
+ export interface AllocateToInstallmentsPayload {
54
+ userId: string;
55
+ walletId: string;
56
+ /** Optional: limit to specific contract */
57
+ contractId?: string;
58
+ /** Optional: limit to specific amount */
59
+ maxAmount?: number;
60
+ }
61
+ /**
62
+ * Payload for processing an installment payment
63
+ */
64
+ export interface ProcessInstallmentPaymentPayload {
65
+ installmentId: string;
66
+ amount: number;
67
+ walletId: string;
68
+ userId: string;
69
+ reference: string;
70
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Payment event types for the payment service queue
3
+ * These are internal service events, not user-facing notifications
4
+ */
5
+ export var PaymentEventType;
6
+ (function (PaymentEventType) {
7
+ // Wallet events (published by payment service)
8
+ PaymentEventType["WALLET_CREDITED"] = "wallet.credited";
9
+ PaymentEventType["WALLET_DEBITED"] = "wallet.debited";
10
+ PaymentEventType["WALLET_CREATED"] = "wallet.created";
11
+ // Allocation commands (published by mortgage service or after wallet credit)
12
+ PaymentEventType["ALLOCATE_TO_INSTALLMENTS"] = "payment.allocate_to_installments";
13
+ // Payment commands (published by mortgage service)
14
+ PaymentEventType["PROCESS_INSTALLMENT_PAYMENT"] = "payment.process_installment";
15
+ PaymentEventType["REFUND_PAYMENT"] = "payment.refund";
16
+ // Virtual account events
17
+ PaymentEventType["VIRTUAL_ACCOUNT_FUNDED"] = "virtualaccount.funded";
18
+ })(PaymentEventType || (PaymentEventType = {}));
@@ -0,0 +1,46 @@
1
+ import { PaymentEventType, PaymentEventMeta } from './payment-event';
2
+ /**
3
+ * Configuration for the payment event publisher
4
+ */
5
+ interface PaymentPublisherConfig {
6
+ region?: string;
7
+ endpoint?: string;
8
+ topicArn?: string;
9
+ }
10
+ /**
11
+ * Payment Event Publisher for sending payment events to SNS
12
+ * Used by payment-service and mortgage-service to communicate
13
+ */
14
+ export declare class PaymentEventPublisher {
15
+ private readonly snsClient;
16
+ private readonly topicArn;
17
+ private readonly serviceName;
18
+ constructor(serviceName: string, config?: PaymentPublisherConfig);
19
+ /**
20
+ * Publish a payment event to SNS
21
+ */
22
+ publish<T>(type: PaymentEventType, payload: T, meta?: Partial<PaymentEventMeta>): Promise<string>;
23
+ /**
24
+ * Publish wallet credited event
25
+ */
26
+ publishWalletCredited(payload: {
27
+ walletId: string;
28
+ userId: string;
29
+ transactionId: string;
30
+ amount: number;
31
+ currency: string;
32
+ newBalance: number;
33
+ reference: string;
34
+ source: 'virtual_account' | 'manual' | 'refund';
35
+ }, meta?: Partial<PaymentEventMeta>): Promise<string>;
36
+ /**
37
+ * Publish allocate to installments command
38
+ */
39
+ publishAllocateToInstallments(payload: {
40
+ userId: string;
41
+ walletId: string;
42
+ contractId?: string;
43
+ maxAmount?: number;
44
+ }, meta?: Partial<PaymentEventMeta>): Promise<string>;
45
+ }
46
+ export {};
@@ -0,0 +1,90 @@
1
+ import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';
2
+ import { PaymentEventType, } from './payment-event';
3
+ /**
4
+ * Get SNS client configured for LocalStack or AWS
5
+ */
6
+ function createSNSClient(config) {
7
+ const endpoint = config.endpoint || process.env.LOCALSTACK_ENDPOINT;
8
+ const region = config.region || process.env.AWS_REGION || 'us-east-1';
9
+ const clientConfig = { region };
10
+ // For LocalStack, set custom endpoint
11
+ if (endpoint) {
12
+ clientConfig.endpoint = endpoint;
13
+ }
14
+ return new SNSClient(clientConfig);
15
+ }
16
+ /**
17
+ * Payment Event Publisher for sending payment events to SNS
18
+ * Used by payment-service and mortgage-service to communicate
19
+ */
20
+ export class PaymentEventPublisher {
21
+ snsClient;
22
+ topicArn;
23
+ serviceName;
24
+ constructor(serviceName, config) {
25
+ this.serviceName = serviceName;
26
+ this.snsClient = createSNSClient(config || {});
27
+ // Topic ARN can be passed directly or constructed from env vars
28
+ const stage = process.env.STAGE || process.env.NODE_ENV || 'test';
29
+ const region = config?.region || process.env.AWS_REGION || 'us-east-1';
30
+ const accountId = process.env.AWS_ACCOUNT_ID || '000000000000';
31
+ this.topicArn = config?.topicArn ||
32
+ process.env.PAYMENTS_TOPIC_ARN ||
33
+ `arn:aws:sns:${region}:${accountId}:qshelter-${stage}-payments`;
34
+ }
35
+ /**
36
+ * Publish a payment event to SNS
37
+ */
38
+ async publish(type, payload, meta) {
39
+ const event = {
40
+ type,
41
+ payload,
42
+ meta: {
43
+ source: this.serviceName,
44
+ timestamp: new Date().toISOString(),
45
+ correlationId: meta?.correlationId || crypto.randomUUID(),
46
+ userId: meta?.userId,
47
+ tenantId: meta?.tenantId,
48
+ },
49
+ };
50
+ const command = new PublishCommand({
51
+ TopicArn: this.topicArn,
52
+ Message: JSON.stringify(event),
53
+ MessageAttributes: {
54
+ eventType: {
55
+ DataType: 'String',
56
+ StringValue: type,
57
+ },
58
+ source: {
59
+ DataType: 'String',
60
+ StringValue: this.serviceName,
61
+ },
62
+ },
63
+ });
64
+ const result = await this.snsClient.send(command);
65
+ console.log(`[PaymentEventPublisher] Published ${type} event to SNS`, {
66
+ topicArn: this.topicArn,
67
+ messageId: result.MessageId,
68
+ correlationId: event.meta.correlationId,
69
+ });
70
+ return result.MessageId || '';
71
+ }
72
+ /**
73
+ * Publish wallet credited event
74
+ */
75
+ async publishWalletCredited(payload, meta) {
76
+ return this.publish(PaymentEventType.WALLET_CREDITED, payload, {
77
+ ...meta,
78
+ userId: payload.userId,
79
+ });
80
+ }
81
+ /**
82
+ * Publish allocate to installments command
83
+ */
84
+ async publishAllocateToInstallments(payload, meta) {
85
+ return this.publish(PaymentEventType.ALLOCATE_TO_INSTALLMENTS, payload, {
86
+ ...meta,
87
+ userId: payload.userId,
88
+ });
89
+ }
90
+ }
package/package.json CHANGED
@@ -1,10 +1,20 @@
1
1
  {
2
2
  "name": "@valentine-efagene/qshelter-common",
3
- "version": "2.0.83",
3
+ "version": "2.0.84",
4
4
  "description": "Shared database schemas and utilities for QShelter services",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
7
7
  "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "tsc --watch",
11
+ "generate:prisma": "prisma generate && node scripts/generate-models-index.mjs",
12
+ "postgenerate": "node scripts/generate-models-index.mjs",
13
+ "migrate:dev": "prisma migrate dev",
14
+ "patch": "npm version patch && npm run build && npm publish --access public",
15
+ "prepublishOnly": "npm run build",
16
+ "publish:public": "npm publish --access public"
17
+ },
8
18
  "keywords": [
9
19
  "qshelter",
10
20
  "common",
@@ -47,14 +57,5 @@
47
57
  "@types/node": "^25.0.3",
48
58
  "typescript": "^5.7.3",
49
59
  "zod": "^4.0.0"
50
- },
51
- "scripts": {
52
- "build": "tsc",
53
- "dev": "tsc --watch",
54
- "generate:prisma": "prisma generate && node scripts/generate-models-index.mjs",
55
- "postgenerate": "node scripts/generate-models-index.mjs",
56
- "migrate:dev": "prisma migrate dev",
57
- "patch": "npm version patch && npm run build && npm publish --access public",
58
- "publish:public": "npm publish --access public"
59
60
  }
60
- }
61
+ }