@things-factory/worklist 10.0.18 → 10.1.0

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 (215) hide show
  1. package/dist-client/activity-cells.d.ts +21 -0
  2. package/dist-client/activity-cells.js +117 -0
  3. package/dist-client/activity-cells.js.map +1 -0
  4. package/dist-client/activity-summary-generator.js +57 -11
  5. package/dist-client/activity-summary-generator.js.map +1 -1
  6. package/dist-client/approval-progress.d.ts +18 -0
  7. package/dist-client/approval-progress.js +31 -0
  8. package/dist-client/approval-progress.js.map +1 -0
  9. package/dist-client/bootstrap.js +6 -11
  10. package/dist-client/bootstrap.js.map +1 -1
  11. package/dist-client/chip-filters.d.ts +53 -0
  12. package/dist-client/chip-filters.js +60 -0
  13. package/dist-client/chip-filters.js.map +1 -0
  14. package/dist-client/components/activity-approval-ribon.d.ts +19 -0
  15. package/dist-client/components/activity-approval-ribon.js +50 -126
  16. package/dist-client/components/activity-approval-ribon.js.map +1 -1
  17. package/dist-client/components/activity-fields.d.ts +50 -0
  18. package/dist-client/components/activity-fields.js +393 -0
  19. package/dist-client/components/activity-fields.js.map +1 -0
  20. package/dist-client/components/activity-instance-ribon.d.ts +19 -0
  21. package/dist-client/components/activity-instance-ribon.js +55 -122
  22. package/dist-client/components/activity-instance-ribon.js.map +1 -1
  23. package/dist-client/components/activity-thread-ribon.d.ts +25 -0
  24. package/dist-client/components/activity-thread-ribon.js +64 -121
  25. package/dist-client/components/activity-thread-ribon.js.map +1 -1
  26. package/dist-client/components/activity-thread-timeline.d.ts +14 -2
  27. package/dist-client/components/activity-thread-timeline.js +234 -104
  28. package/dist-client/components/activity-thread-timeline.js.map +1 -1
  29. package/dist-client/components/state-ribon.d.ts +40 -0
  30. package/dist-client/components/state-ribon.js +200 -0
  31. package/dist-client/components/state-ribon.js.map +1 -0
  32. package/dist-client/due.d.ts +16 -0
  33. package/dist-client/due.js +78 -0
  34. package/dist-client/due.js.map +1 -0
  35. package/dist-client/pages/activity/activity-list-page.js +4 -6
  36. package/dist-client/pages/activity/activity-list-page.js.map +1 -1
  37. package/dist-client/pages/activity-approval/activity-approval-list-page.js +2 -1
  38. package/dist-client/pages/activity-approval/activity-approval-list-page.js.map +1 -1
  39. package/dist-client/pages/activity-approval/activity-approval-page.d.ts +52 -5
  40. package/dist-client/pages/activity-approval/activity-approval-page.js +265 -118
  41. package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
  42. package/dist-client/pages/activity-instance/activity-instance-list-page.d.ts +0 -1
  43. package/dist-client/pages/activity-instance/activity-instance-list-page.js +8 -24
  44. package/dist-client/pages/activity-instance/activity-instance-list-page.js.map +1 -1
  45. package/dist-client/pages/activity-instance/activity-instance-start-page.d.ts +1 -0
  46. package/dist-client/pages/activity-instance/activity-instance-start-page.js +7 -0
  47. package/dist-client/pages/activity-instance/activity-instance-start-page.js.map +1 -1
  48. package/dist-client/pages/activity-instance/activity-instance-view.js +1 -1
  49. package/dist-client/pages/activity-instance/activity-instance-view.js.map +1 -1
  50. package/dist-client/pages/activity-stats/activity-stats-list-page.js +2 -1
  51. package/dist-client/pages/activity-stats/activity-stats-list-page.js.map +1 -1
  52. package/dist-client/pages/activity-thread/activity-thread-page.d.ts +30 -4
  53. package/dist-client/pages/activity-thread/activity-thread-page.js +142 -66
  54. package/dist-client/pages/activity-thread/activity-thread-page.js.map +1 -1
  55. package/dist-client/pages/activity-thread/activity-thread-view-page.d.ts +17 -6
  56. package/dist-client/pages/activity-thread/activity-thread-view-page.js +118 -65
  57. package/dist-client/pages/activity-thread/activity-thread-view-page.js.map +1 -1
  58. package/dist-client/pages/activity-thread/activity-thread-view.d.ts +24 -7
  59. package/dist-client/pages/activity-thread/activity-thread-view.js +84 -308
  60. package/dist-client/pages/activity-thread/activity-thread-view.js.map +1 -1
  61. package/dist-client/pages/installable-activity/installable-activity-list-page.d.ts +1 -1
  62. package/dist-client/pages/installable-activity/installable-activity-list-page.js +13 -9
  63. package/dist-client/pages/installable-activity/installable-activity-list-page.js.map +1 -1
  64. package/dist-client/pages/todo/approval-done-list-page.d.ts +1 -0
  65. package/dist-client/pages/todo/approval-done-list-page.js +111 -58
  66. package/dist-client/pages/todo/approval-done-list-page.js.map +1 -1
  67. package/dist-client/pages/todo/approval-pending-list-page.d.ts +32 -1
  68. package/dist-client/pages/todo/approval-pending-list-page.js +485 -130
  69. package/dist-client/pages/todo/approval-pending-list-page.js.map +1 -1
  70. package/dist-client/pages/todo/done-list-calendar-page.d.ts +2 -0
  71. package/dist-client/pages/todo/done-list-calendar-page.js +213 -29
  72. package/dist-client/pages/todo/done-list-calendar-page.js.map +1 -1
  73. package/dist-client/pages/todo/done-list-page.d.ts +1 -0
  74. package/dist-client/pages/todo/done-list-page.js +126 -62
  75. package/dist-client/pages/todo/done-list-page.js.map +1 -1
  76. package/dist-client/pages/todo/draft-list-page.d.ts +1 -0
  77. package/dist-client/pages/todo/draft-list-page.js +82 -34
  78. package/dist-client/pages/todo/draft-list-page.js.map +1 -1
  79. package/dist-client/pages/todo/pickable-list-page.js +6 -10
  80. package/dist-client/pages/todo/pickable-list-page.js.map +1 -1
  81. package/dist-client/pages/todo/todo-list-page.d.ts +1 -1
  82. package/dist-client/pages/todo/todo-list-page.js +102 -78
  83. package/dist-client/pages/todo/todo-list-page.js.map +1 -1
  84. package/dist-client/route.d.ts +1 -1
  85. package/dist-client/route.js +0 -6
  86. package/dist-client/route.js.map +1 -1
  87. package/dist-client/templates/activity-approval-context-template.js +60 -138
  88. package/dist-client/templates/activity-approval-context-template.js.map +1 -1
  89. package/dist-client/templates/activity-instance-context-template.js +13 -172
  90. package/dist-client/templates/activity-instance-context-template.js.map +1 -1
  91. package/dist-client/templates/activity-thread-context-template.js +39 -131
  92. package/dist-client/templates/activity-thread-context-template.js.map +1 -1
  93. package/dist-client/templates/context-panel.d.ts +26 -0
  94. package/dist-client/templates/context-panel.js +182 -0
  95. package/dist-client/templates/context-panel.js.map +1 -0
  96. package/dist-client/tsconfig.tsbuildinfo +1 -1
  97. package/dist-client/when.d.ts +4 -0
  98. package/dist-client/when.js +72 -0
  99. package/dist-client/when.js.map +1 -0
  100. package/dist-server/controllers/activity-approval/_abort.js +2 -1
  101. package/dist-server/controllers/activity-approval/_abort.js.map +1 -1
  102. package/dist-server/controllers/activity-approval/approval-line.d.ts +106 -0
  103. package/dist-server/controllers/activity-approval/approval-line.js +151 -0
  104. package/dist-server/controllers/activity-approval/approval-line.js.map +1 -0
  105. package/dist-server/controllers/activity-approval/approve.js +61 -51
  106. package/dist-server/controllers/activity-approval/approve.js.map +1 -1
  107. package/dist-server/controllers/activity-approval/claim.d.ts +42 -0
  108. package/dist-server/controllers/activity-approval/claim.js +77 -0
  109. package/dist-server/controllers/activity-approval/claim.js.map +1 -0
  110. package/dist-server/controllers/activity-approval/create-approval.d.ts +41 -0
  111. package/dist-server/controllers/activity-approval/create-approval.js +78 -0
  112. package/dist-server/controllers/activity-approval/create-approval.js.map +1 -0
  113. package/dist-server/controllers/activity-approval/delegate.d.ts +16 -0
  114. package/dist-server/controllers/activity-approval/delegate.js +43 -7
  115. package/dist-server/controllers/activity-approval/delegate.js.map +1 -1
  116. package/dist-server/controllers/activity-approval/opinion.d.ts +10 -0
  117. package/dist-server/controllers/activity-approval/opinion.js +43 -0
  118. package/dist-server/controllers/activity-approval/opinion.js.map +1 -0
  119. package/dist-server/controllers/activity-approval/reject.js +21 -1
  120. package/dist-server/controllers/activity-approval/reject.js.map +1 -1
  121. package/dist-server/controllers/activity-approval/save.js +26 -2
  122. package/dist-server/controllers/activity-approval/save.js.map +1 -1
  123. package/dist-server/controllers/activity-installation/activity-installation-controller.d.ts +26 -0
  124. package/dist-server/controllers/activity-installation/activity-installation-controller.js +45 -0
  125. package/dist-server/controllers/activity-installation/activity-installation-controller.js.map +1 -1
  126. package/dist-server/controllers/activity-instance/approval-expectation.d.ts +34 -0
  127. package/dist-server/controllers/activity-instance/approval-expectation.js +18 -0
  128. package/dist-server/controllers/activity-instance/approval-expectation.js.map +1 -0
  129. package/dist-server/controllers/activity-instance/issue.js +32 -0
  130. package/dist-server/controllers/activity-instance/issue.js.map +1 -1
  131. package/dist-server/controllers/activity-thread/restart.js +17 -1
  132. package/dist-server/controllers/activity-thread/restart.js.map +1 -1
  133. package/dist-server/controllers/activity-thread/submit.js +23 -43
  134. package/dist-server/controllers/activity-thread/submit.js.map +1 -1
  135. package/dist-server/controllers/common.js +46 -0
  136. package/dist-server/controllers/common.js.map +1 -1
  137. package/dist-server/controllers/index.d.ts +1 -0
  138. package/dist-server/controllers/index.js +8 -0
  139. package/dist-server/controllers/index.js.map +1 -1
  140. package/dist-server/service/activity/activity-mutation.js +25 -5
  141. package/dist-server/service/activity/activity-mutation.js.map +1 -1
  142. package/dist-server/service/activity/activity-type.d.ts +14 -0
  143. package/dist-server/service/activity/activity-type.js +8 -0
  144. package/dist-server/service/activity/activity-type.js.map +1 -1
  145. package/dist-server/service/activity/activity.d.ts +18 -0
  146. package/dist-server/service/activity/activity.js +5 -0
  147. package/dist-server/service/activity/activity.js.map +1 -1
  148. package/dist-server/service/activity-approval/activity-approval-mutation.js +3 -2
  149. package/dist-server/service/activity-approval/activity-approval-mutation.js.map +1 -1
  150. package/dist-server/service/activity-approval/activity-approval-query.d.ts +19 -1
  151. package/dist-server/service/activity-approval/activity-approval-query.js +186 -56
  152. package/dist-server/service/activity-approval/activity-approval-query.js.map +1 -1
  153. package/dist-server/service/activity-approval/activity-approval.d.ts +29 -1
  154. package/dist-server/service/activity-approval/activity-approval.js +19 -0
  155. package/dist-server/service/activity-approval/activity-approval.js.map +1 -1
  156. package/dist-server/service/activity-approval/my-pending-approvals.d.ts +21 -0
  157. package/dist-server/service/activity-approval/my-pending-approvals.js +40 -0
  158. package/dist-server/service/activity-approval/my-pending-approvals.js.map +1 -0
  159. package/dist-server/service/activity-instance/activity-instance-type.d.ts +20 -0
  160. package/dist-server/service/activity-instance/activity-instance-type.js +11 -0
  161. package/dist-server/service/activity-instance/activity-instance-type.js.map +1 -1
  162. package/dist-server/service/activity-instance/activity-instance.d.ts +6 -0
  163. package/dist-server/service/activity-instance/activity-instance.js +5 -0
  164. package/dist-server/service/activity-instance/activity-instance.js.map +1 -1
  165. package/dist-server/service/activity-stats/activity-stats-query.d.ts +5 -0
  166. package/dist-server/service/activity-stats/activity-stats-query.js +149 -11
  167. package/dist-server/service/activity-stats/activity-stats-query.js.map +1 -1
  168. package/dist-server/service/activity-stats/activity-stats-type.d.ts +19 -6
  169. package/dist-server/service/activity-stats/activity-stats-type.js +37 -10
  170. package/dist-server/service/activity-stats/activity-stats-type.js.map +1 -1
  171. package/dist-server/service/activity-stats/event-placement.d.ts +55 -0
  172. package/dist-server/service/activity-stats/event-placement.js +82 -0
  173. package/dist-server/service/activity-stats/event-placement.js.map +1 -0
  174. package/dist-server/service/activity-thread/activity-thread-query.js +48 -24
  175. package/dist-server/service/activity-thread/activity-thread-query.js.map +1 -1
  176. package/dist-server/service/activity-thread/my-open-threads.d.ts +15 -0
  177. package/dist-server/service/activity-thread/my-open-threads.js +40 -0
  178. package/dist-server/service/activity-thread/my-open-threads.js.map +1 -0
  179. package/dist-server/service/activity-thread/todo-order.d.ts +49 -0
  180. package/dist-server/service/activity-thread/todo-order.js +70 -0
  181. package/dist-server/service/activity-thread/todo-order.js.map +1 -0
  182. package/dist-server/service/installable-activity/installable-activity-mutation.d.ts +6 -0
  183. package/dist-server/service/installable-activity/installable-activity-mutation.js +7 -24
  184. package/dist-server/service/installable-activity/installable-activity-mutation.js.map +1 -1
  185. package/dist-server/service/nulls-last.d.ts +30 -0
  186. package/dist-server/service/nulls-last.js +37 -0
  187. package/dist-server/service/nulls-last.js.map +1 -0
  188. package/dist-server/tsconfig.tsbuildinfo +1 -1
  189. package/helps/dataset/activity-instance-search-page.ko.md +5 -0
  190. package/helps/dataset/activity-instance-search-page.md +13 -0
  191. package/helps/worklist/activity-approval.ko.md +5 -0
  192. package/helps/worklist/activity-approval.md +14 -0
  193. package/helps/worklist/activity-bank-page.ko.md +5 -0
  194. package/helps/worklist/activity-bank-page.md +13 -0
  195. package/helps/worklist/activity-reporter-list.ko.md +5 -0
  196. package/helps/worklist/activity-reporter-list.md +13 -0
  197. package/helps/worklist/activity-store.ko.md +5 -0
  198. package/helps/worklist/activity-store.md +13 -0
  199. package/helps/worklist/activity-template.ko.md +5 -0
  200. package/helps/worklist/activity-template.md +13 -0
  201. package/helps/worklist/installable-activity.ko.md +5 -0
  202. package/helps/worklist/installable-activity.md +13 -0
  203. package/package.json +13 -12
  204. package/things-factory.config.js +0 -5
  205. package/translations/en.json +129 -51
  206. package/translations/ja.json +130 -52
  207. package/translations/ko.json +82 -4
  208. package/translations/ms.json +129 -51
  209. package/translations/zh.json +132 -54
  210. package/dist-client/pages/dashboard/dashboard-home.d.ts +0 -1
  211. package/dist-client/pages/dashboard/dashboard-home.js +0 -22
  212. package/dist-client/pages/dashboard/dashboard-home.js.map +0 -1
  213. package/dist-client/pages/worklist-home.d.ts +0 -1
  214. package/dist-client/pages/worklist-home.js +0 -17
  215. package/dist-client/pages/worklist-home.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { Domain, ListParam } from '@things-factory/shell';
