@explorins/pers-sdk 1.6.45 → 1.6.47

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.
Files changed (137) hide show
  1. package/README.md +185 -0
  2. package/dist/analytics.cjs +12 -0
  3. package/dist/analytics.cjs.map +1 -1
  4. package/dist/analytics.js +1 -1
  5. package/dist/business/api/business-membership-api.d.ts +186 -0
  6. package/dist/business/api/business-membership-api.d.ts.map +1 -0
  7. package/dist/business/index.d.ts +2 -0
  8. package/dist/business/index.d.ts.map +1 -1
  9. package/dist/business/services/business-membership-service.d.ts +186 -0
  10. package/dist/business/services/business-membership-service.d.ts.map +1 -0
  11. package/dist/business.cjs +727 -9
  12. package/dist/business.cjs.map +1 -1
  13. package/dist/business.js +711 -2
  14. package/dist/business.js.map +1 -1
  15. package/dist/campaign/api/campaign-api.d.ts +7 -10
  16. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  17. package/dist/campaign/services/campaign-service.d.ts +18 -7
  18. package/dist/campaign/services/campaign-service.d.ts.map +1 -1
  19. package/dist/campaign.cjs +13 -1
  20. package/dist/campaign.cjs.map +1 -1
  21. package/dist/campaign.js +2 -2
  22. package/dist/chunks/{campaign-service-CJPXgFBe.js → campaign-service-CKwkiOLx.js} +29 -39
  23. package/dist/chunks/campaign-service-CKwkiOLx.js.map +1 -0
  24. package/dist/chunks/{campaign-service-B1tQMNqA.cjs → campaign-service-D-v9ZlUB.cjs} +29 -39
  25. package/dist/chunks/campaign-service-D-v9ZlUB.cjs.map +1 -0
  26. package/dist/chunks/{pers-sdk-DzS7mkm7.cjs → pers-sdk-DULFjOW2.cjs} +862 -97
  27. package/dist/chunks/pers-sdk-DULFjOW2.cjs.map +1 -0
  28. package/dist/chunks/{pers-sdk-VGEG59g3.js → pers-sdk-VmeBqUEP.js} +858 -97
  29. package/dist/chunks/pers-sdk-VmeBqUEP.js.map +1 -0
  30. package/dist/chunks/transaction-request.builder-DltmruUC.js +296 -0
  31. package/dist/chunks/transaction-request.builder-DltmruUC.js.map +1 -0
  32. package/dist/chunks/transaction-request.builder-DrqTWcyC.cjs +303 -0
  33. package/dist/chunks/transaction-request.builder-DrqTWcyC.cjs.map +1 -0
  34. package/dist/chunks/{user-service-D1Rn4U8u.cjs → user-service-B89wBOV1.cjs} +60 -10
  35. package/dist/chunks/user-service-B89wBOV1.cjs.map +1 -0
  36. package/dist/chunks/{user-service-D6mTa_WZ.js → user-service-doT5vsBD.js} +60 -10
  37. package/dist/chunks/user-service-doT5vsBD.js.map +1 -0
  38. package/dist/chunks/{web3-chain-service-BLFxB5TA.cjs → web3-chain-service-6vsVHPjl.cjs} +116 -16
  39. package/dist/chunks/web3-chain-service-6vsVHPjl.cjs.map +1 -0
  40. package/dist/chunks/{web3-chain-service-JRSwxr-s.js → web3-chain-service-BcUeeujC.js} +111 -17
  41. package/dist/chunks/web3-chain-service-BcUeeujC.js.map +1 -0
  42. package/dist/core/auth/api/auth-api.d.ts +35 -0
  43. package/dist/core/auth/api/auth-api.d.ts.map +1 -1
  44. package/dist/core/auth/auth-provider.interface.d.ts +7 -1
  45. package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
  46. package/dist/core/auth/services/auth-service.d.ts +26 -1
  47. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  48. package/dist/core/auth/token-storage.d.ts +3 -2
  49. package/dist/core/auth/token-storage.d.ts.map +1 -1
  50. package/dist/core/errors/index.d.ts +75 -6
  51. package/dist/core/errors/index.d.ts.map +1 -1
  52. package/dist/core/events/event-emitter.d.ts +106 -0
  53. package/dist/core/events/event-emitter.d.ts.map +1 -0
  54. package/dist/core/events/event-types.d.ts +127 -0
  55. package/dist/core/events/event-types.d.ts.map +1 -0
  56. package/dist/core/events/index.d.ts +22 -0
  57. package/dist/core/events/index.d.ts.map +1 -0
  58. package/dist/core/index.d.ts +3 -0
  59. package/dist/core/index.d.ts.map +1 -1
  60. package/dist/core/pers-api-client.d.ts +12 -0
  61. package/dist/core/pers-api-client.d.ts.map +1 -1
  62. package/dist/core/version.d.ts +15 -0
  63. package/dist/core/version.d.ts.map +1 -0
  64. package/dist/core.cjs +19 -6
  65. package/dist/core.cjs.map +1 -1
  66. package/dist/core.js +6 -6
  67. package/dist/donation.cjs +12 -0
  68. package/dist/donation.cjs.map +1 -1
  69. package/dist/donation.js +1 -1
  70. package/dist/index.cjs +43 -9
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.js +7 -6
  73. package/dist/index.js.map +1 -1
  74. package/dist/managers/auth-manager.d.ts +77 -4
  75. package/dist/managers/auth-manager.d.ts.map +1 -1
  76. package/dist/managers/business-manager.d.ts +192 -4
  77. package/dist/managers/business-manager.d.ts.map +1 -1
  78. package/dist/managers/campaign-manager.d.ts +48 -65
  79. package/dist/managers/campaign-manager.d.ts.map +1 -1
  80. package/dist/managers/redemption-manager.d.ts +3 -1
  81. package/dist/managers/redemption-manager.d.ts.map +1 -1
  82. package/dist/managers/transaction-manager.d.ts +4 -2
  83. package/dist/managers/transaction-manager.d.ts.map +1 -1
  84. package/dist/managers/user-manager.d.ts +57 -1
  85. package/dist/managers/user-manager.d.ts.map +1 -1
  86. package/dist/managers/web3-manager.d.ts.map +1 -1
  87. package/dist/package.json +2 -2
  88. package/dist/payment.cjs +12 -0
  89. package/dist/payment.cjs.map +1 -1
  90. package/dist/payment.js +1 -1
  91. package/dist/pers-sdk.d.ts +49 -0
  92. package/dist/pers-sdk.d.ts.map +1 -1
  93. package/dist/redemption.cjs +12 -0
  94. package/dist/redemption.cjs.map +1 -1
  95. package/dist/redemption.js +1 -1
  96. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +2 -1
  97. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
  98. package/dist/tenant.cjs +12 -0
  99. package/dist/tenant.cjs.map +1 -1
  100. package/dist/tenant.js +1 -1
  101. package/dist/token.cjs +12 -0
  102. package/dist/token.cjs.map +1 -1
  103. package/dist/token.js +1 -1
  104. package/dist/transaction/models/index.d.ts +2 -0
  105. package/dist/transaction/models/index.d.ts.map +1 -1
  106. package/dist/transaction/models/transaction-request.builder.d.ts +256 -0
  107. package/dist/transaction/models/transaction-request.builder.d.ts.map +1 -0
  108. package/dist/transaction.cjs +7 -0
  109. package/dist/transaction.cjs.map +1 -1
  110. package/dist/transaction.js +1 -0
  111. package/dist/transaction.js.map +1 -1
  112. package/dist/user/api/user-api.d.ts +28 -7
  113. package/dist/user/api/user-api.d.ts.map +1 -1
  114. package/dist/user/services/user-service.d.ts +21 -0
  115. package/dist/user/services/user-service.d.ts.map +1 -1
  116. package/dist/user-status.cjs +12 -0
  117. package/dist/user-status.cjs.map +1 -1
  118. package/dist/user-status.js +1 -1
  119. package/dist/user.cjs +13 -1
  120. package/dist/user.cjs.map +1 -1
  121. package/dist/user.js +2 -2
  122. package/dist/web3-chain.cjs +13 -1
  123. package/dist/web3-chain.cjs.map +1 -1
  124. package/dist/web3-chain.js +2 -2
  125. package/package.json +2 -2
  126. package/dist/chunks/business-service-8Xd3d5oY.js +0 -238
  127. package/dist/chunks/business-service-8Xd3d5oY.js.map +0 -1
  128. package/dist/chunks/business-service-P9o4cwQL.cjs +0 -241
  129. package/dist/chunks/business-service-P9o4cwQL.cjs.map +0 -1
  130. package/dist/chunks/campaign-service-B1tQMNqA.cjs.map +0 -1
  131. package/dist/chunks/campaign-service-CJPXgFBe.js.map +0 -1
  132. package/dist/chunks/pers-sdk-DzS7mkm7.cjs.map +0 -1
  133. package/dist/chunks/pers-sdk-VGEG59g3.js.map +0 -1
  134. package/dist/chunks/user-service-D1Rn4U8u.cjs.map +0 -1
  135. package/dist/chunks/user-service-D6mTa_WZ.js.map +0 -1
  136. package/dist/chunks/web3-chain-service-BLFxB5TA.cjs.map +0 -1
  137. package/dist/chunks/web3-chain-service-JRSwxr-s.js.map +0 -1
