@devxcrew/platform 0.1.2 → 0.1.6

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 (280) hide show
  1. package/README.md +7 -1
  2. package/dist/index.d.ts +6 -4
  3. package/dist/index.js +4 -2
  4. package/dist/modules/identity/audit/audit.controller.d.ts +17 -0
  5. package/dist/modules/identity/audit/audit.controller.js +12 -0
  6. package/dist/modules/identity/audit/audit.migration.d.ts +1 -0
  7. package/dist/modules/identity/audit/audit.migration.js +1 -0
  8. package/dist/modules/identity/audit/audit.provider.d.ts +24 -0
  9. package/dist/modules/identity/audit/audit.provider.js +14 -0
  10. package/dist/modules/identity/audit/audit.repository.d.ts +26 -0
  11. package/dist/modules/identity/audit/audit.repository.js +46 -0
  12. package/dist/modules/identity/audit/audit.routes.d.ts +5 -0
  13. package/dist/modules/identity/audit/audit.routes.js +2 -0
  14. package/dist/modules/identity/audit/audit.schema.d.ts +1 -0
  15. package/dist/modules/identity/audit/audit.schema.js +1 -0
  16. package/dist/modules/identity/audit/audit.seed.d.ts +1 -0
  17. package/dist/modules/identity/audit/audit.seed.js +1 -0
  18. package/dist/modules/identity/audit/audit.service.d.ts +23 -0
  19. package/dist/modules/identity/audit/audit.service.js +46 -0
  20. package/dist/modules/identity/audit/audit.types.d.ts +12 -0
  21. package/dist/modules/identity/audit/audit.types.js +1 -0
  22. package/dist/modules/identity/audit/index.d.ts +4 -0
  23. package/dist/modules/identity/audit/index.js +3 -0
  24. package/dist/modules/identity/{identity.administration-service.d.ts → composition/identity.composition.d.ts} +59 -27
  25. package/dist/modules/identity/composition/identity.composition.js +171 -0
  26. package/dist/modules/identity/composition/identity.seed.d.ts +3 -0
  27. package/dist/modules/identity/composition/identity.seed.js +16 -0
  28. package/dist/modules/identity/identity.controller.d.ts +8 -6
  29. package/dist/modules/identity/identity.controller.js +90 -70
  30. package/dist/modules/identity/identity.migration.d.ts +1 -2
  31. package/dist/modules/identity/identity.migration.js +1 -79
  32. package/dist/modules/identity/identity.provider.d.ts +39 -13
  33. package/dist/modules/identity/identity.provider.js +19 -73
  34. package/dist/modules/identity/identity.public-schemas.d.ts +9 -3
  35. package/dist/modules/identity/identity.public-schemas.js +9 -3
  36. package/dist/modules/identity/identity.repository.d.ts +1 -40
  37. package/dist/modules/identity/identity.repository.js +1 -196
  38. package/dist/modules/identity/identity.routes.d.ts +2 -5
  39. package/dist/modules/identity/identity.routes.js +3 -11
  40. package/dist/modules/identity/identity.schema.d.ts +1 -27
  41. package/dist/modules/identity/identity.schema.js +1 -34
  42. package/dist/modules/identity/identity.seed.d.ts +1 -3
  43. package/dist/modules/identity/identity.seed.js +1 -81
  44. package/dist/modules/identity/identity.service.d.ts +1 -32
  45. package/dist/modules/identity/identity.service.js +1 -83
  46. package/dist/modules/identity/identity.types.d.ts +13 -106
  47. package/dist/modules/identity/index.d.ts +18 -11
  48. package/dist/modules/identity/index.js +14 -8
  49. package/dist/modules/identity/{identity.administration-migration.js → legacy/identity.administration-migration.js} +3 -11
  50. package/dist/modules/identity/legacy/identity.migration.d.ts +2 -0
  51. package/dist/modules/identity/legacy/identity.migration.js +72 -0
  52. package/dist/modules/identity/organization/index.d.ts +6 -0
  53. package/dist/modules/identity/organization/index.js +5 -0
  54. package/dist/modules/identity/organization/organization.controller.d.ts +35 -0
  55. package/dist/modules/identity/organization/organization.controller.js +18 -0
  56. package/dist/modules/identity/organization/organization.migration.d.ts +1 -0
  57. package/dist/modules/identity/organization/organization.migration.js +1 -0
  58. package/dist/modules/identity/organization/organization.provider.d.ts +46 -0
  59. package/dist/modules/identity/organization/organization.provider.js +33 -0
  60. package/dist/modules/identity/organization/organization.repository.d.ts +58 -0
  61. package/dist/modules/identity/organization/organization.repository.js +101 -0
  62. package/dist/modules/identity/organization/organization.routes.d.ts +5 -0
  63. package/dist/modules/identity/organization/organization.routes.js +2 -0
  64. package/dist/modules/identity/organization/organization.schema.d.ts +11 -0
  65. package/dist/modules/identity/organization/organization.schema.js +18 -0
  66. package/dist/modules/identity/organization/organization.seed.d.ts +3 -0
  67. package/dist/modules/identity/organization/organization.seed.js +11 -0
  68. package/dist/modules/identity/organization/organization.service.d.ts +39 -0
  69. package/dist/modules/identity/organization/organization.service.js +55 -0
  70. package/dist/modules/identity/organization/organization.types.d.ts +19 -0
  71. package/dist/modules/identity/organization/organization.types.js +1 -0
  72. package/dist/modules/identity/permission/index.d.ts +9 -0
  73. package/dist/modules/identity/permission/index.js +6 -0
  74. package/dist/modules/identity/permission/permission.controller.d.ts +21 -0
  75. package/dist/modules/identity/permission/permission.controller.js +12 -0
  76. package/dist/modules/identity/{identity.permission-declarations-migration.js → permission/permission.declarations.migration.js} +9 -4
  77. package/dist/modules/identity/{identity.permission-labels-migration.js → permission/permission.labels.migration.js} +5 -2
  78. package/dist/modules/identity/permission/permission.migration.d.ts +2 -0
  79. package/dist/modules/identity/permission/permission.migration.js +2 -0
  80. package/dist/modules/identity/permission/permission.provider.d.ts +19 -0
  81. package/dist/modules/identity/permission/permission.provider.js +14 -0
  82. package/dist/modules/identity/permission/permission.repository.d.ts +51 -0
  83. package/dist/modules/identity/permission/permission.repository.js +84 -0
  84. package/dist/modules/identity/permission/permission.routes.d.ts +5 -0
  85. package/dist/modules/identity/permission/permission.routes.js +2 -0
  86. package/dist/modules/identity/permission/permission.schema.d.ts +14 -0
  87. package/dist/modules/identity/permission/permission.schema.js +29 -0
  88. package/dist/modules/identity/permission/permission.seed.d.ts +4 -0
  89. package/dist/modules/identity/permission/permission.seed.js +17 -0
  90. package/dist/modules/identity/permission/permission.service.d.ts +31 -0
  91. package/dist/modules/identity/permission/permission.service.js +77 -0
  92. package/dist/modules/identity/permission/permission.types.d.ts +15 -0
  93. package/dist/modules/identity/permission/permission.types.js +1 -0
  94. package/dist/modules/identity/role/index.d.ts +10 -0
  95. package/dist/modules/identity/role/index.js +6 -0
  96. package/dist/modules/identity/role/role.controller.d.ts +42 -0
  97. package/dist/modules/identity/role/role.controller.js +25 -0
  98. package/dist/modules/identity/{identity.roles-migration.js → role/role.migration.js} +5 -18
  99. package/dist/modules/identity/role/role.provider.d.ts +14 -0
  100. package/dist/modules/identity/role/role.provider.js +30 -0
  101. package/dist/modules/identity/role/role.repository.d.ts +38 -0
  102. package/dist/modules/identity/role/role.repository.js +46 -0
  103. package/dist/modules/identity/role/role.routes.d.ts +5 -0
  104. package/dist/modules/identity/role/role.routes.js +2 -0
  105. package/dist/modules/identity/role/role.schema.d.ts +16 -0
  106. package/dist/modules/identity/role/role.schema.js +27 -0
  107. package/dist/modules/identity/role/role.seed.d.ts +3 -0
  108. package/dist/modules/identity/role/role.seed.js +8 -0
  109. package/dist/modules/identity/role/role.service.d.ts +69 -0
  110. package/dist/modules/identity/role/role.service.js +192 -0
  111. package/dist/modules/identity/role/role.types.d.ts +17 -0
  112. package/dist/modules/identity/role/role.types.js +1 -0
  113. package/dist/modules/identity/role-permission/index.d.ts +6 -0
  114. package/dist/modules/identity/role-permission/index.js +4 -0
  115. package/dist/modules/identity/role-permission/role-permission.controller.d.ts +1 -0
  116. package/dist/modules/identity/role-permission/role-permission.controller.js +1 -0
  117. package/dist/modules/identity/role-permission/role-permission.migration.d.ts +1 -0
  118. package/dist/modules/identity/role-permission/role-permission.migration.js +1 -0
  119. package/dist/modules/identity/role-permission/role-permission.provider.d.ts +14 -0
  120. package/dist/modules/identity/role-permission/role-permission.provider.js +15 -0
  121. package/dist/modules/identity/role-permission/role-permission.repository.d.ts +12 -0
  122. package/dist/modules/identity/role-permission/role-permission.repository.js +51 -0
  123. package/dist/modules/identity/role-permission/role-permission.routes.d.ts +1 -0
  124. package/dist/modules/identity/role-permission/role-permission.routes.js +2 -0
  125. package/dist/modules/identity/role-permission/role-permission.schema.d.ts +2 -0
  126. package/dist/modules/identity/role-permission/role-permission.schema.js +3 -0
  127. package/dist/modules/identity/role-permission/role-permission.seed.d.ts +3 -0
  128. package/dist/modules/identity/role-permission/role-permission.seed.js +10 -0
  129. package/dist/modules/identity/role-permission/role-permission.service.d.ts +13 -0
  130. package/dist/modules/identity/role-permission/role-permission.service.js +35 -0
  131. package/dist/modules/identity/role-permission/role-permission.types.d.ts +12 -0
  132. package/dist/modules/identity/role-permission/role-permission.types.js +1 -0
  133. package/dist/modules/identity/session/index.d.ts +6 -0
  134. package/dist/modules/identity/session/index.js +5 -0
  135. package/dist/modules/identity/session/session.authentication.controller.d.ts +30 -0
  136. package/dist/modules/identity/session/session.authentication.controller.js +37 -0
  137. package/dist/modules/identity/session/session.controller.d.ts +18 -0
  138. package/dist/modules/identity/session/session.controller.js +15 -0
  139. package/dist/modules/identity/session/session.migration.d.ts +1 -0
  140. package/dist/modules/identity/session/session.migration.js +1 -0
  141. package/dist/modules/identity/session/session.provider.d.ts +34 -0
  142. package/dist/modules/identity/session/session.provider.js +23 -0
  143. package/dist/modules/identity/session/session.repository.d.ts +36 -0
  144. package/dist/modules/identity/session/session.repository.js +128 -0
  145. package/dist/modules/identity/session/session.routes.d.ts +27 -0
  146. package/dist/modules/identity/session/session.routes.js +13 -0
  147. package/dist/modules/identity/session/session.schema.d.ts +6 -0
  148. package/dist/modules/identity/session/session.schema.js +12 -0
  149. package/dist/modules/identity/session/session.seed.d.ts +1 -0
  150. package/dist/modules/identity/session/session.seed.js +1 -0
  151. package/dist/modules/identity/session/session.service.d.ts +20 -0
  152. package/dist/modules/identity/session/session.service.js +27 -0
  153. package/dist/modules/identity/session/session.types.d.ts +17 -0
  154. package/dist/modules/identity/session/session.types.js +1 -0
  155. package/dist/modules/identity/settings/index.d.ts +5 -0
  156. package/dist/modules/identity/settings/index.js +4 -0
  157. package/dist/modules/identity/settings/settings.controller.d.ts +35 -0
  158. package/dist/modules/identity/settings/settings.controller.js +18 -0
  159. package/dist/modules/identity/settings/settings.migration.d.ts +1 -0
  160. package/dist/modules/identity/settings/settings.migration.js +1 -0
  161. package/dist/modules/identity/settings/settings.provider.d.ts +35 -0
  162. package/dist/modules/identity/settings/settings.provider.js +14 -0
  163. package/dist/modules/identity/settings/settings.repository.d.ts +49 -0
  164. package/dist/modules/identity/settings/settings.repository.js +75 -0
  165. package/dist/modules/identity/settings/settings.routes.d.ts +1 -0
  166. package/dist/modules/identity/settings/settings.routes.js +7 -0
  167. package/dist/modules/identity/settings/settings.schema.d.ts +15 -0
  168. package/dist/modules/identity/settings/settings.schema.js +27 -0
  169. package/dist/modules/identity/settings/settings.seed.d.ts +1 -0
  170. package/dist/modules/identity/settings/settings.seed.js +1 -0
  171. package/dist/modules/identity/settings/settings.service.d.ts +40 -0
  172. package/dist/modules/identity/settings/settings.service.js +101 -0
  173. package/dist/modules/identity/settings/settings.types.d.ts +20 -0
  174. package/dist/modules/identity/settings/settings.types.js +1 -0
  175. package/dist/modules/identity/support/identity.schema.d.ts +8 -0
  176. package/dist/modules/identity/support/identity.schema.js +10 -0
  177. package/dist/modules/identity/support/pagination.d.ts +13 -0
  178. package/dist/modules/identity/support/pagination.js +27 -0
  179. package/dist/modules/identity/support/pagination.schema.d.ts +43 -0
  180. package/dist/modules/identity/support/pagination.schema.js +15 -0
  181. package/dist/modules/identity/support/resource-controller.d.ts +14 -0
  182. package/dist/modules/identity/support/resource-controller.js +1 -0
  183. package/dist/modules/identity/user/index.d.ts +13 -0
  184. package/dist/modules/identity/user/index.js +11 -0
  185. package/dist/modules/identity/user/user.administration.service.d.ts +59 -0
  186. package/dist/modules/identity/user/user.administration.service.js +159 -0
  187. package/dist/modules/identity/user/user.controller.d.ts +44 -0
  188. package/dist/modules/identity/user/user.controller.js +21 -0
  189. package/dist/modules/identity/user/user.lifecycle.controller.d.ts +58 -0
  190. package/dist/modules/identity/user/user.lifecycle.controller.js +27 -0
  191. package/dist/modules/identity/{identity.lifecycle-schema.js → user/user.lifecycle.schema.js} +5 -5
  192. package/dist/modules/identity/{identity.lifecycle-service.d.ts → user/user.lifecycle.service.d.ts} +8 -4
  193. package/dist/modules/identity/{identity.lifecycle-service.js → user/user.lifecycle.service.js} +66 -118
  194. package/dist/modules/identity/user/user.migration.d.ts +1 -0
  195. package/dist/modules/identity/user/user.migration.js +1 -0
  196. package/dist/modules/identity/{identity.password.js → user/user.password.js} +1 -1
  197. package/dist/modules/identity/user/user.provider.d.ts +80 -0
  198. package/dist/modules/identity/user/user.provider.js +22 -0
  199. package/dist/modules/identity/user/user.repository.d.ts +64 -0
  200. package/dist/modules/identity/user/user.repository.js +129 -0
  201. package/dist/modules/identity/user/user.routes.d.ts +12 -0
  202. package/dist/modules/identity/user/user.routes.js +9 -0
  203. package/dist/modules/identity/user/user.schema.d.ts +34 -0
  204. package/dist/modules/identity/user/user.schema.js +46 -0
  205. package/dist/modules/identity/user/user.seed.d.ts +14 -0
  206. package/dist/modules/identity/user/user.seed.js +47 -0
  207. package/dist/modules/identity/user/user.service.d.ts +33 -0
  208. package/dist/modules/identity/user/user.service.js +76 -0
  209. package/dist/modules/identity/user/user.types.d.ts +27 -0
  210. package/dist/modules/identity/user/user.types.js +1 -0
  211. package/dist/modules/identity/user-role/index.d.ts +8 -0
  212. package/dist/modules/identity/user-role/index.js +6 -0
  213. package/dist/modules/identity/user-role/user-role.controller.d.ts +42 -0
  214. package/dist/modules/identity/user-role/user-role.controller.js +21 -0
  215. package/dist/modules/identity/user-role/user-role.migration.d.ts +1 -0
  216. package/dist/modules/identity/user-role/user-role.migration.js +1 -0
  217. package/dist/modules/identity/user-role/user-role.policy.d.ts +3 -0
  218. package/dist/modules/identity/user-role/user-role.policy.js +25 -0
  219. package/dist/modules/identity/user-role/user-role.provider.d.ts +18 -0
  220. package/dist/modules/identity/user-role/user-role.provider.js +23 -0
  221. package/dist/modules/identity/user-role/user-role.repository.d.ts +34 -0
  222. package/dist/modules/identity/user-role/user-role.repository.js +87 -0
  223. package/dist/modules/identity/user-role/user-role.routes.d.ts +5 -0
  224. package/dist/modules/identity/user-role/user-role.routes.js +2 -0
  225. package/dist/modules/identity/user-role/user-role.schema.d.ts +14 -0
  226. package/dist/modules/identity/user-role/user-role.schema.js +25 -0
  227. package/dist/modules/identity/user-role/user-role.seed.d.ts +7 -0
  228. package/dist/modules/identity/user-role/user-role.seed.js +11 -0
  229. package/dist/modules/identity/user-role/user-role.service.d.ts +60 -0
  230. package/dist/modules/identity/user-role/user-role.service.js +216 -0
  231. package/dist/modules/identity/user-role/user-role.types.d.ts +12 -0
  232. package/dist/modules/identity/user-role/user-role.types.js +1 -0
  233. package/dist/modules/tenant/index.d.ts +6 -0
  234. package/dist/modules/tenant/index.js +5 -0
  235. package/dist/modules/tenant/tenant.command.d.ts +3 -0
  236. package/dist/modules/tenant/tenant.command.js +43 -0
  237. package/dist/modules/tenant/tenant.controller.d.ts +4 -0
  238. package/dist/modules/tenant/tenant.controller.js +12 -0
  239. package/dist/modules/tenant/tenant.migration.d.ts +5 -0
  240. package/dist/modules/tenant/tenant.migration.js +46 -0
  241. package/dist/modules/tenant/tenant.provider.d.ts +3 -0
  242. package/dist/modules/tenant/tenant.provider.js +44 -0
  243. package/dist/modules/tenant/tenant.readiness.d.ts +6 -0
  244. package/dist/modules/tenant/tenant.readiness.js +45 -0
  245. package/dist/modules/tenant/tenant.repository.d.ts +15 -0
  246. package/dist/modules/tenant/tenant.repository.js +23 -0
  247. package/dist/modules/tenant/tenant.routes.d.ts +4 -0
  248. package/dist/modules/tenant/tenant.routes.js +7 -0
  249. package/dist/modules/tenant/tenant.schema.d.ts +20 -0
  250. package/dist/modules/tenant/tenant.schema.js +31 -0
  251. package/dist/modules/tenant/tenant.seed.d.ts +8 -0
  252. package/dist/modules/tenant/tenant.seed.js +40 -0
  253. package/dist/modules/tenant/tenant.service.d.ts +16 -0
  254. package/dist/modules/tenant/tenant.service.js +72 -0
  255. package/dist/modules/tenant/tenant.types.d.ts +39 -0
  256. package/dist/modules/tenant/tenant.types.js +1 -0
  257. package/package.json +9 -5
  258. package/dist/modules/identity/identity.administration-repository.d.ts +0 -19
  259. package/dist/modules/identity/identity.administration-repository.js +0 -102
  260. package/dist/modules/identity/identity.administration-schema.d.ts +0 -113
  261. package/dist/modules/identity/identity.administration-schema.js +0 -121
  262. package/dist/modules/identity/identity.administration-service.js +0 -517
  263. package/dist/modules/identity/identity.membership-policy.d.ts +0 -3
  264. package/dist/modules/identity/identity.membership-policy.js +0 -27
  265. package/dist/modules/identity/identity.permission-declarations.d.ts +0 -23
  266. package/dist/modules/identity/identity.permission-declarations.js +0 -57
  267. package/dist/modules/identity/identity.presentation-service.d.ts +0 -23
  268. package/dist/modules/identity/identity.presentation-service.js +0 -51
  269. package/dist/modules/identity/identity.roles-service.d.ts +0 -49
  270. package/dist/modules/identity/identity.roles-service.js +0 -327
  271. /package/dist/modules/identity/{identity.administration-migration.d.ts → legacy/identity.administration-migration.d.ts} +0 -0
  272. /package/dist/modules/identity/{identity.permission-declarations-migration.d.ts → permission/permission.declarations.migration.d.ts} +0 -0
  273. /package/dist/modules/identity/{identity.permission-labels-migration.d.ts → permission/permission.labels.migration.d.ts} +0 -0
  274. /package/dist/modules/identity/{identity.roles-migration.d.ts → role/role.migration.d.ts} +0 -0
  275. /package/dist/modules/identity/{identity.error.d.ts → support/identity.error.d.ts} +0 -0
  276. /package/dist/modules/identity/{identity.error.js → support/identity.error.js} +0 -0
  277. /package/dist/modules/identity/{identity.request-context.d.ts → support/identity.request-context.d.ts} +0 -0
  278. /package/dist/modules/identity/{identity.request-context.js → support/identity.request-context.js} +0 -0
  279. /package/dist/modules/identity/{identity.lifecycle-schema.d.ts → user/user.lifecycle.schema.d.ts} +0 -0
  280. /package/dist/modules/identity/{identity.password.d.ts → user/user.password.d.ts} +0 -0
