@c15t/backend 2.0.0-rc.0 → 2.0.0-rc.10

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 (336) hide show
  1. package/README.md +3 -3
  2. package/dist/302.js +473 -0
  3. package/dist/583.js +540 -0
  4. package/dist/915.js +1771 -0
  5. package/dist/cache.cjs +5 -5
  6. package/dist/cache.js +4 -415
  7. package/dist/core.cjs +1356 -120
  8. package/dist/core.js +163 -1981
  9. package/dist/db/adapters/drizzle.cjs +1 -1
  10. package/dist/db/adapters/drizzle.js +1 -2
  11. package/dist/db/adapters/kysely.cjs +1 -1
  12. package/dist/db/adapters/kysely.js +1 -2
  13. package/dist/db/adapters/mongo.cjs +1 -1
  14. package/dist/db/adapters/mongo.js +1 -2
  15. package/dist/db/adapters/prisma.cjs +1 -1
  16. package/dist/db/adapters/prisma.js +1 -2
  17. package/dist/db/adapters/typeorm.cjs +1 -1
  18. package/dist/db/adapters/typeorm.js +1 -2
  19. package/dist/db/adapters.cjs +1 -1
  20. package/dist/db/migrator.cjs +1 -1
  21. package/dist/db/schema.cjs +43 -3
  22. package/dist/db/schema.js +35 -4
  23. package/dist/define-config.cjs +1 -1
  24. package/dist/edge.cjs +1106 -0
  25. package/dist/edge.js +190 -0
  26. package/dist/router.cjs +885 -123
  27. package/dist/router.js +1 -1507
  28. package/dist/{types.cjs → types/index.cjs} +1 -1
  29. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  30. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  31. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  32. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  33. package/{dist → dist-types}/cache/gvl-resolver.d.ts +0 -1
  34. package/{dist → dist-types}/cache/index.d.ts +0 -1
  35. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  36. package/{dist → dist-types}/cache/types.d.ts +0 -1
  37. package/{dist → dist-types}/core.d.ts +8 -1
  38. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  39. package/dist-types/db/registry/consent-policy.d.ts +78 -0
  40. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  41. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  42. package/dist-types/db/registry/index.d.ts +118 -0
  43. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  44. package/{dist → dist-types}/db/registry/subject.d.ts +0 -2
  45. package/{dist → dist-types}/db/registry/types.d.ts +1 -1
  46. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  47. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  48. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  49. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  50. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  51. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  52. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  53. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  54. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -32
  55. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -2
  56. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  57. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +3 -3
  58. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  59. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +7 -2
  60. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  61. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +455 -28
  62. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  63. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -3
  64. package/{dist → dist-types}/db/schema/index.d.ts +908 -86
  65. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  66. package/dist-types/define-config.d.ts +17 -0
  67. package/dist-types/edge/index.d.ts +5 -0
  68. package/dist-types/edge/init-handler.d.ts +40 -0
  69. package/dist-types/edge/resolve-consent.d.ts +80 -0
  70. package/dist-types/edge/types.d.ts +13 -0
  71. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  72. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  73. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  74. package/{dist → dist-types}/handlers/init/index.d.ts +2 -3
  75. package/dist-types/handlers/init/policy.d.ts +26 -0
  76. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  77. package/dist-types/handlers/init/translations.d.ts +48 -0
  78. package/dist-types/handlers/legal-document/current.handler.d.ts +11 -0
  79. package/dist-types/handlers/legal-document/snapshot.d.ts +39 -0
  80. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  81. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  82. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  83. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +3 -2
  84. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  85. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +3 -2
  86. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -2
  87. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  88. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +3 -1
  89. package/{dist → dist-types}/init.d.ts +4 -7
  90. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  91. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  92. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  93. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  94. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +0 -1
  95. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  96. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  97. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  98. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  99. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  100. package/dist-types/policies/builder.d.ts +127 -0
  101. package/dist-types/policies/defaults.d.ts +2 -0
  102. package/dist-types/policies/matchers.d.ts +3 -0
  103. package/{dist → dist-types}/router.d.ts +0 -1
  104. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  105. package/{dist → dist-types}/routes/index.d.ts +1 -1
  106. package/{dist → dist-types}/routes/init.d.ts +0 -1
  107. package/dist-types/routes/legal-document.d.ts +7 -0
  108. package/{dist → dist-types}/routes/status.d.ts +0 -1
  109. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  110. package/{dist → dist-types}/types/api.d.ts +0 -1
  111. package/dist-types/types/index.d.ts +464 -0
  112. package/dist-types/utils/background.d.ts +6 -0
  113. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  114. package/{dist → dist-types}/utils/env.d.ts +0 -1
  115. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  116. package/{dist → dist-types}/utils/instrumentation.d.ts +2 -3
  117. package/{dist → dist-types}/utils/logger.d.ts +0 -1
  118. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  119. package/dist-types/version.d.ts +1 -0
  120. package/docs/README.md +49 -0
  121. package/docs/api/configuration.md +208 -0
  122. package/docs/api/endpoints.md +211 -0
  123. package/docs/guides/caching.md +85 -0
  124. package/docs/guides/database-setup.md +128 -0
  125. package/docs/guides/edge-deployment.md +251 -0
  126. package/docs/guides/framework-integration.md +142 -0
  127. package/docs/guides/iab-tcf.md +89 -0
  128. package/docs/guides/observability.md +96 -0
  129. package/docs/guides/policy-packs.md +396 -0
  130. package/docs/quickstart.md +129 -0
  131. package/package.json +53 -39
  132. package/.turbo/turbo-build.log +0 -49
  133. package/CHANGELOG.md +0 -89
  134. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  135. package/dist/cache/adapters/index.d.ts.map +0 -1
  136. package/dist/cache/adapters/memory.d.ts.map +0 -1
  137. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  138. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  139. package/dist/cache/index.d.ts.map +0 -1
  140. package/dist/cache/keys.d.ts.map +0 -1
  141. package/dist/cache/types.d.ts.map +0 -1
  142. package/dist/core.d.ts.map +0 -1
  143. package/dist/db/adapters/drizzle.d.ts +0 -2
  144. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  145. package/dist/db/adapters/index.d.ts +0 -2
  146. package/dist/db/adapters/index.d.ts.map +0 -1
  147. package/dist/db/adapters/kysely.d.ts +0 -2
  148. package/dist/db/adapters/kysely.d.ts.map +0 -1
  149. package/dist/db/adapters/mongo.d.ts +0 -2
  150. package/dist/db/adapters/mongo.d.ts.map +0 -1
  151. package/dist/db/adapters/prisma.d.ts +0 -2
  152. package/dist/db/adapters/prisma.d.ts.map +0 -1
  153. package/dist/db/adapters/typeorm.d.ts +0 -2
  154. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  155. package/dist/db/migrator/index.d.ts.map +0 -1
  156. package/dist/db/registry/consent-policy.d.ts +0 -23
  157. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  158. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  159. package/dist/db/registry/domain.d.ts.map +0 -1
  160. package/dist/db/registry/index.d.ts +0 -57
  161. package/dist/db/registry/index.d.ts.map +0 -1
  162. package/dist/db/registry/subject.d.ts.map +0 -1
  163. package/dist/db/registry/types.d.ts.map +0 -1
  164. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  165. package/dist/db/registry/utils.d.ts.map +0 -1
  166. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  167. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  168. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  169. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  170. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  171. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  172. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  173. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  174. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  175. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  176. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  177. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  178. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  179. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  180. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  181. package/dist/db/schema/index.d.ts.map +0 -1
  182. package/dist/db/tenant-scope.d.ts.map +0 -1
  183. package/dist/define-config.d.ts +0 -5
  184. package/dist/define-config.d.ts.map +0 -1
  185. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  186. package/dist/handlers/consent/index.d.ts +0 -12
  187. package/dist/handlers/consent/index.d.ts.map +0 -1
  188. package/dist/handlers/init/geo.d.ts.map +0 -1
  189. package/dist/handlers/init/index.d.ts.map +0 -1
  190. package/dist/handlers/init/translations.d.ts +0 -28
  191. package/dist/handlers/init/translations.d.ts.map +0 -1
  192. package/dist/handlers/status/index.d.ts +0 -7
  193. package/dist/handlers/status/index.d.ts.map +0 -1
  194. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  195. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  196. package/dist/handlers/subject/index.d.ts +0 -10
  197. package/dist/handlers/subject/index.d.ts.map +0 -1
  198. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  199. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  200. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  201. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  202. package/dist/init.d.ts.map +0 -1
  203. package/dist/middleware/auth/index.d.ts.map +0 -1
  204. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  205. package/dist/middleware/cors/cors.d.ts.map +0 -1
  206. package/dist/middleware/cors/index.d.ts +0 -30
  207. package/dist/middleware/cors/index.d.ts.map +0 -1
  208. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  209. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  210. package/dist/middleware/openapi/config.d.ts.map +0 -1
  211. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  212. package/dist/middleware/openapi/index.d.ts +0 -12
  213. package/dist/middleware/openapi/index.d.ts.map +0 -1
  214. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  215. package/dist/router.d.ts.map +0 -1
  216. package/dist/routes/consent.d.ts.map +0 -1
  217. package/dist/routes/index.d.ts.map +0 -1
  218. package/dist/routes/init.d.ts.map +0 -1
  219. package/dist/routes/status.d.ts.map +0 -1
  220. package/dist/routes/subject.d.ts.map +0 -1
  221. package/dist/types/api.d.ts.map +0 -1
  222. package/dist/types/index.d.ts +0 -255
  223. package/dist/types/index.d.ts.map +0 -1
  224. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  225. package/dist/utils/env.d.ts.map +0 -1
  226. package/dist/utils/extract-error-message.d.ts.map +0 -1
  227. package/dist/utils/index.d.ts +0 -4
  228. package/dist/utils/index.d.ts.map +0 -1
  229. package/dist/utils/instrumentation.d.ts.map +0 -1
  230. package/dist/utils/logger.d.ts.map +0 -1
  231. package/dist/utils/metrics.d.ts.map +0 -1
  232. package/dist/version.d.ts +0 -2
  233. package/dist/version.d.ts.map +0 -1
  234. package/knip.json +0 -31
  235. package/rslib.config.ts +0 -93
  236. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  237. package/src/cache/adapters/index.ts +0 -22
  238. package/src/cache/adapters/memory.ts +0 -111
  239. package/src/cache/adapters/upstash-redis.ts +0 -113
  240. package/src/cache/gvl-resolver.ts +0 -289
  241. package/src/cache/index.ts +0 -34
  242. package/src/cache/keys.ts +0 -68
  243. package/src/cache/types.ts +0 -66
  244. package/src/core.ts +0 -368
  245. package/src/db/migrator/index.ts +0 -80
  246. package/src/db/registry/consent-policy.test.ts +0 -451
  247. package/src/db/registry/consent-policy.ts +0 -82
  248. package/src/db/registry/consent-purpose.test.ts +0 -428
  249. package/src/db/registry/consent-purpose.ts +0 -61
  250. package/src/db/registry/domain.test.ts +0 -445
  251. package/src/db/registry/domain.ts +0 -91
  252. package/src/db/registry/index.ts +0 -14
  253. package/src/db/registry/subject.test.ts +0 -388
  254. package/src/db/registry/subject.ts +0 -129
  255. package/src/db/registry/types.ts +0 -10
  256. package/src/db/registry/utils/generate-id.test.ts +0 -216
  257. package/src/db/registry/utils/generate-id.ts +0 -133
  258. package/src/db/registry/utils.ts +0 -133
  259. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  260. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  261. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  262. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  263. package/src/db/schema/1.0.0/consent.ts +0 -20
  264. package/src/db/schema/1.0.0/domain.ts +0 -12
  265. package/src/db/schema/1.0.0/index.ts +0 -48
  266. package/src/db/schema/1.0.0/subject.ts +0 -12
  267. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  268. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  269. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  270. package/src/db/schema/2.0.0/consent.ts +0 -26
  271. package/src/db/schema/2.0.0/domain.ts +0 -12
  272. package/src/db/schema/2.0.0/index.ts +0 -47
  273. package/src/db/schema/2.0.0/subject.ts +0 -14
  274. package/src/db/schema/index.ts +0 -15
  275. package/src/db/tenant-scope.test.ts +0 -750
  276. package/src/db/tenant-scope.ts +0 -103
  277. package/src/define-config.ts +0 -5
  278. package/src/handlers/consent/check.handler.ts +0 -126
  279. package/src/handlers/init/geo.test.ts +0 -317
  280. package/src/handlers/init/geo.ts +0 -195
  281. package/src/handlers/init/index.test.ts +0 -205
  282. package/src/handlers/init/index.ts +0 -114
  283. package/src/handlers/init/translations.test.ts +0 -121
  284. package/src/handlers/init/translations.ts +0 -72
  285. package/src/handlers/status/status.handler.test.ts +0 -155
  286. package/src/handlers/status/status.handler.ts +0 -51
  287. package/src/handlers/subject/get.handler.ts +0 -93
  288. package/src/handlers/subject/list.handler.ts +0 -93
  289. package/src/handlers/subject/patch.handler.ts +0 -122
  290. package/src/handlers/subject/post.handler.test.ts +0 -294
  291. package/src/handlers/subject/post.handler.ts +0 -254
  292. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  293. package/src/handlers/utils/consent-enrichment.ts +0 -218
  294. package/src/init.test.ts +0 -126
  295. package/src/init.ts +0 -87
  296. package/src/middleware/auth/index.ts +0 -11
  297. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  298. package/src/middleware/auth/validate-api-key.ts +0 -107
  299. package/src/middleware/cors/cors.test.ts +0 -135
  300. package/src/middleware/cors/cors.ts +0 -186
  301. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  302. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  303. package/src/middleware/cors/process-cors.ts +0 -91
  304. package/src/middleware/openapi/config.ts +0 -29
  305. package/src/middleware/openapi/handlers.ts +0 -34
  306. package/src/middleware/process-ip/index.test.ts +0 -195
  307. package/src/middleware/process-ip/index.ts +0 -199
  308. package/src/router.ts +0 -15
  309. package/src/routes/consent.ts +0 -52
  310. package/src/routes/index.ts +0 -10
  311. package/src/routes/init.ts +0 -102
  312. package/src/routes/status.ts +0 -46
  313. package/src/routes/subject.ts +0 -152
  314. package/src/types/api.ts +0 -48
  315. package/src/types/index.ts +0 -288
  316. package/src/utils/create-telemetry-options.test.ts +0 -302
  317. package/src/utils/create-telemetry-options.ts +0 -229
  318. package/src/utils/env.ts +0 -84
  319. package/src/utils/extract-error-message.ts +0 -21
  320. package/src/utils/instrumentation.test.ts +0 -185
  321. package/src/utils/instrumentation.ts +0 -196
  322. package/src/utils/logger.ts +0 -41
  323. package/src/utils/metrics.test.ts +0 -323
  324. package/src/utils/metrics.ts +0 -402
  325. package/src/utils/telemetry-pii.test.ts +0 -325
  326. package/src/version.ts +0 -2
  327. package/tsconfig.json +0 -11
  328. package/vitest.config.ts +0 -28
  329. /package/dist/{types.js → types/index.js} +0 -0
  330. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  331. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  332. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  333. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  334. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  335. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  336. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