package/README.md CHANGED
@@ -16,6 +16,14 @@ Platform-agnostic TypeScript SDK for PERS (Phygital Experience Rewards System) -
16
16
  - [Platform Integration](#platform-integration)
17
17
  - [Architecture](#architecture)
18
18
  - [Core Features](#core-features)
19
+ - [Event System](#event-system)
20
+ - [Authentication](#authentication)
21
+ - [Business Management](#business-management)
22
+ - [Campaign System](#campaign-system)
23
+ - [Token Management](#token-management)
24
+ - [User Token Balances](#user-token-balances-on-chain)
25
+ - [Transaction Request Building](#transaction-request-building)
26
+ - [Purchase/Payment Processing](#purchasepayment-processing)
19
27
  - [Configuration](#configuration)
20
28
  - [Advanced Authentication](#advanced-authentication)
21
29
  - [Error Handling](#error-handling)
@@ -332,6 +340,85 @@ await apiClient.post('/custom-endpoint', { data: 'value' });
332
340
 
333
341
  ## Core Features
334
342
 
343
+ ### Event System
344
+
345
+ The SDK provides a platform-agnostic event system for subscribing to SDK-wide events. All events have a `userMessage` field ready for UI display.
346
+
347
+ ```typescript
348
+ // Subscribe to ALL events - one handler
349
+ const unsubscribe = sdk.events.subscribe((event) => {
350
+ showNotification(event.userMessage, event.level);
351
+ });
352
+
353
+ // Filter by domain and level
354
+ sdk.events.subscribe((event) => {
355
+ logToSentry(event);
356
+ }, { level: 'error' });
357
+
358
+ // Only transaction successes
359
+ sdk.events.subscribe((event) => {
360
+ playSuccessSound();
361
+ confetti();
362
+ }, { domain: 'transaction', level: 'success' });
363
+
364
+ // One-time event (auto-unsubscribe)
365
+ sdk.events.once((event) => {
366
+ console.log('First event:', event.type);
367
+ });
368
+
369
+ // Cleanup
370
+ unsubscribe();
371
+ ```
372
+
373
+ #### Event Domains
374
+
375
+ | Domain | Manager | Events |
376
+ |--------|---------|--------|
377
+ | `authentication` | `sdk.auth` | `LOGIN_SUCCESS` |
378
+ | `user` | `sdk.users` | `PROFILE_UPDATED` |
379
+ | `business` | `sdk.businesses` | `BUSINESS_CREATED`, `BUSINESS_UPDATED`, `MEMBERSHIP_UPDATED` |
380
+ | `campaign` | `sdk.campaigns` | `CAMPAIGN_CLAIMED` |
381
+ | `redemption` | `sdk.redemptions` | `REDEMPTION_COMPLETED` |
382
+ | `transaction` | `sdk.transactions` | `TRANSACTION_CREATED`, `TRANSACTION_SUBMITTED` |
383
+
384
+ #### Event Types
385
+
386
+ ```typescript
387
+ import type {
388
+ PersEvent, // Base event type (discriminated union)
389
+ SuccessEvent, // Success events (business domains)
390
+ ErrorEvent, // Error events (all domains including technical)
391
+ EventFilter, // Filter for subscriptions
392
+ EventHandler // Handler type (sync or async)
393
+ } from '@explorins/pers-sdk/core';
394
+
395
+ // Event structure
396
+ interface PersEvent {
397
+ id: string; // Unique event ID
398
+ timestamp: number; // Unix timestamp (ms)
399
+ domain: string; // Event domain
400
+ type: string; // Event type within domain
401
+ level: 'success' | 'error';
402
+ userMessage: string; // Ready for UI display
403
+ action?: string; // Suggested action
404
+ code?: string; // Backend error code
405
+ details?: object; // Additional data for logging
406
+ }
407
+ ```
408
+
409
+ #### Async Handler Support
410
+
411
+ Event handlers can be synchronous or asynchronous. Async errors are caught automatically:
412
+
413
+ ```typescript
414
+ sdk.events.subscribe(async (event) => {
415
+ await saveToDatabase(event); // Async operations supported
416
+ await sendAnalytics(event);
417
+ });
418
+ ```
419
+
420
+ ---
421
+
335
422
  ### Authentication
336
423
 
337
424
  The SDK uses **external JWT tokens** for authentication. You provide a JWT from your authentication provider (Firebase, Auth0, Cognito, etc.), and the SDK exchanges it for PERS access tokens.
@@ -538,6 +625,104 @@ async function loadUserTokenBalances(sdk: PersSDK) {
538
625
  }
539
626
  ```
540
627
 
628
+ ### Transaction Request Building
629
+
630
+ The SDK provides factory functions for building transaction request DTOs. These are tree-shakeable and provide type-safe transaction creation:
631
+
632
+ ```typescript
633
+ import {
634
+ buildMintRequest,
635
+ buildBurnRequest,
636
+ buildTransferRequest,
637
+ buildPOSTransferRequest,
638
+ buildSubmissionRequest
639
+ } from '@explorins/pers-sdk/transaction';
640
+ import { AccountOwnerType } from '@explorins/pers-shared';
641
+
642
+ // Mint tokens to a recipient
643
+ const mintRequest = buildMintRequest({
644
+ amount: 100,
645
+ contractAddress: '0x...',
646
+ chainId: 137,
647
+ recipientAccountId: 'user-123',
648
+ recipientAccountType: AccountOwnerType.USER
649
+ });
650
+
651
+ // Burn tokens
652
+ const burnRequest = buildBurnRequest({
653
+ amount: 50,
654
+ contractAddress: '0x...',
655
+ chainId: 137,
656
+ senderAccountId: 'user-123',
657
+ senderAccountType: AccountOwnerType.USER
658
+ });
659
+
660
+ // Transfer tokens between accounts
661
+ const transferRequest = buildTransferRequest({
662
+ amount: 100,
663
+ contractAddress: '0x...',
664
+ chainId: 137,
665
+ senderAccountId: 'user-123',
666
+ senderAccountType: AccountOwnerType.USER,
667
+ recipientAccountId: 'business-456',
668
+ recipientAccountType: AccountOwnerType.BUSINESS
669
+ });
670
+
671
+ // Submit the transaction
672
+ const result = await sdk.transactions.createTransaction(mintRequest);
673
+ ```
674
+
675
+ #### POS Transaction Flow
676
+
677
+ For Point-of-Sale scenarios where a **business submits a transaction on behalf of a user**, use `buildPOSTransferRequest`:
678
+
679
+ ```typescript
680
+ import { buildPOSTransferRequest } from '@explorins/pers-sdk/transaction';
681
+
682
+ // POS flow: User pays business, business authorized to submit
683
+ const posRequest = buildPOSTransferRequest({
684
+ amount: 100,
685
+ contractAddress: '0x...',
686
+ chainId: 137,
687
+ userAccountId: 'user-123', // User sending tokens
688
+ businessAccountId: 'business-456' // Business receiving & authorized to submit
689
+ });
690
+
691
+ // This automatically sets:
692
+ // - engagedBusinessId: 'business-456' (for reporting)
693
+ // - authorizedSubmitterId: 'business-456' (can submit the signed tx)
694
+ // - authorizedSubmitterType: AccountOwnerType.BUSINESS
695
+
696
+ const result = await sdk.transactions.createTransaction(posRequest);
697
+ ```
698
+
699
+ For custom authorization scenarios, use `buildTransferRequest` with manual POS fields:
700
+
701
+ ```typescript
702
+ import { buildTransferRequest, type POSAuthorizationOptions } from '@explorins/pers-sdk/transaction';
703
+
704
+ const customPOSRequest = buildTransferRequest({
705
+ amount: 100,
706
+ contractAddress: '0x...',
707
+ chainId: 137,
708
+ senderAccountId: 'user-123',
709
+ senderAccountType: AccountOwnerType.USER,
710
+ recipientAccountId: 'business-456',
711
+ recipientAccountType: AccountOwnerType.BUSINESS,
712
+ // POS authorization fields
713
+ engagedBusinessId: 'business-456',
714
+ authorizedSubmitterId: 'business-456',
715
+ authorizedSubmitterType: AccountOwnerType.BUSINESS
716
+ });
717
+ ```
718
+
719
+ | POS Field | Type | Description |
720
+ |-----------|------|-------------|
721
+ | `engagedBusinessId` | `string` | Business commercially involved (for stats/reporting) |
722
+ | `authorizedSubmitterId` | `string` | Entity authorized to submit the signed transaction |
723
+ | `authorizedSubmitterType` | `AccountOwnerType` | Type of authorized submitter (`USER` or `BUSINESS`) |
724
+ ```
725
+
541
726
  ### Purchase/Payment Processing
542
727
 
543
728
  ```typescript
@@ -15,8 +15,20 @@ Object.defineProperty(exports, "ApiKeyType", {
15
15
  enumerable: true,
16
16
  get: function () { return persShared.ApiKeyType; }
17
17
  });
18
+ Object.defineProperty(exports, "MEMBERSHIP_ROLE_HIERARCHY", {
19
+ enumerable: true,
20
+ get: function () { return persShared.MEMBERSHIP_ROLE_HIERARCHY; }
21
+ });
22
+ Object.defineProperty(exports, "MembershipRole", {
23
+ enumerable: true,
24
+ get: function () { return persShared.MembershipRole; }
25
+ });
18
26
  Object.defineProperty(exports, "NativeTokenTypes", {
19
27
  enumerable: true,
20
28
  get: function () { return persShared.NativeTokenTypes; }
21
29
  });
30
+ Object.defineProperty(exports, "hasMinimumRole", {
31
+ enumerable: true,
32
+ get: function () { return persShared.hasMinimumRole; }
33
+ });
22
34
  //# sourceMappingURL=analytics.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"analytics.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/analytics.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { A as AnalyticsApi, a as AnalyticsService } from './chunks/analytics-service-CxyrOwel.js';
2
- export { AccountOwnerType, ApiKeyType, NativeTokenTypes } from '@explorins/pers-shared';
2
+ export { AccountOwnerType, ApiKeyType, MEMBERSHIP_ROLE_HIERARCHY, MembershipRole, NativeTokenTypes, hasMinimumRole } from '@explorins/pers-shared';
3
3
  //# sourceMappingURL=analytics.js.map
@@ -0,0 +1,186 @@
1
+ import { PersApiClient } from '../../core/pers-api-client';
2
+ import { BusinessMembershipDTO, AddBusinessMemberRequestDTO, UpdateBusinessMembershipRequestDTO, MembershipRole } from '../../shared/interfaces/pers-shared-lib.interfaces';
3
+ /**
4
+ * Business Membership API Client
5
+ *
6
+ * Platform-agnostic API client for managing business memberships.
7
+ * Handles user access to businesses with role-based permissions.
8
+ *
9
+ * Base Path: /businesses/:businessId/members
10
+ *
11
+ * Required Headers:
12
+ * - Authorization: Bearer <business_jwt_token>
13
+ * - X-Project-Key: <project_key>
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const membershipApi = new BusinessMembershipApi(apiClient);
18
+ *
19
+ * // List all members of a business
20
+ * const members = await membershipApi.getMembers('business-123');
21
+ *
22
+ * // Add a new member
23
+ * const newMember = await membershipApi.addMember('business-123', {
24
+ * userId: 'user-456',
25
+ * role: MembershipRole.EDITOR
26
+ * });
27
+ * ```
28
+ *
29
+ * @version 2.0.0
30
+ */
31
+ export declare class BusinessMembershipApi {
32
+ private apiClient;
33
+ constructor(apiClient: PersApiClient);
34
+ /**
35
+ * Build the membership endpoint path for a business
36
+ */
37
+ private getMembersPath;
38
+ /**
39
+ * Build the membership endpoint path for a specific member
40
+ */
41
+ private getMemberPath;
42
+ /**
43
+ * List all members of a business
44
+ *
45
+ * Endpoint: GET /businesses/:businessId/members
46
+ * Min Role: VIEWER (any member can view)
47
+ *
48
+ * @param businessId - The business UUID
49
+ * @returns Array of business memberships with user and role details
50
+ *
51
+ * @throws {AuthenticationError} 401 - Not authenticated
52
+ * @throws {PersApiError} 403 - businessId in path doesn't match JWT's business
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const members = await membershipApi.getMembers('business-123');
57
+ * members.forEach(m => console.log(`${m.userId}: ${m.role}`));
58
+ * ```
59
+ */
60
+ getMembers(businessId: string): Promise<BusinessMembershipDTO[]>;
61
+ /**
62
+ * Add a member to a business
63
+ *
64
+ * Endpoint: POST /businesses/:businessId/members
65
+ * Min Role: ADMIN
66
+ *
67
+ * @param businessId - The business UUID
68
+ * @param request - The add member request with userId and optional role
69
+ * @returns The created business membership
70
+ *
71
+ * @throws {AuthenticationError} 401 - Not authenticated
72
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
73
+ * @throws {PersApiError} 404 - User not found
74
+ * @throws {PersApiError} 409 - User is already a member
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const newMember = await membershipApi.addMember('business-123', {
79
+ * userId: 'user-456',
80
+ * role: MembershipRole.EDITOR
81
+ * });
82
+ * ```
83
+ */
84
+ addMember(businessId: string, request: AddBusinessMemberRequestDTO): Promise<BusinessMembershipDTO>;
85
+ /**
86
+ * Add a member to a business with explicit parameters
87
+ *
88
+ * Convenience method that constructs the request DTO internally.
89
+ *
90
+ * @param businessId - The business UUID
91
+ * @param userId - The user UUID to add
92
+ * @param role - The role to assign (defaults to VIEWER)
93
+ * @returns The created business membership
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const member = await membershipApi.addMemberByUserId(
98
+ * 'business-123',
99
+ * 'user-456',
100
+ * MembershipRole.EDITOR
101
+ * );
102
+ * ```
103
+ */
104
+ addMemberByUserId(businessId: string, userId: string, role?: MembershipRole): Promise<BusinessMembershipDTO>;
105
+ /**
106
+ * Update a member's role in a business
107
+ *
108
+ * Endpoint: PUT /businesses/:businessId/members/:userId
109
+ * Min Role: ADMIN
110
+ *
111
+ * Business Rules:
112
+ * - Cannot demote the last OWNER (must transfer ownership first)
113
+ * - Can only assign roles up to your own level (ADMIN cannot create OWNER)
114
+ *
115
+ * @param businessId - The business UUID
116
+ * @param userId - The user UUID to update
117
+ * @param request - The update request with new role
118
+ * @returns The updated business membership
119
+ *
120
+ * @throws {AuthenticationError} 401 - Not authenticated
121
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
122
+ * @throws {PersApiError} 404 - Membership not found
123
+ * @throws {PersApiError} 400 - Cannot demote last OWNER
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * const updated = await membershipApi.updateMemberRole(
128
+ * 'business-123',
129
+ * 'user-456',
130
+ * { role: MembershipRole.ADMIN }
131
+ * );
132
+ * ```
133
+ */
134
+ updateMemberRole(businessId: string, userId: string, request: UpdateBusinessMembershipRequestDTO): Promise<BusinessMembershipDTO>;
135
+ /**
136
+ * Update a member's role with explicit parameters
137
+ *
138
+ * Convenience method that constructs the request DTO internally.
139
+ *
140
+ * @param businessId - The business UUID
141
+ * @param userId - The user UUID to update
142
+ * @param role - The new role to assign
143
+ * @returns The updated business membership
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const updated = await membershipApi.setMemberRole(
148
+ * 'business-123',
149
+ * 'user-456',
150
+ * MembershipRole.ADMIN
151
+ * );
152
+ * ```
153
+ */
154
+ setMemberRole(businessId: string, userId: string, role: MembershipRole): Promise<BusinessMembershipDTO>;
155
+ /**
156
+ * Remove a member from a business
157
+ *
158
+ * Endpoint: DELETE /businesses/:businessId/members/:userId
159
+ * Min Role: ADMIN
160
+ *
161
+ * Business Rules:
162
+ * - Cannot remove the last OWNER
163
+ * - Cannot remove yourself (use leave endpoint or transfer ownership)
164
+ *
165
+ * @param businessId - The business UUID
166
+ * @param userId - The user UUID to remove
167
+ * @returns Success confirmation
168
+ *
169
+ * @throws {AuthenticationError} 401 - Not authenticated
170
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
171
+ * @throws {PersApiError} 404 - Membership not found
172
+ * @throws {PersApiError} 400 - Cannot remove last OWNER
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * const result = await membershipApi.removeMember('business-123', 'user-456');
177
+ * if (result.success) {
178
+ * console.log('Member removed successfully');
179
+ * }
180
+ * ```
181
+ */
182
+ removeMember(businessId: string, userId: string): Promise<{
183
+ success: boolean;
184
+ }>;
185
+ }
186
+ //# sourceMappingURL=business-membership-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-membership-api.d.ts","sourceRoot":"","sources":["../../../src/business/api/business-membership-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,kCAAkC,EAClC,cAAc,EACf,MAAM,oDAAoD,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,qBAAqB;IACpB,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,aAAa;IAE5C;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;;;;;;;;;;;;;;OAiBG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAUtE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC;IAOjC;;;;;;;;;;;;;;;;;;OAkBG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAsC,GAC3C,OAAO,CAAC,qBAAqB,CAAC;IAQjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,qBAAqB,CAAC;IAOjC;;;;;;;;;;;;;;;;;;OAkBG;IACG,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,qBAAqB,CAAC;IAQjC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAKjC"}
@@ -5,6 +5,8 @@
5
5
  * Focuses on non-admin business operations
6
6
  */
7
7
  export { BusinessApi } from './api/business-api';
8
+ export { BusinessMembershipApi } from './api/business-membership-api';
8
9
  export { BusinessService } from './services/business-service';
10
+ export { BusinessMembershipService } from './services/business-membership-service';
9
11
  export * from '../shared/interfaces/pers-shared-lib.interfaces';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/business/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,cAAc,iDAAiD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/business/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAGnF,cAAc,iDAAiD,CAAC"}
@@ -0,0 +1,186 @@
1
+ import { BusinessMembershipApi } from '../api/business-membership-api';
2
+ import { BusinessMembershipDTO, MembershipRole } from '../../shared/interfaces/pers-shared-lib.interfaces';
3
+ /**
4
+ * Business Membership Service
5
+ *
6
+ * Platform-agnostic service for managing business memberships.
7
+ * Provides business logic layer on top of the API client with
8
+ * convenience methods and role-based utilities.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const service = new BusinessMembershipService(membershipApi);
13
+ *
14
+ * // Get members with admin permissions
15
+ * const admins = await service.getMembersByRole('business-123', MembershipRole.ADMIN);
16
+ *
17
+ * // Check permissions
18
+ * const canManage = service.canManageMembers(MembershipRole.ADMIN); // true
19
+ * ```
20
+ *
21
+ * @version 2.0.0
22
+ */
23
+ export declare class BusinessMembershipService {
24
+ private membershipApi;
25
+ constructor(membershipApi: BusinessMembershipApi);
26
+ /**
27
+ * Get all members of a business
28
+ *
29
+ * @param businessId - The business UUID
30
+ * @returns Array of business memberships
31
+ */
32
+ getMembers(businessId: string): Promise<BusinessMembershipDTO[]>;
33
+ /**
34
+ * Get members filtered by role
35
+ *
36
+ * @param businessId - The business UUID
37
+ * @param role - The role to filter by
38
+ * @returns Array of memberships with the specified role
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const owners = await service.getMembersByRole('biz-123', MembershipRole.OWNER);
43
+ * const adminsAndAbove = await service.getMembersWithMinRole('biz-123', MembershipRole.ADMIN);
44
+ * ```
45
+ */
46
+ getMembersByRole(businessId: string, role: MembershipRole): Promise<BusinessMembershipDTO[]>;
47
+ /**
48
+ * Get members with at least a minimum role level
49
+ *
50
+ * Uses the role hierarchy: OWNER > ADMIN > EDITOR > VIEWER
51
+ *
52
+ * @param businessId - The business UUID
53
+ * @param minRole - The minimum role level
54
+ * @returns Array of memberships with role >= minRole
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Get all members who can manage content (EDITOR and above)
59
+ * const editors = await service.getMembersWithMinRole('biz-123', MembershipRole.EDITOR);
60
+ * ```
61
+ */
62
+ getMembersWithMinRole(businessId: string, minRole: MembershipRole): Promise<BusinessMembershipDTO[]>;
63
+ /**
64
+ * Get a specific member by user ID
65
+ *
66
+ * @param businessId - The business UUID
67
+ * @param userId - The user UUID to find
68
+ * @returns The membership if found, undefined otherwise
69
+ */
70
+ getMemberByUserId(businessId: string, userId: string): Promise<BusinessMembershipDTO | undefined>;
71
+ /**
72
+ * Count members by role
73
+ *
74
+ * @param businessId - The business UUID
75
+ * @returns Object with count per role
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const counts = await service.getMemberCountsByRole('biz-123');
80
+ * // { OWNER: 1, ADMIN: 2, EDITOR: 5, VIEWER: 10 }
81
+ * ```
82
+ */
83
+ getMemberCountsByRole(businessId: string): Promise<Record<MembershipRole, number>>;
84
+ /**
85
+ * Add a new member to a business
86
+ *
87
+ * @param businessId - The business UUID
88
+ * @param userId - The user UUID to add
89
+ * @param role - The role to assign (defaults to VIEWER)
90
+ * @returns The created membership
91
+ */
92
+ addMember(businessId: string, userId: string, role?: MembershipRole): Promise<BusinessMembershipDTO>;
93
+ /**
94
+ * Update a member's role
95
+ *
96
+ * @param businessId - The business UUID
97
+ * @param userId - The user UUID to update
98
+ * @param newRole - The new role to assign
99
+ * @returns The updated membership
100
+ */
101
+ updateMemberRole(businessId: string, userId: string, newRole: MembershipRole): Promise<BusinessMembershipDTO>;
102
+ /**
103
+ * Remove a member from a business
104
+ *
105
+ * @param businessId - The business UUID
106
+ * @param userId - The user UUID to remove
107
+ * @returns Success confirmation
108
+ */
109
+ removeMember(businessId: string, userId: string): Promise<{
110
+ success: boolean;
111
+ }>;
112
+ /**
113
+ * Promote a member to a higher role
114
+ *
115
+ * @param businessId - The business UUID
116
+ * @param userId - The user UUID to promote
117
+ * @param targetRole - The target role (must be higher than current)
118
+ * @returns The updated membership
119
+ * @throws Error if target role is not higher than current
120
+ */
121
+ promoteMember(businessId: string, userId: string, targetRole: MembershipRole): Promise<BusinessMembershipDTO>;
122
+ /**
123
+ * Demote a member to a lower role
124
+ *
125
+ * Note: Cannot demote the last OWNER
126
+ *
127
+ * @param businessId - The business UUID
128
+ * @param userId - The user UUID to demote
129
+ * @param targetRole - The target role (must be lower than current)
130
+ * @returns The updated membership
131
+ * @throws Error if target role is not lower than current
132
+ */
133
+ demoteMember(businessId: string, userId: string, targetRole: MembershipRole): Promise<BusinessMembershipDTO>;
134
+ /**
135
+ * Check if a role can view members (any member)
136
+ */
137
+ canViewMembers(role: MembershipRole | null): boolean;
138
+ /**
139
+ * Check if a role can manage members (ADMIN or higher)
140
+ */
141
+ canManageMembers(role: MembershipRole | null): boolean;
142
+ /**
143
+ * Check if a role can edit content (EDITOR or higher)
144
+ */
145
+ canEditContent(role: MembershipRole | null): boolean;
146
+ /**
147
+ * Check if a role can delete the business (OWNER only)
148
+ */
149
+ canDeleteBusiness(role: MembershipRole | null): boolean;
150
+ /**
151
+ * Get permissions object for a role
152
+ *
153
+ * Useful for UI components to conditionally render based on permissions.
154
+ *
155
+ * @param role - The membership role (or null if not a member)
156
+ * @returns Object with boolean permission flags
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const perms = service.getPermissions(MembershipRole.EDITOR);
161
+ * // { canViewMembers: true, canManageMembers: false, canEditContent: true, canDeleteBusiness: false }
162
+ *
163
+ * if (perms.canManageMembers) {
164
+ * showAddMemberButton();
165
+ * }
166
+ * ```
167
+ */
168
+ getPermissions(role: MembershipRole | null): {
169
+ canViewMembers: boolean;
170
+ canManageMembers: boolean;
171
+ canEditContent: boolean;
172
+ canDeleteBusiness: boolean;
173
+ };
174
+ /**
175
+ * Check if a role can assign another role
176
+ *
177
+ * Rule: Can only assign roles up to your own level
178
+ * (ADMIN cannot create OWNER, but OWNER can create anything)
179
+ *
180
+ * @param assignerRole - The role of the user assigning
181
+ * @param targetRole - The role being assigned
182
+ * @returns true if the assigner can assign the target role
183
+ */
184
+ canAssignRole(assignerRole: MembershipRole, targetRole: MembershipRole): boolean;
185
+ }
186
+ //# sourceMappingURL=business-membership-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-membership-service.d.ts","sourceRoot":"","sources":["../../../src/business/services/business-membership-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EACL,qBAAqB,EACrB,cAAc,EAEf,MAAM,oDAAoD,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,yBAAyB;IACxB,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,qBAAqB;IAMxD;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAItE;;;;;;;;;;;;OAYG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAKnC;;;;;;;;;;;;;;OAcG;IACG,qBAAqB,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAKnC;;;;;;OAMG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAK7C;;;;;;;;;;;OAWG;IACG,qBAAqB,CACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAuB1C;;;;;;;OAOG;IACG,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAsC,GAC3C,OAAO,CAAC,qBAAqB,CAAC;IAIjC;;;;;;;OAOG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC;IAIjC;;;;;;OAMG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIhC;;;;;;;;OAQG;IACG,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC,qBAAqB,CAAC;IAejC;;;;;;;;;;OAUG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC,qBAAqB,CAAC;IAmBjC;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO;IAIpD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO;IAItD;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO;IAIpD;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO;IAIvD;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG;QAC3C,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,cAAc,EAAE,OAAO,CAAC;QACxB,iBAAiB,EAAE,OAAO,CAAC;KAC5B;IASD;;;;;;;;;OASG;IACH,aAAa,CAAC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO;CASjF"}