create-mithaq 0.0.0-stage → 0.1.1

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 (357) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSES/payload.txt +22 -0
  3. package/LICENSES/ponytail.txt +21 -0
  4. package/index.js +127 -0
  5. package/package.json +19 -4
  6. package/template/apps/asas-platform/components.json +25 -0
  7. package/template/apps/asas-platform/gitignore +3 -0
  8. package/template/apps/asas-platform/package.json +55 -0
  9. package/template/apps/asas-platform/public/favicon.svg +1 -0
  10. package/template/apps/asas-platform/src/api.ts +147 -0
  11. package/template/apps/asas-platform/src/auth-frame.tsx +150 -0
  12. package/template/apps/asas-platform/src/components/mithaq/cells.tsx +112 -0
  13. package/template/apps/asas-platform/src/components/mithaq/controls.tsx +650 -0
  14. package/template/apps/asas-platform/src/components/mithaq/field-shell.tsx +53 -0
  15. package/template/apps/asas-platform/src/components/mithaq/filter-operators.ts +108 -0
  16. package/template/apps/asas-platform/src/components/mithaq/form.tsx +1467 -0
  17. package/template/apps/asas-platform/src/components/mithaq/list-columns.tsx +108 -0
  18. package/template/apps/asas-platform/src/components/mithaq/list-filters.tsx +368 -0
  19. package/template/apps/asas-platform/src/components/mithaq/list-pagination.tsx +153 -0
  20. package/template/apps/asas-platform/src/components/mithaq/list-query.ts +432 -0
  21. package/template/apps/asas-platform/src/components/mithaq/list-selection.tsx +74 -0
  22. package/template/apps/asas-platform/src/components/mithaq/list.tsx +865 -0
  23. package/template/apps/asas-platform/src/components/mithaq/nav.tsx +871 -0
  24. package/template/apps/asas-platform/src/components/mithaq/nodes.tsx +1024 -0
  25. package/template/apps/asas-platform/src/components/mithaq/relationship-cell.tsx +127 -0
  26. package/template/apps/asas-platform/src/components/mithaq/relationship-control.tsx +400 -0
  27. package/template/apps/asas-platform/src/components/mithaq/rich-text-nodes.ts +6 -0
  28. package/template/apps/asas-platform/src/components/mithaq/rich-text.tsx +1083 -0
  29. package/template/apps/asas-platform/src/components/mithaq/upload.tsx +686 -0
  30. package/template/apps/asas-platform/src/components/ui/accordion.tsx +74 -0
  31. package/template/apps/asas-platform/src/components/ui/alert-dialog.tsx +185 -0
  32. package/template/apps/asas-platform/src/components/ui/avatar.tsx +106 -0
  33. package/template/apps/asas-platform/src/components/ui/badge.tsx +48 -0
  34. package/template/apps/asas-platform/src/components/ui/breadcrumb.tsx +124 -0
  35. package/template/apps/asas-platform/src/components/ui/button-group.tsx +87 -0
  36. package/template/apps/asas-platform/src/components/ui/button.tsx +55 -0
  37. package/template/apps/asas-platform/src/components/ui/calendar.tsx +223 -0
  38. package/template/apps/asas-platform/src/components/ui/card.tsx +102 -0
  39. package/template/apps/asas-platform/src/components/ui/chart.tsx +371 -0
  40. package/template/apps/asas-platform/src/components/ui/checkbox.tsx +28 -0
  41. package/template/apps/asas-platform/src/components/ui/collapsible.tsx +19 -0
  42. package/template/apps/asas-platform/src/components/ui/combobox.tsx +308 -0
  43. package/template/apps/asas-platform/src/components/ui/dialog.tsx +158 -0
  44. package/template/apps/asas-platform/src/components/ui/direction.tsx +6 -0
  45. package/template/apps/asas-platform/src/components/ui/directional-icon.tsx +20 -0
  46. package/template/apps/asas-platform/src/components/ui/drawer.tsx +216 -0
  47. package/template/apps/asas-platform/src/components/ui/dropdown-menu.tsx +267 -0
  48. package/template/apps/asas-platform/src/components/ui/field.tsx +236 -0
  49. package/template/apps/asas-platform/src/components/ui/input-group.tsx +155 -0
  50. package/template/apps/asas-platform/src/components/ui/input-otp.tsx +84 -0
  51. package/template/apps/asas-platform/src/components/ui/input.tsx +19 -0
  52. package/template/apps/asas-platform/src/components/ui/label.tsx +19 -0
  53. package/template/apps/asas-platform/src/components/ui/popover.tsx +90 -0
  54. package/template/apps/asas-platform/src/components/ui/radio-group.tsx +37 -0
  55. package/template/apps/asas-platform/src/components/ui/resizable.tsx +47 -0
  56. package/template/apps/asas-platform/src/components/ui/scroll-area.tsx +54 -0
  57. package/template/apps/asas-platform/src/components/ui/select.tsx +204 -0
  58. package/template/apps/asas-platform/src/components/ui/separator.tsx +24 -0
  59. package/template/apps/asas-platform/src/components/ui/sheet.tsx +139 -0
  60. package/template/apps/asas-platform/src/components/ui/sidebar.tsx +714 -0
  61. package/template/apps/asas-platform/src/components/ui/skeleton.tsx +13 -0
  62. package/template/apps/asas-platform/src/components/ui/slider.tsx +55 -0
  63. package/template/apps/asas-platform/src/components/ui/spinner.tsx +10 -0
  64. package/template/apps/asas-platform/src/components/ui/switch.tsx +29 -0
  65. package/template/apps/asas-platform/src/components/ui/table.tsx +115 -0
  66. package/template/apps/asas-platform/src/components/ui/tabs.tsx +79 -0
  67. package/template/apps/asas-platform/src/components/ui/textarea.tsx +17 -0
  68. package/template/apps/asas-platform/src/components/ui/toggle-group.tsx +89 -0
  69. package/template/apps/asas-platform/src/components/ui/toggle.tsx +44 -0
  70. package/template/apps/asas-platform/src/components/ui/tooltip.tsx +63 -0
  71. package/template/apps/asas-platform/src/copy.ts +1 -0
  72. package/template/apps/asas-platform/src/hooks/use-mobile.ts +19 -0
  73. package/template/apps/asas-platform/src/lib/utils.ts +1 -0
  74. package/template/apps/asas-platform/src/links.ts +38 -0
  75. package/template/apps/asas-platform/src/locale-switch.tsx +26 -0
  76. package/template/apps/asas-platform/src/redirect.ts +1 -0
  77. package/template/apps/asas-platform/src/request-headers.ts +11 -0
  78. package/template/apps/asas-platform/src/routeTree.gen.ts +181 -0
  79. package/template/apps/asas-platform/src/router.tsx +7 -0
  80. package/template/apps/asas-platform/src/routes/(screens)/platform/files.ts +4 -0
  81. package/template/apps/asas-platform/src/routes/(screens)/platform/screen.json +3609 -0
  82. package/template/apps/asas-platform/src/routes/(screens)/platform/types.ts +145 -0
  83. package/template/apps/asas-platform/src/routes/(screens)/platform.$.tsx +17 -0
  84. package/template/apps/asas-platform/src/routes/(screens)/platform.index.tsx +10 -0
  85. package/template/apps/asas-platform/src/routes/(screens)/platform.tsx +13 -0
  86. package/template/apps/asas-platform/src/routes/__root.tsx +95 -0
  87. package/template/apps/asas-platform/src/routes/api/$.ts +30 -0
  88. package/template/apps/asas-platform/src/routes/auth.sign-in.tsx +72 -0
  89. package/template/apps/asas-platform/src/routes/unauthorized.tsx +122 -0
  90. package/template/apps/asas-platform/src/screen-form.tsx +34 -0
  91. package/template/apps/asas-platform/src/screen-list.tsx +139 -0
  92. package/template/apps/asas-platform/src/screen-names.ts +10 -0
  93. package/template/apps/asas-platform/src/screens.tsx +868 -0
  94. package/template/apps/asas-platform/src/server.ts +20 -0
  95. package/template/apps/asas-platform/src/slide.ts +22 -0
  96. package/template/apps/asas-platform/src/start.ts +42 -0
  97. package/template/apps/asas-platform/src/styles.css +200 -0
  98. package/template/apps/asas-platform/src/theme.ts +2 -0
  99. package/template/apps/asas-platform/tsconfig.json +19 -0
  100. package/template/apps/asas-platform/vite.config.ts +26 -0
  101. package/template/apps/asas-tanstack/components.json +25 -0
  102. package/template/apps/asas-tanstack/gitignore +3 -0
  103. package/template/apps/asas-tanstack/package.json +56 -0
  104. package/template/apps/asas-tanstack/public/favicon.svg +1 -0
  105. package/template/apps/asas-tanstack/src/api.ts +147 -0
  106. package/template/apps/asas-tanstack/src/auth-frame.tsx +150 -0
  107. package/template/apps/asas-tanstack/src/components/mithaq/cells.tsx +112 -0
  108. package/template/apps/asas-tanstack/src/components/mithaq/controls.tsx +650 -0
  109. package/template/apps/asas-tanstack/src/components/mithaq/field-shell.tsx +53 -0
  110. package/template/apps/asas-tanstack/src/components/mithaq/filter-operators.ts +108 -0
  111. package/template/apps/asas-tanstack/src/components/mithaq/form.tsx +1467 -0
  112. package/template/apps/asas-tanstack/src/components/mithaq/list-columns.tsx +108 -0
  113. package/template/apps/asas-tanstack/src/components/mithaq/list-filters.tsx +368 -0
  114. package/template/apps/asas-tanstack/src/components/mithaq/list-pagination.tsx +153 -0
  115. package/template/apps/asas-tanstack/src/components/mithaq/list-query.ts +432 -0
  116. package/template/apps/asas-tanstack/src/components/mithaq/list-selection.tsx +74 -0
  117. package/template/apps/asas-tanstack/src/components/mithaq/list.tsx +865 -0
  118. package/template/apps/asas-tanstack/src/components/mithaq/nav.tsx +871 -0
  119. package/template/apps/asas-tanstack/src/components/mithaq/nodes.tsx +1024 -0
  120. package/template/apps/asas-tanstack/src/components/mithaq/relationship-cell.tsx +127 -0
  121. package/template/apps/asas-tanstack/src/components/mithaq/relationship-control.tsx +400 -0
  122. package/template/apps/asas-tanstack/src/components/mithaq/rich-text-nodes.ts +6 -0
  123. package/template/apps/asas-tanstack/src/components/mithaq/rich-text.tsx +1083 -0
  124. package/template/apps/asas-tanstack/src/components/mithaq/upload.tsx +686 -0
  125. package/template/apps/asas-tanstack/src/components/ui/accordion.tsx +10 -0
  126. package/template/apps/asas-tanstack/src/components/ui/alert-dialog.tsx +173 -0
  127. package/template/apps/asas-tanstack/src/components/ui/avatar.tsx +104 -0
  128. package/template/apps/asas-tanstack/src/components/ui/badge.tsx +48 -0
  129. package/template/apps/asas-tanstack/src/components/ui/breadcrumb.tsx +125 -0
  130. package/template/apps/asas-tanstack/src/components/ui/button-group.tsx +87 -0
  131. package/template/apps/asas-tanstack/src/components/ui/button.tsx +56 -0
  132. package/template/apps/asas-tanstack/src/components/ui/calendar.tsx +223 -0
  133. package/template/apps/asas-tanstack/src/components/ui/card.tsx +94 -0
  134. package/template/apps/asas-tanstack/src/components/ui/chart.tsx +369 -0
  135. package/template/apps/asas-tanstack/src/components/ui/checkbox.tsx +27 -0
  136. package/template/apps/asas-tanstack/src/components/ui/collapsible.tsx +19 -0
  137. package/template/apps/asas-tanstack/src/components/ui/combobox.tsx +300 -0
  138. package/template/apps/asas-tanstack/src/components/ui/dialog.tsx +149 -0
  139. package/template/apps/asas-tanstack/src/components/ui/direction.tsx +5 -0
  140. package/template/apps/asas-tanstack/src/components/ui/directional-icon.tsx +20 -0
  141. package/template/apps/asas-tanstack/src/components/ui/drawer.tsx +215 -0
  142. package/template/apps/asas-tanstack/src/components/ui/dropdown-menu.tsx +267 -0
  143. package/template/apps/asas-tanstack/src/components/ui/field.tsx +225 -0
  144. package/template/apps/asas-tanstack/src/components/ui/input-group.tsx +147 -0
  145. package/template/apps/asas-tanstack/src/components/ui/input-otp.tsx +20 -0
  146. package/template/apps/asas-tanstack/src/components/ui/input.tsx +20 -0
  147. package/template/apps/asas-tanstack/src/components/ui/label.tsx +18 -0
  148. package/template/apps/asas-tanstack/src/components/ui/popover.tsx +50 -0
  149. package/template/apps/asas-tanstack/src/components/ui/radio-group.tsx +10 -0
  150. package/template/apps/asas-tanstack/src/components/ui/resizable.tsx +47 -0
  151. package/template/apps/asas-tanstack/src/components/ui/scroll-area.tsx +52 -0
  152. package/template/apps/asas-tanstack/src/components/ui/select.tsx +190 -0
  153. package/template/apps/asas-tanstack/src/components/ui/separator.tsx +23 -0
  154. package/template/apps/asas-tanstack/src/components/ui/sheet.tsx +127 -0
  155. package/template/apps/asas-tanstack/src/components/ui/sidebar.tsx +716 -0
  156. package/template/apps/asas-tanstack/src/components/ui/skeleton.tsx +13 -0
  157. package/template/apps/asas-tanstack/src/components/ui/slider.tsx +13 -0
  158. package/template/apps/asas-tanstack/src/components/ui/spinner.tsx +11 -0
  159. package/template/apps/asas-tanstack/src/components/ui/switch.tsx +8 -0
  160. package/template/apps/asas-tanstack/src/components/ui/table.tsx +119 -0
  161. package/template/apps/asas-tanstack/src/components/ui/tabs.tsx +80 -0
  162. package/template/apps/asas-tanstack/src/components/ui/textarea.tsx +18 -0
  163. package/template/apps/asas-tanstack/src/components/ui/toggle-group.tsx +8 -0
  164. package/template/apps/asas-tanstack/src/components/ui/toggle.tsx +44 -0
  165. package/template/apps/asas-tanstack/src/components/ui/tooltip.tsx +68 -0
  166. package/template/apps/asas-tanstack/src/copy.ts +870 -0
  167. package/template/apps/asas-tanstack/src/hooks/use-mobile.ts +19 -0
  168. package/template/apps/asas-tanstack/src/lib/utils.ts +6 -0
  169. package/template/apps/asas-tanstack/src/links.ts +38 -0
  170. package/template/apps/asas-tanstack/src/locale-switch.tsx +26 -0
  171. package/template/apps/asas-tanstack/src/quiet-abort.ts +25 -0
  172. package/template/apps/asas-tanstack/src/redirect.ts +20 -0
  173. package/template/apps/asas-tanstack/src/request-headers.ts +11 -0
  174. package/template/apps/asas-tanstack/src/routeTree.gen.ts +382 -0
  175. package/template/apps/asas-tanstack/src/router.tsx +7 -0
  176. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/files.ts +4 -0
  177. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/screen.json +3883 -0
  178. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/types.ts +158 -0
  179. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.$.tsx +17 -0
  180. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.index.tsx +10 -0
  181. package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.tsx +13 -0
  182. package/template/apps/asas-tanstack/src/routes/(screens)/portal/files.ts +4 -0
  183. package/template/apps/asas-tanstack/src/routes/(screens)/portal/screen.json +1800 -0
  184. package/template/apps/asas-tanstack/src/routes/(screens)/portal/types.ts +92 -0
  185. package/template/apps/asas-tanstack/src/routes/(screens)/portal.$.tsx +17 -0
  186. package/template/apps/asas-tanstack/src/routes/(screens)/portal.index.tsx +10 -0
  187. package/template/apps/asas-tanstack/src/routes/(screens)/portal.tsx +13 -0
  188. package/template/apps/asas-tanstack/src/routes/__root.tsx +99 -0
  189. package/template/apps/asas-tanstack/src/routes/api/$.ts +11 -0
  190. package/template/apps/asas-tanstack/src/routes/auth.accept-invitation.tsx +101 -0
  191. package/template/apps/asas-tanstack/src/routes/auth.forgot-password.tsx +94 -0
  192. package/template/apps/asas-tanstack/src/routes/auth.handoff.ts +39 -0
  193. package/template/apps/asas-tanstack/src/routes/auth.reset-password.tsx +109 -0
  194. package/template/apps/asas-tanstack/src/routes/auth.sign-in.tsx +86 -0
  195. package/template/apps/asas-tanstack/src/routes/auth.sign-up.tsx +122 -0
  196. package/template/apps/asas-tanstack/src/routes/index.tsx +142 -0
  197. package/template/apps/asas-tanstack/src/routes/unauthorized.tsx +122 -0
  198. package/template/apps/asas-tanstack/src/screen-form.tsx +34 -0
  199. package/template/apps/asas-tanstack/src/screen-list.tsx +139 -0
  200. package/template/apps/asas-tanstack/src/screen-names.ts +10 -0
  201. package/template/apps/asas-tanstack/src/screens.tsx +868 -0
  202. package/template/apps/asas-tanstack/src/server.ts +16 -0
  203. package/template/apps/asas-tanstack/src/slide.ts +22 -0
  204. package/template/apps/asas-tanstack/src/start.ts +57 -0
  205. package/template/apps/asas-tanstack/src/styles.css +159 -0
  206. package/template/apps/asas-tanstack/src/theme.ts +5 -0
  207. package/template/apps/asas-tanstack/tsconfig.json +19 -0
  208. package/template/apps/asas-tanstack/vite.config.ts +28 -0
  209. package/template/package.json +16 -0
  210. package/template/templates/asas/.env.example +16 -0
  211. package/template/templates/asas/components.json +22 -0
  212. package/template/templates/asas/mithaq.hints.json +25 -0
  213. package/template/templates/asas/package.json +38 -0
  214. package/template/templates/asas/src/asas.ts +93 -0
  215. package/template/templates/asas/src/audit-log/audit-log.ts +187 -0
  216. package/template/templates/asas/src/audit-log/sink.ts +89 -0
  217. package/template/templates/asas/src/audit-log/ui/activity.tsx +243 -0
  218. package/template/templates/asas/src/courses/courses.ts +612 -0
  219. package/template/templates/asas/src/courses/ui/archive-button.tsx +25 -0
  220. package/template/templates/asas/src/courses/ui/fee-cell.tsx +19 -0
  221. package/template/templates/asas/src/courses/ui/no-courses-on-offer.tsx +11 -0
  222. package/template/templates/asas/src/courses/ui/no-courses.tsx +13 -0
  223. package/template/templates/asas/src/courses/ui/on-offer.ts +6 -0
  224. package/template/templates/asas/src/courses/ui/status-cell.tsx +31 -0
  225. package/template/templates/asas/src/enrollments/enrollments.ts +137 -0
  226. package/template/templates/asas/src/enrollments/ui/session-cell.tsx +65 -0
  227. package/template/templates/asas/src/kayan/auth/user/account.access.ts +8 -0
  228. package/template/templates/asas/src/kayan/auth/user/account.ts +31 -0
  229. package/template/templates/asas/src/kayan/auth/user/index.ts +18 -0
  230. package/template/templates/asas/src/kayan/auth/user/invitation.access.ts +4 -0
  231. package/template/templates/asas/src/kayan/auth/user/invitation.ts +27 -0
  232. package/template/templates/asas/src/kayan/auth/user/member.access.ts +10 -0
  233. package/template/templates/asas/src/kayan/auth/user/member.screens.ts +37 -0
  234. package/template/templates/asas/src/kayan/auth/user/member.ts +25 -0
  235. package/template/templates/asas/src/kayan/auth/user/organization.access.ts +20 -0
  236. package/template/templates/asas/src/kayan/auth/user/organization.screens.ts +37 -0
  237. package/template/templates/asas/src/kayan/auth/user/organization.ts +24 -0
  238. package/template/templates/asas/src/kayan/auth/user/organizationRole.access.ts +8 -0
  239. package/template/templates/asas/src/kayan/auth/user/organizationRole.ts +25 -0
  240. package/template/templates/asas/src/kayan/auth/user/session.access.ts +8 -0
  241. package/template/templates/asas/src/kayan/auth/user/session.ts +28 -0
  242. package/template/templates/asas/src/kayan/auth/user/user.access.ts +29 -0
  243. package/template/templates/asas/src/kayan/auth/user/user.screens.ts +45 -0
  244. package/template/templates/asas/src/kayan/auth/user/user.ts +31 -0
  245. package/template/templates/asas/src/kayan/auth/user/verification.access.ts +8 -0
  246. package/template/templates/asas/src/kayan/auth/user/verification.ts +23 -0
  247. package/template/templates/asas/src/local-users/local-users.ts +143 -0
  248. package/template/templates/asas/src/media/media.ts +137 -0
  249. package/template/templates/asas/src/media/ui/preview.tsx +143 -0
  250. package/template/templates/asas/src/member-roles/member-roles.ts +207 -0
  251. package/template/templates/asas/src/messages/account.json +106 -0
  252. package/template/templates/asas/src/messages/auditLog.json +186 -0
  253. package/template/templates/asas/src/messages/courses.json +270 -0
  254. package/template/templates/asas/src/messages/enrollments.json +42 -0
  255. package/template/templates/asas/src/messages/invitation.json +66 -0
  256. package/template/templates/asas/src/messages/localUsers.json +42 -0
  257. package/template/templates/asas/src/messages/media.json +66 -0
  258. package/template/templates/asas/src/messages/member.json +42 -0
  259. package/template/templates/asas/src/messages/memberRoles.json +42 -0
  260. package/template/templates/asas/src/messages/mithaq.json +170 -0
  261. package/template/templates/asas/src/messages/organization.json +50 -0
  262. package/template/templates/asas/src/messages/organizationRole.json +50 -0
  263. package/template/templates/asas/src/messages/roles.json +58 -0
  264. package/template/templates/asas/src/messages/session.json +82 -0
  265. package/template/templates/asas/src/messages/sessions.json +106 -0
  266. package/template/templates/asas/src/messages/settings.json +66 -0
  267. package/template/templates/asas/src/messages/tags.json +38 -0
  268. package/template/templates/asas/src/messages/user.json +90 -0
  269. package/template/templates/asas/src/messages/verification.json +50 -0
  270. package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/migration.sql +177 -0
  271. package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/snapshot.json +2169 -0
  272. package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/migration.sql +1 -0
  273. package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/snapshot.json +2182 -0
  274. package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/migration.sql +20 -0
  275. package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/snapshot.json +2409 -0
  276. package/template/templates/asas/src/migrations/20260922082945_military_ironclad/migration.sql +15 -0
  277. package/template/templates/asas/src/migrations/20260922082945_military_ironclad/snapshot.json +2627 -0
  278. package/template/templates/asas/src/migrations/20260922112630_bitter_chat/migration.sql +5 -0
  279. package/template/templates/asas/src/migrations/20260922112630_bitter_chat/snapshot.json +2691 -0
  280. package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/migration.sql +8 -0
  281. package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/snapshot.json +2795 -0
  282. package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/migration.sql +3 -0
  283. package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/snapshot.json +2834 -0
  284. package/template/templates/asas/src/migrations/20260927212525_bent_prowler/migration.sql +9 -0
  285. package/template/templates/asas/src/migrations/20260927212525_bent_prowler/snapshot.json +2870 -0
  286. package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/migration.sql +1 -0
  287. package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/snapshot.json +2881 -0
  288. package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/migration.sql +15 -0
  289. package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/snapshot.json +3073 -0
  290. package/template/templates/asas/src/migrations/20260929024407_grey_morlun/migration.sql +21 -0
  291. package/template/templates/asas/src/migrations/20260929024407_grey_morlun/snapshot.json +3098 -0
  292. package/template/templates/asas/src/migrations/20260929130530_bored_jackal/migration.sql +21 -0
  293. package/template/templates/asas/src/migrations/20260929130530_bored_jackal/snapshot.json +3124 -0
  294. package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/migration.sql +32 -0
  295. package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/snapshot.json +3324 -0
  296. package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/migration.sql +2 -0
  297. package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/snapshot.json +3350 -0
  298. package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/migration.sql +21 -0
  299. package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/snapshot.json +3635 -0
  300. package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/migration.sql +8 -0
  301. package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/snapshot.json +3635 -0
  302. package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/migration.sql +18 -0
  303. package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/snapshot.json +3635 -0
  304. package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/migration.sql +18 -0
  305. package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/snapshot.json +3635 -0
  306. package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/migration.sql +11 -0
  307. package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/snapshot.json +3667 -0
  308. package/template/templates/asas/src/migrations/20261012000752_organization_ownership/migration.sql +48 -0
  309. package/template/templates/asas/src/migrations/20261012000752_organization_ownership/snapshot.json +3891 -0
  310. package/template/templates/asas/src/migrations/drizzle.config.ts +11 -0
  311. package/template/templates/asas/src/migrations/schema.ts +29 -0
  312. package/template/templates/asas/src/mithaq.ts +406 -0
  313. package/template/templates/asas/src/pages.ts +74 -0
  314. package/template/templates/asas/src/platform-http.ts +96 -0
  315. package/template/templates/asas/src/rich-text-nodes.ts +11 -0
  316. package/template/templates/asas/src/roles/grants.ts +47 -0
  317. package/template/templates/asas/src/roles/roles.ts +184 -0
  318. package/template/templates/asas/src/roles/ui/role-form.tsx +226 -0
  319. package/template/templates/asas/src/roles/ui/roles.tsx +166 -0
  320. package/template/templates/asas/src/roles.ts +16 -0
  321. package/template/templates/asas/src/seed.ts +325 -0
  322. package/template/templates/asas/src/sessions/sessions.ts +155 -0
  323. package/template/templates/asas/src/settings/settings.ts +69 -0
  324. package/template/templates/asas/src/statements.ts +11 -0
  325. package/template/templates/asas/src/steps/expected-updated-at.ts +41 -0
  326. package/template/templates/asas/src/storage/defaults.ts +156 -0
  327. package/template/templates/asas/src/storage/index.ts +95 -0
  328. package/template/templates/asas/src/storage/local.ts +143 -0
  329. package/template/templates/asas/src/storage/r2.ts +5 -0
  330. package/template/templates/asas/src/storage/s3.ts +91 -0
  331. package/template/templates/asas/src/storage/uploadthing.ts +59 -0
  332. package/template/templates/asas/src/tags/tags.ts +80 -0
  333. package/template/templates/asas/src/tenant-access.ts +221 -0
  334. package/template/templates/asas/src/tenant-roles.ts +262 -0
  335. package/template/templates/asas/src/ui/app-shell.tsx +260 -0
  336. package/template/templates/asas/src/ui/kpi-card.tsx +25 -0
  337. package/template/templates/asas/src/ui/record-page.tsx +50 -0
  338. package/template/templates/asas/src/ui/rich-text-nodes.tsx +15 -0
  339. package/template/templates/asas/src/ui/screen-nav.tsx +28 -0
  340. package/template/templates/asas/src/ui/session-labels.tsx +36 -0
  341. package/template/templates/asas/src/ui/table-page.tsx +9 -0
  342. package/template/templates/asas/src/ui/top-shell.tsx +60 -0
  343. package/template/templates/asas/src/ui-dashboard/dashboard.tsx +294 -0
  344. package/template/templates/asas/src/ui-dashboard/members.tsx +630 -0
  345. package/template/templates/asas/src/ui-dashboard/theme-provider.tsx +10 -0
  346. package/template/templates/asas/src/ui-dashboard/versions.tsx +432 -0
  347. package/template/templates/asas/src/ui-platform/home.tsx +63 -0
  348. package/template/templates/asas/src/ui-platform/organization-actions.tsx +114 -0
  349. package/template/templates/asas/src/ui-platform/record-page.tsx +30 -0
  350. package/template/templates/asas/src/ui-platform/role-cells.tsx +52 -0
  351. package/template/templates/asas/src/ui-platform/user-actions.tsx +251 -0
  352. package/template/templates/asas/src/ui-portal/home.tsx +77 -0
  353. package/template/templates/asas/src/ui-portal/page.tsx +11 -0
  354. package/template/templates/auth/package.json +14 -0
  355. package/template/templates/auth/src/index.ts +690 -0
  356. package/template/templates/auth/src/platform-roles.ts +87 -0
  357. package/README.md +0 -3
