@ketvietlab/ketsuite 0.1.22 → 0.1.25

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 (237) hide show
  1. package/dist/cli.js +9 -3
  2. package/dist/cli.js.map +1 -1
  3. package/dist/demo/crm.d.ts +3 -0
  4. package/dist/demo/crm.d.ts.map +1 -0
  5. package/dist/demo/crm.js +418 -0
  6. package/dist/demo/crm.js.map +1 -0
  7. package/dist/demo/partner.d.ts +8 -0
  8. package/dist/demo/partner.d.ts.map +1 -0
  9. package/dist/demo/partner.js +179 -0
  10. package/dist/demo/partner.js.map +1 -0
  11. package/dist/demo/product.d.ts +25 -0
  12. package/dist/demo/product.d.ts.map +1 -0
  13. package/dist/demo/product.js +579 -0
  14. package/dist/demo/product.js.map +1 -0
  15. package/dist/demo/purchase.d.ts +4 -0
  16. package/dist/demo/purchase.d.ts.map +1 -0
  17. package/dist/demo/purchase.js +58 -0
  18. package/dist/demo/purchase.js.map +1 -0
  19. package/dist/demo/sale.d.ts +4 -0
  20. package/dist/demo/sale.d.ts.map +1 -0
  21. package/dist/demo/sale.js +52 -0
  22. package/dist/demo/sale.js.map +1 -0
  23. package/dist/demo/seed.d.ts +14 -0
  24. package/dist/demo/seed.d.ts.map +1 -0
  25. package/dist/demo/seed.js +88 -0
  26. package/dist/demo/seed.js.map +1 -0
  27. package/dist/demo/stock.d.ts +7 -0
  28. package/dist/demo/stock.d.ts.map +1 -0
  29. package/dist/demo/stock.js +26 -0
  30. package/dist/demo/stock.js.map +1 -0
  31. package/dist/demo/user.d.ts +4 -0
  32. package/dist/demo/user.d.ts.map +1 -0
  33. package/dist/demo/user.js +41 -0
  34. package/dist/demo/user.js.map +1 -0
  35. package/dist/demo/util.d.ts +7 -0
  36. package/dist/demo/util.d.ts.map +1 -0
  37. package/dist/demo/util.js +19 -0
  38. package/dist/demo/util.js.map +1 -0
  39. package/dist/modules/backend/design/client/backend-shell.d.mts +2 -2
  40. package/dist/modules/backend/design/client/backend-shell.d.mts.map +1 -1
  41. package/dist/modules/backend/design/client/backend-shell.mjs +1 -1
  42. package/dist/modules/backend/design/client/backend-shell.mjs.map +3 -3
  43. package/dist/modules/backend/design/forms.css +7 -0
  44. package/dist/modules/backend/screen.d.ts.map +1 -1
  45. package/dist/modules/backend/screen.js +11 -2
  46. package/dist/modules/backend/screen.js.map +1 -1
  47. package/dist/modules/crm/functions/access.d.ts +3 -0
  48. package/dist/modules/crm/functions/access.d.ts.map +1 -0
  49. package/dist/modules/crm/functions/access.js +89 -0
  50. package/dist/modules/crm/functions/access.js.map +1 -0
  51. package/dist/modules/crm/functions/activities.d.ts +3 -0
  52. package/dist/modules/crm/functions/activities.d.ts.map +1 -0
  53. package/dist/modules/crm/functions/activities.js +174 -0
  54. package/dist/modules/crm/functions/activities.js.map +1 -0
  55. package/dist/modules/crm/functions/cases.d.ts +3 -0
  56. package/dist/modules/crm/functions/cases.d.ts.map +1 -0
  57. package/dist/modules/crm/functions/cases.js +585 -0
  58. package/dist/modules/crm/functions/cases.js.map +1 -0
  59. package/dist/modules/crm/functions/configuration.d.ts +3 -0
  60. package/dist/modules/crm/functions/configuration.d.ts.map +1 -0
  61. package/dist/modules/crm/functions/configuration.js +331 -0
  62. package/dist/modules/crm/functions/configuration.js.map +1 -0
  63. package/dist/modules/crm/functions/gamification.d.ts +3 -0
  64. package/dist/modules/crm/functions/gamification.d.ts.map +1 -0
  65. package/dist/modules/crm/functions/gamification.js +58 -0
  66. package/dist/modules/crm/functions/gamification.js.map +1 -0
  67. package/dist/modules/crm/functions/index.d.ts +4 -0
  68. package/dist/modules/crm/functions/index.d.ts.map +1 -0
  69. package/dist/modules/crm/functions/index.js +33 -0
  70. package/dist/modules/crm/functions/index.js.map +1 -0
  71. package/dist/modules/crm/functions/modal-context.d.ts +3 -0
  72. package/dist/modules/crm/functions/modal-context.d.ts.map +1 -0
  73. package/dist/modules/crm/functions/modal-context.js +248 -0
  74. package/dist/modules/crm/functions/modal-context.js.map +1 -0
  75. package/dist/modules/crm/functions/previews.d.ts +3 -0
  76. package/dist/modules/crm/functions/previews.d.ts.map +1 -0
  77. package/dist/modules/crm/functions/previews.js +20 -0
  78. package/dist/modules/crm/functions/previews.js.map +1 -0
  79. package/dist/modules/crm/functions/shared.d.ts +31 -0
  80. package/dist/modules/crm/functions/shared.d.ts.map +1 -0
  81. package/dist/modules/crm/functions/shared.js +194 -0
  82. package/dist/modules/crm/functions/shared.js.map +1 -0
  83. package/dist/modules/crm/index.d.ts +1 -1
  84. package/dist/modules/crm/index.d.ts.map +1 -1
  85. package/dist/modules/crm/index.js +2 -2
  86. package/dist/modules/crm/index.js.map +1 -1
  87. package/dist/modules/crm/messages.d.ts +4 -1
  88. package/dist/modules/crm/messages.d.ts.map +1 -1
  89. package/dist/modules/crm/messages.js +6 -0
  90. package/dist/modules/crm/messages.js.map +1 -1
  91. package/dist/modules/crm/record-modal-labels.d.ts +9 -0
  92. package/dist/modules/crm/record-modal-labels.d.ts.map +1 -0
  93. package/dist/modules/crm/record-modal-labels.js +36 -0
  94. package/dist/modules/crm/record-modal-labels.js.map +1 -0
  95. package/dist/modules/crm/types.d.ts +5 -0
  96. package/dist/modules/crm/types.d.ts.map +1 -1
  97. package/dist/modules/crm/types.js +9 -0
  98. package/dist/modules/crm/types.js.map +1 -1
  99. package/dist/modules/crm_backend/client/crm-configuration-modal.d.mts +352 -0
  100. package/dist/modules/crm_backend/client/crm-configuration-modal.d.mts.map +1 -0
  101. package/dist/modules/crm_backend/client/crm-configuration-modal.mjs +2 -0
  102. package/dist/modules/crm_backend/client/crm-configuration-modal.mjs.map +7 -0
  103. package/dist/modules/crm_backend/index.d.ts.map +1 -1
  104. package/dist/modules/crm_backend/index.js +5 -1
  105. package/dist/modules/crm_backend/index.js.map +1 -1
  106. package/dist/modules/crm_backend/islands.d.ts +27 -0
  107. package/dist/modules/crm_backend/islands.d.ts.map +1 -1
  108. package/dist/modules/crm_backend/islands.js +22 -0
  109. package/dist/modules/crm_backend/islands.js.map +1 -1
  110. package/dist/modules/crm_backend/messages.d.ts +30 -0
  111. package/dist/modules/crm_backend/messages.d.ts.map +1 -1
  112. package/dist/modules/crm_backend/messages.js +30 -0
  113. package/dist/modules/crm_backend/messages.js.map +1 -1
  114. package/dist/modules/crm_backend/modal/configuration-modal-view.d.ts +55 -0
  115. package/dist/modules/crm_backend/modal/configuration-modal-view.d.ts.map +1 -0
  116. package/dist/modules/crm_backend/modal/configuration-modal-view.js +601 -0
  117. package/dist/modules/crm_backend/modal/configuration-modal-view.js.map +1 -0
  118. package/dist/modules/crm_backend/routes.d.ts.map +1 -1
  119. package/dist/modules/crm_backend/routes.js +69 -359
  120. package/dist/modules/crm_backend/routes.js.map +1 -1
  121. package/dist/modules/crm_backend/screens/configuration.d.ts +24 -32
  122. package/dist/modules/crm_backend/screens/configuration.d.ts.map +1 -1
  123. package/dist/modules/crm_backend/screens/configuration.js +183 -274
  124. package/dist/modules/crm_backend/screens/configuration.js.map +1 -1
  125. package/dist/modules/crm_backend/screens/index.d.ts +2 -2
  126. package/dist/modules/crm_backend/screens/index.d.ts.map +1 -1
  127. package/dist/modules/crm_backend/screens/index.js +1 -1
  128. package/dist/modules/crm_backend/screens/index.js.map +1 -1
  129. package/dist/modules/product/functions.d.ts +14 -1
  130. package/dist/modules/product/functions.d.ts.map +1 -1
  131. package/dist/modules/product/functions.js +36 -31
  132. package/dist/modules/product/functions.js.map +1 -1
  133. package/dist/modules/product/product-modal-context.d.ts +3 -0
  134. package/dist/modules/product/product-modal-context.d.ts.map +1 -0
  135. package/dist/modules/product/product-modal-context.js +173 -0
  136. package/dist/modules/product/product-modal-context.js.map +1 -0
  137. package/dist/modules/product/product-record-tabs.d.ts +14 -0
  138. package/dist/modules/product/product-record-tabs.d.ts.map +1 -0
  139. package/dist/modules/product/product-record-tabs.js +23 -0
  140. package/dist/modules/product/product-record-tabs.js.map +1 -0
  141. package/dist/modules/product_backend/client/product-modal.d.mts +144 -0
  142. package/dist/modules/product_backend/client/product-modal.d.mts.map +1 -0
  143. package/dist/modules/product_backend/client/product-modal.mjs +2 -0
  144. package/dist/modules/product_backend/client/product-modal.mjs.map +7 -0
  145. package/dist/modules/product_backend/index.d.ts.map +1 -1
  146. package/dist/modules/product_backend/index.js +25 -0
  147. package/dist/modules/product_backend/index.js.map +1 -1
  148. package/dist/modules/product_backend/islands.d.ts +1 -0
  149. package/dist/modules/product_backend/islands.d.ts.map +1 -1
  150. package/dist/modules/product_backend/islands.js +9 -0
  151. package/dist/modules/product_backend/islands.js.map +1 -1
  152. package/dist/modules/product_backend/modal/product-modal-view.d.ts +49 -0
  153. package/dist/modules/product_backend/modal/product-modal-view.d.ts.map +1 -0
  154. package/dist/modules/product_backend/modal/product-modal-view.js +609 -0
  155. package/dist/modules/product_backend/modal/product-modal-view.js.map +1 -0
  156. package/dist/modules/product_backend/routes.d.ts.map +1 -1
  157. package/dist/modules/product_backend/routes.js +44 -330
  158. package/dist/modules/product_backend/routes.js.map +1 -1
  159. package/dist/modules/product_backend/screens/detail.d.ts.map +1 -1
  160. package/dist/modules/product_backend/screens/detail.js +6 -108
  161. package/dist/modules/product_backend/screens/detail.js.map +1 -1
  162. package/dist/modules/product_backend/screens/index.d.ts +0 -1
  163. package/dist/modules/product_backend/screens/index.d.ts.map +1 -1
  164. package/dist/modules/product_backend/screens/index.js +0 -1
  165. package/dist/modules/product_backend/screens/index.js.map +1 -1
  166. package/dist/modules/product_backend/screens/list.d.ts +3 -1
  167. package/dist/modules/product_backend/screens/list.d.ts.map +1 -1
  168. package/dist/modules/product_backend/screens/list.js +6 -5
  169. package/dist/modules/product_backend/screens/list.js.map +1 -1
  170. package/dist/modules/user/authorization.d.ts.map +1 -1
  171. package/dist/modules/user/authorization.js +114 -0
  172. package/dist/modules/user/authorization.js.map +1 -1
  173. package/dist/modules/user/functions.d.ts.map +1 -1
  174. package/dist/modules/user/functions.js +2 -0
  175. package/dist/modules/user/functions.js.map +1 -1
  176. package/dist/modules/user/user-modal-context.d.ts +3 -0
  177. package/dist/modules/user/user-modal-context.d.ts.map +1 -0
  178. package/dist/modules/user/user-modal-context.js +151 -0
  179. package/dist/modules/user/user-modal-context.js.map +1 -0
  180. package/dist/modules/user_backend/client/user-modal.d.mts +72 -0
  181. package/dist/modules/user_backend/client/user-modal.d.mts.map +1 -0
  182. package/dist/modules/user_backend/client/user-modal.mjs +2 -0
  183. package/dist/modules/user_backend/client/user-modal.mjs.map +7 -0
  184. package/dist/modules/user_backend/index.d.ts.map +1 -1
  185. package/dist/modules/user_backend/index.js +9 -0
  186. package/dist/modules/user_backend/index.js.map +1 -1
  187. package/dist/modules/user_backend/islands.d.ts +15 -0
  188. package/dist/modules/user_backend/islands.d.ts.map +1 -0
  189. package/dist/modules/user_backend/islands.js +14 -0
  190. package/dist/modules/user_backend/islands.js.map +1 -0
  191. package/dist/modules/user_backend/messages.d.ts +30 -0
  192. package/dist/modules/user_backend/messages.d.ts.map +1 -1
  193. package/dist/modules/user_backend/messages.js +30 -0
  194. package/dist/modules/user_backend/messages.js.map +1 -1
  195. package/dist/modules/user_backend/modal/user-modal-view.d.ts +26 -0
  196. package/dist/modules/user_backend/modal/user-modal-view.d.ts.map +1 -0
  197. package/dist/modules/user_backend/modal/user-modal-view.js +320 -0
  198. package/dist/modules/user_backend/modal/user-modal-view.js.map +1 -0
  199. package/dist/modules/user_backend/routes.d.ts.map +1 -1
  200. package/dist/modules/user_backend/routes.js +15 -3
  201. package/dist/modules/user_backend/routes.js.map +1 -1
  202. package/dist/permission-catalogue.d.ts.map +1 -1
  203. package/dist/permission-catalogue.js +8 -0
  204. package/dist/permission-catalogue.js.map +1 -1
  205. package/dist/scaffold/index.js +1 -1
  206. package/dist/ui/client/record-modal-form.d.ts +67 -0
  207. package/dist/ui/client/record-modal-form.d.ts.map +1 -0
  208. package/dist/ui/client/record-modal-form.js +45 -0
  209. package/dist/ui/client/record-modal-form.js.map +1 -0
  210. package/dist/ui/client/record-modal.d.ts +103 -6
  211. package/dist/ui/client/record-modal.d.ts.map +1 -1
  212. package/dist/ui/client/record-modal.js +333 -65
  213. package/dist/ui/client/record-modal.js.map +1 -1
  214. package/dist/ui/index.d.ts +2 -1
  215. package/dist/ui/index.d.ts.map +1 -1
  216. package/dist/ui/index.js +2 -1
  217. package/dist/ui/index.js.map +1 -1
  218. package/dist/ui/nav.d.ts +7 -0
  219. package/dist/ui/nav.d.ts.map +1 -1
  220. package/dist/ui/nav.js +1 -1
  221. package/dist/ui/nav.js.map +1 -1
  222. package/dist/ui/record-modal.d.ts +15 -0
  223. package/dist/ui/record-modal.d.ts.map +1 -1
  224. package/dist/ui/record-modal.js +12 -0
  225. package/dist/ui/record-modal.js.map +1 -1
  226. package/dist/ui/table.d.ts.map +1 -1
  227. package/dist/ui/table.js +1 -1
  228. package/dist/ui/table.js.map +1 -1
  229. package/package.json +4 -4
  230. package/dist/modules/crm/functions.d.ts +0 -10
  231. package/dist/modules/crm/functions.d.ts.map +0 -1
  232. package/dist/modules/crm/functions.js +0 -1394
  233. package/dist/modules/crm/functions.js.map +0 -1
  234. package/dist/modules/product_backend/screens/create.d.ts +0 -16
  235. package/dist/modules/product_backend/screens/create.d.ts.map +0 -1
  236. package/dist/modules/product_backend/screens/create.js +0 -86
  237. package/dist/modules/product_backend/screens/create.js.map +0 -1