2
- import { User } from '@things-factory/auth-base';
2
+ import { Role, User } from '@things-factory/auth-base';
3
3
  import { ActivityThread } from '../activity-thread/activity-thread.js';
4
4
  import { ActivityApproval } from './activity-approval.js';
5
5
  import { ActivityApprovalList } from './activity-approval-type.js';
@@ -7,10 +7,28 @@ export declare class ActivityApprovalQuery {
7
7
  activityApproval(id: string, context: ResolverContext): Promise<ActivityApproval>;
8
8
  activityApprovals(params: ListParam, context: ResolverContext): Promise<ActivityApprovalList>;
9
9
  approvalPendingList(params: ListParam, context: ResolverContext): Promise<ActivityApprovalList>;
10
+ /**
11
+ * **내가 참조로 걸린 것** — 결재하는 것이 아니라 보고 의견을 낼 수 있는 것.
12
+ *
13
+ * 승인 대기 목록과 나눈다. 섞으면 참조자가 「내가 승인해야 하나」로 읽고, 결재자는 남의 참조 건까지
14
+ * 훑게 된다. 두 목록의 물음이 다르다 — 「내가 결정할 것」과 「내가 알아야 할 것」.
15
+ *
16
+ * 끝난 건도 보인다. 결재가 끝난 뒤에 의견이 달릴 수 있고(참조는 막지 않으므로 늦게 올 수 있다),
17
+ * 그 사실을 화면이 「결정 후」로 표시해야 한다.
18
+ */
19
+ approvalReferenceList(params: ListParam, context: ResolverContext): Promise<ActivityApprovalList>;
10
20
  approvalDoneList(params: ListParam, context: ResolverContext): Promise<ActivityApprovalList>;
11
21
  activityThread(activityApproval: ActivityApproval): Promise<ActivityThread>;
12
22
  domain(activityApproval: ActivityApproval): Promise<Domain>;
13
23
  approver(activityApproval: ActivityApproval): Promise<User>;
24
+ /**
25
+ * 누가 결재해야 하나가 **역할**일 때.
26
+ *
27
+ * 이 리졸버가 없어서 `approverRole` 이 늘 `null` 로 나갔다. DB 에는 들어 있는데 질의가 관계를 안
28
+ * 싣기 때문이다. 그래서 결재 목록이 「누가 결재해야 하나」를 못 보였다 — 개인으로 지정한 건만 보이고
29
+ * 역할로 지정한 건은 빈칸이었다.
30
+ */
31
+ approverRole(activityApproval: ActivityApproval): Promise<Role>;
14
32
  updater(activityApproval: ActivityApproval): Promise<User>;
15
33
  creator(activityApproval: ActivityApproval): Promise<User>;
16
34
  terminator(activityApproval: ActivityApproval): Promise<User>;
@@ -3,12 +3,120 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ActivityApprovalQuery = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const typeorm_1 = require("typeorm");
6
+ const DriverUtils_js_1 = require("typeorm/driver/DriverUtils.js");
6
7
  const type_graphql_1 = require("type-graphql");
7
8
  const shell_1 = require("@things-factory/shell");
8
9
  const auth_base_1 = require("@things-factory/auth-base");
9
10
  const activity_thread_js_1 = require("../activity-thread/activity-thread.js");
10
11
  const activity_approval_js_1 = require("./activity-approval.js");
11
12
  const activity_approval_type_js_1 = require("./activity-approval-type.js");
13
+ const approval_line_js_1 = require("../../controllers/activity-approval/approval-line.js");
14
+ const my_pending_approvals_js_1 = require("./my-pending-approvals.js");
15
+ const activity_instance_js_1 = require("../activity-instance/activity-instance.js");
16
+ const nulls_last_js_1 = require("../nulls-last.js");
17
+ /*
18
+ * **결재 목록이 걸러 볼 수 있는 칸** — 네 목록이 같은 표를 쓴다.
19
+ *
20
+ * ── 왜 하나로 모으나 (2026-09-05) ──────────────────────────────────────────
21
+ * 이 칸들은 `ActivityApproval` 에 없다. 활동 인스턴스에 있고, 결재는 스레드를 거쳐 그것을 본다.
22
+ * 그래서 목록마다 `filtersMap` 으로 길을 알려 줘야 하고, 안 알려 주면 **그 칸으로 거르는 순간
23
+ * 500 이 난다.**
24
+ *
25
+ * 표를 손으로 네 벌 들고 있었고, 실제로 갈라졌다.
26
+ *
27
+ * approvalPendingList name · description · priority · dueAt
28
+ * approvalDoneList name · description · priority · dueAt
29
+ * approvalReferenceList name · description ← `dueAt` 에서 터졌다
30
+ * activityApprovals (표가 아예 없다) ← `name` 에서도 터진다
31
+ *
32
+ * 화면은 넷에 같은 칩을 보낸다(`client/chip-filters.ts` 의 「24시간 내 마감」이 `dueAt lte` 를
33
+ * 보낸다). 그러니 목록마다 표가 다르면 **어느 목록에서만 터지는** 모양이 된다 — 실측된 것이 그
34
+ * 모양이었다.
35
+ *
36
+ * 다섯 번째 목록이 생길 때 또 갈라지지 않게 한 곳에 둔다.
37
+ */
38
+ const APPROVAL_FILTERS_MAP = {
39
+ ...['name', 'description', 'priority'].reduce((map, columnName) => ({ ...map, [columnName]: { relationColumn: 'activityThread.activityInstance', columnName } }), {}),
40
+ /*
41
+ * 기한은 **스레드의 것**이다 — 인스턴스에도 같은 이름의 칸이 있지만 화면이 보여 주는 것은 스레드
42
+ * 쪽이다(approval-pending-list-page 는 인스턴스를 펼친 뒤 `dueAt: thread.dueAt` 으로 덮어쓴다).
43
+ *
44
+ * 매핑이 인스턴스를 가리키고 있었다. 지금 자료에서는 두 값이 같아 드러나지 않지만 다른 칸이고,
45
+ * 어긋나는 순간 목록이 **보이지 않는 값으로** 정렬되고 「만기」 칩도 보이지 않는 값으로 거른다.
46
+ * 화면이 보여 주는 것과 같은 칸을 본다.
47
+ */
48
+ dueAt: { relationColumn: 'activityThread', columnName: 'dueAt' }
49
+ };
50
+ /** 결재선 스레드가 아니라 업무 인스턴스 쪽 칸으로 정렬하는 이름들. 나머지는 결재 행(ap) 자신이다. */
51
+ const APPROVAL_INSTANCE_SORTS = new Set(['name', 'description', 'priority']);
52
+ /** 스레드(at) 쪽 칸으로 정렬하는 이름들. 화면이 보여 주는 것과 같은 칸이다. */
53
+ const APPROVAL_THREAD_SORTS = new Set(['dueAt', 'assignedAt', 'state']);
54
+ /** 값이 없으면 뒤로 보낼 칸. 기한이 없는 건은 「언제까지」를 묻는 정렬에서 맨 뒤가 맞다. */
55
+ const APPROVAL_NULLS_LAST = new Set(['dueAt']);
56
+ /**
57
+ * 내 결재함의 정렬 — **기한이 없는 건은 뒤로 간다.**
58
+ *
59
+ * 공통 빌더에 맡기면 NULL 자리를 정할 수 없다. sqlite 는 오름차순에서 NULL 을 먼저 내므로 기본
60
+ * 정렬이 기한 순인 목록의 맨 위가 **기한 없는 건**으로 채워진다 — 급한 것부터 보라는 정렬인데
61
+ * 정작 급한 것이 아래로 밀린다. 「할 일」 목록이 같은 이유로 이미 이 처리를 갖고 있고, 규칙은
62
+ * nulls-last.ts 한 곳에 있다.
63
+ *
64
+ * 정렬에 쓸 join 은 여기서 직접 건다. 공통 빌더의 join 은 filter 가 있을 때만 생기므로, 정렬만
65
+ * 하는 요청에서는 기댈 것이 없다.
66
+ */
67
+ function applyApprovalSortings(queryBuilder, sortings) {
68
+ const escape = (part) => queryBuilder.connection.driver.escape(part);
69
+ const fieldOf = (name) => {
70
+ const metadata = (0, shell_1.getRepository)(APPROVAL_INSTANCE_SORTS.has(name) ? activity_instance_js_1.ActivityInstance : activity_thread_js_1.ActivityThread).metadata;
71
+ const column = metadata.findColumnWithPropertyName(name);
72
+ /* 이름을 못 찾으면 SQL 을 지어내지 않는다. */
73
+ return column ? `${escape(APPROVAL_INSTANCE_SORTS.has(name) ? 'ai' : 'at')}.${escape(column.databaseName)}` : undefined;
74
+ };
75
+ const terms = [];
76
+ for (const sorting of sortings || []) {
77
+ if (!sorting?.name) {
78
+ continue;
79
+ }
80
+ const direction = sorting.desc ? 'DESC' : 'ASC';
81
+ if (APPROVAL_NULLS_LAST.has(sorting.name)) {
82
+ const field = fieldOf(sorting.name);
83
+ /* 방향이 뒤집혀도 값 없는 것은 뒤다 — 이 항목만 늘 오름차순이다. */
84
+ if (field) {
85
+ terms.push({ expression: nulls_last_js_1.NULL_RANK_ALIAS, direction: 'ASC', select: (0, nulls_last_js_1.nullsLastSelect)(field) });
86
+ }
87
+ }
88
+ const alias = APPROVAL_INSTANCE_SORTS.has(sorting.name)
89
+ ? 'ai'
90
+ : APPROVAL_THREAD_SORTS.has(sorting.name)
91
+ ? 'at'
92
+ : 'ap';
93
+ /*
94
+ * join 한 칸으로 정렬하면 그 칸이 select 에 있어야 한다.
95
+ *
96
+ * 여기 join 은 leftJoin 이라 칸을 싣지 않는데, 정렬 + 페이지네이션은 TypeORM 의 distinct 경로를
97
+ * 타고 모든 것을 서브쿼리로 감싼 뒤 ORDER BY 를 `distinctAlias.<별칭>` 으로 다시 쓴다. 실을 것이
98
+ * 없으면 그 이름이 없다 — 실측: `no such column: distinctAlias.at_due_at`.
99
+ *
100
+ * 별칭은 TypeORM 이 찾을 때 쓰는 그 함수로 만든다. property 이름으로 지으면 dueAt 처럼 DB 칸
101
+ * 이름과 철자가 다른 칸에서 어긋난다(shell 의 applyJoins 가 같은 이유로 고쳐졌다).
102
+ */
103
+ if (alias !== 'ap') {
104
+ const metadata = (0, shell_1.getRepository)(alias === 'ai' ? activity_instance_js_1.ActivityInstance : activity_thread_js_1.ActivityThread).metadata;
105
+ const column = metadata.findColumnWithPropertyName(sorting.name);
106
+ if (column) {
107
+ queryBuilder.addSelect(`${alias}.${sorting.name}`, DriverUtils_js_1.DriverUtils.buildAlias(queryBuilder.connection.driver, undefined, alias, column.databaseName));
108
+ }
109
+ }
110
+ terms.push({ expression: `${alias}.${sorting.name}`, direction });
111
+ }
112
+ terms.forEach(({ expression, direction, select }, index) => {
113
+ /* 식은 select 에 이름 붙여 올린다 — orderBy 는 점이 든 식을 alias 로 읽는다(nulls-last 머리말). */
114
+ if (select) {
115
+ queryBuilder.addSelect(select, expression);
116
+ }
117
+ index === 0 ? queryBuilder.orderBy(expression, direction) : queryBuilder.addOrderBy(expression, direction);
118
+ });
119
+ }
12
120
  let ActivityApprovalQuery = class ActivityApprovalQuery {
13
121
  async activityApproval(id, context) {
14
122
  const { domain } = context.state;
@@ -22,7 +130,8 @@ let ActivityApprovalQuery = class ActivityApprovalQuery {
22
130
  domain,
23
131
  params,
24
132
  repository: (0, shell_1.getRepository)(activity_approval_js_1.ActivityApproval),
25
- searchables: ['name', 'description']
133
+ searchables: ['name', 'description'],
134
+ filtersMap: APPROVAL_FILTERS_MAP
26
135
  });
27
136
  const [items, total] = await queryBuilder.getManyAndCount();
28
137
  return { items, total };
@@ -34,81 +143,75 @@ let ActivityApprovalQuery = class ActivityApprovalQuery {
34
143
  relations: ['roles']
35
144
  });
36
145
  const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id);