@@ -0,0 +1,207 @@
1
+ import { sql } from 'mithaq/drizzle'
2
+ import type { NodePgDatabase } from 'mithaq/drizzle/node-postgres'
3
+ import { assignableRole, conflict, defaultFields, defaultOperations, denied, type Ctx, type WriteTools } from 'mithaq'
4
+ import { defineKayan, platformUi, rows, organization } from '../mithaq.ts'
5
+ import { platformList, platformRecord } from '../pages.ts'
6
+ import { tenantRoles } from '../roles.ts'
7
+ import { platformReads } from '../tenant-access.ts'
8
+ import { managesRoles, OWNER, OWNER_ROLE } from '../roles/grants.ts'
9
+
10
+ const role = { field: 'role', cell: platformUi('role-cells.tsx#RoleName') } as const
11
+
12
+ /**
13
+ * Nobody takes from themselves the role that lets them manage roles: their own
14
+ * `administrator`, or any role holding a key that manages roles. Another member
15
+ * holding the same keys removes it.
16
+ *
17
+ * A custom role's keys are read as the actor, through the role kayan's own
18
+ * access, so a role the actor may not read is refused rather than taken off
19
+ * unchecked. It guards a member's own row; two administrators removing each
20
+ * other at once are `managerRemains`' to refuse.
21
+ */
22
+ const keepsOwnManager = async (ctx: Ctx, tools: WriteTools): Promise<Ctx> => {
23
+ const before = ctx.dataBefore
24
+ const me = (ctx.actor as { id?: unknown } | undefined)?.id
25
+ if (!before || me === undefined || before.user !== me) return ctx
26
+ const after = { ...before, ...(ctx.data as Record<string, unknown>) }
27
+ if (tools.kind === 'update' && after.user === before.user && after.role === before.role) return ctx
28
+ const role = String(before.role)
29
+ const roles = (tools.kayans as { roles: { find(input: object): Promise<{ docs: { permissions?: unknown }[] }> } }).roles
30
+ const keys = Object.hasOwn(tenantRoles, role)
31
+ ? tenantRoles[role as keyof typeof tenantRoles].permissions
32
+ : (await roles.find({ where: { name: { equals: role } } })).docs.flatMap((row) => (Array.isArray(row.permissions) ? (row.permissions as string[]) : []))
33
+ if (!managesRoles(keys)) return ctx
34
+ throw denied({
35
+ message: `Forbidden: role "${role}" is what lets this member manage roles, so it is not taken from themselves. Another member who may manage roles removes it.`,
36
+ key: 'error.forbidden.own_role',
37
+ params: { kayan: ctx.kayan.name, role },
38
+ })
39
+ }
40
+
41
+ /** The write's transaction, which is drizzle's here. */
42
+ const txOf = (ctx: Ctx) => ctx.tx as NodePgDatabase
43
+
44
+ /**
45
+ * How many assignments of one tenant name one role, counted inside the write's
46
+ * own transaction rather than read as the actor: a number leaves this function
47
+ * and no row does, so a role's author needs no `memberRoles` key to learn
48
+ * whether a name is still carried.
49
+ */
50
+ export const assignedCount = async ({ ctx, tenantId, role }: { ctx: Ctx; tenantId: unknown; role: string }): Promise<number> => {
51
+ const [found] = (
52
+ await txOf(ctx).execute<{ total: number }>(sql`select count(*)::int as total from member_roles where organization_id = ${String(tenantId)} and role = ${role}`)
53
+ ).rows
54
+ return found?.total ?? 0
55
+ }
56
+
57
+ /**
58
+ * What a write changes about who manages roles: an assignment removed, or
59
+ * moved to another member or role, or a custom role's keys, which are `[]`
60
+ * when it is deleted.
61
+ */
62
+ type Change = { assignment: Readonly<Record<string, unknown>>; becomes?: { user: unknown; role: unknown } } | { role: string; keys: readonly string[] }
63
+
64
+ /**
65
+ * **Every tenant keeps a member who may manage roles**: one holding a role whose
66
+ * keys `managesRoles` answers for, or the organization's owner, who always holds
67
+ * `administrator`. A write that would leave none is refused 409
68
+ * `error.conflict.last_manager`. Removing the owner's own `administrator` row
69
+ * changes nothing the owner holds, so it is refused too, 403
70
+ * `error.forbidden.owner_role`.
71
+ *
72
+ * The check runs under `pg_advisory_xact_lock` on the tenant, held to the end of
73
+ * the write's transaction, and every guarded write takes the same lock first, so
74
+ * two administrators removing each other at once are serialized and the second
75
+ * reads the first's removal. `FOR UPDATE` on the manager assignments would not
76
+ * do: which assignments manage roles also depends on the roles table, and a role
77
+ * losing its keys touches no assignment row.
78
+ *
79
+ * Rows are read through the store rather than as the actor, because the answer
80
+ * is about every member of the tenant and the actor may read few of them;
81
+ * nothing read leaves this function but the refusal.
82
+ */
83
+ export const managerRemains = async ({ ctx, tenantId, change }: { ctx: Ctx; tenantId: unknown; change: Change }): Promise<void> => {
84
+ const tx = txOf(ctx)
85
+ const tenant = String(tenantId)
86
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext('mithaq.managers'), hashtext(${tenant}))`)
87
+ const owners = (
88
+ await tx.execute<{ user: string }>(
89
+ sql`select user_id as "user" from member where organization_id = ${tenant} and ${OWNER} = any(string_to_array(role, ','))`,
90
+ )
91
+ ).rows.map((row) => row.user)
92
+ if ('assignment' in change) {
93
+ const { assignment, becomes } = change
94
+ if (assignment.role === OWNER_ROLE && owners.includes(String(assignment.user)) && (becomes?.role !== assignment.role || becomes.user !== assignment.user)) {
95
+ throw denied({
96
+ message: `Forbidden: the organization's owner always holds "${OWNER_ROLE}", so the row saying so is not taken from them.`,
97
+ key: 'error.forbidden.owner_role',
98
+ params: { kayan: ctx.kayan.name, role: OWNER_ROLE },
99
+ })
100
+ }
101
+ }
102
+ if (owners.length) return
103
+ const assigned = (await tx.execute<{ id: string; user: string; role: string }>(sql`select id, user_id as "user", role from member_roles where organization_id = ${tenant}`)).rows
104
+ const custom = new Map<string, readonly string[]>(
105
+ (await tx.execute<{ name: string; permissions: string[] }>(sql`select name, permissions from roles where organization_id = ${tenant}`)).rows.map((row) => [row.name, row.permissions] as const),
106
+ )
107
+ if ('keys' in change) custom.set(change.role, change.keys)
108
+ const keysOf = (role: string) => (Object.hasOwn(tenantRoles, role) ? tenantRoles[role as keyof typeof tenantRoles].permissions : (custom.get(role) ?? []))
109
+ const after = assigned.flatMap((row) => {
110
+ if (!('assignment' in change) || row.id !== change.assignment.id) return [row]
111
+ return change.becomes ? [{ ...row, role: String(change.becomes.role) }] : []
112
+ })
113
+ if (after.some((row) => managesRoles(keysOf(row.role)))) return
114
+ throw conflict({
115
+ message: `This write would leave the tenant with no member who may manage roles, so it is refused. Give another member such a role first.`,
116
+ key: 'error.conflict.last_manager',
117
+ params: { kayan: ctx.kayan.name },
118
+ })
119
+ }
120
+
121
+ /** `managerRemains` for an assignment's update or delete; an update that neither moves the row nor changes its role changes nothing. */
122
+ const keepsAManager = async (ctx: Ctx, tools: WriteTools): Promise<Ctx> => {
123
+ const before = ctx.dataBefore
124
+ if (!before) return ctx
125
+ const after = tools.kind === 'update' ? { ...before, ...(ctx.data as Record<string, unknown>) } : undefined
126
+ if (after && after.user === before.user && after.role === before.role) return ctx
127
+ await managerRemains({ ctx, tenantId: before.organization, change: { assignment: before, ...(after && { becomes: { user: after.user, role: after.role } }) } })
128
+ return ctx
129
+ }
130
+
131
+ /**
132
+ * Who holds which of this project's roles, per tenant: one row per member per
133
+ * role. It exists so that Better Auth's own `member.role` never carries a
134
+ * business role name beside its governance one: a role name holding a comma would
135
+ * be accepted by `create-role` and could never be assigned again, because that
136
+ * column is comma-delimited.
137
+ *
138
+ * The access target reads it straight from the store while the actor is being
139
+ * made, filtered on this tenant and this member, so another tenant's row is
140
+ * never in what comes back.
141
+ */
142
+ export const memberRoles = defineKayan({
143
+ name: 'memberRoles',
144
+ dbName: 'member_roles',
145
+ targets: {
146
+ // Every organization's rows on the platform, read-only, and each row's
147
+ // record. An assignment is looked for by its person, is titled by them, and
148
+ // reads its role by the role's label, never its slug.
149
+ platform: {
150
+ useAsTitle: 'user',
151
+ pages: {
152
+ ...platformList('/member-roles', { columns: ['user', role, 'organization'], filters: ['organization', 'user', 'role'], search: ['user.name', 'user.email'] }),
153
+ ...platformRecord({ path: '/member-roles/:id', main: [{ section: 'assignment', label: { en: 'Assignment', ar: 'الإسناد' }, fields: ['user', role] }] }),
154
+ },
155
+ },
156
+ // No dashboard page and so no nav entry: a member's roles are changed on the
157
+ // Members page's sheet, which writes these rows through the operations below,
158
+ // guards and all.
159
+ service: {
160
+ operations: {
161
+ ...defaultOperations,
162
+ // The gate in front of the store step: the runner has parsed by then, so
163
+ // the column is a string, and the write has not happened, so a refused
164
+ // assignment leaves no row. Without it a custom role holding
165
+ // `memberRoles.create` assigns itself `administrator`. It is handed the
166
+ // tenant roles alone, so a platform role such as `support` reads as an
167
+ // unknown custom role and is refused 400. `'roles'` is the kayan it reads
168
+ // the tenant's custom roles from.
169
+ create: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), steps.insert] },
170
+ update: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), keepsOwnManager, keepsAManager, steps.update] },
171
+ // Removing an assignment is measured the way handing it out is. Without it
172
+ // an actor delegated `memberRoles.delete` removes the tenant's only
173
+ // administrator row. The guard reads the row the store holds, because a
174
+ // delete names no column.
175
+ delete: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), keepsOwnManager, keepsAManager, steps.remove] },
176
+ },
177
+ },
178
+ },
179
+ // Its own rows, since the inherited table would close the instructor's
180
+ // delete here. Every platform role reads the assignments of every tenant in
181
+ // the platform app and changes none; in the tenant app `assignedRoles` omits
182
+ // the platform slugs.
183
+ access: rows({
184
+ '*': { create: true, read: true, update: true, delete: true },
185
+ ...platformReads,
186
+ }),
187
+ /** A member holds a role once per tenant. A second assignment answers 409 `error.conflict.unique`. */
188
+ indexes: [{ within: 'organization', unique: [['user', 'role']] }],
189
+ fields: {
190
+ ...defaultFields,
191
+ organization,
192
+ user: {
193
+ kind: 'relationship',
194
+ label: { ar: 'العضو', en: 'Member' },
195
+ relationTo: 'user',
196
+ // The assignment goes with the member: a deleted user holds no role, and
197
+ // `restrict`, which a required relationship takes by default, would leave a
198
+ // row nothing can reach standing in the way of the delete.
199
+ rules: { required: true, index: true, onDelete: 'cascade' },
200
+ },
201
+ role: {
202
+ kind: 'text',
203
+ label: { ar: 'الدور', en: 'Role' },
204
+ rules: { required: true, maxLength: 60, index: true },
205
+ },
206
+ },
207
+ })
@@ -0,0 +1,106 @@
1
+ {
2
+ "accessToken.invalid": {
3
+ "ar": "هذا ليس نصا.",
4
+ "en": "This is not text."
5
+ },
6
+ "accessToken.required": {
7
+ "ar": "هذا الحقل مطلوب.",
8
+ "en": "This field is required."
9
+ },
10
+ "accessTokenExpiresAt.invalid": {
11
+ "ar": "هذا ليس تاريخا ووقتا.",
12
+ "en": "This is not a date and time."
13
+ },
14
+ "accessTokenExpiresAt.required": {
15
+ "ar": "هذا الحقل مطلوب.",
16
+ "en": "This field is required."
17
+ },
18
+ "accountId.invalid": {
19
+ "ar": "هذا ليس نصا.",
20
+ "en": "This is not text."
21
+ },
22
+ "accountId.required": {
23
+ "ar": "هذا الحقل مطلوب.",
24
+ "en": "This field is required."
25
+ },
26
+ "createdAt.invalid": {
27
+ "ar": "هذا ليس تاريخا ووقتا.",
28
+ "en": "This is not a date and time."
29
+ },
30
+ "createdAt.required": {
31
+ "ar": "هذا الحقل مطلوب.",
32
+ "en": "This field is required."
33
+ },
34
+ "id.invalid": {
35
+ "ar": "هذا ليس نصا.",
36
+ "en": "This is not text."
37
+ },
38
+ "id.required": {
39
+ "ar": "هذا الحقل مطلوب.",
40
+ "en": "This field is required."
41
+ },
42
+ "idToken.invalid": {
43
+ "ar": "هذا ليس نصا.",
44
+ "en": "This is not text."
45
+ },
46
+ "idToken.required": {
47
+ "ar": "هذا الحقل مطلوب.",
48
+ "en": "This field is required."
49
+ },
50
+ "password.invalid": {
51
+ "ar": "هذا ليس نصا.",
52
+ "en": "This is not text."
53
+ },
54
+ "password.required": {
55
+ "ar": "هذا الحقل مطلوب.",
56
+ "en": "This field is required."
57
+ },
58
+ "providerId.invalid": {
59
+ "ar": "هذا ليس نصا.",
60
+ "en": "This is not text."
61
+ },
62
+ "providerId.required": {
63
+ "ar": "هذا الحقل مطلوب.",
64
+ "en": "This field is required."
65
+ },
66
+ "refreshToken.invalid": {
67
+ "ar": "هذا ليس نصا.",
68
+ "en": "This is not text."
69
+ },
70
+ "refreshToken.required": {
71
+ "ar": "هذا الحقل مطلوب.",
72
+ "en": "This field is required."
73
+ },
74
+ "refreshTokenExpiresAt.invalid": {
75
+ "ar": "هذا ليس تاريخا ووقتا.",
76
+ "en": "This is not a date and time."
77
+ },
78
+ "refreshTokenExpiresAt.required": {
79
+ "ar": "هذا الحقل مطلوب.",
80
+ "en": "This field is required."
81
+ },
82
+ "scope.invalid": {
83
+ "ar": "هذا ليس نصا.",
84
+ "en": "This is not text."
85
+ },
86
+ "scope.required": {
87
+ "ar": "هذا الحقل مطلوب.",
88
+ "en": "This field is required."
89
+ },
90
+ "updatedAt.invalid": {
91
+ "ar": "هذا ليس تاريخا ووقتا.",
92
+ "en": "This is not a date and time."
93
+ },
94
+ "updatedAt.required": {
95
+ "ar": "هذا الحقل مطلوب.",
96
+ "en": "This field is required."
97
+ },
98
+ "userId.invalid": {
99
+ "ar": "اختر عنصرًا من القائمة.",
100
+ "en": "Pick one of the listed entries."
101
+ },
102
+ "userId.required": {
103
+ "ar": "هذا الحقل مطلوب.",
104
+ "en": "This field is required."
105
+ }
106
+ }
@@ -0,0 +1,186 @@
1
+ {
2
+ "action.archive": {
3
+ "ar": "أُرشف",
4
+ "en": "Archived"
5
+ },
6
+ "action.archiveMany": {
7
+ "ar": "أُرشف",
8
+ "en": "Archived"
9
+ },
10
+ "action.create": {
11
+ "ar": "أُنشئ",
12
+ "en": "Created"
13
+ },
14
+ "action.delete": {
15
+ "ar": "حُذف",
16
+ "en": "Deleted"
17
+ },
18
+ "action.deleteMany": {
19
+ "ar": "حُذف",
20
+ "en": "Deleted"
21
+ },
22
+ "action.restoreVersion": {
23
+ "ar": "استُعيد إصدار",
24
+ "en": "Restored a version"
25
+ },
26
+ "action.update": {
27
+ "ar": "حُدِّث",
28
+ "en": "Updated"
29
+ },
30
+ "action.updateMany": {
31
+ "ar": "حُدِّث",
32
+ "en": "Updated"
33
+ },
34
+ "activity": {
35
+ "ar": "النشاط",
36
+ "en": "Activity"
37
+ },
38
+ "actor": {
39
+ "ar": "المنفذ",
40
+ "en": "Actor"
41
+ },
42
+ "actor.invalid": {
43
+ "ar": "هذا ليس نصا.",
44
+ "en": "This is not text."
45
+ },
46
+ "actor.required": {
47
+ "ar": "هذا الحقل مطلوب.",
48
+ "en": "This field is required."
49
+ },
50
+ "changes": {
51
+ "ar": "التغييرات",
52
+ "en": "Changes"
53
+ },
54
+ "changes.invalid": {
55
+ "ar": "هذا ليس نصا.",
56
+ "en": "This is not text."
57
+ },
58
+ "changes.required": {
59
+ "ar": "هذا الحقل مطلوب.",
60
+ "en": "This field is required."
61
+ },
62
+ "command": {
63
+ "ar": "الأمر {command} ({user})",
64
+ "en": "the command {command} ({user})"
65
+ },
66
+ "empty": {
67
+ "ar": "لم يتغير شيء هنا بعد.",
68
+ "en": "Nothing has changed here yet."
69
+ },
70
+ "event": {
71
+ "ar": "{action} بواسطة {actor}",
72
+ "en": "{action} by {actor}"
73
+ },
74
+ "eventYou": {
75
+ "ar": "{action} بواسطتك",
76
+ "en": "{action} by You"
77
+ },
78
+ "failed": {
79
+ "ar": "تعذرت قراءة النشاط.",
80
+ "en": "The activity could not be read."
81
+ },
82
+ "id.invalid": {
83
+ "ar": "هذا ليس معرفا فريدا.",
84
+ "en": "This is not a unique identifier."
85
+ },
86
+ "id.required": {
87
+ "ar": "هذا الحقل مطلوب.",
88
+ "en": "This field is required."
89
+ },
90
+ "impersonated": {
91
+ "ar": "{staff} بصفة {member}",
92
+ "en": "{staff} as {member}"
93
+ },
94
+ "impersonatedBy": {
95
+ "ar": "انتحل الصفة",
96
+ "en": "Impersonated by"
97
+ },
98
+ "impersonatedBy.invalid": {
99
+ "ar": "هذا ليس نصا.",
100
+ "en": "This is not text."
101
+ },
102
+ "impersonatedBy.required": {
103
+ "ar": "هذا الحقل مطلوب.",
104
+ "en": "This field is required."
105
+ },
106
+ "kayan": {
107
+ "ar": "الكيان",
108
+ "en": "Kayan"
109
+ },
110
+ "kayan.invalid": {
111
+ "ar": "هذا ليس نصا.",
112
+ "en": "This is not text."
113
+ },
114
+ "kayan.maxLength": {
115
+ "ar": "القيمة طويلة جدًا.",
116
+ "en": "The value is too long."
117
+ },
118
+ "kayan.required": {
119
+ "ar": "هذا الحقل مطلوب.",
120
+ "en": "This field is required."
121
+ },
122
+ "loading": {
123
+ "ar": "جارٍ تحميل النشاط…",
124
+ "en": "Loading activity…"
125
+ },
126
+ "more": {
127
+ "ar": "عرض الأقدم",
128
+ "en": "Show older"
129
+ },
130
+ "none": {
131
+ "ar": "لم يتغير حقل يمكنك قراءته.",
132
+ "en": "No field you may read changed."
133
+ },
134
+ "operation": {
135
+ "ar": "العملية",
136
+ "en": "Operation"
137
+ },
138
+ "operation.invalid": {
139
+ "ar": "هذا ليس نصا.",
140
+ "en": "This is not text."
141
+ },
142
+ "operation.maxLength": {
143
+ "ar": "القيمة طويلة جدًا.",
144
+ "en": "The value is too long."
145
+ },
146
+ "operation.required": {
147
+ "ar": "هذا الحقل مطلوب.",
148
+ "en": "This field is required."
149
+ },
150
+ "organization": {
151
+ "ar": "المؤسسة",
152
+ "en": "Organization"
153
+ },
154
+ "plural": {
155
+ "ar": "سجل التدقيق",
156
+ "en": "Audit log"
157
+ },
158
+ "record": {
159
+ "ar": "السجل",
160
+ "en": "Record"
161
+ },
162
+ "record.invalid": {
163
+ "ar": "هذا ليس نصا.",
164
+ "en": "This is not text."
165
+ },
166
+ "record.required": {
167
+ "ar": "هذا الحقل مطلوب.",
168
+ "en": "This field is required."
169
+ },
170
+ "singular": {
171
+ "ar": "سجل تدقيق",
172
+ "en": "Audit entry"
173
+ },
174
+ "someone": {
175
+ "ar": "شخص ما",
176
+ "en": "Someone"
177
+ },
178
+ "system": {
179
+ "ar": "النظام",
180
+ "en": "The system"
181
+ },
182
+ "you": {
183
+ "ar": "أنت",
184
+ "en": "You"
185
+ }
186
+ }