@m5kdev/backend 0.1.3 → 0.1.5

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 (309) hide show
  1. package/dist/src/lib/posthog.d.ts +0 -1
  2. package/dist/src/lib/sentry.d.ts +0 -1
  3. package/dist/src/modules/access/access.repository.d.ts +0 -1
  4. package/dist/src/modules/access/access.service.d.ts +0 -1
  5. package/dist/src/modules/access/access.test.d.ts +0 -1
  6. package/dist/src/modules/access/access.utils.d.ts +0 -1
  7. package/dist/src/modules/ai/ai.db.d.ts +0 -1
  8. package/dist/src/modules/ai/ai.prompt.d.ts +0 -1
  9. package/dist/src/modules/ai/ai.repository.d.ts +0 -1
  10. package/dist/src/modules/ai/ai.router.d.ts +0 -1
  11. package/dist/src/modules/ai/ai.service.d.ts +0 -1
  12. package/dist/src/modules/ai/ai.trpc.d.ts +4 -5
  13. package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts +0 -1
  14. package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts +0 -1
  15. package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts +0 -1
  16. package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts +0 -1
  17. package/dist/src/modules/ai/ideogram/ideogram.service.d.ts +0 -1
  18. package/dist/src/modules/auth/auth.db.d.ts +0 -1
  19. package/dist/src/modules/auth/auth.dto.d.ts +7 -8
  20. package/dist/src/modules/auth/auth.lib.d.ts +8 -9
  21. package/dist/src/modules/auth/auth.middleware.d.ts +0 -1
  22. package/dist/src/modules/auth/auth.repository.d.ts +0 -1
  23. package/dist/src/modules/auth/auth.service.d.ts +0 -1
  24. package/dist/src/modules/auth/auth.trpc.d.ts +17 -18
  25. package/dist/src/modules/auth/auth.utils.d.ts +0 -1
  26. package/dist/src/modules/base/base.abstract.d.ts +0 -1
  27. package/dist/src/modules/base/base.dto.d.ts +2 -3
  28. package/dist/src/modules/base/base.grants.d.ts +0 -1
  29. package/dist/src/modules/base/base.grants.test.d.ts +0 -1
  30. package/dist/src/modules/base/base.repository.d.ts +0 -1
  31. package/dist/src/modules/base/base.service.d.ts +0 -1
  32. package/dist/src/modules/base/base.types.d.ts +0 -1
  33. package/dist/src/modules/billing/billing.db.d.ts +0 -1
  34. package/dist/src/modules/billing/billing.repository.d.ts +0 -1
  35. package/dist/src/modules/billing/billing.router.d.ts +0 -1
  36. package/dist/src/modules/billing/billing.service.d.ts +0 -1
  37. package/dist/src/modules/billing/billing.trpc.d.ts +4 -5
  38. package/dist/src/modules/clay/clay.repository.d.ts +0 -1
  39. package/dist/src/modules/clay/clay.service.d.ts +0 -1
  40. package/dist/src/modules/connect/connect.db.d.ts +0 -1
  41. package/dist/src/modules/connect/connect.dto.d.ts +8 -9
  42. package/dist/src/modules/connect/connect.linkedin.d.ts +0 -1
  43. package/dist/src/modules/connect/connect.oauth.d.ts +0 -1
  44. package/dist/src/modules/connect/connect.repository.d.ts +3 -4
  45. package/dist/src/modules/connect/connect.router.d.ts +0 -1
  46. package/dist/src/modules/connect/connect.service.d.ts +6 -7
  47. package/dist/src/modules/connect/connect.trpc.d.ts +6 -7
  48. package/dist/src/modules/connect/connect.types.d.ts +0 -1
  49. package/dist/src/modules/crypto/crypto.db.d.ts +0 -1
  50. package/dist/src/modules/crypto/crypto.repository.d.ts +0 -1
  51. package/dist/src/modules/crypto/crypto.service.d.ts +0 -1
  52. package/dist/src/modules/email/email.service.d.ts +0 -1
  53. package/dist/src/modules/file/file.repository.d.ts +0 -1
  54. package/dist/src/modules/file/file.router.d.ts +0 -1
  55. package/dist/src/modules/file/file.service.d.ts +0 -1
  56. package/dist/src/modules/recurrence/recurrence.db.d.ts +0 -1
  57. package/dist/src/modules/recurrence/recurrence.repository.d.ts +0 -1
  58. package/dist/src/modules/recurrence/recurrence.service.d.ts +0 -1
  59. package/dist/src/modules/recurrence/recurrence.trpc.d.ts +5 -6
  60. package/dist/src/modules/social/social.dto.d.ts +0 -1
  61. package/dist/src/modules/social/social.linkedin.d.ts +0 -1
  62. package/dist/src/modules/social/social.linkedin.test.d.ts +0 -1
  63. package/dist/src/modules/social/social.service.d.ts +0 -1
  64. package/dist/src/modules/social/social.types.d.ts +0 -1
  65. package/dist/src/modules/tag/tag.db.d.ts +0 -1
  66. package/dist/src/modules/tag/tag.dto.d.ts +0 -1
  67. package/dist/src/modules/tag/tag.repository.d.ts +0 -1
  68. package/dist/src/modules/tag/tag.service.d.ts +0 -1
  69. package/dist/src/modules/tag/tag.trpc.d.ts +6 -7
  70. package/dist/src/modules/utils/applyPagination.d.ts +0 -1
  71. package/dist/src/modules/utils/applySorting.d.ts +0 -1
  72. package/dist/src/modules/utils/getConditionsFromFilters.d.ts +0 -1
  73. package/dist/src/modules/video/video.service.d.ts +0 -1
  74. package/dist/src/modules/webhook/webhook.constants.d.ts +0 -1
  75. package/dist/src/modules/webhook/webhook.db.d.ts +0 -1
  76. package/dist/src/modules/webhook/webhook.dto.d.ts +0 -1
  77. package/dist/src/modules/webhook/webhook.repository.d.ts +0 -1
  78. package/dist/src/modules/webhook/webhook.router.d.ts +0 -1
  79. package/dist/src/modules/webhook/webhook.service.d.ts +0 -1
  80. package/dist/src/modules/workflow/workflow.db.d.ts +0 -1
  81. package/dist/src/modules/workflow/workflow.repository.d.ts +0 -1
  82. package/dist/src/modules/workflow/workflow.service.d.ts +0 -1
  83. package/dist/src/modules/workflow/workflow.trpc.d.ts +4 -5
  84. package/dist/src/modules/workflow/workflow.types.d.ts +0 -1
  85. package/dist/src/modules/workflow/workflow.utils.d.ts +0 -1
  86. package/dist/src/test/stubs/utils.d.ts +0 -1
  87. package/dist/src/trpc/context.d.ts +4 -5
  88. package/dist/src/trpc/index.d.ts +0 -1
  89. package/dist/src/trpc/procedures.d.ts +24 -25
  90. package/dist/src/trpc/utils.d.ts +0 -1
  91. package/dist/src/types.d.ts +29 -30
  92. package/dist/src/utils/errors.d.ts +0 -1
  93. package/dist/src/utils/logger.d.ts +0 -1
  94. package/dist/src/utils/posthog.d.ts +0 -1
  95. package/dist/src/utils/types.d.ts +0 -1
  96. package/dist/tsconfig.tsbuildinfo +1 -1
  97. package/package.json +6 -3
  98. package/.cursor/rules/backend.mdc +0 -70
  99. package/.turbo/turbo-build.log +0 -5
  100. package/.turbo/turbo-check-types.log +0 -5
  101. package/.turbo/turbo-lint$colon$fix.log +0 -255
  102. package/CHANGELOG.md +0 -28
  103. package/dist/src/lib/posthog.d.ts.map +0 -1
  104. package/dist/src/lib/sentry.d.ts.map +0 -1
  105. package/dist/src/modules/access/access.repository.d.ts.map +0 -1
  106. package/dist/src/modules/access/access.service.d.ts.map +0 -1
  107. package/dist/src/modules/access/access.test.d.ts.map +0 -1
  108. package/dist/src/modules/access/access.utils.d.ts.map +0 -1
  109. package/dist/src/modules/ai/ai.db.d.ts.map +0 -1
  110. package/dist/src/modules/ai/ai.prompt.d.ts.map +0 -1
  111. package/dist/src/modules/ai/ai.repository.d.ts.map +0 -1
  112. package/dist/src/modules/ai/ai.router.d.ts.map +0 -1
  113. package/dist/src/modules/ai/ai.service.d.ts.map +0 -1
  114. package/dist/src/modules/ai/ai.trpc.d.ts.map +0 -1
  115. package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts.map +0 -1
  116. package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts.map +0 -1
  117. package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts.map +0 -1
  118. package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts.map +0 -1
  119. package/dist/src/modules/ai/ideogram/ideogram.service.d.ts.map +0 -1
  120. package/dist/src/modules/auth/auth.db.d.ts.map +0 -1
  121. package/dist/src/modules/auth/auth.dto.d.ts.map +0 -1
  122. package/dist/src/modules/auth/auth.lib.d.ts.map +0 -1
  123. package/dist/src/modules/auth/auth.middleware.d.ts.map +0 -1
  124. package/dist/src/modules/auth/auth.repository.d.ts.map +0 -1
  125. package/dist/src/modules/auth/auth.service.d.ts.map +0 -1
  126. package/dist/src/modules/auth/auth.trpc.d.ts.map +0 -1
  127. package/dist/src/modules/auth/auth.utils.d.ts.map +0 -1
  128. package/dist/src/modules/base/base.abstract.d.ts.map +0 -1
  129. package/dist/src/modules/base/base.dto.d.ts.map +0 -1
  130. package/dist/src/modules/base/base.grants.d.ts.map +0 -1
  131. package/dist/src/modules/base/base.grants.test.d.ts.map +0 -1
  132. package/dist/src/modules/base/base.repository.d.ts.map +0 -1
  133. package/dist/src/modules/base/base.service.d.ts.map +0 -1
  134. package/dist/src/modules/base/base.types.d.ts.map +0 -1
  135. package/dist/src/modules/billing/billing.db.d.ts.map +0 -1
  136. package/dist/src/modules/billing/billing.repository.d.ts.map +0 -1
  137. package/dist/src/modules/billing/billing.router.d.ts.map +0 -1
  138. package/dist/src/modules/billing/billing.service.d.ts.map +0 -1
  139. package/dist/src/modules/billing/billing.trpc.d.ts.map +0 -1
  140. package/dist/src/modules/clay/clay.repository.d.ts.map +0 -1
  141. package/dist/src/modules/clay/clay.service.d.ts.map +0 -1
  142. package/dist/src/modules/connect/connect.db.d.ts.map +0 -1
  143. package/dist/src/modules/connect/connect.dto.d.ts.map +0 -1
  144. package/dist/src/modules/connect/connect.linkedin.d.ts.map +0 -1
  145. package/dist/src/modules/connect/connect.oauth.d.ts.map +0 -1
  146. package/dist/src/modules/connect/connect.repository.d.ts.map +0 -1
  147. package/dist/src/modules/connect/connect.router.d.ts.map +0 -1
  148. package/dist/src/modules/connect/connect.service.d.ts.map +0 -1
  149. package/dist/src/modules/connect/connect.trpc.d.ts.map +0 -1
  150. package/dist/src/modules/connect/connect.types.d.ts.map +0 -1
  151. package/dist/src/modules/crypto/crypto.db.d.ts.map +0 -1
  152. package/dist/src/modules/crypto/crypto.repository.d.ts.map +0 -1
  153. package/dist/src/modules/crypto/crypto.service.d.ts.map +0 -1
  154. package/dist/src/modules/email/email.service.d.ts.map +0 -1
  155. package/dist/src/modules/file/file.repository.d.ts.map +0 -1
  156. package/dist/src/modules/file/file.router.d.ts.map +0 -1
  157. package/dist/src/modules/file/file.service.d.ts.map +0 -1
  158. package/dist/src/modules/recurrence/recurrence.db.d.ts.map +0 -1
  159. package/dist/src/modules/recurrence/recurrence.repository.d.ts.map +0 -1
  160. package/dist/src/modules/recurrence/recurrence.service.d.ts.map +0 -1
  161. package/dist/src/modules/recurrence/recurrence.trpc.d.ts.map +0 -1
  162. package/dist/src/modules/social/social.dto.d.ts.map +0 -1
  163. package/dist/src/modules/social/social.linkedin.d.ts.map +0 -1
  164. package/dist/src/modules/social/social.linkedin.test.d.ts.map +0 -1
  165. package/dist/src/modules/social/social.service.d.ts.map +0 -1
  166. package/dist/src/modules/social/social.types.d.ts.map +0 -1
  167. package/dist/src/modules/tag/tag.db.d.ts.map +0 -1
  168. package/dist/src/modules/tag/tag.dto.d.ts.map +0 -1
  169. package/dist/src/modules/tag/tag.repository.d.ts.map +0 -1
  170. package/dist/src/modules/tag/tag.service.d.ts.map +0 -1
  171. package/dist/src/modules/tag/tag.trpc.d.ts.map +0 -1
  172. package/dist/src/modules/utils/applyPagination.d.ts.map +0 -1
  173. package/dist/src/modules/utils/applySorting.d.ts.map +0 -1
  174. package/dist/src/modules/utils/getConditionsFromFilters.d.ts.map +0 -1
  175. package/dist/src/modules/video/video.service.d.ts.map +0 -1
  176. package/dist/src/modules/webhook/webhook.constants.d.ts.map +0 -1
  177. package/dist/src/modules/webhook/webhook.db.d.ts.map +0 -1
  178. package/dist/src/modules/webhook/webhook.dto.d.ts.map +0 -1
  179. package/dist/src/modules/webhook/webhook.repository.d.ts.map +0 -1
  180. package/dist/src/modules/webhook/webhook.router.d.ts.map +0 -1
  181. package/dist/src/modules/webhook/webhook.service.d.ts.map +0 -1
  182. package/dist/src/modules/workflow/workflow.db.d.ts.map +0 -1
  183. package/dist/src/modules/workflow/workflow.repository.d.ts.map +0 -1
  184. package/dist/src/modules/workflow/workflow.service.d.ts.map +0 -1
  185. package/dist/src/modules/workflow/workflow.trpc.d.ts.map +0 -1
  186. package/dist/src/modules/workflow/workflow.types.d.ts.map +0 -1
  187. package/dist/src/modules/workflow/workflow.utils.d.ts.map +0 -1
  188. package/dist/src/test/stubs/utils.d.ts.map +0 -1
  189. package/dist/src/trpc/context.d.ts.map +0 -1
  190. package/dist/src/trpc/index.d.ts.map +0 -1
  191. package/dist/src/trpc/procedures.d.ts.map +0 -1
  192. package/dist/src/trpc/utils.d.ts.map +0 -1
  193. package/dist/src/types.d.ts.map +0 -1
  194. package/dist/src/utils/errors.d.ts.map +0 -1
  195. package/dist/src/utils/logger.d.ts.map +0 -1
  196. package/dist/src/utils/posthog.d.ts.map +0 -1
  197. package/dist/src/utils/types.d.ts.map +0 -1
  198. package/jest.config.ts +0 -19
  199. package/src/lib/posthog.ts +0 -5
  200. package/src/lib/sentry.ts +0 -8
  201. package/src/modules/access/access.repository.ts +0 -36
  202. package/src/modules/access/access.service.ts +0 -81
  203. package/src/modules/access/access.test.ts +0 -216
  204. package/src/modules/access/access.utils.ts +0 -46
  205. package/src/modules/ai/ai.db.ts +0 -38
  206. package/src/modules/ai/ai.prompt.ts +0 -47
  207. package/src/modules/ai/ai.repository.ts +0 -53
  208. package/src/modules/ai/ai.router.ts +0 -148
  209. package/src/modules/ai/ai.service.ts +0 -310
  210. package/src/modules/ai/ai.trpc.ts +0 -22
  211. package/src/modules/ai/ideogram/ideogram.constants.ts +0 -170
  212. package/src/modules/ai/ideogram/ideogram.dto.ts +0 -64
  213. package/src/modules/ai/ideogram/ideogram.prompt.ts +0 -858
  214. package/src/modules/ai/ideogram/ideogram.repository.ts +0 -39
  215. package/src/modules/ai/ideogram/ideogram.service.ts +0 -14
  216. package/src/modules/auth/auth.db.ts +0 -224
  217. package/src/modules/auth/auth.dto.ts +0 -47
  218. package/src/modules/auth/auth.lib.ts +0 -349
  219. package/src/modules/auth/auth.middleware.ts +0 -62
  220. package/src/modules/auth/auth.repository.ts +0 -672
  221. package/src/modules/auth/auth.service.ts +0 -261
  222. package/src/modules/auth/auth.trpc.ts +0 -208
  223. package/src/modules/auth/auth.utils.ts +0 -117
  224. package/src/modules/base/base.abstract.ts +0 -62
  225. package/src/modules/base/base.dto.ts +0 -206
  226. package/src/modules/base/base.grants.test.ts +0 -861
  227. package/src/modules/base/base.grants.ts +0 -199
  228. package/src/modules/base/base.repository.ts +0 -433
  229. package/src/modules/base/base.service.ts +0 -154
  230. package/src/modules/base/base.types.ts +0 -7
  231. package/src/modules/billing/billing.db.ts +0 -27
  232. package/src/modules/billing/billing.repository.ts +0 -328
  233. package/src/modules/billing/billing.router.ts +0 -77
  234. package/src/modules/billing/billing.service.ts +0 -177
  235. package/src/modules/billing/billing.trpc.ts +0 -17
  236. package/src/modules/clay/clay.repository.ts +0 -29
  237. package/src/modules/clay/clay.service.ts +0 -61
  238. package/src/modules/connect/connect.db.ts +0 -32
  239. package/src/modules/connect/connect.dto.ts +0 -44
  240. package/src/modules/connect/connect.linkedin.ts +0 -70
  241. package/src/modules/connect/connect.oauth.ts +0 -288
  242. package/src/modules/connect/connect.repository.ts +0 -65
  243. package/src/modules/connect/connect.router.ts +0 -76
  244. package/src/modules/connect/connect.service.ts +0 -171
  245. package/src/modules/connect/connect.trpc.ts +0 -26
  246. package/src/modules/connect/connect.types.ts +0 -27
  247. package/src/modules/crypto/crypto.db.ts +0 -15
  248. package/src/modules/crypto/crypto.repository.ts +0 -13
  249. package/src/modules/crypto/crypto.service.ts +0 -57
  250. package/src/modules/email/email.service.ts +0 -222
  251. package/src/modules/file/file.repository.ts +0 -95
  252. package/src/modules/file/file.router.ts +0 -108
  253. package/src/modules/file/file.service.ts +0 -186
  254. package/src/modules/recurrence/recurrence.db.ts +0 -79
  255. package/src/modules/recurrence/recurrence.repository.ts +0 -70
  256. package/src/modules/recurrence/recurrence.service.ts +0 -105
  257. package/src/modules/recurrence/recurrence.trpc.ts +0 -82
  258. package/src/modules/social/social.dto.ts +0 -22
  259. package/src/modules/social/social.linkedin.test.ts +0 -277
  260. package/src/modules/social/social.linkedin.ts +0 -593
  261. package/src/modules/social/social.service.ts +0 -112
  262. package/src/modules/social/social.types.ts +0 -43
  263. package/src/modules/tag/tag.db.ts +0 -41
  264. package/src/modules/tag/tag.dto.ts +0 -18
  265. package/src/modules/tag/tag.repository.ts +0 -222
  266. package/src/modules/tag/tag.service.ts +0 -48
  267. package/src/modules/tag/tag.trpc.ts +0 -62
  268. package/src/modules/uploads/0581796b-8845-420d-bd95-cd7de79f6d37.webm +0 -0
  269. package/src/modules/uploads/33b1e649-6727-4bd0-94d0-a0b363646865.webm +0 -0
  270. package/src/modules/uploads/49a8c4c0-54d7-4c94-bef4-c93c029f9ed0.webm +0 -0
  271. package/src/modules/uploads/50e31e38-a2f0-47ca-8b7d-2d7fcad9267d.webm +0 -0
  272. package/src/modules/uploads/72ac8cf9-c3a7-4cd8-8a78-6d8e137a4c7e.webm +0 -0
  273. package/src/modules/uploads/75293649-d966-46cd-a675-67518958ae9c.png +0 -0
  274. package/src/modules/uploads/88b7b867-ce15-4891-bf73-81305a7de1f7.wav +0 -0
  275. package/src/modules/uploads/a5d6fee8-6a59-42c6-9d4a-ac8a3c5e7245.webm +0 -0
  276. package/src/modules/uploads/c13a9785-ca5a-4983-af30-b338ed76d370.webm +0 -0
  277. package/src/modules/uploads/caa1a5a7-71ba-4381-902d-7e2cafdf6dcb.webm +0 -0
  278. package/src/modules/uploads/cbeb0b81-374d-445b-914b-40ace7c8e031.webm +0 -0
  279. package/src/modules/uploads/d626aa82-b10f-493f-aee7-87bfb3361dfc.webm +0 -0
  280. package/src/modules/uploads/d7de4c16-de0c-495d-9612-e72260a6ecca.png +0 -0
  281. package/src/modules/uploads/e532e38a-6421-400e-8a5f-8e7bc8ce411b.wav +0 -0
  282. package/src/modules/uploads/e86ec867-6adf-4c51-84e0-00b0836625e8.webm +0 -0
  283. package/src/modules/utils/applyPagination.ts +0 -13
  284. package/src/modules/utils/applySorting.ts +0 -21
  285. package/src/modules/utils/getConditionsFromFilters.ts +0 -216
  286. package/src/modules/video/video.service.ts +0 -89
  287. package/src/modules/webhook/webhook.constants.ts +0 -9
  288. package/src/modules/webhook/webhook.db.ts +0 -15
  289. package/src/modules/webhook/webhook.dto.ts +0 -9
  290. package/src/modules/webhook/webhook.repository.ts +0 -68
  291. package/src/modules/webhook/webhook.router.ts +0 -29
  292. package/src/modules/webhook/webhook.service.ts +0 -78
  293. package/src/modules/workflow/workflow.db.ts +0 -29
  294. package/src/modules/workflow/workflow.repository.ts +0 -171
  295. package/src/modules/workflow/workflow.service.ts +0 -56
  296. package/src/modules/workflow/workflow.trpc.ts +0 -26
  297. package/src/modules/workflow/workflow.types.ts +0 -30
  298. package/src/modules/workflow/workflow.utils.ts +0 -259
  299. package/src/test/stubs/utils.ts +0 -2
  300. package/src/trpc/context.ts +0 -21
  301. package/src/trpc/index.ts +0 -3
  302. package/src/trpc/procedures.ts +0 -43
  303. package/src/trpc/utils.ts +0 -20
  304. package/src/types.ts +0 -22
  305. package/src/utils/errors.ts +0 -148
  306. package/src/utils/logger.ts +0 -8
  307. package/src/utils/posthog.ts +0 -43
  308. package/src/utils/types.ts +0 -5
  309. package/tsconfig.json +0 -21