@@ -0,0 +1,248 @@
1
+ // Record-modal contexts for the CRM configuration catalogues.
2
+ //
3
+ // Each catalogue (team, stage, tag, assignment rule, score rule) opens its rows
4
+ // and its create action in a client-side record modal (KetSuite record-modal
5
+ // contract). One permission-checked read per kind hands the modal everything it
6
+ // renders — the record or its defaults, the choices its form offers and what the
7
+ // viewer may do — so the views never fetch.
8
+ import { defineFn } from '@ketvietlab/ketjs';
9
+ import { AUTHORIZATION_EFFECTS, effectiveFunctionKeys } from '../../user/authorization.js';
10
+ import { CRM_RECORD_MODAL_LABELS } from '../record-modal-labels.js';
11
+ import { n } from '../operations.js';
12
+ import { ASSIGNMENT_MODES, CASE_KINDS, SCORE_RULE_OPERATORS, TERMINAL_STATES } from '../types.js';
13
+ /** Message prefixes the configuration views read, plus the error codes a refusal names. */
14
+ const MESSAGE_PREFIXES = ['crm_backend.', 'crm.'];
15
+ const messagesFor = (ctx, lang) => {
16
+ const catalog = ctx.manifest.messages?.[lang] ?? {};
17
+ const out = {};
18
+ for (const [key, message] of Object.entries(catalog)) {
19
+ if (!MESSAGE_PREFIXES.some((prefix) => key.startsWith(prefix)))
20
+ continue;
21
+ out[key] =
22
+ typeof message === 'string' ? message : String(message.other ?? Object.values(message)[0] ?? key);
23
+ }
24
+ return { ...out, ...CRM_RECORD_MODAL_LABELS[lang] };
25
+ };
26
+ const readEffects = AUTHORIZATION_EFFECTS.filter((effect) => !effect.startsWith('write:'));
27
+ /** What the actor may call. A superuser (null) may call everything; no actor, nothing. */
28
+ const permissionCheck = async (ctx) => {
29
+ const allowed = ctx.actor ? await effectiveFunctionKeys(ctx, ctx.actor) : [];
30
+ return { allowed, can: (fn) => allowed === null || allowed.includes(fn) };
31
+ };
32
+ const byName = (a, b) => String(a.name ?? '').localeCompare(String(b.name ?? '')) || String(a.id).localeCompare(String(b.id));
33
+ /**
34
+ * The people a picker may offer. Listing every user needs `user.listUsers`;
35
+ * without it the modal offers the people already active in a CRM team, exactly as
36
+ * the configuration screen does.
37
+ */
38
+ const peopleFor = async (ctx, can) => {
39
+ const users = await ctx.db.select('user.User', { active: true });
40
+ if (can('user.listUsers'))
41
+ return users.map((user) => ({ id: String(user.id), name: String(user.name ?? user.id) })).sort(byName);
42
+ if (!can('crm.team.member.list'))
43
+ return [];
44
+ const names = new Map(users.map((user) => [String(user.id), String(user.name ?? user.id)]));
45
+ const byUser = new Map();
46
+ for (const member of await ctx.db.select('crm.TeamMember', { active: true })) {
47
+ const id = String(member.userId);
48
+ if (names.has(id) && !byUser.has(id))
49
+ byUser.set(id, { id, name: names.get(id) });
50
+ }
51
+ return [...byUser.values()].sort(byName);
52
+ };
53
+ /**
54
+ * Teams a picker may offer: active ones only. A record still pointing at an
55
+ * archived team keeps that one as an option, marked, so its value stays visible
56
+ * and saving it is refused on the field instead of silently changed.
57
+ */
58
+ const teamChoices = async (ctx, currentId) => {
59
+ const teams = await ctx.db.select('crm.Team');
60
+ return teams
61
+ .filter((team) => team.active !== false || (currentId && String(team.id) === String(currentId)))
62
+ .map((team) => ({
63
+ id: String(team.id),
64
+ name: String(team.name ?? team.code ?? team.id),
65
+ active: team.active !== false,
66
+ }))
67
+ .sort(byName);
68
+ };
69
+ const langOf = (args) => (args.locale === 'en' ? 'en' : 'vi');
70
+ const find = async (ctx, model, id) => id ? ((await ctx.db.select(model, { id }))[0] ?? null) : null;
71
+ const contextInput = { id: 'id?', locale: 'text?' };
72
+ export const modalContextFunctions = {
73
+ 'team.modalContext': defineFn({
74
+ input: contextInput,
75
+ effects: [...readEffects, 'read:crm.Team', 'read:crm.TeamMember', 'read:user.User'],
76
+ handler: async (ctx, args) => {
77
+ const { can } = await permissionCheck(ctx);
78
+ const permissions = {
79
+ save: can('crm.team.save'),
80
+ members: can('crm.team.member.save'),
81
+ };
82
+ const creating = !args.id;
83
+ if (creating && !permissions.save)
84
+ return null;
85
+ const record = creating
86
+ ? { name: '', code: '', leaderUserId: '', assignmentMode: 'manual', active: true }
87
+ : await find(ctx, 'crm.Team', args.id);
88
+ if (!record)
89
+ return null;
90
+ const users = new Map((await ctx.db.select('user.User')).map((user) => [String(user.id), String(user.name ?? user.id)]));
91
+ const members = creating
92
+ ? []
93
+ : (await ctx.db.select('crm.TeamMember', { teamId: args.id }))
94
+ .map((member) => ({
95
+ ...member,
96
+ userName: users.get(String(member.userId)) ?? String(member.userId),
97
+ }))
98
+ .sort((a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id)));
99
+ const lang = langOf(args);
100
+ return {
101
+ data: {
102
+ record,
103
+ members,
104
+ people: await peopleFor(ctx, can),
105
+ assignmentModes: [...ASSIGNMENT_MODES],
106
+ permissions,
107
+ lang,
108
+ },
109
+ messages: messagesFor(ctx, lang),
110
+ };
111
+ },
112
+ }),
113
+ 'stage.modalContext': defineFn({
114
+ input: contextInput,
115
+ effects: [...readEffects, 'read:crm.Stage', 'read:crm.Team'],
116
+ handler: async (ctx, args) => {
117
+ const { can } = await permissionCheck(ctx);
118
+ const permissions = { save: can('crm.stage.save') };
119
+ const creating = !args.id;
120
+ if (creating && !permissions.save)
121
+ return null;
122
+ const record = creating
123
+ ? {
124
+ name: '',
125
+ code: '',
126
+ sequence: 10,
127
+ allowedKinds: [...CASE_KINDS],
128
+ teamId: '',
129
+ terminalState: 'open',
130
+ fold: false,
131
+ active: true,
132
+ }
133
+ : await find(ctx, 'crm.Stage', args.id);
134
+ if (!record)
135
+ return null;
136
+ const lang = langOf(args);
137
+ return {
138
+ data: {
139
+ record,
140
+ teams: await teamChoices(ctx, record.teamId),
141
+ kinds: [...CASE_KINDS],
142
+ terminalStates: [...TERMINAL_STATES],
143
+ permissions,
144
+ lang,
145
+ },
146
+ messages: messagesFor(ctx, lang),
147
+ };
148
+ },
149
+ }),
150
+ 'tag.modalContext': defineFn({
151
+ input: contextInput,
152
+ effects: [...readEffects, 'read:crm.Tag'],
153
+ handler: async (ctx, args) => {
154
+ const { can } = await permissionCheck(ctx);
155
+ const permissions = { save: can('crm.tag.save'), archive: can('crm.tag.archive') };
156
+ const creating = !args.id;
157
+ if (creating && !permissions.save)
158
+ return null;
159
+ const record = creating ? { name: '', color: '', active: true } : await find(ctx, 'crm.Tag', args.id);
160
+ if (!record)
161
+ return null;
162
+ const lang = langOf(args);
163
+ return { data: { record, permissions, lang }, messages: messagesFor(ctx, lang) };
164
+ },
165
+ }),
166
+ 'assignmentRule.modalContext': defineFn({
167
+ input: contextInput,
168
+ effects: [
169
+ ...readEffects,
170
+ 'read:crm.AssignmentRule',
171
+ 'read:crm.Team',
172
+ 'read:crm.TeamMember',
173
+ 'read:user.User',
174
+ ],
175
+ handler: async (ctx, args) => {
176
+ const { can } = await permissionCheck(ctx);
177
+ const permissions = { save: can('crm.assignmentRule.save') };
178
+ const creating = !args.id;
179
+ if (creating && !permissions.save)
180
+ return null;
181
+ const record = creating
182
+ ? {
183
+ name: '',
184
+ priority: 10,
185
+ allowedKinds: [...CASE_KINDS],
186
+ teamId: '',
187
+ assigneeUserId: '',
188
+ utmSource: '',
189
+ minimumScore: null,
190
+ active: true,
191
+ }
192
+ : await find(ctx, 'crm.AssignmentRule', args.id);
193
+ if (!record)
194
+ return null;
195
+ const teams = await teamChoices(ctx, record.teamId);
196
+ const users = new Map((await ctx.db.select('user.User', { active: true })).map((user) => [
197
+ String(user.id),
198
+ String(user.name ?? user.id),
199
+ ]));
200
+ // `assignmentRule.save` accepts only an active member of the chosen team or
201
+ // its leader, so that is all the assignee picker offers for each team.
202
+ const rows = await ctx.db.select('crm.Team');
203
+ const assignees = {};
204
+ for (const team of teams) {
205
+ const leader = rows.find((row) => String(row.id) === team.id)?.leaderUserId;
206
+ const ids = new Set((await ctx.db.select('crm.TeamMember', { teamId: team.id, active: true })).map((member) => String(member.userId)));
207
+ if (leader)
208
+ ids.add(String(leader));
209
+ assignees[String(team.id)] = [...ids]
210
+ .filter((id) => users.has(id))
211
+ .map((id) => ({ id, name: users.get(id) }))
212
+ .sort(byName);
213
+ }
214
+ const lang = langOf(args);
215
+ return {
216
+ data: { record, teams, assignees, kinds: [...CASE_KINDS], permissions, lang },
217
+ messages: messagesFor(ctx, lang),
218
+ };
219
+ },
220
+ }),
221
+ 'scoreRule.modalContext': defineFn({
222
+ input: contextInput,
223
+ effects: [...readEffects, 'read:crm.ScoreRule'],
224
+ handler: async (ctx, args) => {
225
+ const { can } = await permissionCheck(ctx);
226
+ const permissions = { save: can('crm.scoreRule.save') };
227
+ const creating = !args.id;
228
+ if (creating && !permissions.save)
229
+ return null;
230
+ const record = creating
231
+ ? { name: '', field: 'email', operator: 'eq', value: '', points: 0, sequence: 10, active: true }
232
+ : await find(ctx, 'crm.ScoreRule', args.id);
233
+ if (!record)
234
+ return null;
235
+ const lang = langOf(args);
236
+ return {
237
+ data: {
238
+ record,
239
+ operators: Object.fromEntries(Object.entries(SCORE_RULE_OPERATORS).map(([field, list]) => [field, [...list]])),
240
+ permissions,
241
+ lang,
242
+ },
243
+ messages: messagesFor(ctx, lang),
244
+ };
245
+ },
246
+ }),
247
+ };
248
+ //# sourceMappingURL=modal-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-context.js","sourceRoot":"","sources":["../../../../../../../../packages/ketsuite/src/modules/crm/functions/modal-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FnSpec } from '@ketvietlab/ketjs';
2
+ export declare const previewFunctions: Record<string, FnSpec>;
3
+ //# sourceMappingURL=previews.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previews.d.ts","sourceRoot":"","sources":["../../../../../../../packages/ketsuite/src/modules/crm/functions/previews.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAG/C,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiBnD,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { defineFn } from '@ketvietlab/ketjs';
2
+ import { ensureCase } from './shared.js';
3
+ export const previewFunctions = {
4
+ 'enrichment.preview': defineFn({
5
+ input: { caseId: 'id' },
6
+ output: { ok: 'bool', code: 'text', errors: 'json?' },
7
+ effects: ['read:crm.Case'],
8
+ handler: async (ctx, args) => ({
9
+ ok: false,
10
+ code: (await ensureCase(ctx, args.caseId)) ? 'provider_not_configured' : 'case_not_found',
11
+ }),
12
+ }),
13
+ 'mining.preview': defineFn({
14
+ input: { country: 'text?', industry: 'text?' },
15
+ output: { ok: 'bool', code: 'text' },
16
+ effects: [],
17
+ handler: () => ({ ok: false, code: 'provider_not_configured' }),
18
+ }),
19
+ };
20
+ //# sourceMappingURL=previews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previews.js","sourceRoot":"","sources":["../../../../../../../../packages/ketsuite/src/modules/crm/functions/previews.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,oBAAoB,EAAE,QAAQ,CAAC;QAC7B,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;QACvB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;QACrD,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7B,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,CAAC,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,gBAAgB;SAC1F,CAAC;KACH,CAAC;IAEF,gBAAgB,EAAE,QAAQ,CAAC;QACzB,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;QAC9C,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;QACpC,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;KAChE,CAAC;CACH,CAAA"}
@@ -0,0 +1,31 @@
1
+ import type { Ctx, Row } from '@ketvietlab/ketjs';
2
+ import type { CrmResult } from '../operations.ts';
3
+ export declare const caseReadEffects: readonly ['read:crm.Case', 'read:crm.AccessGrant', 'read:crm.Stage', 'read:crm.Team', 'read:crm.TeamMember', 'read:crm.SalesDetail', 'read:crm.CaseTag', 'read:crm.Tag', 'read:crm.TimelineEntry', 'read:crm.Message', 'read:crm.ActivityLink', 'read:crm.CalendarLink', 'read:user.User', 'read:partner.Partner', 'read:activity.Activity', 'read:calendar.Event', 'read:storage.Attachment'];
4
+ export declare const defaultEffects: readonly ['read:crm.Team', 'write:crm.Team', 'read:crm.Stage', 'write:crm.Stage', 'read:activity.Type', 'write:activity.Type'];
5
+ /** Shape rules shared by the long CRM create form and its backend route. */
6
+ export declare const caseFormSchema: (requirements?: {
7
+ partner?: boolean;
8
+ need?: boolean;
9
+ }) => import("@ketvietlab/ketjs").FormSchema<import("@ketvietlab/ketjs").FormValues>;
10
+ export declare const caseWriteEffects: readonly ["read:crm.Case", "read:crm.AccessGrant", "read:crm.Stage", "read:crm.Team", "read:crm.TeamMember", "read:crm.SalesDetail", "read:crm.CaseTag", "read:crm.Tag", "read:crm.TimelineEntry", "read:crm.Message", "read:crm.ActivityLink", "read:crm.CalendarLink", "read:user.User", "read:partner.Partner", "read:activity.Activity", "read:calendar.Event", "read:storage.Attachment", "read:crm.Team", "write:crm.Team", "read:crm.Stage", "write:crm.Stage", "read:activity.Type", "write:activity.Type", "write:crm.Case", "write:crm.SalesDetail", "write:crm.CaseTag", "write:crm.TimelineEntry", "read:mail.Thread", "write:mail.Thread", "enqueue:crm.score"];
11
+ export declare const activityEffects: readonly ["read:crm.Case", "read:crm.AccessGrant", "read:crm.Stage", "read:crm.Team", "read:crm.TeamMember", "read:crm.SalesDetail", "read:crm.CaseTag", "read:crm.Tag", "read:crm.TimelineEntry", "read:crm.Message", "read:crm.ActivityLink", "read:crm.CalendarLink", "read:user.User", "read:partner.Partner", "read:activity.Activity", "read:calendar.Event", "read:storage.Attachment", "read:activity.Type", "read:activity.Plan", "read:activity.PlanStep", "read:activity.Attachment", "write:activity.Activity", "write:activity.Attachment", "write:crm.ActivityLink", "write:crm.TimelineEntry", "read:mail.Thread", "read:mail.Message", "read:mail.Follower", "read:mail.FollowerSubtype", "read:mail.Subtype", "write:mail.Message", "write:mail.MessageAttachment", "write:mail.Mention", "write:mail.TrackingValue", "write:mail.Notification", "read:storage.Attachment"];
12
+ export declare const command: (ctx: Ctx, key: unknown) => CrmResult | null;
13
+ export declare const isSuperuser: (ctx: Ctx) => Promise<boolean>;
14
+ export declare const accessScopes: Set<string>;
15
+ export declare const ensureCase: (ctx: Ctx, id: unknown) => Promise<Row | null>;
16
+ /**
17
+ * One shape for the small configuration lists the pickers read: active first,
18
+ * filtered by name, capped so a keystroke never pulls a whole table.
19
+ */
20
+ export declare const optionRows: (ctx: Ctx, model: string, args: Record<string, unknown>, order?: (a: Row, b: Row) => number) => Promise<Row[]>;
21
+ export declare function moveToTerminal(ctx: Ctx, input: {
22
+ id: string;
23
+ expectedVersion: number;
24
+ terminal: string;
25
+ lostReason?: string;
26
+ closeReason?: string;
27
+ idempotencyKey: string;
28
+ }): Promise<CrmResult>;
29
+ export declare const saveConfiguration: (model: string, prepare: (args: Record<string, unknown>, existing: Row | undefined) => Row, validate?: (ctx: Ctx, args: Record<string, unknown>, existing: Row | undefined) => CrmResult | null | Promise<CrmResult | null>, additionalEffects?: string[]) => import("@ketvietlab/ketjs").FnSpec;
30
+ export declare const createCaseId: () => string;
31
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../../../../packages/ketsuite/src/modules/crm/functions/shared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAajD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,eAAO,MAAM,eAAe,YAC1B,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,CACjB,CAAA;AAEV,eAAO,MAAM,cAAc,YACzB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,CACb,CAAA;AAEV,4EAA4E;AAC5E,eAAO,MAAM,cAAc,kBAAkB;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,mFAc9E,CAAA;AAEJ,eAAO,MAAM,gBAAgB,8oBAUnB,CAAA;AAEV,eAAO,MAAM,eAAe,81BAqBlB,CAAA;AAEV,eAAO,MAAM,OAAO,QAAS,GAAG,OAAO,OAAO,qBAI7C,CAAA;AAED,eAAO,MAAM,WAAW,QAAe,GAAG,KAAG,OAAO,CAAC,OAAO,CAI3D,CAAA;AAED,eAAO,MAAM,YAAY,aAA+C,CAAA;AAExE,eAAO,MAAM,UAAU,QAAe,GAAG,MAAM,OAAO,KAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CACrB,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,UAAU,QAChB,GAAG,SACD,MAAM,QACP,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACrB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,MAAM,KACjC,OAAO,CAAC,GAAG,EAAE,CAcf,CAAA;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAA;IACV,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;CACvB,sBAyDF;AAED,eAAO,MAAM,iBAAiB,UACrB,MAAM,WACJ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,SAAS,KAAK,GAAG,aAC/D,CACT,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,EAAE,GAAG,GAAG,SAAS,KACtB,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,sBAC9B,MAAM,EAAE,uCAgCzB,CAAA;AAEJ,eAAO,MAAM,YAAY,QAAO,MAAsB,CAAA"}
@@ -0,0 +1,194 @@
1
+ // Helpers and effect lists shared by the CRM function groups.
2
+ import { randomUUID } from 'node:crypto';
3
+ import { defineFn, defineFormSchema } from '@ketvietlab/ketjs';
4
+ import { actorRequired, addTimeline, canEditCase, closedAtFor, commandKey, invalid, issue, n, normalized, now, } from '../operations.js';
5
+ export const caseReadEffects = [
6
+ 'read:crm.Case',
7
+ 'read:crm.AccessGrant',
8
+ 'read:crm.Stage',
9
+ 'read:crm.Team',
10
+ 'read:crm.TeamMember',
11
+ 'read:crm.SalesDetail',
12
+ 'read:crm.CaseTag',
13
+ 'read:crm.Tag',
14
+ 'read:crm.TimelineEntry',
15
+ 'read:crm.Message',
16
+ 'read:crm.ActivityLink',
17
+ 'read:crm.CalendarLink',
18
+ 'read:user.User',
19
+ 'read:partner.Partner',
20
+ 'read:activity.Activity',
21
+ 'read:calendar.Event',
22
+ 'read:storage.Attachment',
23
+ ];
24
+ export const defaultEffects = [
25
+ 'read:crm.Team',
26
+ 'write:crm.Team',
27
+ 'read:crm.Stage',
28
+ 'write:crm.Stage',
29
+ 'read:activity.Type',
30
+ 'write:activity.Type',
31
+ ];
32
+ /** Shape rules shared by the long CRM create form and its backend route. */
33
+ export const caseFormSchema = (requirements = {}) => defineFormSchema({
34
+ fields: {
35
+ name: { type: 'text', required: true, trim: true },
36
+ kind: { type: 'text', required: true, oneOf: ['lead', 'opportunity'] },
37
+ partnerId: { type: 'text', required: requirements.partner === true, trim: true },
38
+ description: { type: 'text', required: requirements.need === true, trim: true },
39
+ utmSource: { type: 'text', trim: true },
40
+ priority: { type: 'text', oneOf: ['0', '1', '2', '3'] },
41
+ expectedRevenue: { type: 'decimal', min: 0 },
42
+ probability: { type: 'decimal', min: 0, max: 100 },
43
+ expectedClosing: { type: 'date' },
44
+ },
45
+ unknown: 'drop',
46
+ });
47
+ export const caseWriteEffects = [
48
+ ...caseReadEffects,
49
+ ...defaultEffects,
50
+ 'write:crm.Case',
51
+ 'write:crm.SalesDetail',
52
+ 'write:crm.CaseTag',
53
+ 'write:crm.TimelineEntry',
54
+ 'read:mail.Thread',
55
+ 'write:mail.Thread',
56
+ 'enqueue:crm.score',
57
+ ];
58
+ export const activityEffects = [
59
+ ...caseReadEffects,
60
+ 'read:activity.Type',
61
+ 'read:activity.Plan',
62
+ 'read:activity.PlanStep',
63
+ 'read:activity.Attachment',
64
+ 'write:activity.Activity',
65
+ 'write:activity.Attachment',
66
+ 'write:crm.ActivityLink',
67
+ 'write:crm.TimelineEntry',
68
+ 'read:mail.Thread',
69
+ 'read:mail.Message',
70
+ 'read:mail.Follower',
71
+ 'read:mail.FollowerSubtype',
72
+ 'read:mail.Subtype',
73
+ 'write:mail.Message',
74
+ 'write:mail.MessageAttachment',
75
+ 'write:mail.Mention',
76
+ 'write:mail.TrackingValue',
77
+ 'write:mail.Notification',
78
+ 'read:storage.Attachment',
79
+ ];
80
+ export const command = (ctx, key) => {
81
+ if (!actorRequired(ctx))
82
+ return invalid(issue('actor', 'crm.error.actorRequired'));
83
+ if (!commandKey(key))
84
+ return invalid(issue('idempotencyKey', 'crm.error.idempotencyRequired'));
85
+ return null;
86
+ };
87
+ export const isSuperuser = async (ctx) => {
88
+ if (!ctx.actor)
89
+ return false;
90
+ const actor = (await ctx.db.select('user.User', { id: ctx.actor, active: true }))[0];
91
+ return actor?.superuser === true;
92
+ };
93
+ export const accessScopes = new Set(['none', 'self', 'team', 'company']);
94
+ export const ensureCase = async (ctx, id) => (await ctx.db.select('crm.Case', { id }))[0] ?? null;
95
+ /**
96
+ * One shape for the small configuration lists the pickers read: active first,
97
+ * filtered by name, capped so a keystroke never pulls a whole table.
98
+ */
99
+ export const optionRows = async (ctx, model, args, order) => {
100
+ const rows = await ctx.db.select(model, args.includeArchived === true ? {} : { active: true });
101
+ const needle = normalized(args.search);
102
+ return rows
103
+ .filter((row) => !needle || normalized(row.name).includes(needle) || normalized(row.code).includes(needle))
104
+ .sort((a, b) => (order ? order(a, b) : 0) ||
105
+ String(a.name ?? '').localeCompare(String(b.name ?? '')) ||
106
+ String(a.id).localeCompare(String(b.id)))
107
+ .slice(0, Math.max(1, Math.min(200, n(args.limit ?? 80))));
108
+ };
109
+ export async function moveToTerminal(ctx, input) {
110
+ const error = command(ctx, input.idempotencyKey);
111
+ if (error)
112
+ return error;
113
+ return ctx.tx(async (tx) => {
114
+ const held = await ensureCase(tx, input.id);
115
+ if (!held || !(await canEditCase(tx, held)))
116
+ return invalid(issue('id', 'crm.error.notFound'));
117
+ if (held.kind !== 'opportunity')
118
+ return invalid(issue('kind', 'crm.error.leadConversion'));
119
+ const stages = (await tx.db.select('crm.Stage', { active: true })).filter((stage) => stage.terminalState === input.terminal &&
120
+ Array.isArray(stage.allowedKinds) &&
121
+ stage.allowedKinds.map(String).includes(String(held.kind)));
122
+ const stage = stages.sort((a, b) => n(a.sequence) - n(b.sequence) || String(a.id).localeCompare(String(b.id)))[0];
123
+ if (!stage)
124
+ return invalid(issue('stageId', 'crm.error.invalidStage'));
125
+ if (held.kind === 'opportunity' && input.terminal === 'lost') {
126
+ const detail = (await tx.db.select('crm.SalesDetail', { caseId: input.id }))[0];
127
+ if (detail)
128
+ await tx.db.update('crm.SalesDetail', { id: detail.id }, { lostReason: input.lostReason ?? null });
129
+ }
130
+ const timestamp = now();
131
+ const changed = await tx.db.compareAndSet('crm.Case', { id: input.id }, { version: input.expectedVersion }, {
132
+ stageId: stage.id,
133
+ terminalState: input.terminal,
134
+ active: true,
135
+ version: n(held.version) + 1,
136
+ updatedAt: timestamp,
137
+ closedAt: closedAtFor(held, input.terminal, timestamp),
138
+ });
139
+ if (!('dryRun' in changed) && !changed.matched)
140
+ return invalid(issue('version', 'crm.error.stageConflict', { current: held.version }));
141
+ const event = input.terminal === 'won' ? 'won' : 'lost';
142
+ await addTimeline(tx, {
143
+ id: `timeline:${input.id}:${event}:${input.idempotencyKey}`,
144
+ caseId: input.id,
145
+ eventType: event,
146
+ body: `crm.timeline.${event}`,
147
+ metadata: input.closeReason ? { reason: input.closeReason } : undefined,
148
+ customerVisible: false,
149
+ occurredAt: timestamp,
150
+ });
151
+ if (held.assigneeUserId)
152
+ await tx.jobs.enqueue('crm.gamification', { userId: held.assigneeUserId }, { uniqueKey: `crm.gamification:${String(held.assigneeUserId)}` });
153
+ return { ok: true, id: input.id, version: n(held.version) + 1, terminalState: input.terminal };
154
+ });
155
+ }
156
+ export const saveConfiguration = (model, prepare, validate, additionalEffects = []) => defineFn({
157
+ input: { values: 'json', idempotencyKey: 'text' },
158
+ output: { ok: 'bool', id: 'id?', version: 'int?', errors: 'json?' },
159
+ effects: [`read:${model}`, `write:${model}`, ...additionalEffects],
160
+ idempotent: true,
161
+ agent: true,
162
+ handler: async (ctx, args) => {
163
+ const error = command(ctx, args.idempotencyKey);
164
+ if (error)
165
+ return error;
166
+ if (!args.values || typeof args.values !== 'object')
167
+ return invalid(issue('values', 'crm.error.required'));
168
+ const values = args.values;
169
+ const id = String(values.id ?? '');
170
+ if (!id)
171
+ return invalid(issue('id', 'crm.error.required'));
172
+ const existing = (await ctx.db.select(model, { id }))[0];
173
+ const validation = await validate?.(ctx, values, existing);
174
+ if (validation)
175
+ return validation;
176
+ const expectedVersion = values.expectedVersion == null ? undefined : n(values.expectedVersion);
177
+ if (existing && expectedVersion != null && n(existing.version) !== expectedVersion)
178
+ return invalid(issue('version', 'crm.error.stageConflict', { current: n(existing.version) }));
179
+ const version = n(existing?.version) + 1;
180
+ const row = { ...prepare(values, existing), version };
181
+ if (existing?.version != null) {
182
+ const changed = await ctx.db.compareAndSet(model, { id }, { version: n(existing.version) }, row);
183
+ if (!('dryRun' in changed) && !changed.matched)
184
+ return invalid(issue('version', 'crm.error.stageConflict', { current: n(existing.version) }));
185
+ }
186
+ else if (existing)
187
+ await ctx.db.update(model, { id }, row);
188
+ else
189
+ await ctx.db.insert(model, { id, ...row });
190
+ return { ok: true, id, version };
191
+ },
192
+ });
193
+ export const createCaseId = () => randomUUID();
194
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../../../../../packages/ketsuite/src/modules/crm/functions/shared.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  declare const _default: import("@ketvietlab/ketjs").KetModule;
2
2
  export default _default;
