@misterhomer1992/miit-bot-payment 1.1.7 → 2.0.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 (248) hide show
  1. package/dist/config/ConfigurationManager.d.ts +64 -0
  2. package/dist/config/ConfigurationManager.d.ts.map +1 -0
  3. package/dist/config/ConfigurationManager.js +144 -0
  4. package/dist/config/ConfigurationManager.js.map +1 -0
  5. package/dist/config/defaults.d.ts +18 -0
  6. package/dist/config/defaults.d.ts.map +1 -0
  7. package/dist/config/defaults.js +26 -0
  8. package/dist/config/defaults.js.map +1 -0
  9. package/dist/config/environment.d.ts +38 -0
  10. package/dist/config/environment.d.ts.map +1 -0
  11. package/dist/config/environment.js +91 -0
  12. package/dist/config/environment.js.map +1 -0
  13. package/dist/config/index.d.ts +5 -0
  14. package/dist/config/index.d.ts.map +1 -0
  15. package/dist/config/index.js +18 -0
  16. package/dist/config/index.js.map +1 -0
  17. package/dist/config/types.d.ts +53 -0
  18. package/dist/config/types.d.ts.map +1 -0
  19. package/dist/config/types.js +3 -0
  20. package/dist/config/types.js.map +1 -0
  21. package/dist/index.d.ts +21 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +23 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/modules/cache/InMemoryCache.d.ts +17 -0
  26. package/dist/modules/cache/InMemoryCache.d.ts.map +1 -0
  27. package/dist/modules/cache/InMemoryCache.js +77 -0
  28. package/dist/modules/cache/InMemoryCache.js.map +1 -0
  29. package/dist/modules/cache/index.d.ts +3 -0
  30. package/dist/modules/cache/index.d.ts.map +1 -0
  31. package/dist/modules/cache/index.js +19 -0
  32. package/dist/modules/cache/index.js.map +1 -0
  33. package/dist/modules/cache/types.d.ts +52 -0
  34. package/dist/modules/cache/types.d.ts.map +1 -0
  35. package/dist/modules/cache/types.js +3 -0
  36. package/dist/modules/cache/types.js.map +1 -0
  37. package/dist/modules/errors/index.d.ts +2 -0
  38. package/dist/modules/errors/index.d.ts.map +1 -0
  39. package/dist/modules/errors/index.js +19 -0
  40. package/dist/modules/errors/index.js.map +1 -0
  41. package/dist/modules/errors/types.d.ts +112 -0
  42. package/dist/modules/errors/types.d.ts.map +1 -0
  43. package/dist/modules/errors/types.js +174 -0
  44. package/dist/modules/errors/types.js.map +1 -0
  45. package/dist/modules/payments/api.d.ts +63 -1
  46. package/dist/modules/payments/api.d.ts.map +1 -1
  47. package/dist/modules/payments/api.js +103 -1
  48. package/dist/modules/payments/api.js.map +1 -1
  49. package/dist/modules/payments/const.d.ts.map +1 -1
  50. package/dist/modules/payments/const.js +1 -0
  51. package/dist/modules/payments/const.js.map +1 -1
  52. package/dist/modules/payments/index.d.ts +8 -0
  53. package/dist/modules/payments/index.d.ts.map +1 -1
  54. package/dist/modules/payments/index.js +8 -0
  55. package/dist/modules/payments/index.js.map +1 -1
  56. package/dist/modules/payments/service.d.ts +42 -2
  57. package/dist/modules/payments/service.d.ts.map +1 -1
  58. package/dist/modules/payments/service.js +132 -3
  59. package/dist/modules/payments/service.js.map +1 -1
  60. package/dist/modules/payments/subscription-check-webhook.handler.d.ts +85 -0
  61. package/dist/modules/payments/subscription-check-webhook.handler.d.ts.map +1 -0
  62. package/dist/modules/payments/subscription-check-webhook.handler.js +155 -0
  63. package/dist/modules/payments/subscription-check-webhook.handler.js.map +1 -0
  64. package/dist/modules/payments/subscription-check-webhook.service.d.ts +59 -0
  65. package/dist/modules/payments/subscription-check-webhook.service.d.ts.map +1 -0
  66. package/dist/modules/payments/subscription-check-webhook.service.js +330 -0
  67. package/dist/modules/payments/subscription-check-webhook.service.js.map +1 -0
  68. package/dist/modules/payments/subscription-check-webhook.types.d.ts +25 -0
  69. package/dist/modules/payments/subscription-check-webhook.types.d.ts.map +1 -0
  70. package/dist/modules/payments/subscription-check-webhook.types.js +3 -0
  71. package/dist/modules/payments/subscription-check-webhook.types.js.map +1 -0
  72. package/dist/modules/payments/types.d.ts +69 -2
  73. package/dist/modules/payments/types.d.ts.map +1 -1
  74. package/dist/modules/payments/utils.d.ts +151 -5
  75. package/dist/modules/payments/utils.d.ts.map +1 -1
  76. package/dist/modules/payments/utils.js +253 -9
  77. package/dist/modules/payments/utils.js.map +1 -1
  78. package/dist/modules/payments/wayforpay.service.d.ts +39 -0
  79. package/dist/modules/payments/wayforpay.service.d.ts.map +1 -0
  80. package/dist/modules/payments/wayforpay.service.js +217 -0
  81. package/dist/modules/payments/wayforpay.service.js.map +1 -0
  82. package/dist/modules/payments/wayforpay.types.d.ts +115 -0
  83. package/dist/modules/payments/wayforpay.types.d.ts.map +1 -0
  84. package/dist/modules/payments/wayforpay.types.js +3 -0
  85. package/dist/modules/payments/wayforpay.types.js.map +1 -0
  86. package/dist/modules/payments/webhook.handler.d.ts +98 -0
  87. package/dist/modules/payments/webhook.handler.d.ts.map +1 -0
  88. package/dist/modules/payments/webhook.handler.js +153 -0
  89. package/dist/modules/payments/webhook.handler.js.map +1 -0
  90. package/dist/modules/payments/webhook.service.d.ts +99 -0
  91. package/dist/modules/payments/webhook.service.d.ts.map +1 -0
  92. package/dist/modules/payments/webhook.service.js +672 -0
  93. package/dist/modules/payments/webhook.service.js.map +1 -0
  94. package/dist/modules/payments/webhook.types.d.ts +35 -0
  95. package/dist/modules/payments/webhook.types.d.ts.map +1 -0
  96. package/dist/modules/payments/webhook.types.js +3 -0
  97. package/dist/modules/payments/webhook.types.js.map +1 -0
  98. package/dist/modules/subscription/change.service.d.ts +80 -0
  99. package/dist/modules/subscription/change.service.d.ts.map +1 -0
  100. package/dist/modules/subscription/change.service.js +226 -0
  101. package/dist/modules/subscription/change.service.js.map +1 -0
  102. package/dist/modules/subscription/index.d.ts +2 -0
  103. package/dist/modules/subscription/index.d.ts.map +1 -1
  104. package/dist/modules/subscription/index.js +2 -0
  105. package/dist/modules/subscription/index.js.map +1 -1
  106. package/dist/modules/subscription/service.d.ts +8 -1
  107. package/dist/modules/subscription/service.d.ts.map +1 -1
  108. package/dist/modules/subscription/service.js +58 -1
  109. package/dist/modules/subscription/service.js.map +1 -1
  110. package/dist/modules/subscription/status-check.handler.d.ts +117 -0
  111. package/dist/modules/subscription/status-check.handler.d.ts.map +1 -0
  112. package/dist/modules/subscription/status-check.handler.js +164 -0
  113. package/dist/modules/subscription/status-check.handler.js.map +1 -0
  114. package/dist/modules/subscription/types.d.ts +37 -1
  115. package/dist/modules/subscription/types.d.ts.map +1 -1
  116. package/dist/modules/subscriptionPlan/const.d.ts +5 -0
  117. package/dist/modules/subscriptionPlan/const.d.ts.map +1 -0
  118. package/dist/modules/subscriptionPlan/const.js +106 -0
  119. package/dist/modules/subscriptionPlan/const.js.map +1 -0
  120. package/dist/modules/subscriptionPlan/index.d.ts +5 -0
  121. package/dist/modules/subscriptionPlan/index.d.ts.map +1 -0
  122. package/dist/modules/subscriptionPlan/index.js +21 -0
  123. package/dist/modules/subscriptionPlan/index.js.map +1 -0
  124. package/dist/modules/subscriptionPlan/repository.d.ts +22 -0
  125. package/dist/modules/subscriptionPlan/repository.d.ts.map +1 -0
  126. package/dist/modules/subscriptionPlan/repository.js +95 -0
  127. package/dist/modules/subscriptionPlan/repository.js.map +1 -0
  128. package/dist/modules/subscriptionPlan/service.d.ts +21 -0
  129. package/dist/modules/subscriptionPlan/service.d.ts.map +1 -0
  130. package/dist/modules/subscriptionPlan/service.js +128 -0
  131. package/dist/modules/subscriptionPlan/service.js.map +1 -0
  132. package/dist/modules/subscriptionPlan/types.d.ts +40 -0
  133. package/dist/modules/subscriptionPlan/types.d.ts.map +1 -0
  134. package/dist/modules/subscriptionPlan/types.js +3 -0
  135. package/dist/modules/subscriptionPlan/types.js.map +1 -0
  136. package/dist/modules/token/const.d.ts +7 -0
  137. package/dist/modules/token/const.d.ts.map +1 -0
  138. package/dist/modules/token/const.js +66 -0
  139. package/dist/modules/token/const.js.map +1 -0
  140. package/dist/modules/token/index.d.ts +4 -0
  141. package/dist/modules/token/index.d.ts.map +1 -0
  142. package/dist/modules/token/index.js +20 -0
  143. package/dist/modules/token/index.js.map +1 -0
  144. package/dist/modules/token/service.d.ts +46 -0
  145. package/dist/modules/token/service.d.ts.map +1 -0
  146. package/dist/modules/token/service.js +249 -0
  147. package/dist/modules/token/service.js.map +1 -0
  148. package/dist/modules/token/types.d.ts +109 -0
  149. package/dist/modules/token/types.d.ts.map +1 -0
  150. package/dist/modules/token/types.js +3 -0
  151. package/dist/modules/token/types.js.map +1 -0
  152. package/dist/modules/tokenPack/const.d.ts +4 -0
  153. package/dist/modules/tokenPack/const.d.ts.map +1 -0
  154. package/dist/modules/tokenPack/const.js +10 -0
  155. package/dist/modules/tokenPack/const.js.map +1 -0
  156. package/dist/modules/tokenPack/index.d.ts +5 -0
  157. package/dist/modules/tokenPack/index.d.ts.map +1 -0
  158. package/dist/modules/tokenPack/index.js +21 -0
  159. package/dist/modules/tokenPack/index.js.map +1 -0
  160. package/dist/modules/tokenPack/repository.d.ts +32 -0
  161. package/dist/modules/tokenPack/repository.d.ts.map +1 -0
  162. package/dist/modules/tokenPack/repository.js +103 -0
  163. package/dist/modules/tokenPack/repository.js.map +1 -0
  164. package/dist/modules/tokenPack/service.d.ts +28 -0
  165. package/dist/modules/tokenPack/service.d.ts.map +1 -0
  166. package/dist/modules/tokenPack/service.js +106 -0
  167. package/dist/modules/tokenPack/service.js.map +1 -0
  168. package/dist/modules/tokenPack/types.d.ts +124 -0
  169. package/dist/modules/tokenPack/types.d.ts.map +1 -0
  170. package/dist/modules/tokenPack/types.js +3 -0
  171. package/dist/modules/tokenPack/types.js.map +1 -0
  172. package/package.json +9 -5
  173. package/src/config/ConfigurationManager.ts +159 -0
  174. package/src/config/defaults.ts +27 -0
  175. package/src/config/environment.ts +94 -0
  176. package/src/config/index.ts +22 -0
  177. package/src/config/types.ts +56 -0
  178. package/src/index.ts +29 -0
  179. package/src/modules/cache/InMemoryCache.ts +98 -0
  180. package/src/modules/cache/index.ts +2 -0
  181. package/src/modules/cache/types.ts +60 -0
  182. package/src/modules/cancellableAPI/utils.ts +60 -0
  183. package/src/modules/errors/index.ts +16 -0
  184. package/src/modules/errors/types.ts +201 -0
  185. package/src/modules/invoice/const.ts +7 -0
  186. package/src/modules/invoice/index.ts +4 -0
  187. package/src/modules/invoice/repository.ts +52 -0
  188. package/src/modules/invoice/service.ts +44 -0
  189. package/src/modules/invoice/types.ts +47 -0
  190. package/src/modules/logger/types.ts +8 -0
  191. package/src/modules/network/utils.ts +24 -0
  192. package/src/modules/payments/api.ts +289 -0
  193. package/src/modules/payments/const.ts +11 -0
  194. package/src/modules/payments/index.ts +14 -0
  195. package/src/modules/payments/repository.ts +125 -0
  196. package/src/modules/payments/service.test.ts +400 -0
  197. package/src/modules/payments/service.ts +365 -0
  198. package/src/modules/payments/subscription-check-webhook.handler.integration.test.ts +935 -0
  199. package/src/modules/payments/subscription-check-webhook.handler.ts +211 -0
  200. package/src/modules/payments/subscription-check-webhook.service.ts +398 -0
  201. package/src/modules/payments/subscription-check-webhook.types.ts +29 -0
  202. package/src/modules/payments/types.ts +193 -0
  203. package/src/modules/payments/utils.ts +428 -0
  204. package/src/modules/payments/wayforpay.service.test.ts +375 -0
  205. package/src/modules/payments/wayforpay.service.ts +284 -0
  206. package/src/modules/payments/wayforpay.types.ts +138 -0
  207. package/src/modules/payments/webhook.handler.integration.test.ts +975 -0
  208. package/src/modules/payments/webhook.handler.ts +219 -0
  209. package/src/modules/payments/webhook.service.ts +812 -0
  210. package/src/modules/payments/webhook.types.ts +38 -0
  211. package/src/modules/subscription/change.service.ts +317 -0
  212. package/src/modules/subscription/const.ts +9 -0
  213. package/src/modules/subscription/index.ts +5 -0
  214. package/src/modules/subscription/repository.ts +277 -0
  215. package/src/modules/subscription/service.test.ts +665 -0
  216. package/src/modules/subscription/service.ts +328 -0
  217. package/src/modules/subscription/status-check.handler.ts +254 -0
  218. package/src/modules/subscription/types.ts +267 -0
  219. package/src/modules/subscription/utils.ts +5 -0
  220. package/src/modules/subscriptionPlan/const.ts +106 -0
  221. package/src/modules/subscriptionPlan/index.ts +4 -0
  222. package/src/modules/subscriptionPlan/repository.ts +129 -0
  223. package/src/modules/subscriptionPlan/service.test.ts +401 -0
  224. package/src/modules/subscriptionPlan/service.ts +148 -0
  225. package/src/modules/subscriptionPlan/types.ts +67 -0
  226. package/src/modules/token/const.ts +64 -0
  227. package/src/modules/token/index.ts +3 -0
  228. package/src/modules/token/service.test.ts +499 -0
  229. package/src/modules/token/service.ts +297 -0
  230. package/src/modules/token/types.ts +124 -0
  231. package/src/modules/tokenPack/const.ts +9 -0
  232. package/src/modules/tokenPack/index.ts +4 -0
  233. package/src/modules/tokenPack/repository.ts +144 -0
  234. package/src/modules/tokenPack/service.ts +119 -0
  235. package/src/modules/tokenPack/types.ts +131 -0
  236. package/src/modules/user/index.ts +3 -0
  237. package/src/modules/user/types.ts +143 -0
  238. package/src/modules/user/userRepository.ts +64 -0
  239. package/src/modules/user/userService.ts +68 -0
  240. package/src/types/extend-express.d.ts +16 -0
  241. package/src/types/function.ts +5 -0
  242. package/src/types/utilities.ts +22 -0
  243. package/src/utils.ts +53 -0
  244. package/tsconfig.json +29 -0
  245. package/dist/modules/subscription/subscriptionPlan.d.ts +0 -4
  246. package/dist/modules/subscription/subscriptionPlan.d.ts.map +0 -1
  247. package/dist/modules/subscription/subscriptionPlan.js +0 -67
  248. package/dist/modules/subscription/subscriptionPlan.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ import { Logger } from '../logger/types';
