@things-factory/inquiry 0.0.0-stage → 10.1.251

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 (105) hide show
  1. package/client/bootstrap.ts +27 -0
  2. package/client/components/inquiry-thread.ts +277 -0
  3. package/client/components/inquiry-todo.ts +36 -0
  4. package/client/components/inquiry-writer.ts +208 -0
  5. package/client/index.ts +2 -0
  6. package/client/inquiry-watch.ts +45 -0
  7. package/client/pages/inquiry-list.ts +218 -0
  8. package/client/route.ts +8 -0
  9. package/client/tsconfig.json +13 -0
  10. package/client/utils/inquiry-api.ts +103 -0
  11. package/client/utils/inquiry-badge.ts +46 -0
  12. package/client/utils/inquiry-words.ts +26 -0
  13. package/dist-client/bootstrap.d.ts +2 -0
  14. package/dist-client/bootstrap.js +25 -0
  15. package/dist-client/bootstrap.js.map +1 -0
  16. package/dist-client/components/inquiry-thread.d.ts +28 -0
  17. package/dist-client/components/inquiry-thread.js +303 -0
  18. package/dist-client/components/inquiry-thread.js.map +1 -0
  19. package/dist-client/components/inquiry-todo.d.ts +9 -0
  20. package/dist-client/components/inquiry-todo.js +43 -0
  21. package/dist-client/components/inquiry-todo.js.map +1 -0
  22. package/dist-client/components/inquiry-writer.d.ts +23 -0
  23. package/dist-client/components/inquiry-writer.js +230 -0
  24. package/dist-client/components/inquiry-writer.js.map +1 -0
  25. package/dist-client/index.d.ts +2 -0
  26. package/dist-client/index.js +3 -0
  27. package/dist-client/index.js.map +1 -0
  28. package/dist-client/inquiry-watch.d.ts +2 -0
  29. package/dist-client/inquiry-watch.js +41 -0
  30. package/dist-client/inquiry-watch.js.map +1 -0
  31. package/dist-client/pages/inquiry-list.d.ts +56 -0
  32. package/dist-client/pages/inquiry-list.js +241 -0
  33. package/dist-client/pages/inquiry-list.js.map +1 -0
  34. package/dist-client/route.d.ts +1 -0
  35. package/dist-client/route.js +9 -0
  36. package/dist-client/route.js.map +1 -0
  37. package/dist-client/tsconfig.tsbuildinfo +1 -0
  38. package/dist-client/utils/inquiry-api.d.ts +73 -0
  39. package/dist-client/utils/inquiry-api.js +34 -0
  40. package/dist-client/utils/inquiry-api.js.map +1 -0
  41. package/dist-client/utils/inquiry-badge.d.ts +4 -0
  42. package/dist-client/utils/inquiry-badge.js +47 -0
  43. package/dist-client/utils/inquiry-badge.js.map +1 -0
  44. package/dist-client/utils/inquiry-words.d.ts +13 -0
  45. package/dist-client/utils/inquiry-words.js +22 -0
  46. package/dist-client/utils/inquiry-words.js.map +1 -0
  47. package/dist-server/attachment-reader.d.ts +1 -0
  48. package/dist-server/attachment-reader.js +21 -0
  49. package/dist-server/attachment-reader.js.map +1 -0
  50. package/dist-server/index.d.ts +2 -0
  51. package/dist-server/index.js +22 -0
  52. package/dist-server/index.js.map +1 -0
  53. package/dist-server/inquiry-activity.d.ts +38 -0
  54. package/dist-server/inquiry-activity.js +38 -0
  55. package/dist-server/inquiry-activity.js.map +1 -0
  56. package/dist-server/role-tasks.d.ts +2 -0
  57. package/dist-server/role-tasks.js +14 -0
  58. package/dist-server/role-tasks.js.map +1 -0
  59. package/dist-server/service/index.d.ts +7 -0
  60. package/dist-server/service/index.js +24 -0
  61. package/dist-server/service/index.js.map +1 -0
  62. package/dist-server/service/inquiry/index.d.ts +4 -0
  63. package/dist-server/service/inquiry/index.js +8 -0
  64. package/dist-server/service/inquiry/index.js.map +1 -0
  65. package/dist-server/service/inquiry/inquiry-resolver.d.ts +29 -0
  66. package/dist-server/service/inquiry/inquiry-resolver.js +407 -0
  67. package/dist-server/service/inquiry/inquiry-resolver.js.map +1 -0
  68. package/dist-server/service/inquiry/inquiry-rules.d.ts +88 -0
  69. package/dist-server/service/inquiry/inquiry-rules.js +157 -0
  70. package/dist-server/service/inquiry/inquiry-rules.js.map +1 -0
  71. package/dist-server/service/inquiry/inquiry-service.d.ts +35 -0
  72. package/dist-server/service/inquiry/inquiry-service.js +143 -0
  73. package/dist-server/service/inquiry/inquiry-service.js.map +1 -0
  74. package/dist-server/service/inquiry/inquiry-types.d.ts +18 -0
  75. package/dist-server/service/inquiry/inquiry-types.js +69 -0
  76. package/dist-server/service/inquiry/inquiry-types.js.map +1 -0
  77. package/dist-server/service/inquiry/inquiry.d.ts +48 -0
  78. package/dist-server/service/inquiry/inquiry.js +232 -0
  79. package/dist-server/service/inquiry/inquiry.js.map +1 -0
  80. package/dist-server/tsconfig.tsbuildinfo +1 -0
  81. package/package.json +51 -4
  82. package/server/attachment-reader.ts +18 -0
  83. package/server/index.ts +18 -0
  84. package/server/inquiry-activity.ts +35 -0
  85. package/server/role-tasks.ts +13 -0
  86. package/server/service/index.ts +19 -0
  87. package/server/service/inquiry/index.ts +5 -0
  88. package/server/service/inquiry/inquiry-resolver.ts +321 -0
  89. package/server/service/inquiry/inquiry-rules.ts +173 -0
  90. package/server/service/inquiry/inquiry-service.ts +143 -0
  91. package/server/service/inquiry/inquiry-types.ts +45 -0
  92. package/server/service/inquiry/inquiry.ts +180 -0
  93. package/server/tsconfig.json +11 -0
  94. package/test/inquiry-persistence.test.ts +218 -0
  95. package/test/inquiry-rules.test.ts +121 -0
  96. package/test/open-doors.test.ts +44 -0
  97. package/test/translations.test.ts +53 -0
  98. package/things-factory.config.js +8 -0
  99. package/translations/en.json +93 -0
  100. package/translations/es.json +93 -0
  101. package/translations/ja.json +93 -0
  102. package/translations/ko.json +93 -0
  103. package/translations/ms.json +93 -0
  104. package/translations/zh.json +93 -0
  105. package/README.md +0 -3
