@explorins/pers-sdk 2.1.3 → 2.1.4

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 (97) hide show
  1. package/dist/analytics/api/analytics-api.d.ts +175 -1
  2. package/dist/analytics/api/analytics-api.d.ts.map +1 -1
  3. package/dist/analytics/models/index.d.ts +2 -5
  4. package/dist/analytics/models/index.d.ts.map +1 -1
  5. package/dist/analytics/services/analytics-service.d.ts +32 -1
  6. package/dist/analytics/services/analytics-service.d.ts.map +1 -1
  7. package/dist/analytics.cjs +9 -44
  8. package/dist/analytics.cjs.map +1 -1
  9. package/dist/analytics.js +2 -45
  10. package/dist/analytics.js.map +1 -1
  11. package/dist/campaign/api/campaign-api.d.ts +59 -4
  12. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  13. package/dist/campaign/services/campaign-service.d.ts +49 -7
  14. package/dist/campaign/services/campaign-service.d.ts.map +1 -1
  15. package/dist/campaign.cjs +150 -14
  16. package/dist/campaign.cjs.map +1 -1
  17. package/dist/campaign.js +150 -14
  18. package/dist/campaign.js.map +1 -1
  19. package/dist/chunks/analytics-service-B9IfG6ox.js +271 -0
  20. package/dist/chunks/analytics-service-B9IfG6ox.js.map +1 -0
  21. package/dist/chunks/analytics-service-DwkeBB08.cjs +274 -0
  22. package/dist/chunks/analytics-service-DwkeBB08.cjs.map +1 -0
  23. package/dist/chunks/{pers-sdk-fWg-J3_h.js → pers-sdk-CAM0iQyK.js} +982 -189
  24. package/dist/chunks/pers-sdk-CAM0iQyK.js.map +1 -0
  25. package/dist/chunks/{pers-sdk-BQw3QUWR.cjs → pers-sdk-Di_R6AiT.cjs} +986 -190
  26. package/dist/chunks/pers-sdk-Di_R6AiT.cjs.map +1 -0
  27. package/dist/chunks/{redemption-service-D-hBqh42.js → redemption-service-CQtTLdic.js} +32 -10
  28. package/dist/chunks/redemption-service-CQtTLdic.js.map +1 -0
  29. package/dist/chunks/{redemption-service-rMB6T2W5.cjs → redemption-service-DsH7sRdv.cjs} +32 -10
  30. package/dist/chunks/redemption-service-DsH7sRdv.cjs.map +1 -0
  31. package/dist/chunks/{transaction-request.builder-C1vVVFto.js → transaction-request.builder-C8ahJYwi.js} +122 -70
  32. package/dist/chunks/transaction-request.builder-C8ahJYwi.js.map +1 -0
  33. package/dist/chunks/{transaction-request.builder-BpgtuMMq.cjs → transaction-request.builder-CkYd5bl6.cjs} +122 -70
  34. package/dist/chunks/transaction-request.builder-CkYd5bl6.cjs.map +1 -0
  35. package/dist/core/pers-api-client.d.ts.map +1 -1
  36. package/dist/core.cjs +5 -4
  37. package/dist/core.cjs.map +1 -1
  38. package/dist/core.js +4 -4
  39. package/dist/index.cjs +13 -6
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +5 -5
  44. package/dist/managers/analytics-manager.d.ts +165 -2
  45. package/dist/managers/analytics-manager.d.ts.map +1 -1
  46. package/dist/managers/campaign-manager.d.ts +180 -30
  47. package/dist/managers/campaign-manager.d.ts.map +1 -1
  48. package/dist/managers/index.d.ts +1 -0
  49. package/dist/managers/index.d.ts.map +1 -1
  50. package/dist/managers/redemption-manager.d.ts +52 -2
  51. package/dist/managers/redemption-manager.d.ts.map +1 -1
  52. package/dist/managers/transaction-manager.d.ts +66 -131
  53. package/dist/managers/transaction-manager.d.ts.map +1 -1
  54. package/dist/managers/trigger-source-manager.d.ts +194 -0
  55. package/dist/managers/trigger-source-manager.d.ts.map +1 -0
  56. package/dist/managers/user-manager.d.ts +38 -7
  57. package/dist/managers/user-manager.d.ts.map +1 -1
  58. package/dist/node.cjs +4 -4
  59. package/dist/node.js +4 -4
  60. package/dist/package.json +2 -2
  61. package/dist/pers-sdk.d.ts +33 -2
  62. package/dist/pers-sdk.d.ts.map +1 -1
  63. package/dist/redemption/api/redemption-api.d.ts +8 -4
  64. package/dist/redemption/api/redemption-api.d.ts.map +1 -1
  65. package/dist/redemption/services/redemption-service.d.ts +7 -3
  66. package/dist/redemption/services/redemption-service.d.ts.map +1 -1
  67. package/dist/redemption.cjs +1 -1
  68. package/dist/redemption.js +1 -1
  69. package/dist/transaction/api/transaction-api.d.ts +37 -42
  70. package/dist/transaction/api/transaction-api.d.ts.map +1 -1
  71. package/dist/transaction/models/index.d.ts +21 -0
  72. package/dist/transaction/models/index.d.ts.map +1 -1
  73. package/dist/transaction/services/transaction-service.d.ts +10 -15
  74. package/dist/transaction/services/transaction-service.d.ts.map +1 -1
  75. package/dist/transaction.cjs +1 -1
  76. package/dist/transaction.js +1 -1
  77. package/dist/trigger-source/api/trigger-source-api.d.ts +86 -0
  78. package/dist/trigger-source/api/trigger-source-api.d.ts.map +1 -0
  79. package/dist/trigger-source/index.d.ts +9 -0
  80. package/dist/trigger-source/index.d.ts.map +1 -0
  81. package/dist/trigger-source/services/trigger-source-service.d.ts +42 -0
  82. package/dist/trigger-source/services/trigger-source-service.d.ts.map +1 -0
  83. package/dist/user/api/user-api.d.ts +26 -1
  84. package/dist/user/api/user-api.d.ts.map +1 -1
  85. package/dist/user/services/user-service.d.ts +3 -1
  86. package/dist/user/services/user-service.d.ts.map +1 -1
  87. package/dist/user.cjs +34 -4
  88. package/dist/user.cjs.map +1 -1
  89. package/dist/user.js +34 -4
  90. package/dist/user.js.map +1 -1
  91. package/package.json +2 -2
  92. package/dist/chunks/pers-sdk-BQw3QUWR.cjs.map +0 -1
  93. package/dist/chunks/pers-sdk-fWg-J3_h.js.map +0 -1
  94. package/dist/chunks/redemption-service-D-hBqh42.js.map +0 -1
  95. package/dist/chunks/redemption-service-rMB6T2W5.cjs.map +0 -1
  96. package/dist/chunks/transaction-request.builder-BpgtuMMq.cjs.map +0 -1
  97. package/dist/chunks/transaction-request.builder-C1vVVFto.js.map +0 -1
@@ -7,12 +7,12 @@ var userStatus = require('../user-status.cjs');
7
7
  var tokenService = require('./token-service-BlbXrxnS.cjs');
8
8
  var businessMembershipService = require('./business-membership-service-8KC_qRj7.cjs');
9
9
  var campaign = require('../campaign.cjs');
10
- var redemptionService = require('./redemption-service-rMB6T2W5.cjs');
11
- var transactionRequest_builder = require('./transaction-request.builder-BpgtuMMq.cjs');
10
+ var redemptionService = require('./redemption-service-DsH7sRdv.cjs');
11
+ var transactionRequest_builder = require('./transaction-request.builder-CkYd5bl6.cjs');
12
12
  var paymentService = require('./payment-service-Bkw7ZXev.cjs');
13
13
  var tenantService = require('./tenant-service-fj-pkXTw.cjs');
14
14
  var paginationUtils = require('./pagination-utils-B2jRHMSO.cjs');
15
- var analytics = require('../analytics.cjs');
15
+ var analyticsService = require('./analytics-service-DwkeBB08.cjs');
16
16
  var donation = require('../donation.cjs');
17
17
 
18
18
  /**
@@ -1114,13 +1114,15 @@ class PersApiClient {
1114
1114
  * @internal
1115
1115
  */