2
+ import { SubscriptionPlanEntity, ISubscriptionPlanRepository, ISubscriptionPlanService } from './types';
3
+ export declare class SubscriptionPlanService implements ISubscriptionPlanService {
4
+ private readonly logger;
5
+ private readonly repository;
6
+ private readonly cache;
7
+ constructor({ logger, repository, }: {
8
+ logger: Logger;
9
+ repository?: ISubscriptionPlanRepository;
10
+ });
11
+ getAll(): Promise<SubscriptionPlanEntity[]>;
12
+ getById(id: string): Promise<SubscriptionPlanEntity | null>;
13
+ create(params: Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>): Promise<SubscriptionPlanEntity>;
14
+ update(id: string, params: Partial<Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>>): Promise<SubscriptionPlanEntity>;
15
+ deactivate(id: string): Promise<void>;
16
+ resetCache(): void;
17
+ seedDefaults(): Promise<void>;
18
+ private ensureSeeded;
19
+ private invalidateCache;
20
+ }
21
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/subscriptionPlan/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAKxG,qBAAa,uBAAwB,YAAW,wBAAwB;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;gBAEpD,EACR,MAAM,EACN,UAAU,GACb,EAAE;QACC,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,2BAA2B,CAAC;KAC5C;IAMY,MAAM,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAqB3C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAkB3D,MAAM,CACf,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GACvE,OAAO,CAAC,sBAAsB,CAAC;IAcrB,MAAM,CACf,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,GAChF,OAAO,CAAC,sBAAsB,CAAC;IAcrB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,UAAU,IAAI,IAAI;IAOZ,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAoB5B,YAAY;IAO1B,OAAO,CAAC,eAAe;CAG1B"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionPlanService = void 0;
4
+ const InMemoryCache_1 = require("../cache/InMemoryCache");
5
+ const repository_1 = require("./repository");
6
+ const const_1 = require("./const");
7
+ const CACHE_KEY_ALL_PLANS = 'all_plans';
8
+ class SubscriptionPlanService {
9
+ constructor({ logger, repository, }) {
10
+ this.logger = logger;
11
+ this.repository = repository || new repository_1.SubscriptionPlanRepository();
12
+ this.cache = new InMemoryCache_1.InMemoryCache({ ttl: const_1.CACHE_TTL_MS });
13
+ }
14
+ async getAll() {
15
+ try {
16
+ const cached = this.cache.get(CACHE_KEY_ALL_PLANS);
17
+ if (cached) {
18
+ return cached;
19
+ }
20
+ await this.ensureSeeded();
21
+ const plans = await this.repository.getAll();
22
+ this.cache.set(CACHE_KEY_ALL_PLANS, plans);
23
+ return plans;
24
+ }
25
+ catch (error) {
26
+ this.logger.error({
27
+ message: 'Error in subscription plan service getAll',
28
+ payload: { error: JSON.stringify(error) },
29
+ });
30
+ return [];
31
+ }
32
+ }
33
+ async getById(id) {
34
+ try {
35
+ const allPlans = await this.getAll();
36
+ const cachedPlan = allPlans.find((plan) => plan.id === id);
37
+ if (cachedPlan) {
38
+ return cachedPlan;
39
+ }
40
+ return await this.repository.getById(id);
41
+ }
42
+ catch (error) {
43
+ this.logger.error({
44
+ message: 'Error in subscription plan service getById',
45
+ payload: { id, error: JSON.stringify(error) },
46
+ });
47
+ return null;
48
+ }
49
+ }
50
+ async create(params) {
51
+ try {
52
+ const plan = await this.repository.create(params);
53
+ this.invalidateCache();
54
+ return plan;
55
+ }
56
+ catch (error) {
57
+ this.logger.error({
58
+ message: 'Error in subscription plan service create',
59
+ payload: { params: JSON.stringify(params), error: JSON.stringify(error) },
60
+ });
61
+ throw error;
62
+ }
63
+ }
64
+ async update(id, params) {
65
+ try {
66
+ const plan = await this.repository.update(id, params);
67
+ this.invalidateCache();
68
+ return plan;
69
+ }
70
+ catch (error) {
71
+ this.logger.error({
72
+ message: 'Error in subscription plan service update',
73
+ payload: { id, params: JSON.stringify(params), error: JSON.stringify(error) },
74
+ });
75
+ throw error;
76
+ }
77
+ }
78
+ async deactivate(id) {
79
+ try {
80
+ await this.repository.deactivate(id);
81
+ this.invalidateCache();
82
+ }
83
+ catch (error) {
84
+ this.logger.error({
85
+ message: 'Error in subscription plan service deactivate',
86
+ payload: { id, error: JSON.stringify(error) },
87
+ });
88
+ throw error;
89
+ }
90
+ }
91
+ resetCache() {
92
+ this.cache.clear();
93
+ this.logger.info({
94
+ message: 'Subscription plan cache reset',
95
+ });
96
+ }
97
+ async seedDefaults() {
98
+ try {
99
+ const isEmpty = await this.repository.isEmpty();
100
+ if (isEmpty) {
101
+ await this.repository.seedDefaults(const_1.DEFAULT_SUBSCRIPTION_PLANS);
102
+ this.invalidateCache();
103
+ this.logger.info({
104
+ message: 'Default subscription plans seeded',
105
+ payload: { count: const_1.DEFAULT_SUBSCRIPTION_PLANS.length },
106
+ });
107
+ }
108
+ }
109
+ catch (error) {
110
+ this.logger.error({
111
+ message: 'Error in subscription plan service seedDefaults',
112
+ payload: { error: JSON.stringify(error) },
113
+ });
114
+ throw error;
115
+ }
116
+ }
117
+ async ensureSeeded() {
118
+ const isEmpty = await this.repository.isEmpty();
119
+ if (isEmpty) {
120
+ await this.seedDefaults();
121
+ }
122
+ }
123
+ invalidateCache() {
124
+ this.cache.delete(CACHE_KEY_ALL_PLANS);
125
+ }
126
+ }
127
+ exports.SubscriptionPlanService = SubscriptionPlanService;
128
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/subscriptionPlan/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { NestedPathsAccess } from '../../types/utilities';
2
+ type SubscriptionPlanEntity = {
3
+ id: string;
4
+ titleCode: string;
5
+ descriptionCode: string;
6
+ amount: number;
7
+ currency: 'UAH' | 'USD';
8
+ features: {
9
+ messages: number;
10
+ images: number;
11
+ voice: number;
12
+ };
13
+ regularMode: 'daily' | 'monthly' | 'yearly';
14
+ count: number;
15
+ credits: number;
16
+ isActive: boolean;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ };
20
+ type SubscriptionPlanFieldPath = NestedPathsAccess<SubscriptionPlanEntity>;
21
+ interface ISubscriptionPlanRepository {
22
+ getAll(): Promise<SubscriptionPlanEntity[]>;
23
+ getById(id: string): Promise<SubscriptionPlanEntity | null>;
24
+ create(params: Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>): Promise<SubscriptionPlanEntity>;
25
+ update(id: string, params: Partial<Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>>): Promise<SubscriptionPlanEntity>;
26
+ deactivate(id: string): Promise<void>;
27
+ seedDefaults(defaultPlans: Omit<SubscriptionPlanEntity, 'createdAt' | 'updatedAt'>[]): Promise<void>;
28
+ isEmpty(): Promise<boolean>;
29
+ }
30
+ interface ISubscriptionPlanService {
31
+ getAll(): Promise<SubscriptionPlanEntity[]>;
32
+ getById(id: string): Promise<SubscriptionPlanEntity | null>;
33
+ create(params: Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>): Promise<SubscriptionPlanEntity>;
34
+ update(id: string, params: Partial<Omit<SubscriptionPlanEntity, 'id' | 'createdAt' | 'updatedAt'>>): Promise<SubscriptionPlanEntity>;
35
+ deactivate(id: string): Promise<void>;
36
+ resetCache(): void;
37
+ seedDefaults(): Promise<void>;
38
+ }
39
+ export type { SubscriptionPlanEntity, SubscriptionPlanFieldPath, ISubscriptionPlanRepository, ISubscriptionPlanService, };
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/subscriptionPlan/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,KAAK,sBAAsB,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC;IACxB,QAAQ,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,yBAAyB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAC;AAE3E,UAAU,2BAA2B;IACjC,MAAM,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAE5C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IAE5D,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEhH,MAAM,CACF,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,GAChF,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,GAAG,WAAW,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/B;AAED,UAAU,wBAAwB;IAC9B,MAAM,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAE5C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IAE5D,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEhH,MAAM,CACF,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,GAChF,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,UAAU,IAAI,IAAI,CAAC;IAEnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,YAAY,EACR,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GAC3B,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/modules/subscriptionPlan/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { TokenPackPlan } from './types';
2
+ /**
3
+ * Default token pack plans available for purchase.
4
+ * Fixed packs: 10000, 30000, 75000 tokens
5
+ */
6
+ export declare const DEFAULT_TOKEN_PACK_PLANS: TokenPackPlan[];
7
+ //# sourceMappingURL=const.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/modules/token/const.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,aAAa,EAyDnD,CAAC"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_TOKEN_PACK_PLANS = void 0;
4
+ /**
5
+ * Default token pack plans available for purchase.
6
+ * Fixed packs: 10000, 30000, 75000 tokens
7
+ */
8
+ exports.DEFAULT_TOKEN_PACK_PLANS = [
9
+ // UAH Plans
10
+ {
11
+ id: 'token-pack-small',
12
+ titleCode: 'token.pack.small.title',
13
+ descriptionCode: 'token.pack.small.description',
14
+ tokens: 10000,
15
+ amount: 49,
16
+ currency: 'UAH',
17
+ isActive: true,
18
+ },
19
+ {
20
+ id: 'token-pack-medium',
21
+ titleCode: 'token.pack.medium.title',
22
+ descriptionCode: 'token.pack.medium.description',
23
+ tokens: 30000,
24
+ amount: 129,
25
+ currency: 'UAH',
26
+ isActive: true,
27
+ },
28
+ {
29
+ id: 'token-pack-large',
30
+ titleCode: 'token.pack.large.title',
31
+ descriptionCode: 'token.pack.large.description',
32
+ tokens: 75000,
33
+ amount: 299,
34
+ currency: 'UAH',
35
+ isActive: true,
36
+ },
37
+ // USD Plans
38
+ {
39
+ id: 'token-pack-small-usd',
40
+ titleCode: 'token.pack.small.title',
41
+ descriptionCode: 'token.pack.small.description',
42
+ tokens: 10000,
43
+ amount: 2,
44
+ currency: 'USD',
45
+ isActive: true,
46
+ },
47
+ {
48
+ id: 'token-pack-medium-usd',
49
+ titleCode: 'token.pack.medium.title',
50
+ descriptionCode: 'token.pack.medium.description',
51
+ tokens: 30000,
52
+ amount: 5,
53
+ currency: 'USD',
54
+ isActive: true,
55
+ },
56
+ {
57
+ id: 'token-pack-large-usd',
58
+ titleCode: 'token.pack.large.title',
59
+ descriptionCode: 'token.pack.large.description',
60
+ tokens: 75000,
61
+ amount: 10,
62
+ currency: 'USD',
63
+ isActive: true,
64
+ },
65
+ ];
66
+ //# sourceMappingURL=const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/modules/token/const.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACU,QAAA,wBAAwB,GAAoB;IACrD,YAAY;IACZ;QACI,EAAE,EAAE,kBAAkB;QACtB,SAAS,EAAE,wBAAwB;QACnC,eAAe,EAAE,8BAA8B;QAC/C,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;IACD;QACI,EAAE,EAAE,mBAAmB;QACvB,SAAS,EAAE,yBAAyB;QACpC,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,GAAG;QACX,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;IACD;QACI,EAAE,EAAE,kBAAkB;QACtB,SAAS,EAAE,wBAAwB;QACnC,eAAe,EAAE,8BAA8B;QAC/C,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,GAAG;QACX,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;IACD,YAAY;IACZ;QACI,EAAE,EAAE,sBAAsB;QAC1B,SAAS,EAAE,wBAAwB;QACnC,eAAe,EAAE,8BAA8B;QAC/C,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,CAAC;QACT,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;IACD;QACI,EAAE,EAAE,uBAAuB;QAC3B,SAAS,EAAE,yBAAyB;QACpC,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,CAAC;QACT,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;IACD;QACI,EAAE,EAAE,sBAAsB;QAC1B,SAAS,EAAE,wBAAwB;QACnC,eAAe,EAAE,8BAA8B;QAC/C,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,IAAI;KACjB;CACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './service';
3
+ export * from './const';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/token/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./service"), exports);
19
+ __exportStar(require("./const"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/token/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,4CAA0B;AAC1B,0CAAwB"}
@@ -0,0 +1,46 @@
1
+ import { Logger } from '../logger/types';
2
+ import { ITokenPackService } from '../tokenPack/types';
3
+ import { IPaymentService } from '../payments/types';
4
+ import type { TokenPackPlan, PurchaseUrlResult, CreatePurchaseUrlParams, AddTokensParams, DeductTokensParams, TokenBalance, ITokenService } from './types';
5
+ /**
6
+ * TokenService provides business logic for token pack purchases and balance management.
7
+ * Works independently of subscription status.
8
+ */
9
+ export declare class TokenService implements ITokenService {
10
+ private readonly logger;
11
+ private readonly tokenPackService;
12
+ private readonly paymentService;
13
+ private readonly tokenPackPlans;
14
+ constructor({ logger, tokenPackService, paymentService, tokenPackPlans, }: {
15
+ logger: Logger;
16
+ tokenPackService?: ITokenPackService;
17
+ paymentService?: IPaymentService;
18
+ tokenPackPlans?: TokenPackPlan[];
19
+ });
20
+ /**
21
+ * Returns all available token pack plans for purchase.
22
+ */
23
+ getAvailablePacks(): TokenPackPlan[];
24
+ /**
25
+ * Creates a one-time payment URL for purchasing a token pack.
26
+ */
27
+ createPurchaseUrl(params: CreatePurchaseUrlParams): Promise<PurchaseUrlResult | null>;
28
+ /**
29
+ * Adds tokens to a user's balance by creating a new token pack.
30
+ * Called after successful payment confirmation.
31
+ */
32
+ addTokensToUser(params: AddTokensParams): Promise<void>;
33
+ /**
34
+ * Deducts tokens from a user's available balance.
35
+ * Deducts from oldest packs first (FIFO).
36
+ */
37
+ deductTokens(params: DeductTokensParams): Promise<void>;
38
+ /**
39
+ * Gets the current token balance for a user.
40
+ */
41
+ getBalance(params: {
42
+ userId: string;
43
+ platform: string;
44
+ }): Promise<TokenBalance>;
45
+ }
46
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/token/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,KAAK,EACR,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,aAAa,EAChB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,YAAa,YAAW,aAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;gBAErC,EACR,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,cAAc,GACjB,EAAE;QACC,MAAM,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;QACrC,cAAc,CAAC,EAAE,eAAe,CAAC;QACjC,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;KACpC;IAOD;;OAEG;IACI,iBAAiB,IAAI,aAAa,EAAE;IAI3C;;OAEG;IACU,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAsFlG;;;OAGG;IACU,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCpE;;;OAGG;IACU,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmEpE;;OAEG;IACU,UAAU,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CAwC/F"}
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TokenService = void 0;
7
+ const moment_1 = __importDefault(require("moment"));
8
+ const service_1 = require("../tokenPack/service");
9
+ const service_2 = require("../payments/service");
10
+ const const_1 = require("./const");
11
+ const api_1 = require("../payments/api");
12
+ /**
13
+ * TokenService provides business logic for token pack purchases and balance management.
14
+ * Works independently of subscription status.
15
+ */
16
+ class TokenService {
17
+ constructor({ logger, tokenPackService, paymentService, tokenPackPlans, }) {
18
+ this.logger = logger;
19
+ this.tokenPackService = tokenPackService || new service_1.TokenPackService({ logger });
20
+ this.paymentService = paymentService || new service_2.PaymentService({ logger });
21
+ this.tokenPackPlans = tokenPackPlans || const_1.DEFAULT_TOKEN_PACK_PLANS;
22
+ }
23
+ /**
24
+ * Returns all available token pack plans for purchase.
25
+ */
26
+ getAvailablePacks() {
27
+ return this.tokenPackPlans.filter((plan) => plan.isActive);
28
+ }
29
+ /**
30
+ * Creates a one-time payment URL for purchasing a token pack.
31
+ */
32
+ async createPurchaseUrl(params) {
33
+ const { userId, platform, packId, language = 'UA', returnUrl } = params;
34
+ try {
35
+ // Find the token pack plan
36
+ const plan = this.tokenPackPlans.find((p) => p.id === packId);
37
+ if (!plan) {
38
+ this.logger.error({
39
+ message: 'Token pack plan not found',
40
+ payload: { packId },
41
+ });
42
+ return null;
43
+ }
44
+ if (!plan.isActive) {
45
+ this.logger.error({
46
+ message: 'Token pack plan is not active',
47
+ payload: { packId },
48
+ });
49
+ return null;
50
+ }
51
+ // Create one-time payment URL via WayForPay API
52
+ // Uses the v2 order reference format for token packs (tkn type)
53
+ const paymentResult = await (0, api_1.createTokenPackPaymentAPI)({
54
+ userId,
55
+ platform,
56
+ productName: `Token Pack - ${plan.tokens} tokens`,
57
+ productPrice: plan.amount,
58
+ packId,
59
+ currency: plan.currency,
60
+ language,
61
+ returnUrl,
62
+ });
63
+ if (!paymentResult) {
64
+ this.logger.error({
65
+ message: 'Failed to generate payment URL for token pack',
66
+ payload: { userId, platform, packId },
67
+ });
68
+ return null;
69
+ }
70
+ // Create payment record in database
71
+ await this.paymentService.create({
72
+ orderReference: paymentResult.orderReference,
73
+ userId,
74
+ status: 'pending',
75
+ paymentLink: paymentResult.url,
76
+ planId: packId,
77
+ paymentType: 'token_pack',
78
+ amount: plan.amount,
79
+ currency: plan.currency,
80
+ createdAt: moment_1.default.utc().toISOString(),
81
+ platform,
82
+ provider: 'wayforpay',
83
+ });
84
+ this.logger.info({
85
+ message: 'Token pack purchase URL created',
86
+ payload: {
87
+ userId,
88
+ platform,
89
+ packId,
90
+ orderReference: paymentResult.orderReference,
91
+ },
92
+ });
93
+ return {
94
+ url: paymentResult.url,
95
+ orderReference: paymentResult.orderReference,
96
+ };
97
+ }
98
+ catch (error) {
99
+ this.logger.error({
100
+ message: 'Error creating token pack purchase URL',
101
+ payload: {
102
+ userId,
103
+ platform,
104
+ packId,
105
+ error: JSON.stringify(error),
106
+ },
107
+ });
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Adds tokens to a user's balance by creating a new token pack.
113
+ * Called after successful payment confirmation.
114
+ */
115
+ async addTokensToUser(params) {
116
+ const { userId, platform, packId, tokens } = params;
117
+ try {
118
+ await this.tokenPackService.create({
119
+ userId,
120
+ platform,
121
+ packId,
122
+ tokens,
123
+ purchasedAt: moment_1.default.utc().toISOString(),
124
+ provider: 'wayforpay',
125
+ });
126
+ this.logger.info({
127
+ message: 'Tokens added to user balance',
128
+ payload: {
129
+ userId,
130
+ platform,
131
+ packId,
132
+ tokens,
133
+ },
134
+ });
135
+ }
136
+ catch (error) {
137
+ this.logger.error({
138
+ message: 'Error adding tokens to user balance',
139
+ payload: {
140
+ userId,
141
+ platform,
142
+ packId,
143
+ tokens,
144
+ error: JSON.stringify(error),
145
+ },
146
+ });
147
+ throw error;
148
+ }
149
+ }
150
+ /**
151
+ * Deducts tokens from a user's available balance.
152
+ * Deducts from oldest packs first (FIFO).
153
+ */
154
+ async deductTokens(params) {
155
+ const { userId, platform, amount } = params;
156
+ try {
157
+ // Get active token packs sorted by purchase date (oldest first)
158
+ const activePacks = await this.tokenPackService.getByUser({
159
+ userId,
160
+ platform,
161
+ status: 'active',
162
+ });
163
+ if (activePacks.length === 0) {
164
+ throw new Error(`No active token packs found for user ${userId}`);
165
+ }
166
+ // Sort by purchasedAt (oldest first) for FIFO deduction
167
+ const sortedPacks = activePacks.sort((a, b) => new Date(a.purchasedAt).getTime() - new Date(b.purchasedAt).getTime());
168
+ // Calculate total available tokens
169
+ const totalAvailable = sortedPacks.reduce((sum, pack) => sum + pack.tokensRemaining, 0);
170
+ if (totalAvailable < amount) {
171
+ throw new Error(`Insufficient tokens. Required: ${amount}, Available: ${totalAvailable}`);
172
+ }
173
+ // Deduct tokens from packs (FIFO)
174
+ let remainingToDeduct = amount;
175
+ for (const pack of sortedPacks) {
176
+ if (remainingToDeduct <= 0)
177
+ break;
178
+ const deductFromPack = Math.min(pack.tokensRemaining, remainingToDeduct);
179
+ await this.tokenPackService.deductTokens({
180
+ id: pack.id,
181
+ amount: deductFromPack,
182
+ });
183
+ remainingToDeduct -= deductFromPack;
184
+ }
185
+ this.logger.info({
186
+ message: 'Tokens deducted from user balance',
187
+ payload: {
188
+ userId,
189
+ platform,
190
+ amount,
191
+ remainingTotal: totalAvailable - amount,
192
+ },
193
+ });
194
+ }
195
+ catch (error) {
196
+ this.logger.error({
197
+ message: 'Error deducting tokens from user balance',
198
+ payload: {
199
+ userId,
200
+ platform,
201
+ amount,
202
+ error: JSON.stringify(error),
203
+ },
204
+ });
205
+ throw error;
206
+ }
207
+ }
208
+ /**
209
+ * Gets the current token balance for a user.
210
+ */
211
+ async getBalance(params) {
212
+ const { userId, platform } = params;
213
+ try {
214
+ const activePacks = await this.tokenPackService.getByUser({
215
+ userId,
216
+ platform,
217
+ status: 'active',
218
+ });
219
+ const available = activePacks.reduce((sum, pack) => sum + pack.tokensRemaining, 0);
220
+ const packs = activePacks.map((pack) => ({
221
+ id: pack.id,
222
+ packId: pack.packId,
223
+ tokensRemaining: pack.tokensRemaining,
224
+ purchasedAt: pack.purchasedAt,
225
+ }));
226
+ return {
227
+ available,
228
+ packs,
229
+ };
230
+ }
231
+ catch (error) {
232
+ this.logger.error({
233
+ message: 'Error getting token balance',
234
+ payload: {
235
+ userId,
236
+ platform,
237
+ error: JSON.stringify(error),
238
+ },
239
+ });
240
+ // Return empty balance on error
241
+ return {
242
+ available: 0,
243
+ packs: [],
244
+ };
245
+ }
246
+ }
247
+ }
248
+ exports.TokenService = TokenService;
249
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/token/service.ts"],"names":[],"mappings":"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"}