@@ -0,0 +1,47 @@
1
+ /*
2
+ * The count the menu shows on 문의 · 제안 (ADR-0184 decision 8) - new words on one's own inquiries, and for a handler
3
+ * those waiting on the handlers. An application puts `generateInquiryBadge` on its menu entry; the count is asked again
4
+ * whenever an inquiry notice arrives or an inquiry changes on a screen.
5
+ */
6
+ import { inquiryApi } from './inquiry-api.js';
7
+ let count;
8
+ /* One more each time the count is asked again - a badge that was busy drawing the last one still sees the next. */
9
+ let version = 0;
10
+ const waiting = new Set();
11
+ /** Asks the server again and tells every badge. A count that could not be asked is not zero: it draws nothing. */
12
+ export async function refreshInquiryBadge() {
13
+ try {
14
+ count = (await inquiryApi.summary()).badge;
15
+ }
16
+ catch {
17
+ count = undefined;
18
+ }
19
+ version++;
20
+ for (const wake of [...waiting])
21
+ wake();
22
+ }
23
+ let generation = 0;
24
+ /** One badge's counts. The menu asks for a new one when it draws again; the one before it then ends, as worklist's do. */
25
+ export async function* generateInquiryBadge() {
26
+ const mine = ++generation;
27
+ for (const wake of [...waiting])
28
+ wake();
29
+ let seen = version;
30
+ yield count;
31
+ while (true) {
32
+ if (seen === version) {
33
+ await new Promise(resolve => {
34
+ const wake = () => {
35
+ waiting.delete(wake);
36
+ resolve();
37
+ };
38
+ waiting.add(wake);
39
+ });
40
+ }
41
+ if (mine !== generation)
42
+ return;
43
+ seen = version;
44
+ yield count;
45
+ }
46
+ }
47
+ //# sourceMappingURL=inquiry-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inquiry-badge.js","sourceRoot":"","sources":["../../client/utils/inquiry-badge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,IAAI,KAAyB,CAAA;AAC7B,mHAAmH;AACnH,IAAI,OAAO,GAAG,CAAC,CAAA;AACf,MAAM,OAAO,GAAG,IAAI,GAAG,EAAc,CAAA;AAErC,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,CAAC;QACH,KAAK,GAAG,CAAC,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,SAAS,CAAA;IACnB,CAAC;IACD,OAAO,EAAE,CAAA;IACT,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,CAAA;AACzC,CAAC;AAED,IAAI,UAAU,GAAG,CAAC,CAAA;AAElB,0HAA0H;AAC1H,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,oBAAoB;IACzC,MAAM,IAAI,GAAG,EAAE,UAAU,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,CAAA;IACvC,IAAI,IAAI,GAAG,OAAO,CAAA;IAClB,MAAM,KAAK,CAAA;IACX,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;gBAChC,MAAM,IAAI,GAAG,GAAG,EAAE;oBAChB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;oBACpB,OAAO,EAAE,CAAA;gBACX,CAAC,CAAA;gBACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,UAAU;YAAE,OAAM;QAC/B,IAAI,GAAG,OAAO,CAAA;QACd,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC","sourcesContent":["/*\n * The count the menu shows on 문의 · 제안 (ADR-0184 decision 8) - new words on one's own inquiries, and for a handler\n * those waiting on the handlers. An application puts `generateInquiryBadge` on its menu entry; the count is asked again\n * whenever an inquiry notice arrives or an inquiry changes on a screen.\n */\nimport { inquiryApi } from './inquiry-api.js'\n\nlet count: number | undefined\n/* One more each time the count is asked again - a badge that was busy drawing the last one still sees the next. */\nlet version = 0\nconst waiting = new Set<() => void>()\n\n/** Asks the server again and tells every badge. A count that could not be asked is not zero: it draws nothing. */\nexport async function refreshInquiryBadge(): Promise<void> {\n try {\n count = (await inquiryApi.summary()).badge\n } catch {\n count = undefined\n }\n version++\n for (const wake of [...waiting]) wake()\n}\n\nlet generation = 0\n\n/** One badge's counts. The menu asks for a new one when it draws again; the one before it then ends, as worklist's do. */\nexport async function* generateInquiryBadge() {\n const mine = ++generation\n for (const wake of [...waiting]) wake()\n let seen = version\n yield count\n while (true) {\n if (seen === version) {\n await new Promise<void>(resolve => {\n const wake = () => {\n waiting.delete(wake)\n resolve()\n }\n waiting.add(wake)\n })\n }\n if (mine !== generation) return\n seen = version\n yield count\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ export declare const t: (key: string, options?: Record<string, unknown>) => string;
2
+ export declare const KINDS: string[];
3
+ export declare const VISIBILITIES: string[];
4
+ export declare const STATUSES: string[];
5
+ export declare const kindWord: (code?: string | null) => string;
6
+ export declare const statusWord: (code?: string | null) => string;
7
+ export declare const visibilityWord: (code?: string | null) => string;
8
+ /** The icon of each kind. */
9
+ export declare const KIND_ICONS: Record<string, string>;
10
+ /** A day and time as the reader's locale writes it. */
11
+ export declare function when(value?: string | Date | null): string;
12
+ /** The words of a refusal the server gave, or the fallback. */
13
+ export declare const reasonOf: (error: unknown) => string;
@@ -0,0 +1,22 @@
1
+ /*
2
+ * The words and marks of inquiries - one place for the list, the thread, the writing window and the to-do.
3
+ */
4
+ import { i18next } from '@operato/i18n';
5
+ export const t = (key, options = {}) => String(i18next.t(key, options));
6
+ export const KINDS = ['QUESTION', 'BUG', 'PROPOSAL'];
7
+ export const VISIBILITIES = ['DOMAIN', 'PRIVATE'];
8
+ export const STATUSES = ['RECEIVED', 'IN_PROGRESS', 'ANSWERED', 'PLANNED', 'DECLINED', 'CLOSED'];
9
+ export const kindWord = (code) => (code ? t(`inquiry.kind.${code}`, { defaultValue: code }) : '');
10
+ export const statusWord = (code) => (code ? t(`inquiry.status.${code}`, { defaultValue: code }) : '');
11
+ export const visibilityWord = (code) => (code ? t(`inquiry.visibility.${code}`, { defaultValue: code }) : '');
12
+ /** The icon of each kind. */
13
+ export const KIND_ICONS = { QUESTION: 'help', BUG: 'bug_report', PROPOSAL: 'lightbulb' };
14
+ /** A day and time as the reader's locale writes it. */
15
+ export function when(value) {
16
+ if (!value)
17
+ return '';
18
+ return new Date(value).toLocaleString(i18next.language, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
19
+ }
20
+ /** The words of a refusal the server gave, or the fallback. */
21
+ export const reasonOf = (error) => error?.message || t('inquiry.text.failed');
22
+ //# sourceMappingURL=inquiry-words.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inquiry-words.js","sourceRoot":"","sources":["../../client/utils/inquiry-words.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAW,EAAE,UAAmC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AAExG,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;AAEhG,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACjH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACrH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAE7H,6BAA6B;AAC7B,MAAM,CAAC,MAAM,UAAU,GAA2B,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;AAEhH,uDAAuD;AACvD,MAAM,UAAU,IAAI,CAAC,KAA4B;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;AACpJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAE,EAAE,CAAE,KAAe,EAAE,OAAO,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAA","sourcesContent":["/*\n * The words and marks of inquiries - one place for the list, the thread, the writing window and the to-do.\n */\nimport { i18next } from '@operato/i18n'\n\nexport const t = (key: string, options: Record<string, unknown> = {}) => String(i18next.t(key, options))\n\nexport const KINDS = ['QUESTION', 'BUG', 'PROPOSAL']\nexport const VISIBILITIES = ['DOMAIN', 'PRIVATE']\nexport const STATUSES = ['RECEIVED', 'IN_PROGRESS', 'ANSWERED', 'PLANNED', 'DECLINED', 'CLOSED']\n\nexport const kindWord = (code?: string | null) => (code ? t(`inquiry.kind.${code}`, { defaultValue: code }) : '')\nexport const statusWord = (code?: string | null) => (code ? t(`inquiry.status.${code}`, { defaultValue: code }) : '')\nexport const visibilityWord = (code?: string | null) => (code ? t(`inquiry.visibility.${code}`, { defaultValue: code }) : '')\n\n/** The icon of each kind. */\nexport const KIND_ICONS: Record<string, string> = { QUESTION: 'help', BUG: 'bug_report', PROPOSAL: 'lightbulb' }\n\n/** A day and time as the reader's locale writes it. */\nexport function when(value?: string | Date | null): string {\n if (!value) return ''\n return new Date(value).toLocaleString(i18next.language, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })\n}\n\n/** The words of a refusal the server gave, or the fallback. */\nexport const reasonOf = (error: unknown) => (error as Error)?.message || t('inquiry.text.failed')\n"]}
@@ -0,0 +1 @@
1
+ export declare function registerInquiryFiles(): void;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerInquiryFiles = registerInquiryFiles;
4
+ /*
5
+ * Who may open an inquiry's file by its path - whoever may read the inquiry (ADR-0184 decision 5), a reply's file as
6
+ * its inquiry's. attachment-base has already checked the file is of the request's domain.
7
+ */
8
+ const attachment_base_1 = require("@things-factory/attachment-base");
9
+ const shell_1 = require("@things-factory/shell");
10
+ const inquiry_1 = require("./service/inquiry/inquiry");
11
+ const inquiry_service_1 = require("./service/inquiry/inquiry-service");
12
+ function registerInquiryFiles() {
13
+ (0, attachment_base_1.registerAttachmentReader)(inquiry_service_1.INQUIRY_REF_TYPE, async (attachment, context) => !!attachment.refBy && !!(await (0, inquiry_service_1.visibleInquiry)(attachment.refBy, context)));
14
+ (0, attachment_base_1.registerAttachmentReader)(inquiry_service_1.INQUIRY_REPLY_REF_TYPE, async (attachment, context) => {
15
+ if (!attachment.refBy)
16
+ return false;
17
+ const reply = await (0, shell_1.getRepository)(inquiry_1.InquiryReply).findOneBy({ id: attachment.refBy });
18
+ return !!reply?.inquiryId && !!(await (0, inquiry_service_1.visibleInquiry)(reply.inquiryId, context));
19
+ });
20
+ }
21
+ //# sourceMappingURL=attachment-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-reader.js","sourceRoot":"","sources":["../server/attachment-reader.ts"],"names":[],"mappings":";;AAUA,oDAOC;AAjBD;;;GAGG;AACH,qEAA0E;AAC1E,iDAAqD;AAErD,uDAAwD;AACxD,uEAA4G;AAE5G,SAAgB,oBAAoB;IAClC,IAAA,0CAAwB,EAAC,kCAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,IAAA,gCAAc,EAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IACpJ,IAAA,0CAAwB,EAAC,wCAAsB,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;QAC7E,IAAI,CAAC,UAAU,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QACnC,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,sBAAY,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAA;QACnF,OAAO,CAAC,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,MAAM,IAAA,gCAAc,EAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["/*\n * Who may open an inquiry's file by its path - whoever may read the inquiry (ADR-0184 decision 5), a reply's file as\n * its inquiry's. attachment-base has already checked the file is of the request's domain.\n */\nimport { registerAttachmentReader } from '@things-factory/attachment-base'\nimport { getRepository } from '@things-factory/shell'\n\nimport { InquiryReply } from './service/inquiry/inquiry'\nimport { INQUIRY_REF_TYPE, INQUIRY_REPLY_REF_TYPE, visibleInquiry } from './service/inquiry/inquiry-service'\n\nexport function registerInquiryFiles(): void {\n registerAttachmentReader(INQUIRY_REF_TYPE, async (attachment, context) => !!attachment.refBy && !!(await visibleInquiry(attachment.refBy, context)))\n registerAttachmentReader(INQUIRY_REPLY_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy) return false\n const reply = await getRepository(InquiryReply).findOneBy({ id: attachment.refBy })\n return !!reply?.inquiryId && !!(await visibleInquiry(reply.inquiryId, context))\n })\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './service';
2
+ export { INQUIRY_ACTIVITY, INQUIRY_HANDLING } from './inquiry-activity';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INQUIRY_HANDLING = exports.INQUIRY_ACTIVITY = void 0;
4
+ const tslib_1 = require("tslib");
5
+ tslib_1.__exportStar(require("./service"), exports);
6
+ var inquiry_activity_1 = require("./inquiry-activity");
7
+ Object.defineProperty(exports, "INQUIRY_ACTIVITY", { enumerable: true, get: function () { return inquiry_activity_1.INQUIRY_ACTIVITY; } });
8
+ Object.defineProperty(exports, "INQUIRY_HANDLING", { enumerable: true, get: function () { return inquiry_activity_1.INQUIRY_HANDLING; } });
9
+ const auth_base_1 = require("@things-factory/auth-base");
10
+ const worklist_1 = require("@things-factory/worklist");
11
+ const attachment_reader_1 = require("./attachment-reader");
12
+ const inquiry_activity_2 = require("./inquiry-activity");
13
+ const role_tasks_1 = require("./role-tasks");
14
+ for (const task of role_tasks_1.ROLE_TASKS)
15
+ (0, auth_base_1.registerRoleTask)(task);
16
+ (0, attachment_reader_1.registerInquiryFiles)();
17
+ /*
18
+ * Importing this file registers the handlers' to-do (ADR-0184 decision 7) - a bootstrap hook would be too late for
19
+ * worklist to find it. Which domains have it is the application's call: it installs `INQUIRY_ACTIVITY`.
20
+ */
21
+ worklist_1.ActivityInstallations.installActivityTemplate(inquiry_activity_2.INQUIRY_ACTIVITY);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;;AAAA,oDAAyB;AACzB,uDAAuE;AAA9D,oHAAA,gBAAgB,OAAA;AAAE,oHAAA,gBAAgB,OAAA;AAE3C,yDAA4D;AAC5D,uDAAgE;AAEhE,2DAA0D;AAC1D,yDAAqD;AACrD,6CAAyC;AAEzC,KAAK,MAAM,IAAI,IAAI,uBAAU;IAAE,IAAA,4BAAgB,EAAC,IAAI,CAAC,CAAA;AACrD,IAAA,wCAAoB,GAAE,CAAA;AAEtB;;;GAGG;AACH,gCAAqB,CAAC,uBAAuB,CAAC,mCAAuB,CAAC,CAAA","sourcesContent":["export * from './service'\nexport { INQUIRY_ACTIVITY, INQUIRY_HANDLING } from './inquiry-activity'\n\nimport { registerRoleTask } from '@things-factory/auth-base'\nimport { ActivityInstallations } from '@things-factory/worklist'\n\nimport { registerInquiryFiles } from './attachment-reader'\nimport { INQUIRY_ACTIVITY } from './inquiry-activity'\nimport { ROLE_TASKS } from './role-tasks'\n\nfor (const task of ROLE_TASKS) registerRoleTask(task)\nregisterInquiryFiles()\n\n/*\n * Importing this file registers the handlers' to-do (ADR-0184 decision 7) - a bootstrap hook would be too late for\n * worklist to find it. Which domains have it is the application's call: it installs `INQUIRY_ACTIVITY`.\n */\nActivityInstallations.installActivityTemplate(INQUIRY_ACTIVITY as any)\n"]}
@@ -0,0 +1,38 @@
1
+ export declare const INQUIRY_HANDLING = "Inquiry Handling";
2
+ export declare const INQUIRY_ACTIVITY: {
3
+ name: string;
4
+ label: string;
5
+ description: string;
6
+ guide: string[];
7
+ release: string;
8
+ provider: string;
9
+ category: string;
10
+ activityType: string;
11
+ priority: number;
12
+ startingType: string;
13
+ multiple: string;
14
+ uiType: string;
15
+ uiSource: string;
16
+ searchKeys: {
17
+ name: string;
18
+ description: string;
19
+ inputKey: string;
20
+ tKey: string;
21
+ }[];
22
+ viewType: string;
23
+ viewSource: string;
24
+ model: {
25
+ name: string;
26
+ description: string;
27
+ tag: string;
28
+ hidden: boolean;
29
+ mandatory: boolean;
30
+ inout: string;
31
+ type: string;
32
+ options: {};
33
+ unit: any;
34
+ quantifier: number[];
35
+ spec: {};
36
+ }[];
37
+ standardTime: number;
38
+ };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INQUIRY_ACTIVITY = exports.INQUIRY_HANDLING = void 0;
4
+ /*
5
+ * 문의 처리 (ADR-0184 decision 7) - not an approval: while an inquiry waits on the handlers, one case of this activity is
6
+ * open, pooled on the roles that give inquiry handling. It shows the inquiry through this module's own element
7
+ * (`inquiry-todo`), which opens it; answering, deciding or closing the inquiry closes the case.
8
+ *
9
+ * Data only. An application installs it into its domains (Office `REQUIRED_ACTIVITIES`).
10
+ */
11
+ exports.INQUIRY_HANDLING = 'Inquiry Handling';
12
+ exports.INQUIRY_ACTIVITY = {
13
+ name: exports.INQUIRY_HANDLING,
14
+ label: 'inquiry handling',
15
+ description: 'Answering a question, a bug report or a feature proposal',
16
+ guide: [
17
+ 'while an inquiry waits on the handlers, one case is open for the roles that give inquiry handling - whoever of them picks it.',
18
+ 'it opens the inquiry; answering it, deciding a proposal or closing it closes the case.',
19
+ 'the writer replying to an answer opens a new case.'
20
+ ],
21
+ release: '1.0.0',
22
+ provider: 'hatiolab.com',
23
+ category: 'support',
24
+ activityType: 'user',
25
+ priority: 2,
26
+ startingType: 'issue',
27
+ multiple: 'single',
28
+ uiType: 'custom-element',
29
+ uiSource: 'inquiry-todo',
30
+ searchKeys: [{ name: 'inquiryId', description: 'The inquiry', inputKey: 'inquiryId', tKey: 'field.subject' }],
31
+ viewType: '',
32
+ viewSource: '',
33
+ model: [
34
+ { name: 'inquiryId', description: 'The inquiry this to-do answers', tag: 'inquiryId', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} }
35
+ ],
36
+ standardTime: 3 * 24 * 60 * 60
37
+ };
38
+ //# sourceMappingURL=inquiry-activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inquiry-activity.js","sourceRoot":"","sources":["../server/inquiry-activity.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACU,QAAA,gBAAgB,GAAG,kBAAkB,CAAA;AAErC,QAAA,gBAAgB,GAAG;IAC9B,IAAI,EAAE,wBAAgB;IACtB,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,0DAA0D;IACvE,KAAK,EAAE;QACL,+HAA+H;QAC/H,wFAAwF;QACxF,oDAAoD;KACrD;IACD,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,SAAS;IACnB,YAAY,EAAE,MAAM;IACpB,QAAQ,EAAE,CAAC;IACX,YAAY,EAAE,OAAO;IACrB,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,gBAAgB;IACxB,QAAQ,EAAE,cAAc;IACxB,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAC7G,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;IACd,KAAK,EAAE;QACL,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,gCAAgC,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;KACvM;IACD,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;CAC/B,CAAA","sourcesContent":["/*\n * 문의 처리 (ADR-0184 decision 7) - not an approval: while an inquiry waits on the handlers, one case of this activity is\n * open, pooled on the roles that give inquiry handling. It shows the inquiry through this module's own element\n * (`inquiry-todo`), which opens it; answering, deciding or closing the inquiry closes the case.\n *\n * Data only. An application installs it into its domains (Office `REQUIRED_ACTIVITIES`).\n */\nexport const INQUIRY_HANDLING = 'Inquiry Handling'\n\nexport const INQUIRY_ACTIVITY = {\n name: INQUIRY_HANDLING,\n label: 'inquiry handling',\n description: 'Answering a question, a bug report or a feature proposal',\n guide: [\n 'while an inquiry waits on the handlers, one case is open for the roles that give inquiry handling - whoever of them picks it.',\n 'it opens the inquiry; answering it, deciding a proposal or closing it closes the case.',\n 'the writer replying to an answer opens a new case.'\n ],\n release: '1.0.0',\n provider: 'hatiolab.com',\n category: 'support',\n activityType: 'user',\n priority: 2,\n startingType: 'issue',\n multiple: 'single',\n uiType: 'custom-element',\n uiSource: 'inquiry-todo',\n searchKeys: [{ name: 'inquiryId', description: 'The inquiry', inputKey: 'inquiryId', tKey: 'field.subject' }],\n viewType: '',\n viewSource: '',\n model: [\n { name: 'inquiryId', description: 'The inquiry this to-do answers', tag: 'inquiryId', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} }\n ],\n standardTime: 3 * 24 * 60 * 60\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { RoleTask } from '@things-factory/auth-base';
2
+ export declare const ROLE_TASKS: RoleTask[];
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /*
3
+ * The work this module names, for the seats applications build (ADR-0139 decision 11).
4
+ *
5
+ * Writing an inquiry, and reading one's own and the open ones, is no task: anyone signed in to the domain asks
6
+ * (ADR-0184 decision 6). Taking, answering, deciding where one stands and reading the private ones is
7
+ * `inquiry.answering`.
8
+ *
9
+ * Data only - `server/index.ts` registers it - so an application's tests read it without starting the framework.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ROLE_TASKS = void 0;
13
+ exports.ROLE_TASKS = [{ id: 'inquiry.answering', grants: [{ category: 'inquiry', axes: ['mutation'] }] }];
14
+ //# sourceMappingURL=role-tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-tasks.js","sourceRoot":"","sources":["../server/role-tasks.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIU,QAAA,UAAU,GAAe,CAAC,EAAE,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA","sourcesContent":["/*\n * The work this module names, for the seats applications build (ADR-0139 decision 11).\n *\n * Writing an inquiry, and reading one's own and the open ones, is no task: anyone signed in to the domain asks\n * (ADR-0184 decision 6). Taking, answering, deciding where one stands and reading the private ones is\n * `inquiry.answering`.\n *\n * Data only - `server/index.ts` registers it - so an application's tests read it without starting the framework.\n */\n\nimport type { RoleTask } from '@things-factory/auth-base'\n\nexport const ROLE_TASKS: RoleTask[] = [{ id: 'inquiry.answering', grants: [{ category: 'inquiry', axes: ['mutation'] }] }]\n"]}
@@ -0,0 +1,7 @@
1
+ export * from './inquiry/inquiry';
2
+ export * from './inquiry/inquiry-rules';
3
+ export { INQUIRY_REF_TYPE, INQUIRY_REPLY_REF_TYPE, visibleInquiry } from './inquiry/inquiry-service';
4
+ export declare const entities: (typeof import("./inquiry/inquiry").Inquiry | typeof import("./inquiry/inquiry").InquiryReply)[];
5
+ export declare const schema: {
6
+ resolverClasses: (typeof import("./inquiry/inquiry-resolver").InquiryResolver | typeof import("./inquiry/inquiry-resolver").InquiryReplyResolver)[];
7
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.schema = exports.entities = exports.visibleInquiry = exports.INQUIRY_REPLY_REF_TYPE = exports.INQUIRY_REF_TYPE = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /* EXPORT ENTITY TYPES */
6
+ tslib_1.__exportStar(require("./inquiry/inquiry"), exports);
7
+ tslib_1.__exportStar(require("./inquiry/inquiry-rules"), exports);
8
+ var inquiry_service_1 = require("./inquiry/inquiry-service");
9
+ Object.defineProperty(exports, "INQUIRY_REF_TYPE", { enumerable: true, get: function () { return inquiry_service_1.INQUIRY_REF_TYPE; } });
10
+ Object.defineProperty(exports, "INQUIRY_REPLY_REF_TYPE", { enumerable: true, get: function () { return inquiry_service_1.INQUIRY_REPLY_REF_TYPE; } });
11
+ Object.defineProperty(exports, "visibleInquiry", { enumerable: true, get: function () { return inquiry_service_1.visibleInquiry; } });
12
+ /* IMPORT ENTITIES AND RESOLVERS */
13
+ const inquiry_1 = require("./inquiry");
14
+ exports.entities = [
15
+ /* ENTITIES */
16
+ ...inquiry_1.entities
17
+ ];
18
+ exports.schema = {
19
+ resolverClasses: [
20
+ /* RESOLVER CLASSES */
21
+ ...inquiry_1.resolvers
22
+ ]
23
+ };
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yBAAyB;AACzB,4DAAiC;AACjC,kEAAuC;AACvC,6DAAoG;AAA3F,mHAAA,gBAAgB,OAAA;AAAE,yHAAA,sBAAsB,OAAA;AAAE,iHAAA,cAAc,OAAA;AAEjE,mCAAmC;AACnC,uCAAsF;AAEzE,QAAA,QAAQ,GAAG;IACtB,cAAc;IACd,GAAG,kBAAe;CACnB,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACtB,GAAG,mBAAgB;KACpB;CACF,CAAA","sourcesContent":["/* EXPORT ENTITY TYPES */\nexport * from './inquiry/inquiry'\nexport * from './inquiry/inquiry-rules'\nexport { INQUIRY_REF_TYPE, INQUIRY_REPLY_REF_TYPE, visibleInquiry } from './inquiry/inquiry-service'\n\n/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as InquiryEntities, resolvers as InquiryResolvers } from './inquiry'\n\nexport const entities = [\n /* ENTITIES */\n ...InquiryEntities\n]\n\nexport const schema = {\n resolverClasses: [\n /* RESOLVER CLASSES */\n ...InquiryResolvers\n ]\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { Inquiry, InquiryReply } from './inquiry';
2
+ import { InquiryReplyResolver, InquiryResolver } from './inquiry-resolver';
3
+ export declare const entities: (typeof Inquiry | typeof InquiryReply)[];
4
+ export declare const resolvers: (typeof InquiryResolver | typeof InquiryReplyResolver)[];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolvers = exports.entities = void 0;
4
+ const inquiry_1 = require("./inquiry");
5
+ const inquiry_resolver_1 = require("./inquiry-resolver");
6
+ exports.entities = [inquiry_1.Inquiry, inquiry_1.InquiryReply];
7
+ exports.resolvers = [inquiry_resolver_1.InquiryResolver, inquiry_resolver_1.InquiryReplyResolver];
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/inquiry/index.ts"],"names":[],"mappings":";;;AAAA,uCAAiD;AACjD,yDAA0E;AAE7D,QAAA,QAAQ,GAAG,CAAC,iBAAO,EAAE,sBAAY,CAAC,CAAA;AAClC,QAAA,SAAS,GAAG,CAAC,kCAAe,EAAE,uCAAoB,CAAC,CAAA","sourcesContent":["import { Inquiry, InquiryReply } from './inquiry'\nimport { InquiryReplyResolver, InquiryResolver } from './inquiry-resolver'\n\nexport const entities = [Inquiry, InquiryReply]\nexport const resolvers = [InquiryResolver, InquiryReplyResolver]\n"]}
@@ -0,0 +1,29 @@
1
+ import type { FileUpload } from 'graphql-upload/GraphQLUpload.js';
2
+ import { Attachment } from '@things-factory/attachment-base';
3
+ import { User } from '@things-factory/auth-base';
4
+ import { ListParam } from '@things-factory/shell';
5
+ import { Inquiry, InquiryReply } from './inquiry';
6
+ import { InquiryInput, InquiryList, InquirySummary } from './inquiry-types';
7
+ export declare class InquiryResolver {
8
+ inquiries(params: ListParam, scope: string, context: ResolverContext): Promise<InquiryList>;
9
+ inquiry(id: string, context: ResolverContext): Promise<Inquiry | undefined>;
10
+ inquirySummary(context: ResolverContext): Promise<InquirySummary>;
11
+ createInquiry(input: InquiryInput, attachments: FileUpload[], context: ResolverContext): Promise<Inquiry>;
12
+ replyInquiry(id: string, body: string, answer: boolean, attachments: FileUpload[], context: ResolverContext): Promise<Inquiry>;
13
+ moveInquiry(id: string, status: string, reason: string, context: ResolverContext): Promise<Inquiry>;
14
+ takeInquiry(id: string, context: ResolverContext): Promise<Inquiry>;
15
+ readInquiry(id: string, context: ResolverContext): Promise<Inquiry>;
16
+ replies(one: Inquiry): Promise<InquiryReply[]>;
17
+ attachments(one: Inquiry, context: ResolverContext): Promise<Attachment[]>;
18
+ mine(one: Inquiry, context: ResolverContext): boolean;
19
+ isNew(one: Inquiry, context: ResolverContext): boolean;
20
+ canReply(one: Inquiry, context: ResolverContext): Promise<boolean>;
21
+ asHandler(one: Inquiry, context: ResolverContext): Promise<boolean>;
22
+ moves(one: Inquiry, context: ResolverContext): Promise<string[]>;
23
+ creator(one: Inquiry): Promise<User | null>;
24
+ assignee(one: Inquiry): Promise<User | null>;
25
+ }
26
+ export declare class InquiryReplyResolver {
27
+ attachments(one: InquiryReply, context: ResolverContext): Promise<Attachment[]>;
28
+ creator(one: InquiryReply): Promise<User | null>;
29
+ }