3
3
  export * from './types.ts';
4
- export { caseWriteEffects, functions } from './functions.ts';
4
+ export { caseWriteEffects, functions } from './functions/index.ts';
5
5
  export { addCaseMessage, addTimeline, activeStage, actorRequired, applyCaseScore, canAssignCase, canEditCase, canReadCase, caseAudience, caseDetail, closedAtFor, commandKey, crmActivityType, duplicateCases, ensureCrmDefaults, firstStage, gamificationProfile, invalid, issue, n, normalized, now, ownedKinds, ownsKind, pipelineSummary, reassignCase, saveCase, seededId, serializeCaseList, stageKinds, visibleCases, } from './operations.ts';
6
6
  export type { CaseAccessScope, CaseAction, CaseAudience } from './operations.ts';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketsuite/src/modules/crm/index.ts"],"names":[],"mappings":";;AAmBA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,OAAO,EACP,KAAK,EACL,CAAC,EACD,UAAU,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketsuite/src/modules/crm/index.ts"],"names":[],"mappings":";;AAmBA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,OAAO,EACP,KAAK,EACL,CAAC,EACD,UAAU,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { defineModule } from '@ketvietlab/ketjs';
2
- import { functions } from './functions.js';
2
+ import { functions } from './functions/index.js';
3
3
  import { jobFunctions, jobs } from './jobs.js';