@@ -1,154 +0,0 @@
1
- import type { QueryFilter, QueryInput } from "@m5kdev/commons/modules/schemas/query.schema";
2
- import { err, ok } from "neverthrow";
3
- import type { Session, User } from "#modules/auth/auth.lib";
4
- import { Base } from "#modules/base/base.abstract";
5
- import type { ServerResult, ServerResultAsync } from "#modules/base/base.dto";
6
- import {
7
- checkPermissionAsync,
8
- checkPermissionSync,
9
- type Entity,
10
- type ResourceActionGrant,
11
- type ResourceGrant,
12
- } from "#modules/base/base.grants";
13
- import type { BaseExternaRepository, BaseRepository } from "#modules/base/base.repository";
14
- import type { Context } from "#trpc";
15
- export class BaseService<
16
- Repositories extends Record<string, BaseRepository<any, any, any> | BaseExternaRepository>,
17
- Services extends Record<string, BaseService<any, any>>,
18
- > extends Base {
19
- constructor(
20
- public repository: Repositories = {} as Repositories,
21
- public service: Services = {} as Services
22
- ) {
23
- super("service");
24
- this.repository = repository;
25
- this.service = service;
26
- }
27
-
28
- addUserFilter(
29
- value: string,
30
- query?: QueryInput,
31
- columnId = "userId",
32
- method: QueryFilter["method"] = "equals"
33
- ): QueryInput {
34
- const userFilter: QueryFilter = {
35
- columnId,
36
- type: "string",
37
- method,
38
- value,
39
- };
40
- return query
41
- ? { ...query, filters: [...(query?.filters ?? []), userFilter] }
42
- : { filters: [userFilter] };
43
- }
44
-
45
- addContextFilter(
46
- ctx: Awaited<ReturnType<Context>>,
47
- include: { user?: boolean; organization?: boolean; team?: boolean } = {
48
- user: true,
49
- organization: false,
50
- team: false,
51
- },
52
- query?: QueryInput,
53
- map: Record<string, { columnId: string; method: QueryFilter["method"] }> = {
54
- userId: {
55
- columnId: "userId",
56
- method: "equals",
57
- },
58
- organizationId: {
59
- columnId: "organizationId",
60
- method: "equals",
61
- },
62
- teamId: {
63
- columnId: "teamId",
64
- method: "equals",
65
- },
66
- }
67
- ): QueryInput {
68
- const filters: QueryFilter[] = [];
69
- if (include.user) {
70
- filters.push({
71
- columnId: map.userId.columnId,
72
- type: "string",
73
- method: map.userId.method,
74
- value: ctx.user.id,
75
- });
76
- }
77
- if (include.organization) {
78
- filters.push({
79
- columnId: map.organizationId.columnId,
80
- type: "string",
81
- method: map.organizationId.method,
82
- value: ctx.session.activeOrganizationId ?? "",
83
- });
84
- }
85
- if (include.team) {
86
- filters.push({
87
- columnId: map.teamId.columnId,
88
- type: "string",
89
- method: map.teamId.method,
90
- value: ctx.session.activeTeamId ?? "",
91
- });
92
- }
93
- return query ? { ...query, filters: [...(query?.filters ?? []), ...filters] } : { filters };
94
- }
95
- }
96
-
97
- export class BasePermissionService<
98
- Repositories extends Record<string, BaseRepository<any, any, any> | BaseExternaRepository>,
99
- Services extends Record<string, BaseService<any, any>>,
100
- > extends BaseService<Repositories, Services> {
101
- grants: ResourceGrant[];
102
- constructor(repository: Repositories, service: Services, grants: ResourceGrant[] = []) {
103
- super(repository, service);
104
- this.grants = grants;
105
- }
106
-
107
- accessGuard<T extends Entity>(
108
- ctx: { session: Session; user: User },
109
- action: string,
110
- entities?: T | T[],
111
- grants?: ResourceActionGrant[]
112
- ): ServerResult<true> {
113
- const hasPermission = this.checkPermission(ctx, action, entities, grants);
114
- if (!hasPermission) return this.error("FORBIDDEN");
115
- return ok(true);
116
- }
117
-
118
- async accessGuardAsync<T extends Entity>(
119
- ctx: { session: Session; user: User },
120
- action: string,
121
- getEntities: () => ServerResultAsync<T | T[] | undefined>,
122
- grants?: ResourceActionGrant[]
123
- ): ServerResultAsync<true> {
124
- const hasPermission = await this.checkPermissionAsync(ctx, action, getEntities, grants);
125
- if (hasPermission.isErr()) return err(hasPermission.error);
126
- if (!hasPermission.value) return this.error("FORBIDDEN");
127
- return ok(true);
128
- }
129
-
130
- checkPermission<T extends Entity>(
131
- ctx: { session: Session; user: User },
132
- action: string,
133
- entities?: T | T[],
134
- grants?: ResourceActionGrant[]
135
- ): boolean {
136
- const actionGrants = grants ?? this.grants.filter((grant) => grant.action === action);
137
- return checkPermissionSync(ctx, actionGrants, entities);
138
- }
139
-
140
- async checkPermissionAsync<T extends Entity>(
141
- ctx: { session: Session; user: User },
142
- action: string,
143
- getEntities: () => ServerResultAsync<T | T[] | undefined>,
144
- grants?: ResourceActionGrant[]
145
- ): ServerResultAsync<boolean> {
146
- const actionGrants = grants ?? this.grants.filter((grant) => grant.action === action);
147
- const permission = await checkPermissionAsync(ctx, actionGrants, getEntities);
148
- if (permission.isErr())
149
- return this.error("INTERNAL_SERVER_ERROR", "Failed to check permission", {
150
- cause: permission.error,
151
- });
152
- return ok(permission.value);
153
- }
154
- }
@@ -1,7 +0,0 @@
1
- export type ServerErrorLayer =
2
- | "unknown"
3
- | "repository"
4
- | "service"
5
- | "controller"
6
- | "auth"
7
- | "workflow";
@@ -1,27 +0,0 @@
1
- import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
2
- import { v4 as uuidv4 } from "uuid";
3
-
4
- export const subscriptions = sqliteTable("subscriptions", {
5
- id: text("id").primaryKey().$default(uuidv4),
6
- createdAt: integer("created_at", { mode: "timestamp" })
7
- .notNull()
8
- .$default(() => new Date()),
9
- updatedAt: integer("updated_at", { mode: "timestamp" }),
10
- plan: text("plan").notNull(),
11
- referenceId: text("reference_id").notNull(),
12
- stripeCustomerId: text("stripe_customer_id"),
13
- stripeSubscriptionId: text("stripe_subscription_id"),
14
- status: text("status").notNull(),
15
- periodStart: integer("period_start", { mode: "timestamp" }),
16
- periodEnd: integer("period_end", { mode: "timestamp" }),
17
- priceId: text("price_id"),
18
- interval: text("interval"),
19
- unitAmount: integer("unit_amount", { mode: "number" }),
20
- discounts: text("discounts", { mode: "json" }).$type<string[]>(),
21
- cancelAtPeriodEnd: integer("cancel_at_period_end", { mode: "boolean" }),
22
- cancelAt: integer("cancel_at", { mode: "timestamp" }),
23
- canceledAt: integer("canceled_at", { mode: "timestamp" }),
24
- seats: integer("seats", { mode: "number" }),
25
- trialStart: integer("trial_start", { mode: "timestamp" }),
26
- trialEnd: integer("trial_end", { mode: "timestamp" }),
27
- });
@@ -1,328 +0,0 @@
1
- import type { BillingSchema } from "@m5kdev/commons/modules/billing/billing.schema";
2
- import type { StripePlan } from "@m5kdev/commons/modules/billing/billing.types";
3
- import { and, desc, eq, type InferSelectModel, inArray } from "drizzle-orm";
4
- import type { LibSQLDatabase } from "drizzle-orm/libsql";
5
- import { err, ok } from "neverthrow";
6
- import type { Stripe } from "stripe";
7
- import * as auth from "#modules/auth/auth.db";
8
- import type { ServerResult, ServerResultAsync } from "#modules/base/base.dto";
9
- import { BaseTableRepository } from "#modules/base/base.repository";
10
- import * as billing from "#modules/billing/billing.db";
11
- import { posthogCapture } from "#utils/posthog";
12
-
13
- const schema = { ...auth, ...billing };
14
- type Schema = typeof schema;
15
- type Orm = LibSQLDatabase<Schema>;
16
-
17
- export class BillingRepository extends BaseTableRepository<
18
- Orm,
19
- Schema,
20
- Record<string, never>,
21
- Schema["subscriptions"]
22
- > {
23
- public stripe: Stripe;
24
- public plans: StripePlan[];
25
- public trial?: StripePlan;
26
-
27
- constructor(options: {
28
- orm: Orm;
29
- schema: Schema;
30
- table: Schema["subscriptions"];
31
- libs: { stripe: Stripe };
32
- config: {
33
- trial?: StripePlan;
34
- plans: StripePlan[];
35
- };
36
- }) {
37
- const { libs, config, ...rest } = options;
38
- super(rest);
39
- this.stripe = libs.stripe;
40
- this.plans = config.plans;
41
- this.trial = config.trial;
42
- }
43
- hasTrial(): boolean {
44
- return !!this.trial;
45
- }
46
-
47
- getPlanByPriceId(priceId: string): StripePlan | undefined {
48
- return this.plans.find(
49
- (plan) => plan.priceId === priceId || plan.annualDiscountPriceId === priceId
50
- );
51
- }
52
-
53
- getCustomerByEmail(email: string): ServerResultAsync<Stripe.Customer | null> {
54
- return this.throwableAsync(async () => {
55
- const customers = await this.stripe.customers.list({
56
- email,
57
- limit: 1,
58
- });
59
- return ok(customers.data[0] ?? null);
60
- });
61
- }
62
-
63
- getUserByCustomerId(
64
- customerId: string
65
- ): ServerResultAsync<InferSelectModel<Schema["users"]> | null> {
66
- return this.throwableAsync(async () => {
67
- const [user] = await this.orm
68
- .select()
69
- .from(this.schema.users)
70
- .where(eq(this.schema.users.stripeCustomerId, customerId))
71
- .limit(1);
72
- return ok(user ?? null);
73
- });
74
- }
75
-
76
- createCustomer({
77
- email,
78
- name,
79
- userId,
80
- }: {
81
- email: string;
82
- name?: string;
83
- userId: string;
84
- }): ServerResultAsync<Stripe.Customer> {
85
- return this.throwableAsync(async () => {
86
- const customer = await this.stripe.customers.create({
87
- email,
88
- name,
89
- metadata: {
90
- userId,
91
- },
92
- });
93
- return ok(customer);
94
- });
95
- }
96
-
97
- async createTrialSubscription(customerId: string): ServerResultAsync<Stripe.Subscription> {
98
- if (!this.trial) return this.error("NOT_FOUND", "Trial plan not found");
99
- const stripeSubscription = await this.createSubscription({
100
- customerId,
101
- priceId: this.trial.priceId,
102
- trialDays: this.trial.freeTrial?.days ?? 7,
103
- });
104
- if (stripeSubscription.isErr()) return err(stripeSubscription.error);
105
- if (!stripeSubscription.value)
106
- return this.error("INTERNAL_SERVER_ERROR", "Failed to create trial subscription");
107
- return ok(stripeSubscription.value);
108
- }
109
-
110
- createSubscription({
111
- customerId,
112
- priceId,
113
- quantity = 1,
114
- trialDays,
115
- }: {
116
- customerId: string;
117
- priceId: string;
118
- quantity?: number;
119
- trialDays?: number;
120
- }): ServerResultAsync<Stripe.Subscription> {
121
- return this.throwableAsync(async () => {
122
- const stripeSubscription = await this.stripe.subscriptions.create({
123
- customer: customerId,
124
- items: [{ price: priceId, quantity }], // quantity = seats if you want
125
- ...(trialDays
126
- ? {
127
- trial_period_days: trialDays,
128
- trial_settings: {
129
- end_behavior: {
130
- missing_payment_method: "cancel",
131
- },
132
- },
133
- }
134
- : {}),
135
- });
136
- return ok(stripeSubscription);
137
- });
138
- }
139
-
140
- updateUserCustomerId({
141
- userId,
142
- customerId,
143
- }: {
144
- userId: string;
145
- customerId: string;
146
- }): ServerResultAsync<InferSelectModel<Schema["users"]>> {
147
- return this.throwableAsync(async () => {
148
- const [user] = await this.orm
149
- .update(this.schema.users)
150
- .set({ stripeCustomerId: customerId })
151
- .where(eq(this.schema.users.id, userId))
152
- .returning();
153
- if (!user) return this.error("NOT_FOUND", "User not found");
154
- return ok(user);
155
- });
156
- }
157
-
158
- getLatestSubscription(referenceId: string): ServerResultAsync<BillingSchema | null> {
159
- return this.throwableAsync(async () => {
160
- const subscriptions = await this.orm
161
- .select()
162
- .from(this.schema.subscriptions)
163
- .where(eq(this.schema.subscriptions.referenceId, referenceId))
164
- .orderBy(desc(this.schema.subscriptions.createdAt))
165
- .limit(1);
166
-
167
- return ok(subscriptions[0] ?? null);
168
- });
169
- }
170
-
171
- getActiveSubscription(referenceId: string): ServerResultAsync<BillingSchema | null> {
172
- return this.throwableAsync(async () => {
173
- const [subscription] = await this.orm
174
- .select()
175
- .from(this.schema.subscriptions)
176
- .where(
177
- and(
178
- eq(this.schema.subscriptions.referenceId, referenceId),
179
- inArray(this.schema.subscriptions.status, ["active", "trialing"])
180
- )
181
- )
182
- .orderBy(desc(this.schema.subscriptions.createdAt))
183
- .limit(1);
184
-
185
- return ok(subscription ?? null);
186
- });
187
- }
188
-
189
- listInvoices(customerId: string): ServerResultAsync<Stripe.Invoice[]> {
190
- return this.throwableAsync(async () => {
191
- const invoices = await this.stripe.invoices.list({
192
- customer: customerId,
193
- });
194
- return ok(invoices.data);
195
- });
196
- }
197
-
198
- createCheckoutSession({
199
- customerId,
200
- priceId,
201
- userId,
202
- }: {
203
- customerId: string;
204
- priceId: string;
205
- userId: string;
206
- }): ServerResultAsync<Stripe.Checkout.Session> {
207
- return this.throwableAsync(async () => {
208
- const session = await this.stripe.checkout.sessions.create({
209
- client_reference_id: userId,
210
- customer: customerId,
211
- success_url: `${process.env.VITE_SERVER_URL}/stripe/success`,
212
- cancel_url: `${process.env.VITE_APP_URL}/billing`,
213
- mode: "subscription",
214
- line_items: [
215
- {
216
- price: priceId,
217
- quantity: 1,
218
- },
219
- ],
220
- });
221
- return ok(session);
222
- });
223
- }
224
-
225
- createBillingPortalSession(customerId: string): ServerResultAsync<Stripe.BillingPortal.Session> {
226
- return this.throwableAsync(async () => {
227
- const session = await this.stripe.billingPortal.sessions.create({
228
- customer: customerId,
229
- return_url: `${process.env.VITE_SERVER_URL}/stripe/success`,
230
- });
231
- return ok(session);
232
- });
233
- }
234
-
235
- async syncStripeData({
236
- customerId,
237
- userId,
238
- }: {
239
- customerId: string;
240
- userId: string;
241
- }): ServerResultAsync<boolean> {
242
- return this.throwableAsync(async () => {
243
- // Fetch latest subscription data from Stripe
244
-
245
- const stripeSubscriptions = await this.stripe.subscriptions.list({
246
- customer: customerId,
247
- limit: 1,
248
- status: "all",
249
- expand: ["data.default_payment_method"],
250
- });
251
- const [stripeSubscription] = stripeSubscriptions.data;
252
- if (!stripeSubscription) return this.error("NOT_FOUND", "Subscription not found");
253
-
254
- const plan = this.getPlanByPriceId(stripeSubscription.items.data[0]?.price.id!);
255
- if (!plan)
256
- return this.error(
257
- "NOT_FOUND",
258
- `Plan not found for price ID: ${stripeSubscription.items.data[0]?.price.id}`
259
- );
260
-
261
- const values = {
262
- stripeCustomerId: customerId,
263
- referenceId: userId,
264
- plan: plan.name,
265
- status: stripeSubscription.status,
266
- seats: stripeSubscription.items.data[0]?.quantity || 1,
267
- periodEnd: new Date(stripeSubscription.items.data[0]?.current_period_end! * 1000),
268
- periodStart: new Date(stripeSubscription.items.data[0]?.current_period_start! * 1000),
269
- priceId: stripeSubscription.items.data[0]?.price.id!,
270
- interval: stripeSubscription.items.data[0]?.price.recurring?.interval,
271
- unitAmount: stripeSubscription.items.data[0]?.price.unit_amount,
272
- discounts: stripeSubscription.discounts.map((discount) =>
273
- typeof discount === "string" ? discount : discount.id
274
- ),
275
- stripeSubscriptionId: stripeSubscription.id,
276
- cancelAtPeriodEnd: stripeSubscription.cancel_at_period_end,
277
- cancelAt: stripeSubscription.cancel_at
278
- ? new Date(stripeSubscription.cancel_at * 1000)
279
- : null,
280
- canceledAt: stripeSubscription.canceled_at
281
- ? new Date(stripeSubscription.canceled_at * 1000)
282
- : null,
283
- ...(stripeSubscription.trial_start && stripeSubscription.trial_end
284
- ? {
285
- trialStart: new Date(stripeSubscription.trial_start * 1000),
286
- trialEnd: new Date(stripeSubscription.trial_end * 1000),
287
- }
288
- : {}),
289
- };
290
-
291
- const existingSubscription = await this.getActiveSubscription(userId);
292
- if (existingSubscription.isErr()) return err(existingSubscription.error);
293
-
294
- if (!existingSubscription.value) {
295
- await this.orm.insert(this.schema.subscriptions).values(values);
296
- posthogCapture({
297
- distinctId: userId,
298
- event: "stripe.subscription_created",
299
- properties: values,
300
- });
301
- return ok(true);
302
- }
303
-
304
- await this.orm
305
- .update(this.schema.subscriptions)
306
- .set({ ...values, updatedAt: new Date() })
307
- .where(eq(this.schema.subscriptions.id, existingSubscription.value.id));
308
- posthogCapture({
309
- distinctId: userId,
310
- event: "stripe.subscription_updated",
311
- properties: values,
312
- });
313
-
314
- return ok(false);
315
- });
316
- }
317
-
318
- constructEvent(
319
- body: Buffer | string,
320
- signature: string,
321
- secret: string
322
- ): ServerResult<Stripe.Event> {
323
- return this.throwable(() => {
324
- const event = this.stripe.webhooks.constructEvent(body, signature, secret);
325
- return ok(event);
326
- });
327
- }
328
- }
@@ -1,77 +0,0 @@
1
- import bodyParser from "body-parser";
2
- import { Router } from "express";
3
- import type { AuthMiddleware, AuthRequest } from "#modules/auth/auth.middleware";
4
- import type { BillingService } from "#modules/billing/billing.service";
5
-
6
- export function createBillingRouter(
7
- authMiddleware: AuthMiddleware,
8
- service: BillingService
9
- ): Router {
10
- const billingRouter = Router();
11
-
12
- billingRouter.get("/checkout/:priceId", authMiddleware, async (req: AuthRequest, res) => {
13
- const user = req.user!;
14
-
15
- const session = await service.createCheckoutSession({ priceId: req.params.priceId }, { user });
16
- if (session.isErr()) {
17
- return res.status(500).json({ message: session.error.message });
18
- }
19
-
20
- if (!session.value.url) {
21
- return res.status(500).json({ message: "Failed to create checkout session" });
22
- }
23
-
24
- return res.redirect(session.value.url);
25
- });
26
-
27
- billingRouter.get("/portal", authMiddleware, async (req: AuthRequest, res) => {
28
- const user = req.user!;
29
-
30
- const session = await service.createBillingPortalSession({ user });
31
-
32
- if (session.isErr()) {
33
- return res.status(500).json({ message: session.error.message });
34
- }
35
-
36
- return res.redirect(session.value.url);
37
- });
38
-
39
- billingRouter.get("/success", authMiddleware, async (req: AuthRequest, res) => {
40
- const user = req.user!;
41
-
42
- if (!user.stripeCustomerId) {
43
- return res.redirect(`${process.env.VITE_APP_URL}/billing`);
44
- }
45
-
46
- const result = await service.syncStripeData(user.stripeCustomerId);
47
-
48
- if (result.isErr()) {
49
- return res.redirect(`${process.env.VITE_APP_URL}/billing?error=SYNC_FAILED`);
50
- }
51
-
52
- return res.redirect(`${process.env.VITE_APP_URL}/billing`);
53
- });
54
-
55
- billingRouter.post("/webhook", bodyParser.raw({ type: "application/json" }), async (req, res) => {
56
- const signature = req.headers["stripe-signature"];
57
-
58
- if (!signature) return res.status(400).json({ message: "No signature" });
59
-
60
- if (typeof signature !== "string")
61
- return res.status(500).json({ message: "Signature is not a string" });
62
-
63
- const event = service.constructEvent(req.body, signature);
64
- if (event.isErr()) {
65
- return res.status(500).json({ message: event.error.message });
66
- }
67
-
68
- const result = await service.processEvent(event.value);
69
- if (result.isErr()) {
70
- return res.status(500).json({ message: result.error.message });
71
- }
72
-
73
- return res.status(200).json({ received: true });
74
- });
75
-
76
- return billingRouter;
77
- }