@@ -0,0 +1,7 @@
1
+ import type { Transaction } from "kysely";
2
+ import type { IdentitySchema, Portal } from "../identity.types.js";
3
+ export declare function seedMemberships(trx: Transaction<IdentitySchema>, created: Array<{
4
+ userId: string;
5
+ tenantId: string;
6
+ portal: Portal;
7
+ }>): Promise<void>;
@@ -0,0 +1,11 @@
1
+ export async function seedMemberships(trx, created) {
2
+ for (const account of created)
3
+ await trx
4
+ .insertInto("identity_memberships")
5
+ .values({
6
+ user_id: account.userId,
7
+ tenant_id: account.tenantId,
8
+ role_id: account.portal
9
+ })
10
+ .execute();
11
+ }
@@ -0,0 +1,60 @@
1
+ import type { Kysely, Transaction } from "kysely";
2
+ import type { IdentitySchema, Portal, Principal } from "../identity.types.js";
3
+ import type { IdentityRoleResolver } from "../role/index.js";
4
+ import type { IdentityMutation } from "../identity.types.js";
5
+ import { type MembershipReadSources } from "./user-role.repository.js";
6
+ import type { IdentityListQuery } from "../support/pagination.schema.js";
7
+ export declare class IdentityUserRoleService {
8
+ private readonly db;
9
+ private readonly readSources;
10
+ private readonly activeUsers;
11
+ private readonly resolveRole;
12
+ private readonly customRoleInApp;
13
+ private readonly mutate;
14
+ private readonly assertUserVisible;
15
+ private readonly activeOrganization;
16
+ private readonly recordAudit;
17
+ private readonly revokeMembershipSessions;
18
+ constructor(db: Kysely<IdentitySchema>, readSources: MembershipReadSources, activeUsers: (db: Kysely<IdentitySchema>, ids: string[]) => Promise<string[]>, resolveRole: IdentityRoleResolver, customRoleInApp: (db: Kysely<IdentitySchema>, id: string, appId: string) => Promise<unknown>, mutate: IdentityMutation, assertUserVisible: (actor: Principal, userId: string) => Promise<unknown>, activeOrganization: (trx: Transaction<IdentitySchema>, id: string) => Promise<unknown>, recordAudit: (trx: Transaction<IdentitySchema>, actor: Principal, tenantId: string, action: string, id: string) => Promise<void>, revokeMembershipSessions: (trx: Transaction<IdentitySchema>, appId: string, userId: string, tenantId: string, portal: Portal) => Promise<void>);
19
+ list(actor: Principal, query: IdentityListQuery): Promise<{
20
+ data: {
21
+ active: boolean;
22
+ version: number;
23
+ }[];
24
+ meta: {
25
+ page: number;
26
+ perPage: number;
27
+ total: number;
28
+ lastPage: number;
29
+ };
30
+ }>;
31
+ show(actor: Principal, id: string): Promise<{
32
+ active: boolean;
33
+ version: number;
34
+ } | undefined>;
35
+ createMembership(actor: Principal, raw: unknown): Promise<{
36
+ id: string;
37
+ userId: string;
38
+ tenantId: string;
39
+ roleId: string;
40
+ portal: Portal;
41
+ active: boolean;
42
+ version: number;
43
+ }>;
44
+ assignInitialMembership(trx: Transaction<IdentitySchema>, actor: Principal, userId: string, tenantId: string, roleId: string): Promise<void>;
45
+ updateMembership(actor: Principal, id: string, raw: unknown): Promise<{
46
+ id: string;
47
+ userId: string;
48
+ tenantId: string;
49
+ roleId: string;
50
+ portal: Portal;
51
+ active: boolean;
52
+ version: number;
53
+ }>;
54
+ removeMembership(actor: Principal, id: string, expectedVersion?: number): Promise<void>;
55
+ private manage;
56
+ private scope;
57
+ private tenantId;
58
+ private activeTenant;
59
+ private audit;
60
+ }
@@ -0,0 +1,216 @@
1
+ import { IdentityError } from "../support/identity.error.js";
2
+ import { checkIdentityRequest } from "../support/identity.request-context.js";
3
+ import { protectAdministrators } from "./user-role.policy.js";
4
+ import { membershipSchema, membershipUpdateSchema } from "./user-role.schema.js";
5
+ import { listMemberships, showMembership } from "./user-role.repository.js";
6
+ export class IdentityUserRoleService {
7
+ db;
8
+ readSources;
9
+ activeUsers;
10
+ resolveRole;
11
+ customRoleInApp;
12
+ mutate;
13
+ assertUserVisible;
14
+ activeOrganization;
15
+ recordAudit;
16
+ revokeMembershipSessions;
17
+ constructor(db, readSources, activeUsers, resolveRole, customRoleInApp, mutate, assertUserVisible, activeOrganization, recordAudit, revokeMembershipSessions) {
18
+ this.db = db;
19
+ this.readSources = readSources;
20
+ this.activeUsers = activeUsers;
21
+ this.resolveRole = resolveRole;
22
+ this.customRoleInApp = customRoleInApp;
23
+ this.mutate = mutate;
24
+ this.assertUserVisible = assertUserVisible;
25
+ this.activeOrganization = activeOrganization;
26
+ this.recordAudit = recordAudit;
27
+ this.revokeMembershipSessions = revokeMembershipSessions;
28
+ }
29
+ list(actor, query) {
30
+ this.manage(actor);
31
+ return listMemberships(this.db, actor, query, this.readSources);
32
+ }
33
+ show(actor, id) {
34
+ this.manage(actor);
35
+ return showMembership(this.db, actor, id, this.readSources);
36
+ }
37
+ async createMembership(actor, raw) {
38
+ this.manage(actor);
39
+ const input = membershipSchema.parse(raw);
40
+ const tenantId = this.tenantId(actor, input.tenantId);
41
+ const selected = await this.resolveRole(this.db, actor, input.roleId, tenantId);
42
+ await this.assertUserVisible(actor, input.userId);
43
+ const id = `${input.userId}~${tenantId}~${selected.portal}`;
44
+ return this.mutate(actor, "memberships", id, async (trx) => {
45
+ await this.activeTenant(trx, tenantId);
46
+ const currentRole = await this.resolveRole(trx, actor, input.roleId, tenantId);
47
+ if (await trx
48
+ .selectFrom("identity_memberships")
49
+ .select("user_id")
50
+ .where("user_id", "=", input.userId)
51
+ .where("tenant_id", "=", tenantId)
52
+ .where("role_id", "=", currentRole.portal)
53
+ .executeTakeFirst())
54
+ throw new IdentityError(409, "Membership already exists.");
55
+ await trx
56
+ .insertInto("identity_memberships")
57
+ .values({
58
+ user_id: input.userId,
59
+ tenant_id: tenantId,
60
+ role_id: currentRole.portal,
61
+ custom_role_id: currentRole.customRoleId
62
+ })
63
+ .execute();
64
+ return {
65
+ id,
66
+ userId: input.userId,
67
+ tenantId,
68
+ roleId: input.roleId,
69
+ portal: currentRole.portal,
70
+ active: true,
71
+ version: 0
72
+ };
73
+ });
74
+ }
75
+ async assignInitialMembership(trx, actor, userId, tenantId, roleId) {
76
+ this.manage(actor);
77
+ this.tenantId(actor, tenantId);
78
+ await this.activeTenant(trx, tenantId);
79
+ const selected = await this.resolveRole(trx, actor, roleId, tenantId);
80
+ await trx
81
+ .insertInto("identity_memberships")
82
+ .values({
83
+ user_id: userId,
84
+ tenant_id: tenantId,
85
+ role_id: selected.portal,
86
+ custom_role_id: selected.customRoleId
87
+ })
88
+ .execute();
89
+ }
90
+ async updateMembership(actor, id, raw) {
91
+ this.manage(actor);
92
+ const input = membershipUpdateSchema.parse(raw);
93
+ const [userId, tenantId, oldPortal, extra] = id.split("~");
94
+ if (!userId || !tenantId || !oldPortal || extra)
95
+ throw new IdentityError(404, "Membership not found.");
96
+ this.scope(actor, tenantId);
97
+ if (actor.portal !== "super-admin" && oldPortal !== "user")
98
+ throw new IdentityError(403, "Only super administrators can change privileged memberships.");
99
+ return this.db.transaction().execute(async (trx) => {
100
+ checkIdentityRequest();
101
+ const current = await trx
102
+ .selectFrom("identity_memberships")
103
+ .selectAll()
104
+ .where("user_id", "=", userId)
105
+ .where("tenant_id", "=", tenantId)
106
+ .where("role_id", "=", oldPortal)
107
+ .executeTakeFirst();
108
+ if (!current)
109
+ throw new IdentityError(404, "Membership not found.");
110
+ if (current.custom_role_id &&
111
+ !(await this.customRoleInApp(trx, current.custom_role_id, actor.appId)))
112
+ throw new IdentityError(404, "Membership not found.");
113
+ if (input.active && !(await this.activeOrganization(trx, tenantId)))
114
+ throw new IdentityError(422, "Organization is inactive or unavailable.");
115
+ if (Number(current.version) !== input.expectedVersion)
116
+ throw new IdentityError(409, "This record changed. Reload before saving.");
117
+ const selected = await this.resolveRole(trx, actor, input.roleId, tenantId);
118
+ if (!input.active || selected.portal !== oldPortal)
119
+ await protectAdministrators(trx, userId, this.activeUsers, tenantId, oldPortal);
120
+ if (selected.portal !== oldPortal &&
121
+ (await trx
122
+ .selectFrom("identity_memberships")
123
+ .select("user_id")
124
+ .where("user_id", "=", userId)
125
+ .where("tenant_id", "=", tenantId)
126
+ .where("role_id", "=", selected.portal)
127
+ .executeTakeFirst()))
128
+ throw new IdentityError(409, "This account already has that portal membership.");
129
+ const changed = await trx
130
+ .updateTable("identity_memberships")
131
+ .set({
132
+ role_id: selected.portal,
133
+ custom_role_id: selected.customRoleId,
134
+ active: Number(input.active),
135
+ version: input.expectedVersion + 1
136
+ })
137
+ .where("user_id", "=", userId)
138
+ .where("tenant_id", "=", tenantId)
139
+ .where("role_id", "=", oldPortal)
140
+ .where("version", "=", input.expectedVersion)
141
+ .executeTakeFirst();
142
+ if (changed.numUpdatedRows !== 1n)
143
+ throw new IdentityError(409, "This record changed. Reload before saving.");
144
+ await this.revokeMembershipSessions(trx, actor.appId, userId, tenantId, oldPortal);
145
+ const nextId = `${userId}~${tenantId}~${selected.portal}`;
146
+ await this.audit(trx, actor, tenantId, "identity.membership.changed", nextId);
147
+ checkIdentityRequest();
148
+ return {
149
+ id: nextId,
150
+ userId,
151
+ tenantId,
152
+ roleId: selected.customRoleId ?? selected.portal,
153
+ portal: selected.portal,
154
+ active: input.active,
155
+ version: input.expectedVersion + 1
156
+ };
157
+ });
158
+ }
159
+ async removeMembership(actor, id, expectedVersion) {
160
+ this.manage(actor);
161
+ if (!Number.isInteger(expectedVersion) || Number(expectedVersion) < 0)
162
+ throw new IdentityError(422, "Provide the current membership version.");
163
+ const [userId, tenantId, portal, extra] = id.split("~");
164
+ if (!userId || !tenantId || !portal || extra)
165
+ throw new IdentityError(404, "Membership not found.");
166
+ this.scope(actor, tenantId);
167
+ if (actor.portal !== "super-admin" && portal !== "user")
168
+ throw new IdentityError(403, "Only super administrators can change privileged memberships.");
169
+ await this.db.transaction().execute(async (trx) => {
170
+ checkIdentityRequest();
171
+ const current = await trx
172
+ .selectFrom("identity_memberships")
173
+ .select(["custom_role_id", "version"])
174
+ .where("user_id", "=", userId)
175
+ .where("tenant_id", "=", tenantId)
176
+ .where("role_id", "=", portal)
177
+ .executeTakeFirst();
178
+ if (!current ||
179
+ (current.custom_role_id &&
180
+ !(await this.customRoleInApp(trx, current.custom_role_id, actor.appId))))
181
+ throw new IdentityError(404, "Membership not found.");
182
+ if (Number(current.version) !== expectedVersion)
183
+ throw new IdentityError(409, "This record changed. Reload before saving.");
184
+ await protectAdministrators(trx, userId, this.activeUsers, tenantId, portal);
185
+ await trx
186
+ .deleteFrom("identity_memberships")
187
+ .where("user_id", "=", userId)
188
+ .where("tenant_id", "=", tenantId)
189
+ .where("role_id", "=", portal)
190
+ .execute();
191
+ await this.revokeMembershipSessions(trx, actor.appId, userId, tenantId, portal);
192
+ await this.audit(trx, actor, tenantId, "identity.membership.removed", id);
193
+ checkIdentityRequest();
194
+ });
195
+ }
196
+ manage(actor) {
197
+ if (actor.portal === "user" || !actor.permissions.includes("identity.manage"))
198
+ throw new IdentityError(403, "Access denied.");
199
+ }
200
+ scope(actor, tenantId) {
201
+ if (actor.portal !== "super-admin" && tenantId !== actor.tenant.id)
202
+ throw new IdentityError(403, "Access denied.");
203
+ }
204
+ tenantId(actor, requested) {
205
+ if (requested && requested !== actor.tenant.id && actor.portal !== "super-admin")
206
+ throw new IdentityError(403, "Access denied.");
207
+ return requested ?? actor.tenant.id;
208
+ }
209
+ async activeTenant(trx, tenantId) {
210
+ if (!(await this.activeOrganization(trx, tenantId)))
211
+ throw new IdentityError(422, "Organization is inactive or unavailable.");
212
+ }
213
+ async audit(trx, actor, tenantId, action, resourceId) {
214
+ await this.recordAudit(trx, actor, tenantId, action, resourceId);
215
+ }
216
+ }
@@ -0,0 +1,12 @@
1
+ import type { Generated } from "kysely";
2
+ export interface IdentityUserRoleTables {
3
+ identity_memberships: {
4
+ user_id: string;
5
+ tenant_id: string;
6
+ role_id: string;
7
+ custom_role_id: Generated<string | null>;
8
+ active: Generated<number>;
9
+ version: Generated<number>;
10
+ };
11
+ }
12
+ export type IdentityMembershipRow = IdentityUserRoleTables["identity_memberships"];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export { createTenantProvider } from "./tenant.provider.js";
2
+ export { tenantConnectionsMigration, createLegacyTenantConnectionsMigration, createTenantConnectionsMigration } from "./tenant.migration.js";
3
+ export type { TenantRegistrySchema, TenantMasterSchema, TenantDatabase, TenantScope, TenantPrincipal, TenantIdentity, TenantProvider } from "./tenant.types.js";
4
+ export { verifyTenantReadiness } from "./tenant.readiness.js";
5
+ export { provisionTenant } from "./tenant.seed.js";
6
+ export { executeTenantCommand } from "./tenant.command.js";
@@ -0,0 +1,5 @@
1
+ export { createTenantProvider } from "./tenant.provider.js";
2
+ export { tenantConnectionsMigration, createLegacyTenantConnectionsMigration, createTenantConnectionsMigration } from "./tenant.migration.js";
3
+ export { verifyTenantReadiness } from "./tenant.readiness.js";
4
+ export { provisionTenant } from "./tenant.seed.js";
5
+ export { executeTenantCommand } from "./tenant.command.js";
@@ -0,0 +1,3 @@
1
+ export declare function executeTenantCommand(database: import("./tenant.types.js").TenantDatabase & {
2
+ provisionConnection(target: import("@devxcrew/framework").ConnectionTarget): Promise<unknown>;
3
+ }, environment: NodeJS.ProcessEnv, command?: string, args?: string[]): Promise<void>;
@@ -0,0 +1,43 @@
1
+ import { backupConnection, checkConnectionBackup } from "@devxcrew/framework";
2
+ import { provisionTenant } from "./tenant.seed.js";
3
+ import { tenantMappingSchema } from "./tenant.schema.js";
4
+ import { TenantRepository } from "./tenant.repository.js";
5
+ import { join } from "node:path";
6
+ export async function executeTenantCommand(database, environment, command = "provision", args = []) {
7
+ if (command === "provision")
8
+ console.info(await provisionTenant(database, environment));
9
+ else if (["backup", "verify-backup", "verify-restore"].includes(command)) {
10
+ const id = environment.IDENTITY_TENANT_ID ?? "default";
11
+ const row = await new TenantRepository(database.database).find(id);
12
+ if (!row)
13
+ throw new Error("Tenant mapping is missing.");
14
+ const mapping = tenantMappingSchema.parse({
15
+ tenantId: id,
16
+ driver: row.driver,
17
+ databaseName: row.databaseName,
18
+ sqlitePath: row.sqlitePath,
19
+ active: Number(row.active),
20
+ version: Number(row.version)
21
+ });
22
+ const target = {
23
+ key: id,
24
+ driver: mapping.driver,
25
+ databaseName: mapping.databaseName,
26
+ sqlitePath: mapping.sqlitePath,
27
+ version: mapping.version
28
+ };
29
+ const path = args[0] ??
30
+ (command === "backup"
31
+ ? join(environment.DB_BACKUP_DIR ?? "storage/private/data/backup", `tenant-${new Date().toISOString().replace(/[:.]/g, "-")}.${mapping.driver === "mariadb" ? "sql" : "sqlite"}`)
32
+ : undefined);
33
+ if (!path)
34
+ throw new Error("Supply a backup path.");
35
+ if (command === "backup")
36
+ await backupConnection(environment, target, path);
37
+ else
38
+ await checkConnectionBackup(environment, target, path, command === "verify-restore");
39
+ console.info(`Tenant ${command} passed: ${path}`);
40
+ }
41
+ else
42
+ throw new Error("Unknown tenant command.");
43
+ }
@@ -0,0 +1,4 @@
1
+ import type { DatabaseInfrastructureSchema } from "@devxcrew/framework";
2
+ import type { IncomingMessage, ServerResponse } from "node:http";
3
+ import type { TenantProvider } from "./tenant.types.js";
4
+ export declare function tenantController<Schema extends DatabaseInfrastructureSchema>(provider: TenantProvider<Schema>, request: IncomingMessage, response: ServerResponse, signal?: AbortSignal): Promise<boolean>;
@@ -0,0 +1,12 @@
1
+ export async function tenantController(provider, request, response, signal) {
2
+ await provider.runRequest(request, async () => {
3
+ const scope = provider.current();
4
+ response.writeHead(200, {
5
+ "Content-Type": "application/json",
6
+ "Cache-Control": "no-store",
7
+ "X-Content-Type-Options": "nosniff"
8
+ });
9
+ response.end(JSON.stringify({ data: { tenantId: scope.tenantId, portal: scope.principal.portal } }));
10
+ }, signal);
11
+ return true;
12
+ }
@@ -0,0 +1,5 @@
1
+ import type { Migration } from "kysely/migration";
2
+ /** Compatibility names come from the consuming app's migration composition. */
3
+ export declare function createLegacyTenantConnectionsMigration(tableName: string): Migration;
4
+ export declare function createTenantConnectionsMigration(previousTable?: string): Migration;
5
+ export declare const tenantConnectionsMigration: Migration;
@@ -0,0 +1,46 @@
1
+ /** Compatibility names come from the consuming app's migration composition. */
2
+ export function createLegacyTenantConnectionsMigration(tableName) {
3
+ assertTableName(tableName);
4
+ return {
5
+ async up(database) {
6
+ await database.schema
7
+ .createTable(tableName)
8
+ .addColumn("tenant_id", "text", (column) => column.primaryKey().references("identity_tenants.id").onDelete("cascade"))
9
+ .addColumn("driver", "text", (column) => column.notNull())
10
+ .addColumn("database_name", "text")
11
+ .addColumn("sqlite_path", "text")
12
+ .addColumn("active", "integer", (column) => column.notNull().defaultTo(1))
13
+ .addColumn("version", "integer", (column) => column.notNull().defaultTo(1))
14
+ .execute();
15
+ },
16
+ async down(database) {
17
+ await database.schema.dropTable(tableName).ifExists().execute();
18
+ }
19
+ };
20
+ }
21
+ export function createTenantConnectionsMigration(previousTable) {
22
+ if (!previousTable)
23
+ return createLegacyTenantConnectionsMigration("tenant_connections");
24
+ assertTableName(previousTable);
25
+ if (previousTable === "tenant_connections")
26
+ throw new Error("The previous mapping table must differ.");
27
+ return {
28
+ async up(database) {
29
+ const tables = new Set((await database.introspection.getTables()).map((table) => table.name));
30
+ if (tables.has(previousTable) && tables.has("tenant_connections"))
31
+ throw new Error("Tenant mapping tables require reconciliation.");
32
+ if (tables.has(previousTable))
33
+ await database.schema.alterTable(previousTable).renameTo("tenant_connections").execute();
34
+ else if (!tables.has("tenant_connections"))
35
+ throw new Error("The previous tenant migration is missing.");
36
+ },
37
+ async down() {
38
+ throw new Error("Tenant mapping rename requires an explicit recovery plan.");
39
+ }
40
+ };
41
+ }
42
+ export const tenantConnectionsMigration = createTenantConnectionsMigration();
43
+ function assertTableName(name) {
44
+ if (!/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(name))
45
+ throw new Error("Invalid migration table name.");
46
+ }
@@ -0,0 +1,3 @@
1
+ import { type DatabaseInfrastructureSchema } from "@devxcrew/framework";
2
+ import type { TenantDatabase, TenantIdentity, TenantProvider } from "./tenant.types.js";
3
+ export declare function createTenantProvider<Schema extends DatabaseInfrastructureSchema = DatabaseInfrastructureSchema>(database: TenantDatabase<Schema>, identity: TenantIdentity, environment: NodeJS.ProcessEnv): TenantProvider<Schema>;
@@ -0,0 +1,44 @@
1
+ import { HttpError } from "@devxcrew/framework";
2
+ import { z } from "zod";
3
+ import { IdentityError, createIdentityTenantDirectory } from "../identity/index.js";
4
+ import { TenantRepository } from "./tenant.repository.js";
5
+ import { TenantService } from "./tenant.service.js";
6
+ import { tenantRequestSchema } from "./tenant.schema.js";
7
+ import { tenantRoutes } from "./tenant.routes.js";
8
+ export function createTenantProvider(database, identity, environment) {
9
+ const mode = z
10
+ .enum(["single-client", "multi-tenant"])
11
+ .parse(environment.IDENTITY_MODE ?? "single-client");
12
+ const clientId = z
13
+ .string()
14
+ .min(1)
15
+ .parse(environment.IDENTITY_TENANT_ID ?? "default");
16
+ const service = new TenantService(new TenantRepository(database.database), createIdentityTenantDirectory(database.database), database, mode, clientId);
17
+ const provider = {
18
+ handle: (request, response, signal) => tenantRoutes(provider, request, response, signal),
19
+ current: () => service.current(),
20
+ verify: () => service.verify(),
21
+ withPrincipal: (...args) => service.withPrincipal(...args),
22
+ async runRequest(request, work, signal) {
23
+ const input = tenantRequestSchema.safeParse({
24
+ portal: request.headers["x-identity-portal"] ?? "user",
25
+ tenantId: request.headers["x-tenant-id"]
26
+ });
27
+ if (!input.success || request.headers["x-tenant-db"] !== undefined)
28
+ throw new HttpError(422, "tenant_context_invalid", "Invalid tenant request context.");
29
+ const principal = await identity
30
+ .authenticateRequest(request, input.data.portal, signal)
31
+ .catch((error) => {
32
+ if (error instanceof IdentityError) {
33
+ const fields = error.fields
34
+ ? Object.fromEntries(Object.entries(error.fields).map(([key, values]) => [key, [...values]]))
35
+ : undefined;
36
+ throw new HttpError(error.status, error.code, error.message, fields);
37
+ }
38
+ throw error;
39
+ });
40
+ return service.withPrincipal(principal, input.data.tenantId, work, signal);
41
+ }
42
+ };
43
+ return provider;
44
+ }
@@ -0,0 +1,6 @@
1
+ import type { TenantDatabase } from "./tenant.types.js";
2
+ export declare function verifyTenantReadiness(database: TenantDatabase): Promise<{
3
+ readonly checked: number;
4
+ readonly unmapped: number;
5
+ readonly status: "partial" | "ready";
6
+ }>;
@@ -0,0 +1,45 @@
1
+ import { createIdentityTenantDirectory } from "../identity/index.js";
2
+ import { TenantRepository } from "./tenant.repository.js";
3
+ import { sql } from "kysely";
4
+ import { tenantMappingSchema } from "./tenant.schema.js";
5
+ export async function verifyTenantReadiness(database) {
6
+ const directory = createIdentityTenantDirectory(database.database);
7
+ const repository = new TenantRepository(database.database);
8
+ let cursor = "";
9
+ let checked = 0;
10
+ let unmapped = 0;
11
+ while (true) {
12
+ const tenants = await directory.listActive(cursor, 50);
13
+ if (!tenants.length)
14
+ break;
15
+ for (const tenant of tenants) {
16
+ cursor = tenant.id;
17
+ const row = await repository.find(tenant.id);
18
+ if (!row) {
19
+ unmapped++;
20
+ continue;
21
+ }
22
+ if (Number(row.active) !== 1)
23
+ continue;
24
+ const parsed = tenantMappingSchema.safeParse({
25
+ ...row,
26
+ active: Number(row.active),
27
+ version: Number(row.version)
28
+ });
29
+ if (!parsed.success)
30
+ throw new Error("An active tenant mapping is invalid.");
31
+ const mapping = parsed.data;
32
+ await database.withConnection({
33
+ key: mapping.tenantId,
34
+ driver: mapping.driver,
35
+ databaseName: mapping.databaseName,
36
+ sqlitePath: mapping.sqlitePath,
37
+ version: mapping.version
38
+ }, async (connection) => {
39
+ await sql `SELECT 1`.execute(connection);
40
+ });
41
+ checked++;
42
+ }
43
+ }
44
+ return { checked, unmapped, status: unmapped ? "partial" : "ready" };
45
+ }
@@ -0,0 +1,15 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { TenantMasterSchema } from "./tenant.types.js";
3
+ export declare class TenantRepository {
4
+ private readonly database;
5
+ constructor(database: Kysely<TenantMasterSchema>);
6
+ find(id: string): Promise<{
7
+ active: number;
8
+ databaseName: string | null;
9
+ driver: "mariadb" | "sqlite";
10
+ sqlitePath: string | null;
11
+ tenantId: string;
12
+ version: number;
13
+ } | undefined>;
14
+ verify(): Promise<void>;
15
+ }
@@ -0,0 +1,23 @@
1
+ export class TenantRepository {
2
+ database;
3
+ constructor(database) {
4
+ this.database = database;
5
+ }
6
+ async find(id) {
7
+ return this.database
8
+ .selectFrom("tenant_connections as connection")
9
+ .select([
10
+ "connection.tenant_id as tenantId",
11
+ "connection.driver",
12
+ "connection.database_name as databaseName",
13
+ "connection.sqlite_path as sqlitePath",
14
+ "connection.active",
15
+ "connection.version"
16
+ ])
17
+ .where("connection.tenant_id", "=", id)
18
+ .executeTakeFirst();
19
+ }
20
+ async verify() {
21
+ await this.database.selectFrom("tenant_connections").select("tenant_id").limit(1).execute();
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ import type { DatabaseInfrastructureSchema } from "@devxcrew/framework";
2
+ import type { IncomingMessage, ServerResponse } from "node:http";
3
+ import type { TenantProvider } from "./tenant.types.js";
4
+ export declare function tenantRoutes<Schema extends DatabaseInfrastructureSchema>(provider: TenantProvider<Schema>, request: IncomingMessage, response: ServerResponse, signal?: AbortSignal): false | Promise<boolean>;
@@ -0,0 +1,7 @@
1
+ import { tenantController } from "./tenant.controller.js";
2
+ export function tenantRoutes(provider, request, response, signal) {
3
+ if (new URL(request.url ?? "/", "http://localhost").pathname !== "/api/v1/tenants/current" ||
4
+ request.method !== "GET")
5
+ return false;
6
+ return tenantController(provider, request, response, signal);
7
+ }
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ export declare const tenantRequestSchema: z.ZodObject<{
3
+ portal: z.ZodDefault<z.ZodEnum<{
4
+ admin: "admin";
5
+ "super-admin": "super-admin";
6
+ user: "user";
7
+ }>>;
8
+ tenantId: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strict>;
10
+ export declare const tenantMappingSchema: z.ZodObject<{
11
+ tenantId: z.ZodString;
12
+ driver: z.ZodEnum<{
13
+ mariadb: "mariadb";
14
+ sqlite: "sqlite";
15
+ }>;
16
+ databaseName: z.ZodNullable<z.ZodString>;
17
+ sqlitePath: z.ZodNullable<z.ZodString>;
18
+ active: z.ZodNumber;
19
+ version: z.ZodNumber;
20
+ }, z.core.$strict>;