4
4
  import { messages } from './messages.js';
5
5
  import { models } from './models.js';
@@ -16,6 +16,6 @@ export default defineModule({
16
16
  messages,
17
17
  });
18
18
  export * from './types.js';
19
- export { caseWriteEffects, functions } from './functions.js';
19
+ export { caseWriteEffects, functions } from './functions/index.js';
20
20
  export { addCaseMessage, addTimeline, activeStage, actorRequired, applyCaseScore, canAssignCase, canEditCase, canReadCase, caseAudience, caseDetail, closedAtFor, commandKey, crmActivityType, duplicateCases, ensureCrmDefaults, firstStage, gamificationProfile, invalid, issue, n, normalized, now, ownedKinds, ownsKind, pipelineSummary, reassignCase, saveCase, seededId, serializeCaseList, stageKinds, visibleCases, } from './operations.js';
21
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/ketsuite/src/modules/crm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC;IACvE,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,6CAA6C;IACtD,QAAQ,EAAE,OAAO;IACjB,MAAM;IACN,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE;IAC5C,IAAI;IACJ,QAAQ;CACT,CAAC,CAAA;AAEF,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,OAAO,EACP,KAAK,EACL,CAAC,EACD,UAAU,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/ketsuite/src/modules/crm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC;IACvE,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,6CAA6C;IACtD,QAAQ,EAAE,OAAO;IACjB,MAAM;IACN,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE;IAC5C,IAAI;IACJ,QAAQ;CACT,CAAC,CAAA;AAEF,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,OAAO,EACP,KAAK,EACL,CAAC,EACD,UAAU,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAA"}
@@ -26,6 +26,9 @@ export declare const messages: {
26
26
  readonly 'error.providerNotConfigured': 'Nhà cung cấp chưa được cấu hình.';
27
27
  readonly 'error.alreadyMerged': 'Hồ sơ này đã được hợp nhất hoặc lưu trữ.';
28
28
  readonly 'error.duplicateName': 'Tên này đã được dùng.';
29
+ readonly 'error.duplicateCode': 'Mã này đã được dùng.';
30
+ readonly 'error.duplicateMember': 'Người này đã là thành viên của đội.';
31
+ readonly 'error.invalidOperator': 'Toán tử không dùng được cho trường đã chọn.';
29
32
  readonly 'error.notTeamMember': 'Người này không thuộc đội đã chọn. Hãy thêm họ vào đội trong phần cấu hình.';
30
33
  readonly 'error.permission': 'Bạn không có quyền thực hiện thao tác này trên hồ sơ.';
31
34
  readonly 'error.invalidAccessScope': 'Phạm vi truy cập không hợp lệ.';
@@ -45,6 +48,6 @@ export declare const messages: {
45
48
  readonly 'timeline.activity_cancelled': 'Đã hủy hoạt động';
46
49
  readonly 'timeline.plan_applied': 'Đã áp dụng kế hoạch';
47
50
  };
48
- en: Record<"app.category" | "app.summary" | "app.title" | "error.actorRequired" | "error.alreadyMerged" | "error.companyRequired" | "error.duplicateName" | "error.idempotencyRequired" | "error.invalidAccessScope" | "error.invalidKind" | "error.invalidStage" | "error.invalidVisibility" | "error.leadConversion" | "error.notFound" | "error.notTeamMember" | "error.permission" | "error.providerNotConfigured" | "error.reassignReason" | "error.required" | "error.stageConflict" | "kind.lead" | "kind.opportunity" | "stage.lost" | "stage.new" | "stage.proposition" | "stage.qualified" | "stage.won" | "terminal.lost" | "terminal.open" | "terminal.won" | "timeline.activity_cancelled" | "timeline.activity_completed" | "timeline.activity_scheduled" | "timeline.assigned" | "timeline.converted" | "timeline.created" | "timeline.lost" | "timeline.merged" | "timeline.message" | "timeline.plan_applied" | "timeline.quotation_created" | "timeline.reassigned" | "timeline.stage" | "timeline.won", string>;
51
+ en: Record<"app.category" | "app.summary" | "app.title" | "error.actorRequired" | "error.alreadyMerged" | "error.companyRequired" | "error.duplicateCode" | "error.duplicateMember" | "error.duplicateName" | "error.idempotencyRequired" | "error.invalidAccessScope" | "error.invalidKind" | "error.invalidOperator" | "error.invalidStage" | "error.invalidVisibility" | "error.leadConversion" | "error.notFound" | "error.notTeamMember" | "error.permission" | "error.providerNotConfigured" | "error.reassignReason" | "error.required" | "error.stageConflict" | "kind.lead" | "kind.opportunity" | "stage.lost" | "stage.new" | "stage.proposition" | "stage.qualified" | "stage.won" | "terminal.lost" | "terminal.open" | "terminal.won" | "timeline.activity_cancelled" | "timeline.activity_completed" | "timeline.activity_scheduled" | "timeline.assigned" | "timeline.converted" | "timeline.created" | "timeline.lost" | "timeline.merged" | "timeline.message" | "timeline.plan_applied" | "timeline.quotation_created" | "timeline.reassigned" | "timeline.stage" | "timeline.won", string>;
49
52
  };