@@ -1,216 +0,0 @@
1
- import { randomBytes } from 'node:crypto';
2
- import type { InferFumaDB } from 'fumadb';
3
- import { afterEach, describe, expect, it, vi } from 'vitest';
4
- import type { LatestDB } from '~/db/schema';
5
- import { generateUniqueId } from './generate-id';
6
-
7
- type MockDB = ReturnType<InferFumaDB<typeof LatestDB>['orm']>;
8
-
9
- // Define regex patterns at the top level for performance
10
- const SUBJECT_ID_PATTERN = /^sub_[A-Za-z0-9]+$/;
11
- const CONSENT_ID_PATTERN = /^cns_[A-Za-z0-9]+$/;
12
- const DOMAIN_ID_PATTERN = /^dom_[A-Za-z0-9]+$/;
13
-
14
- describe('generateUniqueId', () => {
15
- afterEach(() => {
16
- vi.clearAllMocks();
17
- });
18
-
19
- // Ensure crypto.getRandomValues exists in Node/Vitest environments
20
- // that may not provide a Web Crypto global by default.
21
- if (
22
- !(globalThis as { crypto?: { getRandomValues?: unknown } }).crypto
23
- ?.getRandomValues
24
- ) {
25
- (
26
- globalThis as {
27
- crypto: { getRandomValues: (a: Uint8Array) => Uint8Array };
28
- }
29
- ).crypto = {
30
- getRandomValues: (array: Uint8Array) => {
31
- const bytes = randomBytes(array.length);
32
- array.set(bytes);
33
- return array;
34
- },
35
- };
36
- }
37
-
38
- it('should return unique ID on first attempt when no collision exists', async () => {
39
- const mockDb = {
40
- findFirst: vi.fn().mockResolvedValue(null), // No existing record found
41
- } as unknown as MockDB;
42
-
43
- const result = await generateUniqueId(mockDb, 'subject');
44
-
45
- expect(mockDb.findFirst).toHaveBeenCalledTimes(1);
46
- expect(mockDb.findFirst).toHaveBeenCalledWith('subject', {
47
- where: expect.any(Function),
48
- });
49
- expect(result).toMatch(SUBJECT_ID_PATTERN); // Should have 'sub_' prefix
50
- expect(result.length).toBeGreaterThan(4); // Should be longer than just prefix
51
- });
52
-
53
- it('should retry when ID collision occurs and return unique ID on second attempt', async () => {
54
- const mockExistingRecord = { id: 'mock_existing' };
55
- const mockDb = {
56
- findFirst: vi
57
- .fn()
58
- .mockResolvedValueOnce(mockExistingRecord) // First call returns existing record
59
- .mockResolvedValueOnce(null), // Second call returns null (unique)
60
- } as unknown as MockDB;
61
-
62
- const result = await generateUniqueId(mockDb, 'consent');
63
-
64
- expect(mockDb.findFirst).toHaveBeenCalledTimes(2);
65
- expect(result).toMatch(CONSENT_ID_PATTERN); // Should have 'cns_' prefix
66
- });
67
-
68
- it('should handle multiple collisions before finding unique ID', async () => {
69
- const mockExistingRecord = { id: 'mock_existing' };
70
- const mockDb = {
71
- findFirst: vi
72
- .fn()
73
- .mockResolvedValueOnce(mockExistingRecord) // First collision
74
- .mockResolvedValueOnce(mockExistingRecord) // Second collision
75
- .mockResolvedValueOnce(mockExistingRecord) // Third collision
76
- .mockResolvedValueOnce(null), // Finally unique
77
- } as unknown as MockDB;
78
-
79
- const result = await generateUniqueId(mockDb, 'domain');
80
-
81
- expect(mockDb.findFirst).toHaveBeenCalledTimes(4);
82
- expect(result).toMatch(DOMAIN_ID_PATTERN); // Should have 'dom_' prefix
83
- });
84
-
85
- it('should work with different model types and use correct prefixes', async () => {
86
- const mockDb = {
87
- findFirst: vi.fn().mockResolvedValue(null),
88
- } as unknown as MockDB;
89
-
90
- const testCases = [
91
- { model: 'auditLog' as const, expectedPrefix: 'log_' },
92
- { model: 'consent' as const, expectedPrefix: 'cns_' },
93
- { model: 'consentPolicy' as const, expectedPrefix: 'pol_' },
94
- { model: 'consentPurpose' as const, expectedPrefix: 'pur_' },
95
- { model: 'domain' as const, expectedPrefix: 'dom_' },
96
- { model: 'subject' as const, expectedPrefix: 'sub_' },
97
- ];
98
-
99
- for (const { model, expectedPrefix } of testCases) {
100
- const result = await generateUniqueId(mockDb, model);
101
- expect(result).toMatch(
102
- new RegExp(
103
- `^${expectedPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[A-Za-z0-9]+$`
104
- )
105
- );
106
- }
107
-
108
- expect(mockDb.findFirst).toHaveBeenCalledTimes(testCases.length);
109
- });
110
-
111
- it('should call findFirst with correct where clause function', async () => {
112
- const mockDb = {
113
- findFirst: vi.fn().mockResolvedValue(null),
114
- } as unknown as MockDB;
115
-
116
- await generateUniqueId(mockDb, 'subject');
117
-
118
- const mockFindFirst = vi.mocked(mockDb.findFirst);
119
- const [model, options] = mockFindFirst.mock.calls[0] as [
120
- string,
121
- { where: (builder: unknown) => void },
122
- ];
123
- expect(mockFindFirst.mock.calls).toHaveLength(1);
124
- expect(model).toBe('subject');
125
- expect(options).toHaveProperty('where');
126
- expect(typeof options.where).toBe('function');
127
-
128
- // Test the where function behavior
129
- const mockBuilder = vi.fn();
130
- options.where(mockBuilder);
131
- expect(mockBuilder).toHaveBeenCalledWith(
132
- 'id',
133
- '=',
134
- expect.stringMatching(SUBJECT_ID_PATTERN)
135
- );
136
- });
137
-
138
- it('should generate different IDs on subsequent calls', async () => {
139
- const mockDb = {
140
- findFirst: vi.fn().mockResolvedValue(null),
141
- } as unknown as MockDB;
142
-
143
- const id1 = await generateUniqueId(mockDb, 'subject');
144
- const id2 = await generateUniqueId(mockDb, 'subject');
145
- const id3 = await generateUniqueId(mockDb, 'subject');
146
-
147
- expect(id1).not.toBe(id2);
148
- expect(id2).not.toBe(id3);
149
- expect(id1).not.toBe(id3);
150
-
151
- // All should have the same prefix
152
- expect(id1).toMatch(SUBJECT_ID_PATTERN);
153
- expect(id2).toMatch(SUBJECT_ID_PATTERN);
154
- expect(id3).toMatch(SUBJECT_ID_PATTERN);
155
- });
156
-
157
- it('should throw an error when max retries is exceeded', async () => {
158
- const mockExistingRecord = { id: 'mock_existing' };
159
- const mockLogger = {
160
- error: vi.fn(),
161
- debug: vi.fn(),
162
- info: vi.fn(),
163
- success: vi.fn(),
164
- warn: vi.fn(),
165
- };
166
- const mockCtx = { logger: mockLogger };
167
-
168
- const mockDb = {
169
- findFirst: vi.fn().mockResolvedValue(mockExistingRecord), // Always return a collision
170
- } as unknown as MockDB;
171
-
172
- // Use a small maxRetries value for faster test execution
173
- await expect(
174
- generateUniqueId(mockDb, 'subject', mockCtx, { maxRetries: 3 })
175
- ).rejects.toThrow(
176
- 'Failed to generate unique ID for subject after 3 attempts'
177
- );
178
-
179
- // Should have attempted exactly maxRetries times
180
- expect(mockDb.findFirst).toHaveBeenCalledTimes(3);
181
- expect(mockLogger.error).toHaveBeenCalledWith(
182
- 'ID generation failed',
183
- expect.objectContaining({ model: 'subject', maxRetries: 3 })
184
- );
185
- });
186
-
187
- it('should respect custom retry options', async () => {
188
- const mockExistingRecord = { id: 'mock_existing' };
189
- const mockDb = {
190
- findFirst: vi
191
- .fn()
192
- .mockResolvedValueOnce(mockExistingRecord) // First call returns existing record
193
- .mockResolvedValueOnce(null), // Second call returns null (unique)
194
- } as unknown as MockDB;
195
-
196
- // Mock the setTimeout function directly
197
- const originalSetTimeout = global.setTimeout;
198
- global.setTimeout = vi.fn((callback) => {
199
- // Execute callback immediately
200
- callback();
201
- return 1; // Return a timeout ID
202
- }) as any;
203
-
204
- try {
205
- const result = await generateUniqueId(mockDb, 'subject', undefined, {
206
- baseDelay: 100,
207
- });
208
-
209
- expect(mockDb.findFirst).toHaveBeenCalledTimes(2);
210
- expect(result).toMatch(SUBJECT_ID_PATTERN);
211
- } finally {
212
- // Restore original setTimeout
213
- global.setTimeout = originalSetTimeout;
214
- }
215
- });
216
- });
@@ -1,133 +0,0 @@
1
- import baseX from 'base-x';
2
- import type { InferFumaDB } from 'fumadb';
3
- import type { LatestDB } from '~/db/schema';
4
- import type { C15TContext } from '~/types';
5
-
6
- type Tables = InferFumaDB<typeof LatestDB>['schemas'][-1]['tables'];
7
-
8
- const prefixes: Record<keyof Tables, string> = {
9
- auditLog: 'log',
10
- consent: 'cns',
11
- consentPolicy: 'pol',
12
- consentPurpose: 'pur',
13
- domain: 'dom',
14
- subject: 'sub',
15
- } as const;
16
-
17
- const b58 = baseX('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
18
-
19
- /**
20
- * Creates time-ordered, prefixed, base58-encoded identifiers that:
21
- * - Start with the provided prefix for clear identification
22
- * - Embed a timestamp for chronological ordering
23
- * - Include random data for uniqueness
24
- */
25
- function generateId(model: keyof typeof prefixes): string {
26
- const buf = crypto.getRandomValues(new Uint8Array(20));
27
- const prefix = prefixes[model];
28
-
29
- const EPOCH_TIMESTAMP = 1_700_000_000_000;
30
-
31
- const t = Date.now() - EPOCH_TIMESTAMP;
32
-
33
- // Use 8 bytes for the timestamp (0..7) and shift accordingly:
34
- const high = Math.floor(t / 0x100000000);
35
- const low = t >>> 0;
36
- buf[0] = (high >>> 24) & 255;
37
- buf[1] = (high >>> 16) & 255;
38
- buf[2] = (high >>> 8) & 255;
39
- buf[3] = high & 255;
40
- buf[4] = (low >>> 24) & 255;
41
- buf[5] = (low >>> 16) & 255;
42
- buf[6] = (low >>> 8) & 255;
43
- buf[7] = low & 255;
44
-
45
- return `${prefix}_${b58.encode(buf)}`;
46
- }
47
-
48
- /**
49
- * Generates a unique ID for the specified model with conflict handling
50
- *
51
- * @param db - Database ORM instance
52
- * @param model - The model/table name to generate ID for
53
- * @param ctx - Application context containing logger (optional)
54
- * @param options - Configuration options for ID generation
55
- * @returns Promise resolving to a unique ID
56
- *
57
- * @throws {Error} When max retry attempts are exceeded
58
- */
59
- export async function generateUniqueId(
60
- db: ReturnType<InferFumaDB<typeof LatestDB>['orm']>,
61
- model: keyof Tables,
62
- ctx?: Partial<C15TContext> | undefined,
63
- options: {
64
- /** Maximum number of retry attempts (default: 10) */
65
- maxRetries?: number;
66
- /** Current retry attempt (used internally) */
67
- attempt?: number;
68
- /** Base delay for exponential backoff in ms (default: 5) */
69
- baseDelay?: number;
70
- } = {}
71
- ): Promise<string> {
72
- const { maxRetries = 10, attempt = 0, baseDelay = 5 } = options;
73
-
74
- // Check if we've exceeded the maximum retry attempts
75
- if (attempt >= maxRetries) {
76
- const error = new Error(
77
- `Failed to generate unique ID for ${model} after ${maxRetries} attempts`
78
- );
79
- ctx?.logger?.error?.('ID generation failed', { model, maxRetries });
80
- throw error;
81
- }
82
-
83
- const id = generateId(model);
84
-
85
- try {
86
- const existing = await db.findFirst(model, {
87
- where: (b) => b('id', '=', id),
88
- });
89
-
90
- if (existing) {
91
- ctx?.logger?.debug?.('ID conflict detected', {
92
- id,
93
- model,
94
- attempt: attempt + 1,
95
- maxRetries,
96
- });
97
-
98
- // Implement exponential backoff
99
- const delay = Math.min(baseDelay * 2 ** attempt, 1000);
100
-
101
- // Wait before retrying to reduce contention in high-volume scenarios
102
- await new Promise((resolve) => setTimeout(resolve, delay));
103
-
104
- return generateUniqueId(db, model, ctx, {
105
- maxRetries,
106
- attempt: attempt + 1,
107
- baseDelay,
108
- });
109
- }
110
-
111
- return id;
112
- } catch (error) {
113
- ctx?.logger?.error?.('Error checking ID uniqueness', {
114
- error: (error as Error).message,
115
- model,
116
- attempt,
117
- });
118
-
119
- // If database error occurs, retry with backoff
120
- if (attempt < maxRetries - 1) {
121
- const delay = Math.min(baseDelay * 2 ** attempt, 2000);
122
- await new Promise((resolve) => setTimeout(resolve, delay));
123
-
124
- return generateUniqueId(db, model, ctx, {
125
- maxRetries,
126
- attempt: attempt + 1,
127
- baseDelay,
128
- });
129
- }
130
-
131
- throw error;
132
- }
133
- }
@@ -1,133 +0,0 @@
1
- import baseX from 'base-x';
2
- import type { InferFumaDB } from 'fumadb';
3
- import type { DB, LatestDB } from '~/db/schema';
4
- import type { C15TContext } from '~/types';
5
-
6
- type Tables = InferFumaDB<typeof DB>['schemas'][-1]['tables'];
7
-
8
- const prefixes: Record<keyof Tables, string> = {
9
- auditLog: 'log',
10
- consent: 'cns',
11
- consentPolicy: 'pol',
12
- consentPurpose: 'pur',
13
- domain: 'dom',
14
- subject: 'sub',
15
- } as const;
16
-
17
- const b58 = baseX('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
18
-
19
- /**
20
- * Creates time-ordered, prefixed, base58-encoded identifiers that:
21
- * - Start with the provided prefix for clear identification
22
- * - Embed a timestamp for chronological ordering
23
- * - Include random data for uniqueness
24
- */
25
- function generateId(model: keyof typeof prefixes): string {
26
- const buf = crypto.getRandomValues(new Uint8Array(20));
27
- const prefix = prefixes[model];
28
-
29
- const EPOCH_TIMESTAMP = 1_700_000_000_000;
30
-
31
- const t = Date.now() - EPOCH_TIMESTAMP;
32
-
33
- // Use 8 bytes for the timestamp (0..7) and shift accordingly:
34
- const high = Math.floor(t / 0x100000000);
35
- const low = t >>> 0;
36
- buf[0] = (high >>> 24) & 255;
37
- buf[1] = (high >>> 16) & 255;
38
- buf[2] = (high >>> 8) & 255;
39
- buf[3] = high & 255;
40
- buf[4] = (low >>> 24) & 255;
41
- buf[5] = (low >>> 16) & 255;
42
- buf[6] = (low >>> 8) & 255;
43
- buf[7] = low & 255;
44
-
45
- return `${prefix}_${b58.encode(buf)}`;
46
- }
47
-
48
- /**
49
- * Generates a unique ID for the specified model with conflict handling
50
- *
51
- * @param db - Database ORM instance
52
- * @param model - The model/table name to generate ID for
53
- * @param ctx - Application context containing logger (optional)
54
- * @param options - Configuration options for ID generation
55
- * @returns Promise resolving to a unique ID
56
- *
57
- * @throws {Error} When max retry attempts are exceeded
58
- */
59
- export async function generateUniqueId(
60
- db: ReturnType<InferFumaDB<typeof LatestDB>['orm']>,
61
- model: keyof Tables,
62
- ctx?: Partial<C15TContext> | undefined,
63
- options: {
64
- /** Maximum number of retry attempts (default: 10) */
65
- maxRetries?: number;
66
- /** Current retry attempt (used internally) */
67
- attempt?: number;
68
- /** Base delay for exponential backoff in ms (default: 5) */
69
- baseDelay?: number;
70
- } = {}
71
- ): Promise<string> {
72
- const { maxRetries = 10, attempt = 0, baseDelay = 5 } = options;
73
-
74
- // Check if we've exceeded the maximum retry attempts
75
- if (attempt >= maxRetries) {
76
- const error = new Error(
77
- `Failed to generate unique ID for ${model} after ${maxRetries} attempts`
78
- );
79
- ctx?.logger?.error?.('ID generation failed', { model, maxRetries });
80
- throw error;
81
- }
82
-
83
- const id = generateId(model);
84
-
85
- try {
86
- const existing = await db.findFirst(model, {
87
- where: (b) => b('id', '=', id),
88
- });
89
-
90
- if (existing) {
91
- ctx?.logger?.debug?.('ID conflict detected', {
92
- id,
93
- model,
94
- attempt: attempt + 1,
95
- maxRetries,
96
- });
97
-
98
- // Implement exponential backoff
99
- const delay = Math.min(baseDelay * 2 ** attempt, 1000);
100
-
101
- // Wait before retrying to reduce contention in high-volume scenarios
102
- await new Promise((resolve) => setTimeout(resolve, delay));
103
-
104
- return generateUniqueId(db, model, ctx, {
105
- maxRetries,
106
- attempt: attempt + 1,
107
- baseDelay,
108
- });
109
- }
110
-
111
- return id;
112
- } catch (error) {
113
- ctx?.logger?.error?.('Error checking ID uniqueness', {
114
- error: (error as Error).message,
115
- model,
116
- attempt,
117
- });
118
-
119
- // If database error occurs, retry with backoff
120
- if (attempt < maxRetries - 1) {
121
- const delay = Math.min(baseDelay * 2 ** attempt, 2000);
122
- await new Promise((resolve) => setTimeout(resolve, delay));
123
-
124
- return generateUniqueId(db, model, ctx, {
125
- maxRetries,
126
- attempt: attempt + 1,
127
- baseDelay,
128
- });
129
- }
130
-
131
- throw error;
132
- }
133
- }
@@ -1,15 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const auditLogTable = table('auditLog', {
4
- id: idColumn('id', 'varchar(255)'),
5
- entityType: column('entityType', 'string'),
6
- entityId: column('entityId', 'string'),
7
- actionType: column('actionType', 'string'),
8
- subjectId: column('subjectId', 'string').nullable(),
9
- ipAddress: column('ipAddress', 'string').nullable(),
10
- userAgent: column('userAgent', 'string').nullable(),
11
- changes: column('changes', 'json').nullable(),
12
- metadata: column('metadata', 'json').nullable(),
13
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
14
- eventTimezone: column('eventTimezone', 'string').defaultTo$(() => 'UTC'),
15
- });
@@ -1,14 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const consentPolicyTable = table('consentPolicy', {
4
- id: idColumn('id', 'varchar(255)'),
5
- version: column('version', 'string'),
6
- type: column('type', 'string'),
7
- name: column('name', 'string'),
8
- effectiveDate: column('effectiveDate', 'timestamp'),
9
- expirationDate: column('expirationDate', 'timestamp').nullable(),
10
- content: column('content', 'string'),
11
- contentHash: column('contentHash', 'string'),
12
- isActive: column('isActive', 'bool').defaultTo$(() => true),
13
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
14
- });
@@ -1,14 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const consentPurposeTable = table('consentPurpose', {
4
- id: idColumn('id', 'varchar(255)'),
5
- code: column('code', 'string'),
6
- name: column('name', 'string'),
7
- description: column('description', 'string'),
8
- isEssential: column('isEssential', 'bool'),
9
- dataCategory: column('dataCategory', 'string').nullable(),
10
- legalBasis: column('legalBasis', 'string').nullable(),
11
- isActive: column('isActive', 'bool').defaultTo$(() => true),
12
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
13
- updatedAt: column('updatedAt', 'timestamp').defaultTo$('now'),
14
- });
@@ -1,10 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const consentRecordTable = table('consentRecord', {
4
- id: idColumn('id', 'varchar(255)'),
5
- subjectId: column('subjectId', 'string'),
6
- consentId: column('consentId', 'string').nullable(),
7
- actionType: column('actionType', 'string'),
8
- details: column('details', 'json').nullable(),
9
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
10
- });
@@ -1,20 +0,0 @@
1
- import { type Consent, consentSchema } from '@c15t/schema';
2
- import { column, idColumn, table } from 'fumadb/schema';
3
-
4
- export const consentTable = table('consent', {
5
- id: idColumn('id', 'varchar(255)'),
6
- subjectId: column('subjectId', 'string'),
7
- domainId: column('domainId', 'string'),
8
- policyId: column('policyId', 'string').nullable(),
9
- purposeIds: column('purposeIds', 'json'),
10
- metadata: column('metadata', 'json').nullable(),
11
- ipAddress: column('ipAddress', 'string').nullable(),
12
- userAgent: column('userAgent', 'string').nullable(),
13
- status: column('status', 'string').defaultTo$(() => 'active'),
14
- withdrawalReason: column('withdrawalReason', 'string').nullable(),
15
- givenAt: column('givenAt', 'timestamp').defaultTo$('now'),
16
- validUntil: column('validUntil', 'timestamp').nullable(),
17
- isActive: column('isActive', 'bool').defaultTo$(() => true),
18
- });
19
-
20
- export { consentSchema, type Consent };
@@ -1,12 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const domainTable = table('domain', {
4
- id: idColumn('id', 'varchar(255)'),
5
- name: column('name', 'string').unique(),
6
- description: column('description', 'string').nullable(),
7
- allowedOrigins: column('allowedOrigins', 'json').nullable(),
8
- isVerified: column('isVerified', 'bool').defaultTo$(() => true),
9
- isActive: column('isActive', 'bool').defaultTo$(() => true),
10
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
11
- updatedAt: column('updatedAt', 'timestamp').defaultTo$('now'),
12
- });
@@ -1,48 +0,0 @@
1
- import { schema } from 'fumadb/schema';
2
- import { auditLogTable } from './audit-log';
3
- import { consentTable } from './consent';
4
- import { consentPolicyTable } from './consent-policy';
5
- import { consentPurposeTable } from './consent-purpose';
6
- import { consentRecordTable } from './consent-record';
7
- import { domainTable } from './domain';
8
- import { subjectTable } from './subject';
9
-
10
- export const v1 = schema({
11
- version: '1.0.0',
12
- tables: {
13
- subject: subjectTable,
14
- domain: domainTable,
15
- consentPolicy: consentPolicyTable,
16
- consentPurpose: consentPurposeTable,
17
- consent: consentTable,
18
- auditLog: auditLogTable,
19
- consentRecord: consentRecordTable,
20
- },
21
- relations: {
22
- subject: ({ many }) => ({
23
- consents: many('consent'),
24
- consentRecords: many('consentRecord'),
25
- auditLogs: many('auditLog'),
26
- }),
27
- domain: ({ many }) => ({
28
- consents: many('consent'),
29
- }),
30
- consentPolicy: ({ many }) => ({
31
- consents: many('consent'),
32
- }),
33
- consentPurpose: () => ({}),
34
- consent: ({ one, many }) => ({
35
- subject: one('subject', ['subjectId', 'id']).foreignKey(),
36
- domain: one('domain', ['domainId', 'id']).foreignKey(),
37
- policy: one('consentPolicy', ['policyId', 'id']).foreignKey(),
38
- consentRecords: many('consentRecord'),
39
- }),
40
- consentRecord: ({ one }) => ({
41
- subject: one('subject', ['subjectId', 'id']).foreignKey(),
42
- consent: one('consent', ['consentId', 'id']).foreignKey(),
43
- }),
44
- auditLog: ({ one }) => ({
45
- subject: one('subject', ['subjectId', 'id']).foreignKey(),
46
- }),
47
- },
48
- });
@@ -1,12 +0,0 @@
1
- import { column, idColumn, table } from 'fumadb/schema';
2
-
3
- export const subjectTable = table('subject', {
4
- id: idColumn('id', 'varchar(255)'),
5
- isIdentified: column('isIdentified', 'bool').defaultTo$(() => false),
6
- externalId: column('externalId', 'string').nullable(),
7
- identityProvider: column('identityProvider', 'string').nullable(),
8
- lastIpAddress: column('lastIpAddress', 'string').nullable(),
9
- subjectTimezone: column('subjectTimezone', 'string').nullable(),
10
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
11
- updatedAt: column('updatedAt', 'timestamp').defaultTo$('now'),
12
- });
@@ -1,18 +0,0 @@
1
- import { type AuditLog, auditLogSchema } from '@c15t/schema';
2
- import { column, idColumn, table } from 'fumadb/schema';
3
-
4
- export const auditLogTable = table('auditLog', {
5
- id: idColumn('id', 'varchar(255)'),
6
- entityType: column('entityType', 'string'),
7
- entityId: column('entityId', 'string'),
8
- actionType: column('actionType', 'string'),
9
- subjectId: column('subjectId', 'string').nullable(),
10
- ipAddress: column('ipAddress', 'string').nullable(),
11
- userAgent: column('userAgent', 'string').nullable(),
12
- changes: column('changes', 'json').nullable(),
13
- metadata: column('metadata', 'json').nullable(),
14
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
15
- tenantId: column('tenantId', 'string').nullable(),
16
- });
17
-
18
- export { auditLogSchema, type AuditLog };
@@ -1,28 +0,0 @@
1
- import {
2
- type ConsentPolicy,
3
- consentPolicySchema,
4
- type PolicyType,
5
- policyTypeSchema,
6
- } from '@c15t/schema';
7
- import { column, idColumn, table } from 'fumadb/schema';
8
-
9
- export const consentPolicyTable = table('consentPolicy', {
10
- id: idColumn('id', 'varchar(255)'),
11
- version: column('version', 'string'),
12
- type: column('type', 'string'),
13
- effectiveDate: column('effectiveDate', 'timestamp'),
14
- isActive: column('isActive', 'bool').defaultTo$(() => true),
15
- createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
16
- tenantId: column('tenantId', 'string').nullable(),
17
- });
18
-
19
- // Re-export for backward compatibility
20
- export {
21
- consentPolicySchema,
22
- policyTypeSchema,
23
- type ConsentPolicy,
24
- type PolicyType,
25
- };
26
-
27
- // Backward compatible alias
28
- export const PolicyTypeSchema = policyTypeSchema;