37
- const judgment = [
38
- activity_approval_js_1.ActivityApprovalJudgment.Escalated,
39
- activity_approval_js_1.ActivityApprovalJudgment.Delegated,
40
- activity_approval_js_1.ActivityApprovalJudgment.Approved,
41
- activity_approval_js_1.ActivityApprovalJudgment.Rejected
42
- ];
146
+ const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
147
+ repository: (0, shell_1.getRepository)(activity_approval_js_1.ActivityApproval),
148
+ /* 정렬은 아래에서 직접 건다(applyApprovalSortings 머리말) — 여기에 넘기면 NULL 자리를 못 정한다. */
149
+ params: { ...params, sortings: [] },
150
+ domain,
151
+ alias: 'ap',
152
+ searchables: ['name', 'description'],
153
+ filtersMap: APPROVAL_FILTERS_MAP
154
+ })
155
+ /* 정렬이 쓸 join — 정렬만 하는 요청에는 filter 쪽 join 이 없다. */
156
+ .leftJoin('ap.activityThread', 'at')
157
+ .leftJoin('at.activityInstance', 'ai')
158
+ /* 「내가 판단해야 할 것」의 정의는 한 자리에 있다 — 달력도 같은 것을 읽는다. */
159
+ .andWhere((0, my_pending_approvals_js_1.myPendingApprovalsWhere)({ userId: user.id, roles }));
160
+ applyApprovalSortings(queryBuilder, params.sortings || []);
161
+ const [items, total] = await queryBuilder.getManyAndCount();
162
+ return { items, total };
163
+ }
164
+ /**
165
+ * **내가 참조로 걸린 것** — 결재하는 것이 아니라 보고 의견을 낼 수 있는 것.
166
+ *
167
+ * 승인 대기 목록과 나눈다. 섞으면 참조자가 「내가 승인해야 하나」로 읽고, 결재자는 남의 참조 건까지
168
+ * 훑게 된다. 두 목록의 물음이 다르다 — 「내가 결정할 것」과 「내가 알아야 할 것」.
169
+ *
170
+ * 끝난 건도 보인다. 결재가 끝난 뒤에 의견이 달릴 수 있고(참조는 막지 않으므로 늦게 올 수 있다),
171
+ * 그 사실을 화면이 「결정 후」로 표시해야 한다.
172
+ */
173
+ async approvalReferenceList(params, context) {
174
+ var { domain, user } = context.state;
175
+ user = await (0, shell_1.getRepository)(auth_base_1.User).findOne({ where: { id: user.id }, relations: ['roles'] });
176
+ const roles = (user.roles ?? []).filter(role => role.domainId === domain.id).map(role => role.id);
43
177
  const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
44
178
  repository: (0, shell_1.getRepository)(activity_approval_js_1.ActivityApproval),
45
179
  params,
46
180
  domain,
47
181
  alias: 'ap',
48
182
  searchables: ['name', 'description'],
49
- filtersMap: {
50
- name: {
51
- relationColumn: 'activityThread.activityInstance',
52
- columnName: 'name'
53
- },
54
- description: {
55
- relationColumn: 'activityThread.activityInstance',
56
- columnName: 'description'
57
- },
58
- priority: {
59
- relationColumn: 'activityThread.activityInstance',
60
- columnName: 'priority'
61
- },
62
- dueAt: {
63
- relationColumn: 'activityThread.activityInstance',
64
- columnName: 'dueAt'
65
- }
66
- }
67
- }).andWhere(new typeorm_1.Brackets(qb => {
68
- qb.where('ap.judgment NOT IN (:...judgment)', { judgment }).andWhere('ap.approver = :user', { user: user.id });
69
- if (roles.length > 0) {
70
- qb.orWhere(new typeorm_1.Brackets(qb => {
71
- qb.where('ap.approverRole IN (:...roles)', { roles }).andWhere(`ap.approver IS NULL`);
72
- }));
73
- }
183
+ filtersMap: APPROVAL_FILTERS_MAP
184
+ })
185
+ .andWhere(`ap.participation = 'reference'`)
186
+ .andWhere(new typeorm_1.Brackets(qb => {
187
+ qb.where('ap.approver = :user', { user: user.id });
188
+ /* 역할로 걸린 참조는 그 역할을 가진 사람 모두가 본다 — 결재와 같은 규칙이다. */
189
+ if (roles.length > 0)
190
+ qb.orWhere('ap.approverRole IN (:...roles)', { roles });
74
191
  }));
75
192
  const [items, total] = await queryBuilder.getManyAndCount();
76
193
  return { items, total };
77
194
  }