1116
1116
  emitErrorEvent(errorDetails, errorMessage, endpoint, method, status, error) {
1117
- console.log('[PersApiClient] emitErrorEvent called', {
1118
- hasEvents: !!this._events,
1119
- instanceId: this._events?.instanceId ?? 'none',
1120
- subscriberCount: this._events?.subscriberCount ?? 0,
1121
- domain: errorDetails.domain,
1122
- message: errorDetails.message || errorMessage
1123
- });
1117
+ /* console.log('[PersApiClient] emitErrorEvent called', {
1118
+ hasEvents: !!this._events,
1119
+ instanceId: this._events?.instanceId ?? 'none',
1120
+ subscriberCount: this._events?.subscriberCount ?? 0,
1121
+ domain: errorDetails.domain,
1122
+ code: errorDetails.code,
1123
+ status: status,
1124
+ message: errorDetails.message || errorMessage
1125
+ }); */
1124
1126
  this._events?.emitError({
1125
1127
  domain: errorDetails.domain || 'external',
1126
1128
  type: errorDetails.code || 'API_ERROR',
@@ -2083,26 +2085,57 @@ class UserManager {
2083
2085
  * requires administrator privileges and returns full user profiles including
2084
2086
  * private information.
2085
2087
  *
2086
- * @returns Promise resolving to array of all users with complete data
2088
+ * @param options - Pagination and sorting options
2089
+ * @param options.page - Page number (1-based, default: 1)
2090
+ * @param options.limit - Items per page (default: 50)
2091
+ * @param options.sortBy - Sort by field. Supported fields:
2092
+ * - 'id', 'email', 'identifierEmail', 'firstName', 'lastName'
2093
+ * - 'externalId', 'accountAddress', 'isActive'
2094
+ * - 'createdAt', 'updatedAt'
2095
+ * - Default: 'createdAt'
2096
+ * @param options.sortOrder - Sort order: SortOrder.ASC or SortOrder.DESC (default: DESC)
2097
+ * @param search - Optional search query to filter users
2098
+ * @returns Promise resolving to paginated users with complete data
2087
2099
  * @throws {PersApiError} When not authenticated as admin
2088
2100
  *
2089
- * @example
2101
+ * @example Basic Usage
2090
2102
  * ```typescript
2091
2103
  * // Admin operation - requires admin authentication
2092
2104
  * try {
2093
- * const allUsers = await sdk.users.getAllUsers();
2094
- * console.log(`Total users: ${allUsers.length}`);
2105
+ * const result = await sdk.users.getAllUsers();
2106
+ * console.log(`Total users: ${result.pagination.total}`);
2095
2107
  *
2096
- * allUsers.forEach(user => {
2097
- * console.log(`${user.name} - ${user.email} - Active: ${user.isActive}`);
2108
+ * result.data.forEach(user => {
2109
+ * console.log(`${user.firstName} - ${user.email} - Active: ${user.isActive}`);
2098
2110
  * });
2099
2111
  * } catch (error) {
2100
2112
  * console.log('Admin access required');
2101
2113
  * }
2102
2114
  * ```
2115
+ *
2116
+ * @example With Sorting
2117
+ * ```typescript
2118
+ * import { SortOrder } from '@explorins/pers-sdk';
2119
+ *
2120
+ * // Get users sorted by email ascending
2121
+ * const result = await sdk.users.getAllUsers({
2122
+ * page: 1,
2123
+ * limit: 20,
2124
+ * sortBy: 'email',
2125
+ * sortOrder: SortOrder.ASC
2126
+ * });
2127
+ *
2128
+ * // Get users sorted by creation date (newest first)
2129
+ * const recent = await sdk.users.getAllUsers({
2130
+ * page: 1,
2131
+ * limit: 10,
2132
+ * sortBy: 'createdAt',
2133
+ * sortOrder: SortOrder.DESC
2134
+ * });
2135
+ * ```
2103
2136
  */
2104
- async getAllUsers(options) {
2105
- return this.userService.getAllRemoteUsers(options);
2137
+ async getAllUsers(options, search) {
2138
+ return this.userService.getAllRemoteUsers(options, search);
2106
2139
  }
2107
2140
  /**
2108
2141
  * Business/Admin: Create or update a user
@@ -3267,6 +3300,7 @@ class CampaignManager {
3267
3300
  * business partnerships, eligibility criteria, and claiming requirements.
3268
3301
  *
3269
3302
  * @param campaignId - Unique campaign identifier
3303
+ * @param include - Relations to include: 'triggerSources', 'businesses'
3270
3304
  * @returns Promise resolving to campaign data with complete details
3271
3305
  * @throws {PersApiError} When campaign with specified ID is not found
3272
3306
  *
@@ -3295,9 +3329,17 @@ class CampaignManager {
3295
3329
  * console.log('Campaign not found:', error.message);
3296
3330
  * }
3297
3331
  * ```
3332
+ *
3333
+ * @example With Include Relations
3334
+ * ```typescript
3335
+ * // Get campaign with trigger sources and businesses included
3336
+ * const campaign = await sdk.campaigns.getCampaignById('campaign-123', ['triggerSources', 'businesses']);
3337
+ * console.log('Trigger sources:', campaign.included?.triggerSources);
3338
+ * console.log('Businesses:', campaign.included?.businesses);
3339
+ * ```
3298
3340
  */
3299
- async getCampaignById(campaignId) {
3300
- return this.campaignService.getCampaignById(campaignId);
3341
+ async getCampaignById(campaignId, include) {
3342
+ return this.campaignService.getCampaignById(campaignId, include);
3301
3343
  }
3302
3344
  /**
3303
3345
  * Claim a campaign reward
@@ -3442,6 +3484,11 @@ class CampaignManager {
3442
3484
  * page: 1,
3443
3485
  * limit: 25
3444
3486
  * });
3487
+ *
3488
+ * // Include related data (trigger sources and businesses)
3489
+ * const campaignsWithRelations = await sdk.campaigns.getCampaigns({
3490
+ * include: ['triggerSources', 'businesses']
3491
+ * });
3445
3492
  * ```
3446
3493
  */
3447
3494
  async getCampaigns(options) {
@@ -3559,57 +3606,188 @@ class CampaignManager {
3559
3606
  async toggleCampaignTestnet(campaignId) {
3560
3607
  return this.campaignService.toggleCampaignTestnet(campaignId);
3561
3608
  }
3609
+ // ==========================================
3610
+ // CAMPAIGN TRIGGER OPERATIONS
3611
+ // Rules & limits for campaign activation
3612
+ // ==========================================
3562
3613
  /**
3563
- * Admin: Get campaign triggers
3614
+ * Admin: Get all campaign triggers (paginated)
3564
3615
  *
3565
- * Retrieves all available campaign trigger mechanisms that can be used to
3566
- * automatically activate campaigns based on user actions or system events.
3567
- * Requires administrator privileges.
3616
+ * Retrieves all campaign trigger rules that define rate limits, geo-validation,
3617
+ * conditions, and trigger types for campaign activation.
3568
3618
  *
3569
- * @returns Promise resolving to array of campaign trigger definitions
3619
+ * @param options - Pagination options
3620
+ * @returns Promise resolving to paginated list of campaign triggers
3570
3621
  *
3571
3622
  * @example
3572
3623
  * ```typescript
3573
- * // Admin operation - view available triggers
3574
- * const triggers = await sdk.campaigns.getCampaignTriggers();
3575
- *
3576
- * console.log('Available Campaign Triggers:');
3577
- * triggers.forEach(trigger => {
3578
- * console.log(`- ${trigger.name}: ${trigger.description}`);
3579
- * console.log(` Type: ${trigger.type}`);
3580
- * console.log(` Parameters: ${JSON.stringify(trigger.parameters)}`);
3624
+ * const triggers = await sdk.campaigns.getCampaignTriggers({ page: 1, limit: 20 });
3625
+ * console.log(`Found ${triggers.total} triggers`);
3626
+ * triggers.data.forEach(trigger => {
3627
+ * console.log(`- ${trigger.name}: max ${trigger.maxPerDayPerUser}/day`);
3581
3628
  * });
3582
3629
  * ```
3583
3630
  */
3584
3631
  async getCampaignTriggers(options) {
3585
- return this.campaignService.getCampaignTriggers();
3632
+ return this.campaignService.getCampaignTriggers(options);
3633
+ }
3634
+ /**
3635
+ * Admin: Get campaign trigger by ID
3636
+ *
3637
+ * @param triggerId - The campaign trigger ID
3638
+ * @returns Promise resolving to the campaign trigger
3639
+ *
3640
+ * @example
3641
+ * ```typescript
3642
+ * const trigger = await sdk.campaigns.getCampaignTriggerById('trigger-123');
3643
+ * console.log('Max per day:', trigger.maxPerDayPerUser);
3644
+ * ```
3645
+ */
3646
+ async getCampaignTriggerById(triggerId) {
3647
+ return this.campaignService.getCampaignTriggerById(triggerId);
3648
+ }
3649
+ /**
3650
+ * Admin: Create a new campaign trigger
3651
+ *
3652
+ * Creates a trigger rule that defines rate limits, geo-validation, and conditions
3653
+ * for campaign activation. Triggers are created independently and then assigned
3654
+ * to campaigns via `setCampaignTrigger()`.
3655
+ *
3656
+ * @param data - Trigger configuration
3657
+ * @returns Promise resolving to created trigger
3658
+ *
3659
+ * @example
3660
+ * ```typescript
3661
+ * const trigger = await sdk.campaigns.createCampaignTrigger({
3662
+ * name: 'Daily Check-in',
3663
+ * maxPerDayPerUser: 1,
3664
+ * maxPerUser: 100,
3665
+ * minCooldownSeconds: 3600,
3666
+ * maxGeoDistanceInMeters: 50,
3667
+ * triggerType: 'CLAIM_BY_USER'
3668
+ * });
3669
+ *
3670
+ * // Then assign to campaign
3671
+ * await sdk.campaigns.setCampaignTrigger(campaignId, trigger.id);
3672
+ * ```
3673
+ */
3674
+ async createCampaignTrigger(data) {
3675
+ const result = await this.campaignService.createCampaignTrigger(data);
3676
+ this.events?.emitSuccess({
3677
+ domain: 'campaign',
3678
+ type: 'CAMPAIGN_TRIGGER_CREATED',
3679
+ userMessage: `Trigger "${data.name}" created successfully`,
3680
+ details: { triggerId: result.id, name: data.name }
3681
+ });
3682
+ return result;
3683
+ }
3684
+ /**
3685
+ * Admin: Update an existing campaign trigger
3686
+ *
3687
+ * @param triggerId - The campaign trigger ID
3688
+ * @param data - Updated trigger configuration (partial)
3689
+ * @returns Promise resolving to updated trigger
3690
+ *
3691
+ * @example
3692
+ * ```typescript
3693
+ * const updated = await sdk.campaigns.updateCampaignTrigger('trigger-123', {
3694
+ * maxPerDayPerUser: 5,
3695
+ * minCooldownSeconds: 1800
3696
+ * });
3697
+ * ```
3698
+ */
3699
+ async updateCampaignTrigger(triggerId, data) {
3700
+ const result = await this.campaignService.updateCampaignTrigger(triggerId, data);
3701
+ this.events?.emitSuccess({
3702
+ domain: 'campaign',
3703
+ type: 'CAMPAIGN_TRIGGER_UPDATED',
3704
+ userMessage: 'Trigger updated successfully',
3705
+ details: { triggerId, updates: Object.keys(data) }
3706
+ });
3707
+ return result;
3708
+ }
3709
+ /**
3710
+ * Admin: Delete a campaign trigger
3711
+ *
3712
+ * @param triggerId - The campaign trigger ID
3713
+ * @returns Promise resolving to success status
3714
+ *
3715
+ * @example
3716
+ * ```typescript
3717
+ * await sdk.campaigns.deleteCampaignTrigger('trigger-123');
3718
+ * ```
3719
+ */
3720
+ async deleteCampaignTrigger(triggerId) {
3721
+ const result = await this.campaignService.deleteCampaignTrigger(triggerId);
3722
+ this.events?.emitSuccess({
3723
+ domain: 'campaign',
3724
+ type: 'CAMPAIGN_TRIGGER_DELETED',
3725
+ userMessage: 'Trigger deleted successfully',
3726
+ details: { triggerId }
3727
+ });
3728
+ return result;
3586
3729
  }
3587
3730
  /**
3588
- * Admin: Set campaign trigger
3731
+ * Admin: Assign a trigger to a campaign
3589
3732
  *
3590
- * Associates a specific trigger mechanism with a campaign, enabling automatic
3591
- * campaign activation based on defined conditions. Requires administrator privileges.
3733
+ * Associates a trigger rule with a campaign. A campaign can have only one trigger
3734
+ * at a time. Assigning a new trigger replaces any existing trigger.
3592
3735
  *
3593
3736
  * @param campaignId - ID of the campaign
3594
3737
  * @param triggerId - ID of the trigger to associate
3595
- * @returns Promise resolving to updated campaign data
3596
- * @throws {PersApiError} When not authenticated as admin or entities not found
3738
+ * @returns Promise resolving to updated campaign
3597
3739
  *
3598
3740
  * @example
3599
3741
  * ```typescript
3600
- * // Admin operation - set up automatic campaign trigger
3601
3742
  * const updated = await sdk.campaigns.setCampaignTrigger(
3602
- * 'new-user-welcome',
3603
- * 'user-registration-trigger'
3743
+ * 'campaign-123',
3744
+ * 'trigger-456'
3604
3745
  * );
3605
- *
3606
- * console.log('Trigger set for campaign:', updated.title);
3607
- * console.log('Trigger will activate on user registration');
3746
+ * console.log('Trigger assigned:', updated.trigger?.name);
3608
3747
  * ```
3609
3748
  */
3610
3749
  async setCampaignTrigger(campaignId, triggerId) {
3611
- return this.campaignService.setCampaignTrigger(campaignId, triggerId);
3750
+ const result = await this.campaignService.setCampaignTrigger(campaignId, triggerId);
3751
+ this.events?.emitSuccess({
3752
+ domain: 'campaign',
3753
+ type: 'CAMPAIGN_TRIGGER_ASSIGNED',
3754
+ userMessage: 'Trigger assigned to campaign',
3755
+ details: { campaignId, triggerId }
3756
+ });
3757
+ return result;
3612
3758
  }
3759
+ /**
3760
+ * Admin: Remove a trigger from a campaign
3761
+ *
3762
+ * Removes the trigger rule from a campaign. The trigger itself is not deleted
3763
+ * and can be reassigned to other campaigns.
3764
+ *
3765
+ * @param campaignId - ID of the campaign
3766
+ * @param triggerId - ID of the trigger to remove
3767
+ * @returns Promise resolving to updated campaign
3768
+ *
3769
+ * @example
3770
+ * ```typescript
3771
+ * const updated = await sdk.campaigns.removeCampaignTrigger(
3772
+ * 'campaign-123',
3773
+ * 'trigger-456'
3774
+ * );
3775
+ * console.log('Trigger removed:', updated.trigger === null);
3776
+ * ```
3777
+ */
3778
+ async removeCampaignTrigger(campaignId, triggerId) {
3779
+ const result = await this.campaignService.removeCampaignTrigger(campaignId, triggerId);
3780
+ this.events?.emitSuccess({
3781
+ domain: 'campaign',
3782
+ type: 'CAMPAIGN_TRIGGER_REMOVED',
3783
+ userMessage: 'Trigger removed from campaign',
3784
+ details: { campaignId, triggerId }
3785
+ });
3786
+ return result;
3787
+ }
3788
+ // ==========================================
3789
+ // TOKEN UNIT OPERATIONS
3790
+ // ==========================================
3613
3791
  /**
3614
3792
  * Admin: Create campaign token unit
3615
3793
  *
@@ -3818,8 +3996,8 @@ class CampaignManager {
3818
3996
  * });
3819
3997
  * ```
3820
3998
  */
3821
- async getCampaignClaims(filters) {
3822
- return this.campaignService.getCampaignClaims(filters);
3999
+ async getCampaignClaims(filters, include) {
4000
+ return this.campaignService.getCampaignClaims(filters, include);
3823
4001
  }
3824
4002
  /**
3825
4003
  * Admin: Get campaign claims by user ID
@@ -3854,8 +4032,8 @@ class CampaignManager {
3854
4032
  * console.log(`\nTotal rewards earned: ${totalRewards}`);
3855
4033
  * ```
3856
4034
  */
3857
- async getCampaignClaimsByUserId(userId, options) {
3858
- return this.campaignService.getCampaignClaimsByUserId(userId);
4035
+ async getCampaignClaimsByUserId(userId, options, include) {
4036
+ return this.campaignService.getCampaignClaimsByUserId(userId, options, include);
3859
4037
  }
3860
4038
  /**
3861
4039
  * Admin: Get campaign claims by business ID
@@ -3895,8 +4073,79 @@ class CampaignManager {
3895
4073
  * console.log(`\nTotal rewards distributed: ${totalRewardsDistributed}`);
3896
4074
  * ```
3897
4075
  */
3898
- async getCampaignClaimsByBusinessId(businessId, options) {
3899
- return this.campaignService.getCampaignClaimsByBusinessId(businessId);
4076
+ async getCampaignClaimsByBusinessId(businessId, options, include) {
4077
+ return this.campaignService.getCampaignClaimsByBusinessId(businessId, options, include);
4078
+ }
4079
+ // ==========================================
4080
+ // TRIGGER SOURCE ASSIGNMENT
4081
+ // Note: TriggerSource CRUD is in TriggerSourceManager (sdk.triggerSources)
4082
+ // ==========================================
4083
+ /**
4084
+ * Admin: Assign a trigger source to a campaign
4085
+ *
4086
+ * Associates a trigger source with a campaign, enabling the trigger source
4087
+ * to activate campaign rewards when triggered. A campaign can have multiple
4088
+ * trigger sources. Requires administrator privileges.
4089
+ *
4090
+ * Note: To create/update/delete trigger sources, use `sdk.triggerSources`.
4091
+ *
4092
+ * @param campaignId - Campaign UUID
4093
+ * @param triggerSourceId - Trigger source UUID
4094
+ * @returns Promise resolving to updated campaign with trigger source assigned
4095
+ * @throws {PersApiError} When not authenticated as admin or entities not found
4096
+ *
4097
+ * @example
4098
+ * ```typescript
4099
+ * // Create trigger source first
4100
+ * const source = await sdk.triggerSources.create({
4101
+ * type: 'QR_CODE',
4102
+ * name: 'Store Entrance QR'
4103
+ * });
4104
+ *
4105
+ * // Then assign to campaign
4106
+ * const updated = await sdk.campaigns.assignTriggerSource(
4107
+ * 'campaign-123',
4108
+ * source.id
4109
+ * );
4110
+ *
4111
+ * console.log('Trigger source assigned:', updated.triggerSourceIds.length);
4112
+ * ```
4113
+ */
4114
+ async assignTriggerSource(campaignId, triggerSourceId) {
4115
+ const result = await this.campaignService.assignTriggerSourceToCampaign(campaignId, triggerSourceId);
4116
+ this.events?.emitSuccess({
4117
+ domain: 'campaign',
4118
+ type: 'TRIGGER_SOURCE_ASSIGNED',
4119
+ userMessage: 'Trigger source assigned to campaign',
4120
+ details: { campaignId, triggerSourceId }
4121
+ });
4122
+ return result;
4123
+ }
4124
+ /**
4125
+ * Admin: Remove a trigger source from a campaign
4126
+ *
4127
+ * Removes the association between a trigger source and a campaign. The trigger
4128
+ * source itself is not deleted and can be reassigned to other campaigns.
4129
+ * Requires administrator privileges.
4130
+ *
4131
+ * @param campaignId - Campaign UUID
4132
+ * @param triggerSourceId - Trigger source UUID
4133
+ * @returns Promise resolving to updated campaign with trigger source removed
4134
+ * @throws {PersApiError} When not authenticated as admin or entities not found
4135
+ *
4136
+ * @example
4137
+ * ```typescript
4138
+ * // Remove a trigger source from a campaign
4139
+ * const updated = await sdk.campaigns.removeTriggerSource(
4140
+ * 'campaign-123',
4141
+ * 'source-456'
4142
+ * );
4143
+ *
4144
+ * console.log('Remaining trigger source IDs:', updated.triggerSourceIds.length);
4145
+ * ```
4146
+ */
4147
+ async removeTriggerSource(campaignId, triggerSourceId) {
4148
+ return this.campaignService.removeTriggerSourceFromCampaign(campaignId, triggerSourceId);
3900
4149
  }
3901
4150
  /**
3902
4151
  * Get the full campaign service for advanced operations
@@ -4280,8 +4529,57 @@ class RedemptionManager {
4280
4529
  * });
4281
4530
  * ```
4282
4531
  */
4283
- async getUserRedemptions(options) {
4284
- return this.redemptionService.getUserRedeems(options);
4532
+ async getUserRedemptions(options, include) {
4533
+ return this.redemptionService.getUserRedeems(options, include);
4534
+ }
4535
+ /**
4536
+ * Admin: Get all redemption redeems with filtering and enriched data
4537
+ *
4538
+ * Retrieves all redemption redeems across the platform with filtering capabilities.
4539
+ * This is an admin-level operation that allows monitoring and analytics of redemption
4540
+ * activity. Supports filtering by user, redemption offer, and enrichment of related entities.
4541
+ *
4542
+ * @param filters - Filter options (userId, redemptionId, pagination)
4543
+ * @param include - Optional relations to include for enrichment
4544
+ * @returns Promise resolving to paginated list of redemption redeems
4545
+ * @throws {PersApiError} When not authenticated as admin
4546
+ *
4547
+ * @example Get All Redeems
4548
+ * ```typescript
4549
+ * // Admin operation - get all redemption redeems
4550
+ * const { data: allRedeems, pagination } = await sdk.redemptions.getRedemptionRedeems();
4551
+ *
4552
+ * console.log(`Total redeems: ${pagination.total}`);
4553
+ * console.log(`Page ${pagination.page} of ${pagination.pages}`);
4554
+ * ```
4555
+ *
4556
+ * @example Filter by User
4557
+ * ```typescript
4558
+ * // Get redeems for specific user
4559
+ * const { data: userRedeems } = await sdk.redemptions.getRedemptionRedeems({
4560
+ * userId: 'user-123',
4561
+ * limit: 50
4562
+ * });
4563
+ *
4564
+ * console.log(`User has ${userRedeems.length} redemptions`);
4565
+ * ```
4566
+ *
4567
+ * @example With Enriched Data
4568
+ * ```typescript
4569
+ * const { data: redeems } = await sdk.redemptions.getRedemptionRedeems(
4570
+ * { page: 1, limit: 20 },
4571
+ * ['redemption', 'user', 'business']
4572
+ * );
4573
+ *
4574
+ * redeems.forEach(redeem => {
4575
+ * const redemptionName = redeem.included?.redemption?.name || 'Unknown';
4576
+ * const userEmail = redeem.included?.user?.email || redeem.userId;
4577
+ * console.log(`${redemptionName} - ${userEmail}`);
4578
+ * });
4579
+ * ```
4580
+ */
4581
+ async getRedemptionRedeems(filters, include) {
4582
+ return this.redemptionService.getRedemptionRedeems(filters, include);
4285
4583
  }
4286
4584
  /**
4287
4585
  * Admin: Create new redemption offer
@@ -4524,8 +4822,8 @@ class RedemptionManager {
4524
4822
  *
4525
4823
  * @example Administrative Reporting
4526
4824
  * ```typescript
4527
- * // Admin: Get all tenant transactions for analysis
4528
- * const allTransactions = await sdk.transactions.getTenantTransactions();
4825
+ * // Admin: Get paginated transactions for analysis
4826
+ * const allTransactions = await sdk.transactions.getPaginatedTransactions({ page: 1, limit: 100 });
4529
4827
  *
4530
4828
  * // Export transaction data
4531
4829
  * const csvBlob = await sdk.transactions.exportTransactionsCSV();
@@ -4548,13 +4846,18 @@ class TransactionManager {
4548
4846
  * Provides complete transaction audit trail and verification data.
4549
4847
  *
4550
4848
  * @param transactionId - Unique transaction identifier
4849
+ * @param include - Optional relations to include (sender, recipient, business) for enriched entity data
4551
4850
  * @returns Promise resolving to complete transaction data
4552
4851
  * @throws {PersApiError} When transaction with specified ID is not found or access denied
4553
4852
  *
4554
4853
  * @example
4555
4854
  * ```typescript
4556
4855
  * try {
4557
- * const transaction = await sdk.transactions.getTransactionById('txn-abc123');
4856
+ * // Get transaction with enriched sender/recipient data
4857
+ * const transaction = await sdk.transactions.getTransactionById(
4858
+ * 'txn-abc123',
4859
+ * ['sender', 'recipient', 'business']
4860
+ * );
4558
4861
  *
4559
4862
  * console.log('Transaction Details:');
4560
4863
  * console.log('ID:', transaction.id);
@@ -4567,16 +4870,19 @@ class TransactionManager {
4567
4870
  * console.log('Description:', transaction.description);
4568
4871
  * }
4569
4872
  *
4570
- * if (transaction.business) {
4571
- * console.log('Business:', transaction.business.displayName);
4873
+ * // Access enriched sender data
4874
+ * if (transaction.included?.sender) {
4875
+ * console.log('Sender:', transaction.included.sender);
4572
4876
  * }
4573
4877
  *
4574
- * // Show token movements
4575
- * if (transaction.tokenTransfers?.length) {
4576
- * console.log('\nToken Transfers:');
4577
- * transaction.tokenTransfers.forEach(transfer => {
4578
- * console.log(`${transfer.amount} ${transfer.token.symbol} ${transfer.direction}`);
4579
- * });
4878
+ * // Access enriched recipient data
4879
+ * if (transaction.included?.recipient) {
4880
+ * console.log('Recipient:', transaction.included.recipient);
4881
+ * }
4882
+ *
4883
+ * // Access enriched business data
4884
+ * if (transaction.included?.engagedBusiness) {
4885
+ * console.log('Business:', transaction.included.engagedBusiness.displayName);
4580
4886
  * }
4581
4887
  *
4582
4888
  * // Show blockchain confirmation
@@ -4589,8 +4895,8 @@ class TransactionManager {
4589
4895
  * }
4590
4896
  * ```
4591
4897
  */
4592
- async getTransactionById(transactionId) {
4593
- return this.transactionService.getTransactionById(transactionId);
4898
+ async getTransactionById(transactionId, include) {
4899
+ return this.transactionService.getTransactionById(transactionId, include);
4594
4900
  }
4595
4901
  /**
4596
4902
  * Create a new transaction
@@ -4684,150 +4990,62 @@ class TransactionManager {
4684
4990
  /**
4685
4991
  * Get user's transaction history
4686
4992
  *
4687
- * Retrieves transaction history for the authenticated user, filtered by
4688
- * transaction role. Provides chronological view of all user's loyalty
4993
+ * Retrieves transaction history for the authenticated user with comprehensive
4994
+ * filtering options. Provides chronological view of all user's loyalty
4689
4995
  * activities including purchases, rewards, redemptions, and transfers.
4996
+ * Optionally enrich with related entities (sender, recipient, business).
4690
4997
  *
4691
- * @param role - Optional role filter (TransactionRole.SENDER, TransactionRole.RECIPIENT). If undefined, returns all user transactions
4692
- * @param limit - Maximum number of transactions to return (default: 1000)
4693
- * @returns Promise resolving to array of user's transactions
4998
+ * @param options - Query options including filters, pagination, and include relations
4999
+ * @returns Promise resolving to paginated transaction data with optional included entities
4694
5000
  *
4695
5001
  * @example All Transactions
4696
5002
  * ```typescript
4697
- * const allTransactions = await sdk.transactions.getUserTransactionHistory('ALL');
5003
+ * const result = await sdk.transactions.getUserTransactionHistory();
4698
5004
  *
4699
- * console.log(` Transaction History (${allTransactions.length} transactions):`);
5005
+ * console.log(`Transaction History (${result.data.length} of ${result.pagination.total} transactions)`);
4700
5006
  *
4701
- * allTransactions.forEach((transaction, index) => {
5007
+ * result.data.forEach((transaction, index) => {
4702
5008
  * const date = new Date(transaction.createdAt).toLocaleDateString();
4703
5009
  * console.log(`\n${index + 1}. ${transaction.type} - ${date}`);
4704
5010
  * console.log(` ${transaction.description || 'No description'}`);
4705
5011
  * console.log(` Status: ${transaction.status}`);
4706
- *
4707
- * if (transaction.amount && transaction.currency) {
4708
- * console.log(` Amount: ${transaction.amount} ${transaction.currency}`);
4709
- * }
4710
- *
4711
- * if (transaction.business) {
4712
- * console.log(` Business: ${transaction.business.displayName}`);
4713
- * }
4714
5012
  * });
4715
5013
  * ```
4716
5014
  *
4717
- * @example Filtered by Type
5015
+ * @example Filter by Role and Status
4718
5016
  * ```typescript
4719
- * // Get only purchase transactions
4720
- * const purchases = await sdk.transactions.getUserTransactionHistory('PURCHASE');
4721
- *
4722
- * let totalSpent = 0;
4723
- * let totalRewards = 0;
4724
- *
4725
- * purchases.forEach(purchase => {
4726
- * if (purchase.amount) {
4727
- * totalSpent += purchase.amount;
4728
- * }
4729
- *
4730
- * if (purchase.tokensEarned?.length) {
4731
- * purchase.tokensEarned.forEach(reward => {
4732
- * totalRewards += reward.amount;
4733
- * });
4734
- * }
5017
+ * // Get only completed sent transactions
5018
+ * const sent = await sdk.transactions.getUserTransactionHistory({
5019
+ * role: TransactionRole.SENDER,
5020
+ * status: TransactionStatus.COMPLETED,
5021
+ * include: ['recipient', 'business'],
5022
+ * page: 1,
5023
+ * limit: 50
4735
5024
  * });
4736
5025
  *
4737
- * console.log('Purchase Summary:');
4738
- * console.log(`Total purchases: ${purchases.length}`);
4739
- * console.log(`Total spent: $${totalSpent.toFixed(2)}`);
4740
- * console.log(`Total rewards earned: ${totalRewards} points`);
4741
- * ```
4742
- *
4743
- * @example Recent Activity
4744
- * ```typescript
4745
- * const recentTransactions = await sdk.transactions.getUserTransactionHistory('ALL');
4746
- *
4747
- * // Filter to last 30 days
4748
- * const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
4749
- * const recentActivity = recentTransactions.filter(t =>
4750
- * new Date(t.createdAt) > thirtyDaysAgo
4751
- * );
4752
- *
4753
- * console.log(`Recent Activity (${recentActivity.length} transactions in last 30 days):`);
4754
- *
4755
- * // Group by type
4756
- * const activityByType = recentActivity.reduce((acc, t) => {
4757
- * acc[t.type] = (acc[t.type] || 0) + 1;
4758
- * return acc;
4759
- * }, {});
4760
- *
4761
- * Object.entries(activityByType).forEach(([type, count]) => {
4762
- * console.log(`${type}: ${count} transactions`);
5026
+ * sent.data.forEach(tx => {
5027
+ * console.log(`Sent to: ${tx.included?.recipient?.displayName || tx.recipientAddress}`);
4763
5028
  * });
4764
5029
  * ```
4765
- */
4766
- async getUserTransactionHistory(role, options) {
4767
- return this.transactionService.getUserTransactionHistory(role, options);
4768
- }
4769
- /**
4770
- * Admin: Get all tenant transactions
4771
- *
4772
- * Retrieves all transactions across the entire tenant/organization for
4773
- * comprehensive reporting and analysis. This operation requires administrator
4774
- * privileges and provides system-wide transaction visibility.
4775
5030
  *
4776
- * @param limit - Maximum number of transactions to return (default: 1000)
4777
- * @returns Promise resolving to array of all tenant transactions
4778
- * @throws {PersApiError} When not authenticated as administrator
4779
- *
4780
- * @example
5031
+ * @example Filter by Trigger Process (Campaign/Redemption)
4781
5032
  * ```typescript
4782
- * // Admin operation - comprehensive transaction analysis
4783
- * const allTransactions = await sdk.transactions.getTenantTransactions();
4784
- *
4785
- * console.log(`Tenant Transaction Overview:`);
4786
- * console.log(`Total transactions: ${allTransactions.length}`);
4787
- *
4788
- * // Analyze by status
4789
- * const statusCounts = allTransactions.reduce((acc, t) => {
4790
- * acc[t.status] = (acc[t.status] || 0) + 1;
4791
- * return acc;
4792
- * }, {});
4793
- *
4794
- * console.log('\nBy status:');
4795
- * Object.entries(statusCounts).forEach(([status, count]) => {
4796
- * console.log(`${status}: ${count} transactions`);
5033
+ * // Get all transactions triggered by a specific campaign claim
5034
+ * const claimTxs = await sdk.transactions.getUserTransactionHistory({
5035
+ * triggerProcessId: 'claim-abc123',
5036
+ * include: ['sender', 'recipient', 'business']
4797
5037
  * });
4798
5038
  *
4799
- * // Analyze by type
4800
- * const typeCounts = allTransactions.reduce((acc, t) => {
4801
- * acc[t.type] = (acc[t.type] || 0) + 1;
4802
- * return acc;
4803
- * }, {});
4804
- *
4805
- * console.log('\nBy type:');
4806
- * Object.entries(typeCounts).forEach(([type, count]) => {
4807
- * console.log(`${type}: ${count} transactions`);
5039
+ * claimTxs.data.forEach(tx => {
5040
+ * console.log('Transaction from claim:', tx.id);
5041
+ * if (tx.included?.engagedBusiness) {
5042
+ * console.log('Business:', tx.included.engagedBusiness.displayName);
5043
+ * }
4808
5044
  * });
4809
- *
4810
- * // Calculate volume metrics
4811
- * const totalVolume = allTransactions.reduce((sum, t) =>
4812
- * sum + (t.amount || 0), 0
4813
- * );
4814
- *
4815
- * const avgTransactionSize = totalVolume / allTransactions.length;
4816
- *
4817
- * console.log('\nVolume metrics:');
4818
- * console.log(`Total volume: $${totalVolume.toFixed(2)}`);
4819
- * console.log(`Average transaction: $${avgTransactionSize.toFixed(2)}`);
4820
- *
4821
- * // Recent activity analysis
4822
- * const last24Hours = allTransactions.filter(t =>
4823
- * new Date(t.createdAt) > new Date(Date.now() - 24 * 60 * 60 * 1000)
4824
- * );
4825
- *
4826
- * console.log(`\n⏰ Last 24 hours: ${last24Hours.length} transactions`);
4827
5045
  * ```
4828
5046
  */
4829
- async getTenantTransactions(options) {
4830
- return this.transactionService.getTenantTransactions(options);
5047
+ async getUserTransactionHistory(options) {
5048
+ return this.transactionService.getUserTransactionHistory(options);
4831
5049
  }
4832
5050
  /**
4833
5051
  * Admin: Get paginated transactions
@@ -4891,9 +5109,23 @@ class TransactionManager {
4891
5109
  * console.log(`$${transaction.amount} - ${transaction.business?.displayName}`);
4892
5110
  * });
4893
5111
  * ```
5112
+ *
5113
+ * @example With Included Relations
5114
+ * ```typescript
5115
+ * // Include sender and recipient entities
5116
+ * const result = await sdk.transactions.getPaginatedTransactions(
5117
+ * { page: 1, limit: 50 },
5118
+ * ['sender', 'recipient', 'business']
5119
+ * );
5120
+ *
5121
+ * result.data.forEach(tx => {
5122
+ * if (tx.included?.sender) console.log('From:', tx.included.sender);
5123
+ * if (tx.included?.recipient) console.log('To:', tx.included.recipient);
5124
+ * });
5125
+ * ```
4894
5126
  */
4895
- async getPaginatedTransactions(params) {
4896
- return this.transactionService.getPaginatedTransactions(params);
5127
+ async getPaginatedTransactions(params, include) {
5128
+ return this.transactionService.getPaginatedTransactions(params, include);
4897
5129
  }
4898
5130
  /**
4899
5131
  * Admin: Export transactions as CSV
@@ -6370,8 +6602,8 @@ class ApiKeyManager {
6370
6602
  class AnalyticsManager {
6371
6603
  constructor(apiClient) {
6372
6604
  this.apiClient = apiClient;
6373
- const analyticsApi = new analytics.AnalyticsApi(apiClient);
6374
- this.analyticsService = new analytics.AnalyticsService(analyticsApi);
6605
+ const analyticsApi = new analyticsService.AnalyticsApi(apiClient);
6606
+ this.analyticsService = new analyticsService.AnalyticsService(analyticsApi);
6375
6607
  }
6376
6608
  /**
6377
6609
  * Get transaction analytics
@@ -6556,6 +6788,179 @@ class AnalyticsManager {
6556
6788
  async getTransactionAnalytics(request) {
6557
6789
  return this.analyticsService.getTransactionAnalytics(request);
6558
6790
  }
6791
+ /**
6792
+ * Get campaign claim analytics with aggregation
6793
+ *
6794
+ * Retrieves aggregated analytics for campaign claims with flexible grouping,
6795
+ * filtering, and metric selection. Provides insights into campaign performance,
6796
+ * claim patterns, and user engagement across the loyalty ecosystem.
6797
+ *
6798
+ * @param request - Analytics request with filters, groupBy, and metrics
6799
+ * @returns Promise resolving to campaign claim analytics data
6800
+ *
6801
+ * @example Claims per campaign
6802
+ * ```typescript
6803
+ * const analytics = await sdk.analytics.getCampaignClaimAnalytics({
6804
+ * filters: { status: 'COMPLETED' },
6805
+ * groupBy: ['campaignId'],
6806
+ * metrics: ['count'],
6807
+ * sortBy: 'count',
6808
+ * sortOrder: 'DESC',
6809
+ * limit: 10
6810
+ * });
6811
+ *
6812
+ * console.log('Top campaigns:', analytics.results);
6813
+ * ```
6814
+ */
6815
+ async getCampaignClaimAnalytics(request) {
6816
+ return this.analyticsService.getCampaignClaimAnalytics(request);
6817
+ }
6818
+ /**
6819
+ * Get user analytics with engagement metrics
6820
+ *
6821
+ * Retrieves aggregated user statistics including engagement rate, active users,
6822
+ * transaction metrics, and per-active-user averages. Provides comprehensive
6823
+ * insights into user behavior, engagement patterns, and platform adoption metrics.
6824
+ *
6825
+ * NEW: Added per-active-user metrics (averageTransactionsPerActiveUser, etc.) which
6826
+ * show concentrated engagement among active users - more useful than diluted all-user averages.
6827
+ *
6828
+ * Request structure matches TransactionAnalytics and CampaignClaimAnalytics:
6829
+ * - Use filters object for business-specific scoping
6830
+ * - startDate/endDate at root level for date range filtering
6831
+ *
6832
+ * @param request - Analytics request with optional filters and date range
6833
+ * @returns Promise resolving to user analytics data with per-user and per-active-user metrics
6834
+ *
6835
+ * @example Basic user analytics (compare per-user vs per-active-user)
6836
+ * ```typescript
6837
+ * const analytics = await sdk.analytics.getUserAnalytics({});
6838
+ * console.log(`Total users: ${analytics.totalUsers}`);
6839
+ * console.log(`Active users: ${analytics.activeUsers} (${analytics.engagementRate.toFixed(1)}%)`);
6840
+ *
6841
+ * // Per-user averages (includes inactive users - lower numbers)
6842
+ * console.log(`\\nPer-User Averages (all users):`);
6843
+ * console.log(` Transactions: ${analytics.averageTransactionsPerUser.toFixed(2)}`);
6844
+ * console.log(` Claims: ${analytics.averageClaimsPerUser.toFixed(2)}`);
6845
+ * console.log(` Redemptions: ${analytics.averageRedemptionsPerUser.toFixed(2)}`);
6846
+ *
6847
+ * // Per-active-user averages (only engaged users - higher, more meaningful numbers)
6848
+ * console.log(`\\nPer-Active-User Averages (engaged users only):`);
6849
+ * console.log(` Transactions: ${analytics.averageTransactionsPerActiveUser.toFixed(2)}`);
6850
+ * console.log(` Claims: ${analytics.averageClaimsPerActiveUser.toFixed(2)}`);
6851
+ * console.log(` Redemptions: ${analytics.averageRedemptionsPerActiveUser.toFixed(2)}`);
6852
+ * ```
6853
+ *
6854
+ * @example Monthly user analytics with date range
6855
+ * ```typescript
6856
+ * const analytics = await sdk.analytics.getUserAnalytics({
6857
+ * startDate: new Date('2026-02-01'),
6858
+ * endDate: new Date('2026-02-28')
6859
+ * });
6860
+ *
6861
+ * console.log('February 2026 User Metrics:');
6862
+ * console.log(`Total users: ${analytics.totalUsers}`);
6863
+ * console.log(`Active users: ${analytics.activeUsers}`);
6864
+ * console.log(`New users: ${analytics.newUsers}`);
6865
+ * console.log(`Engagement rate: ${analytics.engagementRate.toFixed(2)}%`);
6866
+ * console.log(`Total transaction volume: $${analytics.totalTransactionVolume.toLocaleString()}`);
6867
+ * console.log(`Avg transaction amount: $${analytics.averageTransactionAmount.toFixed(2)}`);
6868
+ * console.log(`\\nFilters applied: ${analytics.metadata.dateRange?.startDate} to ${analytics.metadata.dateRange?.endDate}`);
6869
+ * ```
6870
+ *
6871
+ * @example Business-specific user analytics with filters
6872
+ * ```typescript
6873
+ * const analytics = await sdk.analytics.getUserAnalytics({
6874
+ * filters: { businessId: 'business-123' },
6875
+ * startDate: new Date('2026-01-01'),
6876
+ * endDate: new Date('2026-12-31')
6877
+ * });
6878
+ *
6879
+ * console.log(`Business customer metrics for 2026:`);
6880
+ * console.log(`Active customers: ${analytics.activeUsers} / ${analytics.totalUsers}`);
6881
+ * console.log(`Customer engagement: ${analytics.engagementRate.toFixed(1)}%`);
6882
+ * console.log(`Avg spend per customer: $${analytics.averageTransactionAmount.toFixed(2)}`);
6883
+ * console.log(`Avg spend per active customer: $${(analytics.totalTransactionVolume / analytics.activeUsers).toFixed(2)}`);
6884
+ * console.log(`Avg claims per active customer: ${analytics.averageClaimsPerActiveUser.toFixed(2)}`);
6885
+ * ```
6886
+ */
6887
+ async getUserAnalytics(request = {}) {
6888
+ return this.analyticsService.getUserAnalytics(request);
6889
+ }
6890
+ /**
6891
+ * Get user transaction ranking with enriched user data
6892
+ *
6893
+ * Retrieves ranked list of users with full user details (email, externalUserId)
6894
+ * and transaction metrics. Data enrichment happens via efficient SQL JOINs + UNION
6895
+ * (handles legacy transactions). Ideal for leaderboards, engagement analysis, and
6896
+ * identifying power users for targeted campaigns.
6897
+ *
6898
+ * Use Cases:
6899
+ * - Admin leaderboards showing top users by activity
6900
+ * - User engagement analysis with full user context
6901
+ * - Identifying power users for campaigns
6902
+ * - Customer segmentation by transaction behavior
6903
+ *
6904
+ * @param request - Ranking request with filters, sorting, and limit
6905
+ * @returns Promise resolving to ranked user list with transaction metrics
6906
+ *
6907
+ * @example Top 50 users by transaction count
6908
+ * ```typescript
6909
+ * const ranking = await sdk.analytics.getUserRanking({
6910
+ * sortBy: 'totalTransactions',
6911
+ * sortOrder: 'DESC',
6912
+ * limit: 50
6913
+ * });
6914
+ *
6915
+ * console.log(`Top ${ranking.totalUsers} users:`);
6916
+ * ranking.results.forEach((user, index) => {
6917
+ * console.log(`#${index + 1}: ${user.email || user.externalUserId}`);
6918
+ * console.log(` Transactions: ${user.totalTransactions}`);
6919
+ * console.log(` Token spent: ${user.tokenSpent}`);
6920
+ * });
6921
+ * ```
6922
+ *
6923
+ * @example Top users by STAMP spending
6924
+ * ```typescript
6925
+ * const ranking = await sdk.analytics.getUserRanking({
6926
+ * filters: { tokenType: 'STAMP' },
6927
+ * sortBy: 'tokenSpent',
6928
+ * sortOrder: 'DESC',
6929
+ * limit: 20
6930
+ * });
6931
+ *
6932
+ * console.log('Top 20 STAMP spenders:');
6933
+ * ranking.results.forEach((user, index) => {
6934
+ * const identifier = user.email || user.externalUserId || user.userId;
6935
+ * console.log(`${index + 1}. ${identifier} - ${user.tokenSpent} STAMP`);
6936
+ * });
6937
+ * ```
6938
+ */
6939
+ async getUserRanking(request = {}) {
6940
+ return this.analyticsService.getUserRanking(request);
6941
+ }
6942
+ /**
6943
+ * Get business transaction ranking with enriched business data
6944
+ *
6945
+ * Returns ranked list of businesses with full business details and transaction metrics.
6946
+ *
6947
+ * @param request - Ranking request with filters, sorting, and limit
6948
+ * @returns Promise resolving to ranked business list
6949
+ */
6950
+ async getBusinessRanking(request = {}) {
6951
+ return this.analyticsService.getBusinessRanking(request);
6952
+ }
6953
+ /**
6954
+ * Get monthly user retention analytics
6955
+ *
6956
+ * Returns monthly retention data with user metrics and retention rates.
6957
+ *
6958
+ * @param request - Retention request with monthsBack and filters
6959
+ * @returns Promise resolving to monthly retention data
6960
+ */
6961
+ async getRetentionAnalytics(request = {}) {
6962
+ return this.analyticsService.getRetentionAnalytics(request);
6963
+ }
6559
6964
  /**
6560
6965
  * Get the full analytics service for advanced operations
6561
6966
  *
@@ -6650,6 +7055,360 @@ class DonationManager {
6650
7055
  }
6651
7056
  }
6652
7057
 
7058
+ /**
7059
+ * Platform-Agnostic TriggerSource API Client
7060
+ *
7061
+ * Handles all trigger source operations:
7062
+ * - CRUD operations for trigger sources (QR codes, NFC tags, GPS geofences, webhooks, etc.)
7063
+ * - Trigger sources are independent entities that can be assigned to campaigns
7064
+ *
7065
+ * Uses @explorins/pers-shared DTOs for consistency with backend.
7066
+ */
7067
+ class TriggerSourceApi {
7068
+ constructor(apiClient) {
7069
+ this.apiClient = apiClient;
7070
+ }
7071
+ /**
7072
+ * PUBLIC: Get trigger sources with optional filters and pagination
7073
+ *
7074
+ * @param options - Filter and pagination options
7075
+ * @returns Paginated list of trigger sources
7076
+ *
7077
+ * @example
7078
+ * ```typescript
7079
+ * // Get all QR code trigger sources
7080
+ * const qrSources = await triggerSourceApi.getTriggerSources({ type: 'QR_CODE' });
7081
+ *
7082
+ * // Get trigger sources for a specific campaign
7083
+ * const campaignSources = await triggerSourceApi.getTriggerSources({
7084
+ * campaignId: 'campaign-123',
7085
+ * page: 1,
7086
+ * limit: 20
7087
+ * });
7088
+ * ```
7089
+ */
7090
+ async getTriggerSources(options) {
7091
+ const params = paginationUtils.buildPaginationParams(options);
7092
+ if (options?.type)
7093
+ params.set('type', options.type);
7094
+ if (options?.businessId)
7095
+ params.set('businessId', options.businessId);
7096
+ if (options?.campaignId)
7097
+ params.set('campaignId', options.campaignId);
7098
+ if (options?.active !== undefined)
7099
+ params.set('active', String(options.active));
7100
+ const response = await this.apiClient.get(`/trigger-sources?${params.toString()}`);
7101
+ return paginationUtils.normalizeToPaginated(response);
7102
+ }
7103
+ /**
7104
+ * PUBLIC: Get trigger source by ID
7105
+ *
7106
+ * @param triggerSourceId - UUID of the trigger source
7107
+ * @returns Trigger source details
7108
+ */
7109
+ async getTriggerSourceById(triggerSourceId) {
7110
+ return this.apiClient.get(`/trigger-sources/${triggerSourceId}`);
7111
+ }
7112
+ /**
7113
+ * ADMIN: Create a new trigger source
7114
+ *
7115
+ * @param triggerSource - Trigger source creation data
7116
+ * @returns Created trigger source
7117
+ *
7118
+ * @example
7119
+ * ```typescript
7120
+ * const qrSource = await triggerSourceApi.createTriggerSource({
7121
+ * type: 'QR_CODE',
7122
+ * name: 'Store Entrance QR',
7123
+ * description: 'QR code at main entrance',
7124
+ * businessId: 'business-123',
7125
+ * coordsLatitude: 47.6062,
7126
+ * coordsLongitude: -122.3321
7127
+ * });
7128
+ * ```
7129
+ */
7130
+ async createTriggerSource(triggerSource) {
7131
+ return this.apiClient.post('/trigger-sources', triggerSource);
7132
+ }
7133
+ /**
7134
+ * ADMIN: Update a trigger source
7135
+ *
7136
+ * @param triggerSourceId - UUID of the trigger source to update
7137
+ * @param triggerSource - Updated trigger source data (partial)
7138
+ * @returns Updated trigger source
7139
+ */
7140
+ async updateTriggerSource(triggerSourceId, triggerSource) {
7141
+ return this.apiClient.put(`/trigger-sources/${triggerSourceId}`, triggerSource);
7142
+ }
7143
+ /**
7144
+ * ADMIN: Delete (soft delete) a trigger source
7145
+ *
7146
+ * @param triggerSourceId - UUID of the trigger source to delete
7147
+ * @returns Success status
7148
+ */
7149
+ async deleteTriggerSource(triggerSourceId) {
7150
+ return this.apiClient.delete(`/trigger-sources/${triggerSourceId}`);
7151
+ }
7152
+ }
7153
+
7154
+ /**
7155
+ * Platform-Agnostic TriggerSource Service
7156
+ *
7157
+ * Contains trigger source business logic and operations that work across platforms.
7158
+ * No framework dependencies - pure TypeScript business logic.
7159
+ */
7160
+ class TriggerSourceService {
7161
+ constructor(triggerSourceApi) {
7162
+ this.triggerSourceApi = triggerSourceApi;
7163
+ }
7164
+ /**
7165
+ * Get trigger sources with optional filters
7166
+ */
7167
+ async getTriggerSources(options) {
7168
+ return this.triggerSourceApi.getTriggerSources(options);
7169
+ }
7170
+ /**
7171
+ * Get trigger source by ID
7172
+ */
7173
+ async getTriggerSourceById(triggerSourceId) {
7174
+ return this.triggerSourceApi.getTriggerSourceById(triggerSourceId);
7175
+ }
7176
+ /**
7177
+ * ADMIN: Create a new trigger source
7178
+ */
7179
+ async createTriggerSource(triggerSource) {
7180
+ return this.triggerSourceApi.createTriggerSource(triggerSource);
7181
+ }
7182
+ /**
7183
+ * ADMIN: Update a trigger source
7184
+ */
7185
+ async updateTriggerSource(triggerSourceId, triggerSource) {
7186
+ return this.triggerSourceApi.updateTriggerSource(triggerSourceId, triggerSource);
7187
+ }
7188
+ /**
7189
+ * ADMIN: Delete a trigger source
7190
+ */
7191
+ async deleteTriggerSource(triggerSourceId) {
7192
+ return this.triggerSourceApi.deleteTriggerSource(triggerSourceId);
7193
+ }
7194
+ }
7195
+
7196
+ /**
7197
+ * TriggerSource Manager - Clean, high-level interface for trigger source operations
7198
+ *
7199
+ * Manages trigger sources which are physical or digital activation points for campaigns:
7200
+ * - QR_CODE: Scannable QR codes
7201
+ * - NFC_TAG: NFC tap points
7202
+ * - GPS_GEOFENCE: Location-based triggers
7203
+ * - API_WEBHOOK: External system integration
7204
+ * - TRANSACTION: Purchase/payment based triggers
7205
+ *
7206
+ * Trigger sources are independent entities that can be created, managed, and then
7207
+ * assigned to campaigns. This separation allows reuse and flexible campaign configuration.
7208
+ *
7209
+ * @group Managers
7210
+ * @category TriggerSource Management
7211
+ *
7212
+ * @example Basic TriggerSource Operations
7213
+ * ```typescript
7214
+ * // Get all QR code trigger sources
7215
+ * const qrSources = await sdk.triggerSources.getAll({ type: 'QR_CODE' });
7216
+ *
7217
+ * // Create a new QR code trigger source
7218
+ * const source = await sdk.triggerSources.create({
7219
+ * type: 'QR_CODE',
7220
+ * name: 'Store Entrance QR',
7221
+ * businessId: 'business-123'
7222
+ * });
7223
+ *
7224
+ * // Assign to campaign (via CampaignManager)
7225
+ * await sdk.campaigns.assignTriggerSource('campaign-456', source.id);
7226
+ * ```
7227
+ */
7228
+ class TriggerSourceManager {
7229
+ constructor(apiClient, events) {
7230
+ this.apiClient = apiClient;
7231
+ this.events = events;
7232
+ const triggerSourceApi = new TriggerSourceApi(apiClient);
7233
+ this.triggerSourceService = new TriggerSourceService(triggerSourceApi);
7234
+ }
7235
+ /**
7236
+ * Get trigger sources with optional filters and pagination
7237
+ *
7238
+ * Retrieves trigger sources (QR codes, NFC tags, GPS geofences, webhooks, etc.)
7239
+ * that can be used to activate campaigns. Supports filtering by type, business,
7240
+ * campaign association, and active status.
7241
+ *
7242
+ * @param options - Filter and pagination options
7243
+ * @returns Promise resolving to paginated trigger sources
7244
+ *
7245
+ * @example
7246
+ * ```typescript
7247
+ * // Get all QR code trigger sources
7248
+ * const qrSources = await sdk.triggerSources.getAll({ type: 'QR_CODE' });
7249
+ *
7250
+ * // Get trigger sources for a specific business
7251
+ * const businessSources = await sdk.triggerSources.getAll({
7252
+ * businessId: 'business-123',
7253
+ * active: true,
7254
+ * page: 1,
7255
+ * limit: 20
7256
+ * });
7257
+ *
7258
+ * // Get trigger sources assigned to a campaign
7259
+ * const campaignSources = await sdk.triggerSources.getAll({
7260
+ * campaignId: 'campaign-456'
7261
+ * });
7262
+ * ```
7263
+ */
7264
+ async getAll(options) {
7265
+ return this.triggerSourceService.getTriggerSources(options);
7266
+ }
7267
+ /**
7268
+ * Get trigger source by ID
7269
+ *
7270
+ * Retrieves detailed information for a specific trigger source including
7271
+ * its type, location, metadata, and usage analytics.
7272
+ *
7273
+ * @param triggerSourceId - UUID of the trigger source
7274
+ * @returns Promise resolving to trigger source details
7275
+ * @throws {PersApiError} When trigger source with specified ID is not found
7276
+ *
7277
+ * @example
7278
+ * ```typescript
7279
+ * const source = await sdk.triggerSources.getById('source-123');
7280
+ *
7281
+ * console.log('Trigger Source:', source.name);
7282
+ * console.log('Type:', source.type);
7283
+ * console.log('Active:', source.isActive);
7284
+ *
7285
+ * if (source.coordsLatitude && source.coordsLongitude) {
7286
+ * console.log('Location:', source.coordsLatitude, source.coordsLongitude);
7287
+ * }
7288
+ * ```
7289
+ */
7290
+ async getById(triggerSourceId) {
7291
+ return this.triggerSourceService.getTriggerSourceById(triggerSourceId);
7292
+ }
7293
+ /**
7294
+ * Admin: Create a new trigger source
7295
+ *
7296
+ * Creates a new trigger source (QR code, NFC tag, GPS geofence, webhook, or
7297
+ * transaction-based trigger) that can be assigned to campaigns. Requires
7298
+ * administrator privileges.
7299
+ *
7300
+ * @param triggerSource - Trigger source creation data
7301
+ * @returns Promise resolving to created trigger source
7302
+ * @throws {PersApiError} When not authenticated as admin or validation fails
7303
+ *
7304
+ * @example
7305
+ * ```typescript
7306
+ * // Create a QR code trigger source
7307
+ * const qrSource = await sdk.triggerSources.create({
7308
+ * type: 'QR_CODE',
7309
+ * name: 'Store Entrance QR',
7310
+ * description: 'QR code at main entrance',
7311
+ * businessId: 'business-123',
7312
+ * coordsLatitude: 47.6062,
7313
+ * coordsLongitude: -122.3321
7314
+ * });
7315
+ *
7316
+ * // Create an NFC tag trigger source
7317
+ * const nfcSource = await sdk.triggerSources.create({
7318
+ * type: 'NFC_TAG',
7319
+ * name: 'Product Display NFC',
7320
+ * metadata: { productId: 'SKU-12345' }
7321
+ * });
7322
+ *
7323
+ * // Create a GPS geofence trigger source
7324
+ * const geoSource = await sdk.triggerSources.create({
7325
+ * type: 'GPS_GEOFENCE',
7326
+ * name: 'Store Area',
7327
+ * coordsLatitude: 47.6062,
7328
+ * coordsLongitude: -122.3321,
7329
+ * metadata: { radiusMeters: 100 }
7330
+ * });
7331
+ * ```
7332
+ */
7333
+ async create(triggerSource) {
7334
+ const result = await this.triggerSourceService.createTriggerSource(triggerSource);
7335
+ this.events?.emitSuccess({
7336
+ domain: 'trigger-source',
7337
+ type: 'TRIGGER_SOURCE_CREATED',
7338
+ userMessage: 'Trigger source created successfully',
7339
+ details: { triggerSourceId: result.id, type: result.type }
7340
+ });
7341
+ return result;
7342
+ }
7343
+ /**
7344
+ * Admin: Update a trigger source
7345
+ *
7346
+ * Updates an existing trigger source's configuration. All fields are optional;
7347
+ * only provided fields will be updated. Requires administrator privileges.
7348
+ *
7349
+ * @param triggerSourceId - UUID of the trigger source to update
7350
+ * @param triggerSource - Updated trigger source data (partial)
7351
+ * @returns Promise resolving to updated trigger source
7352
+ * @throws {PersApiError} When not authenticated as admin or trigger source not found
7353
+ *
7354
+ * @example
7355
+ * ```typescript
7356
+ * // Update trigger source name and location
7357
+ * const updated = await sdk.triggerSources.update('source-123', {
7358
+ * name: 'Updated Store Entrance QR',
7359
+ * description: 'New description',
7360
+ * coordsLatitude: 47.6063,
7361
+ * coordsLongitude: -122.3322
7362
+ * });
7363
+ * ```
7364
+ */
7365
+ async update(triggerSourceId, triggerSource) {
7366
+ const result = await this.triggerSourceService.updateTriggerSource(triggerSourceId, triggerSource);
7367
+ this.events?.emitSuccess({
7368
+ domain: 'trigger-source',
7369
+ type: 'TRIGGER_SOURCE_UPDATED',
7370
+ userMessage: 'Trigger source updated successfully',
7371
+ details: { triggerSourceId }
7372
+ });
7373
+ return result;
7374
+ }
7375
+ /**
7376
+ * Admin: Delete a trigger source
7377
+ *
7378
+ * Soft deletes a trigger source, making it inactive. The trigger source will
7379
+ * be removed from any campaigns it was assigned to. Requires administrator
7380
+ * privileges.
7381
+ *
7382
+ * @param triggerSourceId - UUID of the trigger source to delete
7383
+ * @returns Promise resolving to success status
7384
+ * @throws {PersApiError} When not authenticated as admin or trigger source not found
7385
+ *
7386
+ * @example
7387
+ * ```typescript
7388
+ * const success = await sdk.triggerSources.delete('source-123');
7389
+ * console.log('Trigger source deleted:', success);
7390
+ * ```
7391
+ */
7392
+ async delete(triggerSourceId) {
7393
+ const result = await this.triggerSourceService.deleteTriggerSource(triggerSourceId);
7394
+ this.events?.emitSuccess({
7395
+ domain: 'trigger-source',
7396
+ type: 'TRIGGER_SOURCE_DELETED',
7397
+ userMessage: 'Trigger source deleted successfully',
7398
+ details: { triggerSourceId }
7399
+ });
7400
+ return result;
7401
+ }
7402
+ /**
7403
+ * Get the full trigger source service for advanced operations
7404
+ *
7405
+ * @returns TriggerSourceService instance with full API access
7406
+ */
7407
+ getTriggerSourceService() {
7408
+ return this.triggerSourceService;
7409
+ }
7410
+ }
7411
+
6653
7412
  /**
6654
7413
  * @fileoverview PERS SDK - Platform-agnostic TypeScript SDK with High-Level Managers
6655
7414
  *
@@ -7136,6 +7895,40 @@ class PersSDK {
7136
7895
  }
7137
7896
  return this._donations;
7138
7897
  }
7898
+ /**
7899
+ * TriggerSource manager - High-level trigger source operations (Admin Only)
7900
+ *
7901
+ * Provides CRUD operations for managing trigger sources (QR codes, NFC tags,
7902
+ * GPS geofences, API webhooks). TriggerSources are standalone entities that
7903
+ * can be assigned to campaigns via the campaigns manager.
7904
+ *
7905
+ * @returns TriggerSourceManager instance
7906
+ *
7907
+ * @example TriggerSource Operations
7908
+ * ```typescript
7909
+ * // Create a QR code trigger source
7910
+ * const qrSource = await sdk.triggerSources.create({
7911
+ * name: 'Store Entrance QR',
7912
+ * type: 'QR_CODE',
7913
+ * description: 'QR code at main entrance'
7914
+ * });
7915
+ *
7916
+ * // Get all trigger sources
7917
+ * const sources = await sdk.triggerSources.getAll();
7918
+ *
7919
+ * // Update trigger source
7920
+ * await sdk.triggerSources.update(sourceId, { name: 'Updated Name' });
7921
+ *
7922
+ * // Assign to campaign (via campaigns manager)
7923
+ * await sdk.campaigns.assignTriggerSource(campaignId, qrSource.id);
7924
+ * ```
7925
+ */
7926
+ get triggerSources() {
7927
+ if (!this._triggerSources) {
7928
+ this._triggerSources = new TriggerSourceManager(this.apiClient, this._events);
7929
+ }
7930
+ return this._triggerSources;
7931
+ }
7139
7932
  /**
7140
7933
  * Gets the API client for direct PERS API requests
7141
7934
  *
@@ -7217,10 +8010,13 @@ exports.StaticJwtAuthProvider = StaticJwtAuthProvider;
7217
8010
  exports.TenantManager = TenantManager;
7218
8011
  exports.TokenManager = TokenManager;
7219
8012
  exports.TransactionManager = TransactionManager;
8013
+ exports.TriggerSourceApi = TriggerSourceApi;
8014
+ exports.TriggerSourceManager = TriggerSourceManager;
8015
+ exports.TriggerSourceService = TriggerSourceService;
7220
8016
  exports.UserManager = UserManager;
7221
8017
  exports.UserStatusManager = UserStatusManager;
7222
8018
  exports.WebDPoPCryptoProvider = WebDPoPCryptoProvider;
7223
8019
  exports.buildApiRoot = buildApiRoot;
7224
8020
  exports.createPersSDK = createPersSDK;
7225
8021
  exports.mergeWithDefaults = mergeWithDefaults;
7226
- //# sourceMappingURL=pers-sdk-BQw3QUWR.cjs.map
8022
+ //# sourceMappingURL=pers-sdk-Di_R6AiT.cjs.map