50
53
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketsuite/src/modules/crm/messages.ts"],"names":[],"mappings":"AA+FA,eAAO,MAAM,QAAQ;;8BA9FN,KAAK;gCACH,uCAAuC;iCACtC,UAAU;8BACb,WAAW;qCACJ,QAAQ;kCACX,SAAS;iCACV,YAAY;kCACX,UAAU;8BACd,KAAK;oCACC,aAAa;sCACX,SAAS;8BACjB,YAAY;+BACX,UAAU;mCACN,yBAAyB;0CAClB,kCAAkC;wCACpC,2CAA2C;8CACrC,oCAAoC;mCAC/C,2BAA2B;sCACxB,0BAA0B;uCACzB,+CAA+C;wCAC9C,kDAAkD;yCACjD,6CAA6C;4CAC1C,gCAAgC;gDAC5B,kCAAkC;wCAC1C,0CAA0C;wCAC1C,uBAAuB;wCACvB,6EAA6E;qCAChF,uDAAuD;6CAC/C,gCAAgC;yCACpC,6BAA6B;qCACjC,cAAc;mCAChB,qBAAqB;sCAClB,cAAc;wCACZ,2BAA2B;uCAC5B,wBAAwB;oCAC3B,yBAAyB;iCAC5B,wBAAwB;kCACvB,sBAAsB;qCACnB,gBAAgB;+CACN,gBAAgB;gDACf,uBAAuB;gDACvB,yBAAyB;gDACzB,kBAAkB;0CACxB,qBAAqB;;;CAmDd,CAAA"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketsuite/src/modules/crm/messages.ts"],"names":[],"mappings":"AAqGA,eAAO,MAAM,QAAQ;;8BApGN,KAAK;gCACH,uCAAuC;iCACtC,UAAU;8BACb,WAAW;qCACJ,QAAQ;kCACX,SAAS;iCACV,YAAY;kCACX,UAAU;8BACd,KAAK;oCACC,aAAa;sCACX,SAAS;8BACjB,YAAY;+BACX,UAAU;mCACN,yBAAyB;0CAClB,kCAAkC;wCACpC,2CAA2C;8CACrC,oCAAoC;mCAC/C,2BAA2B;sCACxB,0BAA0B;uCACzB,+CAA+C;wCAC9C,kDAAkD;yCACjD,6CAA6C;4CAC1C,gCAAgC;gDAC5B,kCAAkC;wCAC1C,0CAA0C;wCAC1C,uBAAuB;wCACvB,sBAAsB;0CACpB,qCAAqC;0CACrC,6CAA6C;wCAC/C,6EAA6E;qCAChF,uDAAuD;6CAC/C,gCAAgC;yCACpC,6BAA6B;qCACjC,cAAc;mCAChB,qBAAqB;sCAClB,cAAc;wCACZ,2BAA2B;uCAC5B,wBAAwB;oCAC3B,yBAAyB;iCAC5B,wBAAwB;kCACvB,sBAAsB;qCACnB,gBAAgB;+CACN,gBAAgB;gDACf,uBAAuB;gDACvB,yBAAyB;gDACzB,kBAAkB;0CACxB,qBAAqB;;;CAsDd,CAAA"}