78
195
  async approvalDoneList(params, context) {
79
196
  var { domain, user } = context.state;
80
- const judgment = [
81
- activity_approval_js_1.ActivityApprovalJudgment.Escalated,
82
- activity_approval_js_1.ActivityApprovalJudgment.Delegated,
83
- activity_approval_js_1.ActivityApprovalJudgment.Approved,
84
- activity_approval_js_1.ActivityApprovalJudgment.Rejected
85
- ];
197
+ /* 「끝난 것」의 정의는 한 자리에 있다 — 여기서 다시 세면 값이 늘 때 한쪽만 늘어난다. */
198
+ const judgment = [...approval_line_js_1.TERMINATED_JUDGMENTS];
86
199
  const [items, total] = await (0, shell_1.getQueryBuilderFromListParams)({
87
200
  repository: (0, shell_1.getRepository)(activity_approval_js_1.ActivityApproval),
88
201
  params,
89
202
  domain,
90
203
  alias: 'ap',
91
204
  searchables: ['name', 'description'],
92
- filtersMap: {
93
- name: {
94
- relationColumn: 'activityThread.activityInstance',
95
- columnName: 'name'
96
- },
97
- description: {
98
- relationColumn: 'activityThread.activityInstance',
99
- columnName: 'description'
100
- },
101
- priority: {
102
- relationColumn: 'activityThread.activityInstance',
103
- columnName: 'priority'
104
- },
105
- dueAt: {
106
- relationColumn: 'activityThread.activityInstance',
107
- columnName: 'dueAt'
108
- }
109
- }
205
+ filtersMap: APPROVAL_FILTERS_MAP
110
206
  })
111
207
  .andWhere('ap.judgment IN (:...judgment)', { judgment })
208
+ /*
209
+ * 역할로 걸린 결재를 처리하면 이제 `approver` 에 처리한 사람이 들어간다(`approve.ts`·`reject.ts`).
210
+ * 그래서 이 한 줄로 자기가 처리한 것이 다 걸린다 — 개인으로 걸린 것이든 역할로 걸린 것이든.
211
+ *
212
+ * 고치기 전에 처리한 역할 결재는 `approver` 가 비어 있어 여기 안 나온다. 지난 기록을 뒤에서 고쳐
213
+ * 쓰지 않는다는 규율에 따라 그대로 둔다.
214
+ */
112
215
  .andWhere('ap.approver = :user', { user: user.id })
113
216
  .getManyAndCount();
114
217
  return { items, total };
@@ -122,6 +225,16 @@ let ActivityApprovalQuery = class ActivityApprovalQuery {
122
225
  async approver(activityApproval) {
123
226
  return activityApproval.approverId && (await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: activityApproval.approverId }));
124
227
  }
228
+ /**
229
+ * 누가 결재해야 하나가 **역할**일 때.
230
+ *
231
+ * 이 리졸버가 없어서 `approverRole` 이 늘 `null` 로 나갔다. DB 에는 들어 있는데 질의가 관계를 안
232
+ * 싣기 때문이다. 그래서 결재 목록이 「누가 결재해야 하나」를 못 보였다 — 개인으로 지정한 건만 보이고
233
+ * 역할로 지정한 건은 빈칸이었다.
234
+ */
235
+ async approverRole(activityApproval) {
236
+ return activityApproval.approverRoleId && (await (0, shell_1.getRepository)(auth_base_1.Role).findOneBy({ id: activityApproval.approverRoleId }));
237
+ }
125
238
  async updater(activityApproval) {
126
239
  return activityApproval.updaterId && (await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: activityApproval.updaterId }));
127
240
  }
@@ -157,6 +270,16 @@ tslib_1.__decorate([
157
270
  tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
158
271
  tslib_1.__metadata("design:returntype", Promise)
159
272
  ], ActivityApprovalQuery.prototype, "approvalPendingList", null);
273
+ tslib_1.__decorate([
274
+ (0, type_graphql_1.Query)(returns => activity_approval_type_js_1.ActivityApprovalList, {
275
+ description: 'To fetch the approvals where I am a reference — I may comment, I do not decide'
276
+ }),
277
+ tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
278
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
279
+ tslib_1.__metadata("design:type", Function),
280
+ tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
281
+ tslib_1.__metadata("design:returntype", Promise)
282
+ ], ActivityApprovalQuery.prototype, "approvalReferenceList", null);
160
283
  tslib_1.__decorate([
161
284
  (0, type_graphql_1.Query)(returns => activity_approval_type_js_1.ActivityApprovalList, {
162
285
  description: 'To fetch the approvals(ActivityApprovals) which has done by me'
@@ -188,6 +311,13 @@ tslib_1.__decorate([
188
311
  tslib_1.__metadata("design:paramtypes", [activity_approval_js_1.ActivityApproval]),
189
312
  tslib_1.__metadata("design:returntype", Promise)
190
313
  ], ActivityApprovalQuery.prototype, "approver", null);
314
+ tslib_1.__decorate([
315
+ (0, type_graphql_1.FieldResolver)(type => auth_base_1.Role, { nullable: true }),
316
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
317
+ tslib_1.__metadata("design:type", Function),
318
+ tslib_1.__metadata("design:paramtypes", [activity_approval_js_1.ActivityApproval]),
319
+ tslib_1.__metadata("design:returntype", Promise)
320
+ ], ActivityApprovalQuery.prototype, "approverRole", null);
191
321
  tslib_1.__decorate([
192
322
  (0, type_graphql_1.FieldResolver)(type => auth_base_1.User),
193
323
  tslib_1.__param(0, (0, type_graphql_1.Root)()),
@@ -1 +1 @@
1
- {"version":3,"file":"activity-approval-query.js","sourceRoot":"","sources":["../../../server/service/activity-approval/activity-approval-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { ActivityThread } from '../activity-thread/activity-thread.js'\nimport { ActivityApproval, ActivityApprovalJudgment } from './activity-approval.js'\nimport { ActivityApprovalList } from './activity-approval-type.js'\n\n@Resolver(ActivityApproval)\nexport class ActivityApprovalQuery {\n @Query(returns => ActivityApproval!, { nullable: true, description: 'To fetch a ActivityApproval' })\n async activityApproval(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ActivityApproval> {\n const { domain } = context.state\n\n return await getRepository(ActivityApproval).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Query(returns => ActivityApprovalList, { description: 'To fetch multiple ActivityApprovals' })\n async activityApprovals(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: getRepository(ActivityApproval),\n searchables: ['name', 'description']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => ActivityApprovalList, { description: 'To fetch the list of work results I need to review' })\n async approvalPendingList(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n const judgment = [\n ActivityApprovalJudgment.Escalated,\n ActivityApprovalJudgment.Delegated,\n ActivityApprovalJudgment.Approved,\n ActivityApprovalJudgment.Rejected\n ]\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params,\n domain,\n alias: 'ap',\n searchables: ['name', 'description'],\n filtersMap: {\n name: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'name'\n },\n description: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'description'\n },\n priority: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'priority'\n },\n dueAt: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'dueAt'\n }\n }\n }).andWhere(\n new Brackets(qb => {\n qb.where('ap.judgment NOT IN (:...judgment)', { judgment }).andWhere('ap.approver = :user', { user: user.id })\n\n if (roles.length > 0) {\n qb.orWhere(\n new Brackets(qb => {\n qb.where('ap.approverRole IN (:...roles)', { roles }).andWhere(`ap.approver IS NULL`)\n })\n )\n }\n })\n )\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => ActivityApprovalList, {\n description: 'To fetch the approvals(ActivityApprovals) which has done by me'\n })\n async approvalDoneList(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n var { domain, user } = context.state\n\n const judgment = [\n ActivityApprovalJudgment.Escalated,\n ActivityApprovalJudgment.Delegated,\n ActivityApprovalJudgment.Approved,\n ActivityApprovalJudgment.Rejected\n ]\n\n const [items, total] = await getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params,\n domain,\n alias: 'ap',\n searchables: ['name', 'description'],\n filtersMap: {\n name: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'name'\n },\n description: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'description'\n },\n priority: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'priority'\n },\n dueAt: {\n relationColumn: 'activityThread.activityInstance',\n columnName: 'dueAt'\n }\n }\n })\n .andWhere('ap.judgment IN (:...judgment)', { judgment })\n .andWhere('ap.approver = :user', { user: user.id })\n .getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => ActivityThread)\n async activityThread(@Root() activityApproval: ActivityApproval): Promise<ActivityThread> {\n return await getRepository(ActivityThread).findOneBy({ id: activityApproval.activityThreadId })\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() activityApproval: ActivityApproval): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: activityApproval.domainId })\n }\n\n @FieldResolver(type => User)\n async approver(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.approverId && (await getRepository(User).findOneBy({ id: activityApproval.approverId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.updaterId && (await getRepository(User).findOneBy({ id: activityApproval.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.creatorId && (await getRepository(User).findOneBy({ id: activityApproval.creatorId }))\n }\n\n @FieldResolver(type => User)\n async terminator(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.terminatorId && (await getRepository(User).findOneBy({ id: activityApproval.terminatorId }))\n }\n}\n"]}
1
+ {"version":3,"file":"activity-approval-query.js","sourceRoot":"","sources":["../../../server/service/activity-approval/activity-approval-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets } from 'typeorm'\nimport { DriverUtils } from 'typeorm/driver/DriverUtils.js'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { Role, User } from '@things-factory/auth-base'\nimport { ActivityThread } from '../activity-thread/activity-thread.js'\nimport { ActivityApproval } from './activity-approval.js'\nimport { ActivityApprovalList } from './activity-approval-type.js'\nimport { TERMINATED_JUDGMENTS } from '../../controllers/activity-approval/approval-line.js'\nimport { myPendingApprovalsWhere } from './my-pending-approvals.js'\nimport { ActivityInstance } from '../activity-instance/activity-instance.js'\nimport { NULL_RANK_ALIAS, nullsLastSelect } from '../nulls-last.js'\n\n/*\n * **결재 목록이 걸러 볼 수 있는 칸** — 네 목록이 같은 표를 쓴다.\n *\n * ── 왜 하나로 모으나 (2026-09-05) ──────────────────────────────────────────\n * 이 칸들은 `ActivityApproval` 에 없다. 활동 인스턴스에 있고, 결재는 스레드를 거쳐 그것을 본다.\n * 그래서 목록마다 `filtersMap` 으로 길을 알려 줘야 하고, 안 알려 주면 **그 칸으로 거르는 순간\n * 500 이 난다.**\n *\n * 표를 손으로 네 벌 들고 있었고, 실제로 갈라졌다.\n *\n * approvalPendingList name · description · priority · dueAt\n * approvalDoneList name · description · priority · dueAt\n * approvalReferenceList name · description ← `dueAt` 에서 터졌다\n * activityApprovals (표가 아예 없다) ← `name` 에서도 터진다\n *\n * 화면은 넷에 같은 칩을 보낸다(`client/chip-filters.ts` 의 「24시간 내 마감」이 `dueAt lte` 를\n * 보낸다). 그러니 목록마다 표가 다르면 **어느 목록에서만 터지는** 모양이 된다 — 실측된 것이 그\n * 모양이었다.\n *\n * 다섯 번째 목록이 생길 때 또 갈라지지 않게 한 곳에 둔다.\n */\nconst APPROVAL_FILTERS_MAP: Record<string, { relationColumn: string; columnName: string }> = {\n ...['name', 'description', 'priority'].reduce(\n (map, columnName) => ({ ...map, [columnName]: { relationColumn: 'activityThread.activityInstance', columnName } }),\n {} as Record<string, { relationColumn: string; columnName: string }>\n ),\n\n /*\n * 기한은 **스레드의 것**이다 — 인스턴스에도 같은 이름의 칸이 있지만 화면이 보여 주는 것은 스레드\n * 쪽이다(approval-pending-list-page 는 인스턴스를 펼친 뒤 `dueAt: thread.dueAt` 으로 덮어쓴다).\n *\n * 매핑이 인스턴스를 가리키고 있었다. 지금 자료에서는 두 값이 같아 드러나지 않지만 다른 칸이고,\n * 어긋나는 순간 목록이 **보이지 않는 값으로** 정렬되고 「만기」 칩도 보이지 않는 값으로 거른다.\n * 화면이 보여 주는 것과 같은 칸을 본다.\n */\n dueAt: { relationColumn: 'activityThread', columnName: 'dueAt' }\n}\n\n/** 결재선 스레드가 아니라 업무 인스턴스 쪽 칸으로 정렬하는 이름들. 나머지는 결재 행(ap) 자신이다. */\nconst APPROVAL_INSTANCE_SORTS = new Set(['name', 'description', 'priority'])\n\n/** 스레드(at) 쪽 칸으로 정렬하는 이름들. 화면이 보여 주는 것과 같은 칸이다. */\nconst APPROVAL_THREAD_SORTS = new Set(['dueAt', 'assignedAt', 'state'])\n\n/** 값이 없으면 뒤로 보낼 칸. 기한이 없는 건은 「언제까지」를 묻는 정렬에서 맨 뒤가 맞다. */\nconst APPROVAL_NULLS_LAST = new Set(['dueAt'])\n\n/**\n * 내 결재함의 정렬 — **기한이 없는 건은 뒤로 간다.**\n *\n * 공통 빌더에 맡기면 NULL 자리를 정할 수 없다. sqlite 는 오름차순에서 NULL 을 먼저 내므로 기본\n * 정렬이 기한 순인 목록의 맨 위가 **기한 없는 건**으로 채워진다 — 급한 것부터 보라는 정렬인데\n * 정작 급한 것이 아래로 밀린다. 「할 일」 목록이 같은 이유로 이미 이 처리를 갖고 있고, 규칙은\n * nulls-last.ts 한 곳에 있다.\n *\n * 정렬에 쓸 join 은 여기서 직접 건다. 공통 빌더의 join 은 filter 가 있을 때만 생기므로, 정렬만\n * 하는 요청에서는 기댈 것이 없다.\n */\nfunction applyApprovalSortings(queryBuilder: any, sortings: { name: string; desc?: boolean }[]) {\n const escape = (part: string) => queryBuilder.connection.driver.escape(part)\n\n const fieldOf = (name: string) => {\n const metadata = getRepository(APPROVAL_INSTANCE_SORTS.has(name) ? ActivityInstance : ActivityThread).metadata\n const column = metadata.findColumnWithPropertyName(name)\n\n /* 이름을 못 찾으면 SQL 을 지어내지 않는다. */\n return column ? `${escape(APPROVAL_INSTANCE_SORTS.has(name) ? 'ai' : 'at')}.${escape(column.databaseName)}` : undefined\n }\n\n const terms: { expression: string; direction: 'ASC' | 'DESC'; select?: string }[] = []\n\n for (const sorting of sortings || []) {\n if (!sorting?.name) {\n continue\n }\n\n const direction: 'ASC' | 'DESC' = sorting.desc ? 'DESC' : 'ASC'\n\n if (APPROVAL_NULLS_LAST.has(sorting.name)) {\n const field = fieldOf(sorting.name)\n\n /* 방향이 뒤집혀도 값 없는 것은 뒤다 — 이 항목만 늘 오름차순이다. */\n if (field) {\n terms.push({ expression: NULL_RANK_ALIAS, direction: 'ASC', select: nullsLastSelect(field) })\n }\n }\n\n const alias = APPROVAL_INSTANCE_SORTS.has(sorting.name)\n ? 'ai'\n : APPROVAL_THREAD_SORTS.has(sorting.name)\n ? 'at'\n : 'ap'\n\n /*\n * join 한 칸으로 정렬하면 그 칸이 select 에 있어야 한다.\n *\n * 여기 join 은 leftJoin 이라 칸을 싣지 않는데, 정렬 + 페이지네이션은 TypeORM 의 distinct 경로를\n * 타고 모든 것을 서브쿼리로 감싼 뒤 ORDER BY 를 `distinctAlias.<별칭>` 으로 다시 쓴다. 실을 것이\n * 없으면 그 이름이 없다 — 실측: `no such column: distinctAlias.at_due_at`.\n *\n * 별칭은 TypeORM 이 찾을 때 쓰는 그 함수로 만든다. property 이름으로 지으면 dueAt 처럼 DB 칸\n * 이름과 철자가 다른 칸에서 어긋난다(shell 의 applyJoins 가 같은 이유로 고쳐졌다).\n */\n if (alias !== 'ap') {\n const metadata = getRepository(alias === 'ai' ? ActivityInstance : ActivityThread).metadata\n const column = metadata.findColumnWithPropertyName(sorting.name)\n\n if (column) {\n queryBuilder.addSelect(\n `${alias}.${sorting.name}`,\n DriverUtils.buildAlias(queryBuilder.connection.driver, undefined, alias, column.databaseName)\n )\n }\n }\n\n terms.push({ expression: `${alias}.${sorting.name}`, direction })\n }\n\n terms.forEach(({ expression, direction, select }, index) => {\n /* 식은 select 에 이름 붙여 올린다 — orderBy 는 점이 든 식을 alias 로 읽는다(nulls-last 머리말). */\n if (select) {\n queryBuilder.addSelect(select, expression)\n }\n\n index === 0 ? queryBuilder.orderBy(expression, direction) : queryBuilder.addOrderBy(expression, direction)\n })\n}\n\n@Resolver(ActivityApproval)\nexport class ActivityApprovalQuery {\n @Query(returns => ActivityApproval!, { nullable: true, description: 'To fetch a ActivityApproval' })\n async activityApproval(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ActivityApproval> {\n const { domain } = context.state\n\n return await getRepository(ActivityApproval).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Query(returns => ActivityApprovalList, { description: 'To fetch multiple ActivityApprovals' })\n async activityApprovals(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: getRepository(ActivityApproval),\n searchables: ['name', 'description'],\n filtersMap: APPROVAL_FILTERS_MAP\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => ActivityApprovalList, { description: 'To fetch the list of work results I need to review' })\n async approvalPendingList(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n /* 정렬은 아래에서 직접 건다(applyApprovalSortings 머리말) — 여기에 넘기면 NULL 자리를 못 정한다. */\n params: { ...params, sortings: [] },\n domain,\n alias: 'ap',\n searchables: ['name', 'description'],\n filtersMap: APPROVAL_FILTERS_MAP\n })\n /* 정렬이 쓸 join — 정렬만 하는 요청에는 filter 쪽 join 이 없다. */\n .leftJoin('ap.activityThread', 'at')\n .leftJoin('at.activityInstance', 'ai')\n /* 「내가 판단해야 할 것」의 정의는 한 자리에 있다 — 달력도 같은 것을 읽는다. */\n .andWhere(myPendingApprovalsWhere({ userId: user.id, roles }))\n\n applyApprovalSortings(queryBuilder, params.sortings || [])\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /**\n * **내가 참조로 걸린 것** — 결재하는 것이 아니라 보고 의견을 낼 수 있는 것.\n *\n * 승인 대기 목록과 나눈다. 섞으면 참조자가 「내가 승인해야 하나」로 읽고, 결재자는 남의 참조 건까지\n * 훑게 된다. 두 목록의 물음이 다르다 — 「내가 결정할 것」과 「내가 알아야 할 것」.\n *\n * 끝난 건도 보인다. 결재가 끝난 뒤에 의견이 달릴 수 있고(참조는 막지 않으므로 늦게 올 수 있다),\n * 그 사실을 화면이 「결정 후」로 표시해야 한다.\n */\n @Query(returns => ActivityApprovalList, {\n description: 'To fetch the approvals where I am a reference — I may comment, I do not decide'\n })\n async approvalReferenceList(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({ where: { id: user.id }, relations: ['roles'] })\n const roles = (user.roles ?? []).filter(role => role.domainId === domain.id).map(role => role.id)\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params,\n domain,\n alias: 'ap',\n searchables: ['name', 'description'],\n filtersMap: APPROVAL_FILTERS_MAP\n })\n .andWhere(`ap.participation = 'reference'`)\n .andWhere(\n new Brackets(qb => {\n qb.where('ap.approver = :user', { user: user.id })\n /* 역할로 걸린 참조는 그 역할을 가진 사람 모두가 본다 — 결재와 같은 규칙이다. */\n if (roles.length > 0) qb.orWhere('ap.approverRole IN (:...roles)', { roles })\n })\n )\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => ActivityApprovalList, {\n description: 'To fetch the approvals(ActivityApprovals) which has done by me'\n })\n async approvalDoneList(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ActivityApprovalList> {\n var { domain, user } = context.state\n\n /* 「끝난 것」의 정의는 한 자리에 있다 — 여기서 다시 세면 값이 늘 때 한쪽만 늘어난다. */\n const judgment = [...TERMINATED_JUDGMENTS]\n\n const [items, total] = await getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params,\n domain,\n alias: 'ap',\n searchables: ['name', 'description'],\n filtersMap: APPROVAL_FILTERS_MAP\n })\n .andWhere('ap.judgment IN (:...judgment)', { judgment })\n /*\n * 역할로 걸린 결재를 처리하면 이제 `approver` 에 처리한 사람이 들어간다(`approve.ts`·`reject.ts`).\n * 그래서 이 한 줄로 자기가 처리한 것이 다 걸린다 — 개인으로 걸린 것이든 역할로 걸린 것이든.\n *\n * 고치기 전에 처리한 역할 결재는 `approver` 가 비어 있어 여기 안 나온다. 지난 기록을 뒤에서 고쳐\n * 쓰지 않는다는 규율에 따라 그대로 둔다.\n */\n .andWhere('ap.approver = :user', { user: user.id })\n .getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => ActivityThread)\n async activityThread(@Root() activityApproval: ActivityApproval): Promise<ActivityThread> {\n return await getRepository(ActivityThread).findOneBy({ id: activityApproval.activityThreadId })\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() activityApproval: ActivityApproval): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: activityApproval.domainId })\n }\n\n @FieldResolver(type => User)\n async approver(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.approverId && (await getRepository(User).findOneBy({ id: activityApproval.approverId }))\n }\n\n /**\n * 누가 결재해야 하나가 **역할**일 때.\n *\n * 이 리졸버가 없어서 `approverRole` 이 늘 `null` 로 나갔다. DB 에는 들어 있는데 질의가 관계를 안\n * 싣기 때문이다. 그래서 결재 목록이 「누가 결재해야 하나」를 못 보였다 — 개인으로 지정한 건만 보이고\n * 역할로 지정한 건은 빈칸이었다.\n */\n @FieldResolver(type => Role, { nullable: true })\n async approverRole(@Root() activityApproval: ActivityApproval): Promise<Role> {\n return activityApproval.approverRoleId && (await getRepository(Role).findOneBy({ id: activityApproval.approverRoleId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.updaterId && (await getRepository(User).findOneBy({ id: activityApproval.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.creatorId && (await getRepository(User).findOneBy({ id: activityApproval.creatorId }))\n }\n\n @FieldResolver(type => User)\n async terminator(@Root() activityApproval: ActivityApproval): Promise<User> {\n return activityApproval.terminatorId && (await getRepository(User).findOneBy({ id: activityApproval.terminatorId }))\n }\n}\n"]}
@@ -7,7 +7,16 @@ export declare enum ActivityApprovalJudgment {
7
7
  Escalated = "escalated",
8
8
  Delegated = "delegated",
9
9
  Approved = "approved",
10
- Aborted = "aborted"
10
+ Aborted = "aborted",
11
+ /**
12
+ * **건이 끝나서 닫혔다** — 판정한 것이 아니다.
13
+ *
14
+ * 참조는 결재하지 않으므로 승인·반려로 끝나지 않는다. 건이 끝나면 이 값으로 닫는다.
15
+ *
16
+ * 의견을 냈는지는 `comment` 가 말한다. 비어 있으면 **「통지받았고 말하지 않았다」**이고,
17
+ * 그것은 동의가 아니다 — 나중에 결재 이력을 읽는 사람이 침묵을 동의로 읽으면 안 된다.
18
+ */
19
+ Closed = "closed"
11
20
  }
12
21
  export declare class ActivityApproval {
13
22
  readonly id: string;
@@ -20,12 +29,31 @@ export declare class ActivityApproval {
20
29
  activityThreadId?: string;
21
30
  round: number;
22
31
  order?: number;
32
+ /**
33
+ * **무슨 자격으로 서 있나** — `approval` 이면 결재하고 `reference` 면 의견만 낸다.
34
+ *
35
+ * 비어 있으면 결재다. 지금 쌓여 있는 행에는 이 칸이 없고, 그 행들이 전부 결재로 읽혀야 거동이 안 바뀐다.
36
+ *
37
+ * 목록 질의가 이 칸을 본다 — 참조 행이 승인 대기 목록에 나오면 그 사람에게 **승인하라고 요구하는**
38
+ * 것이 되고, 참조의 뜻이 사라진다.
39
+ */
40
+ participation?: string;
23
41
  approver?: User;
24
42
  approverId?: string;
25
43
  approverRole?: Role;
26
44
  approverRoleId?: string;
27
45
  judgment?: ActivityApprovalJudgment;
28
46
  comment?: string;
47
+ /**
48
+ * 의견을 **언제 말했나** — 파생으로 알 수 없다.
49
+ *
50
+ * 화면이 「결정이 끝난 뒤에 달린 의견」을 표시하려면 이 값이 있어야 한다. `updatedAt` 과
51
+ * `terminatedAt` 을 견주는 것으로는 안 된다 — 닫는 코드가 `terminatedAt` 을 저장 전에 만들고
52
+ * `updatedAt` 은 DB 가 쓰는 순간 찍으므로, 닫힌 행은 **전부** 「나중에 바뀌었다」로 보인다.
53
+ *
54
+ * 비어 있으면 말하지 않은 것이다. 침묵은 동의도 반대도 아니다.
55
+ */
56
+ commentedAt?: Date;
29
57
  transaction?: string;
30
58
  createdAt?: Date;
31
59
  updatedAt?: Date;
@@ -15,6 +15,15 @@ var ActivityApprovalJudgment;
15
15
  ActivityApprovalJudgment["Delegated"] = "delegated";
16
16
  ActivityApprovalJudgment["Approved"] = "approved";
17
17
  ActivityApprovalJudgment["Aborted"] = "aborted";
18
+ /**
19
+ * **건이 끝나서 닫혔다** — 판정한 것이 아니다.
20
+ *
21
+ * 참조는 결재하지 않으므로 승인·반려로 끝나지 않는다. 건이 끝나면 이 값으로 닫는다.
22
+ *
23
+ * 의견을 냈는지는 `comment` 가 말한다. 비어 있으면 **「통지받았고 말하지 않았다」**이고,
24
+ * 그것은 동의가 아니다 — 나중에 결재 이력을 읽는 사람이 침묵을 동의로 읽으면 안 된다.
25
+ */
26
+ ActivityApprovalJudgment["Closed"] = "closed";
18
27
  })(ActivityApprovalJudgment || (exports.ActivityApprovalJudgment = ActivityApprovalJudgment = {}));
19
28
  (0, type_graphql_1.registerEnumType)(ActivityApprovalJudgment, {
20
29
  name: 'ActivityApprovalJudgment',
@@ -75,6 +84,11 @@ tslib_1.__decorate([
75
84
  (0, type_graphql_1.Field)({ nullable: true, description: 'Nth order approval for the given activity thread' }),
76
85
  tslib_1.__metadata("design:type", Number)
77
86
  ], ActivityApproval.prototype, "order", void 0);
87
+ tslib_1.__decorate([
88
+ (0, typeorm_1.Column)({ nullable: true }),
89
+ (0, type_graphql_1.Field)({ nullable: true, description: 'In what capacity: approval decides, reference only comments. Empty means approval.' }),
90
+ tslib_1.__metadata("design:type", String)
91
+ ], ActivityApproval.prototype, "participation", void 0);
78
92
  tslib_1.__decorate([
79
93
  (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
80
94
  (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
@@ -103,6 +117,11 @@ tslib_1.__decorate([
103
117
  (0, type_graphql_1.Field)({ nullable: true }),
104
118
  tslib_1.__metadata("design:type", String)
105
119
  ], ActivityApproval.prototype, "comment", void 0);
120
+ tslib_1.__decorate([
121
+ (0, typeorm_1.Column)({ nullable: true }),
122
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the opinion was said. Empty means nothing was said — silence is not consent.' }),
123
+ tslib_1.__metadata("design:type", Date)
124
+ ], ActivityApproval.prototype, "commentedAt", void 0);
106
125
  tslib_1.__decorate([
107
126
  (0, typeorm_1.Column)({ nullable: true }),
108
127
  (0, type_graphql_1.Field)({ nullable: true }),
@@ -1 +1 @@
1
- {"version":3,"file":"activity-approval.js","sourceRoot":"","sources":["../../../server/service/activity-approval/activity-approval.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n OneToMany,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { Domain } from '@things-factory/shell'\nimport { Role, User } from '@things-factory/auth-base'\nimport { ActivityThread } from '../activity-thread/activity-thread.js'\n\nexport enum ActivityApprovalJudgment {\n Pending = '',\n Rejected = 'rejected',\n Escalated = 'escalated',\n Delegated = 'delegated',\n Approved = 'approved',\n Aborted = 'aborted'\n}\n\nregisterEnumType(ActivityApprovalJudgment, {\n name: 'ActivityApprovalJudgment',\n description: 'judgment enumeration of a activityApproval'\n})\n\n@Entity()\n@Index(\n 'ix_activity_approval_0',\n (activityApproval: ActivityApproval) => [\n activityApproval.domain,\n activityApproval.activityThread,\n activityApproval.order,\n activityApproval.approver,\n activityApproval.createdAt\n ],\n { unique: true }\n)\n@ObjectType({ description: 'Entity for ActivityApproval' })\nexport class ActivityApproval {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain)\n domain?: Domain\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.domain)\n domainId?: string\n\n @ManyToOne(type => ActivityApproval, { nullable: true })\n @Field(type => ActivityApproval, { nullable: true, description: 'delegator approval' })\n originalApproval?: ActivityApproval\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.originalApproval)\n originalApprovalId?: string\n\n @OneToMany(type => ActivityApproval, activityApproval => activityApproval.originalApproval)\n @Field(type => [ActivityApproval])\n derivedApprovals?: ActivityApproval\n\n @ManyToOne(type => ActivityThread, { nullable: true })\n @Field(type => ActivityThread, { nullable: true })\n activityThread?: ActivityThread\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.activityThread)\n activityThreadId?: string\n\n @Column({ nullable: true, default: 1 })\n @Field({ nullable: true })\n round: number = 1\n\n @Column({ nullable: true, default: 0 })\n @Field({ nullable: true, description: 'Nth order approval for the given activity thread' })\n order?: number = 0\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n approver?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.approver)\n approverId?: string\n\n @ManyToOne(type => Role, { nullable: true })\n @Field(type => Role, { nullable: true })\n approverRole?: Role\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.approverRole)\n approverRoleId?: string\n\n @Column({ nullable: true, default: '' })\n @Field({ nullable: true })\n judgment?: ActivityApprovalJudgment = ActivityApprovalJudgment.Pending\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n comment?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n transaction?: string\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n terminatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.updater)\n updaterId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field({ nullable: true })\n terminator?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.terminator)\n terminatorId?: string\n}\n"]}
1
+ {"version":3,"file":"activity-approval.js","sourceRoot":"","sources":["../../../server/service/activity-approval/activity-approval.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n OneToMany,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { Domain } from '@things-factory/shell'\nimport { Role, User } from '@things-factory/auth-base'\nimport { ActivityThread } from '../activity-thread/activity-thread.js'\n\nexport enum ActivityApprovalJudgment {\n Pending = '',\n Rejected = 'rejected',\n Escalated = 'escalated',\n Delegated = 'delegated',\n Approved = 'approved',\n Aborted = 'aborted',\n /**\n * **건이 끝나서 닫혔다** — 판정한 것이 아니다.\n *\n * 참조는 결재하지 않으므로 승인·반려로 끝나지 않는다. 건이 끝나면 이 값으로 닫는다.\n *\n * 의견을 냈는지는 `comment` 가 말한다. 비어 있으면 **「통지받았고 말하지 않았다」**이고,\n * 그것은 동의가 아니다 — 나중에 결재 이력을 읽는 사람이 침묵을 동의로 읽으면 안 된다.\n */\n Closed = 'closed'\n}\n\nregisterEnumType(ActivityApprovalJudgment, {\n name: 'ActivityApprovalJudgment',\n description: 'judgment enumeration of a activityApproval'\n})\n\n@Entity()\n@Index(\n 'ix_activity_approval_0',\n (activityApproval: ActivityApproval) => [\n activityApproval.domain,\n activityApproval.activityThread,\n activityApproval.order,\n activityApproval.approver,\n activityApproval.createdAt\n ],\n { unique: true }\n)\n@ObjectType({ description: 'Entity for ActivityApproval' })\nexport class ActivityApproval {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain)\n domain?: Domain\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.domain)\n domainId?: string\n\n @ManyToOne(type => ActivityApproval, { nullable: true })\n @Field(type => ActivityApproval, { nullable: true, description: 'delegator approval' })\n originalApproval?: ActivityApproval\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.originalApproval)\n originalApprovalId?: string\n\n @OneToMany(type => ActivityApproval, activityApproval => activityApproval.originalApproval)\n @Field(type => [ActivityApproval])\n derivedApprovals?: ActivityApproval\n\n @ManyToOne(type => ActivityThread, { nullable: true })\n @Field(type => ActivityThread, { nullable: true })\n activityThread?: ActivityThread\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.activityThread)\n activityThreadId?: string\n\n @Column({ nullable: true, default: 1 })\n @Field({ nullable: true })\n round: number = 1\n\n @Column({ nullable: true, default: 0 })\n @Field({ nullable: true, description: 'Nth order approval for the given activity thread' })\n order?: number = 0\n\n /**\n * **무슨 자격으로 서 있나** — `approval` 이면 결재하고 `reference` 면 의견만 낸다.\n *\n * 비어 있으면 결재다. 지금 쌓여 있는 행에는 이 칸이 없고, 그 행들이 전부 결재로 읽혀야 거동이 안 바뀐다.\n *\n * 목록 질의가 이 칸을 본다 — 참조 행이 승인 대기 목록에 나오면 그 사람에게 **승인하라고 요구하는**\n * 것이 되고, 참조의 뜻이 사라진다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'In what capacity: approval decides, reference only comments. Empty means approval.' })\n participation?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n approver?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.approver)\n approverId?: string\n\n @ManyToOne(type => Role, { nullable: true })\n @Field(type => Role, { nullable: true })\n approverRole?: Role\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.approverRole)\n approverRoleId?: string\n\n @Column({ nullable: true, default: '' })\n @Field({ nullable: true })\n judgment?: ActivityApprovalJudgment = ActivityApprovalJudgment.Pending\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n comment?: string\n\n /**\n * 의견을 **언제 말했나** — 파생으로 알 수 없다.\n *\n * 화면이 「결정이 끝난 뒤에 달린 의견」을 표시하려면 이 값이 있어야 한다. `updatedAt` 과\n * `terminatedAt` 을 견주는 것으로는 안 된다 — 닫는 코드가 `terminatedAt` 을 저장 전에 만들고\n * `updatedAt` 은 DB 가 쓰는 순간 찍으므로, 닫힌 행은 **전부** 「나중에 바뀌었다」로 보인다.\n *\n * 비어 있으면 말하지 않은 것이다. 침묵은 동의도 반대도 아니다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When the opinion was said. Empty means nothing was said — silence is not consent.' })\n commentedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n transaction?: string\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n terminatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.updater)\n updaterId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field({ nullable: true })\n terminator?: User\n\n @RelationId((activityApproval: ActivityApproval) => activityApproval.terminator)\n terminatorId?: string\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { Brackets } from 'typeorm';
2
+ /**
3
+ * The approvals waiting on me — one definition, two readers.
4
+ *
5
+ * 내 결재함 asks this, and so does the calendar. Both have to agree on three things that are easy
6
+ * to get wrong separately:
7
+ *
8
+ * - **참조는 승인 대기가 아니다.** Asking a reference to approve destroys what a reference is. An
9
+ * empty column is an approval: rows created before the column existed have nothing there.
10
+ * - **역할로 걸린 결재도 내 것이다** — but only while unclaimed. A role-held row keeps `approver`
11
+ * empty until someone presses, so without a judgment test finished work stays in the list of
12
+ * everyone holding that role, forever.
13
+ * - **끝난 것의 정의는 한 자리에 있다** (TERMINATED_JUDGMENTS). Counted again here, a new judgment
14
+ * value would land in one reader and not the other.
15
+ *
16
+ * Expects `ap` (ActivityApproval) to be the alias.
17
+ */
18
+ export declare function myPendingApprovalsWhere({ userId, roles }: {
19
+ userId: string;
20
+ roles: string[];
21
+ }): Brackets;